Arts and Sciences, Irving K. Barber School of (Okanagan)
Computer Science, Mathematics, Physics and Statistics, Department of (Okanagan)
DSpace
UBCO
Kudla-Hooper, Michael William
Master of Science - MSc
University of British Columbia
Treatment of vaginal and post-operative locally recurrent endometrial cancers is challenging with currently available commercial High Dose Rate Brachytherapy (HDRBT) applicators. A novel concept, the patient specific cylinder template (PSCT) has been developed to address these challenges. The PSCT is produced in-house using an automated design and 3D printing workflow, which utilizes custom scripts interfacing with both treatment planning and modelling software to create 3D models for 3D printing PSCTs. The workflow and template were tested using images and treatment plans for two patients previously treated using a combination of vaginal cylinder and interstitial catheters. New catheter arrangements were planned using geometries achievable with a PSCT. A template was then modelled and 3D printed, a mock insertion was completed in a gel phantom, and a post-insertion CT scan was completed. These images were registered to the patient images, the final catheter positions were digitized, and a final plan was created. Inserted re-optimized treatment plans demonstrated competitive tumour coverage, while maintaining doses to organs at risk, within acceptable limits. Catheters were inserted with sufficient accuracy to achieve a plan clinically equivalent to the pre-insertion plan, with much greater ease as compared to freehand or perineal template methods. The PSCT, while requiring further development and clinical trials, stands to be a preferable alternative to current HDRBT methods for patients with vaginal and post-operative locally recurrent endometrial cancers.
CUSTOM TEMPLATE DESIGN AND MANUFACTURE AUTOMATION FOR INTERSTITIAL GYNECOLOGICAL BRACHYTHERAPY by Michael William Kudla-Hooper B.Sc., Physics, Walla Walla University, 2014 BSE, Mechanical Engineering, Walla Walla University, 2014 A THESIS SUBMITTED IN PARTIAL FULFILLMENT OF THE REQUIREMENTS FOR THE DEGREE OF MASTER OF SCIENCE in THE COLLEGE OF GRADUATE STUDIES (Medical Physics) THE UNIVERSITY OF BRITISH COLUMBIA (Okanagan) September 2019 © Michael William Kudla-Hooper, 2019 ii The following individuals certify that they have read, and recommend to the College of Graduate Studies for acceptance, a thesis/dissertation entitled: Custom Template Design and Manufacture Automation for Interstitial Gynecological Brachytherapy submitted by Michael William Kudla-Hooper in partial fulfillment of the requirements of the degree of Master of Science. Deidre Batchelar, IKBSAS - Physics & BC Cancer Kelowna Supervisor Andrew Jirasek, IKBSAS - Physics Supervisory Committee Member Danielle Anderson, IKBSAS - Physics & BC Cancer Kelowna Supervisory Committee Member Ingrid Spadinger, UBC Faculty of Medicine & BC Cancer Vancouver University Examiner iii Abstract Treatment of vaginal and post-operative locally recurrent endometrial cancers is challenging with currently available commercial High Dose Rate Brachytherapy (HDRBT) applicators. A novel concept, the patient specific cylinder template (PSCT) has been developed to address these challenges. The PSCT is produced in-house using an automated design and 3D printing workflow, which utilizes custom scripts interfacing with both treatment planning and modelling software to create 3D models for 3D printing PSCTs. The workflow and template were tested using images and treatment plans for two patients previously treated using a combination of vaginal cylinder and interstitial catheters. New catheter arrangements were planned using geometries achievable with a PSCT. A template was then modelled and 3D printed, a mock insertion was completed in a gel phantom, and a post-insertion CT scan was completed. These images were registered to the patient images, the final catheter positions were digitized, and a final plan was created. Inserted re-optimized treatment plans demonstrated competitive tumour coverage, while maintaining doses to organs at risk, within acceptable limits. Catheters were inserted with sufficient accuracy to achieve a plan clinically equivalent to the pre-insertion plan, with much greater ease as compared to freehand or perineal template methods. The PSCT, while requiring further development and clinical trials, stands to be a preferable alternative to current HDRBT methods for patients with vaginal and post-operative locally recurrent endometrial cancers. iv Lay Summary The treatment of vaginal cancers using high dose rate brachytherapy is difficult with currently available clinical tools. A new treatment device to address these difficulties has been developed. A design software and 3D printing based manufacturing workflow for these devices has also been developed. These devices and the workflow have been initially tested to assess the developments. In this thesis, the novel device is described in detail, including important design decisions made for the device. The software and 3D printing based manufacturing workflow is also detailed. In addition, some experiments have been conducted and are described, which assess the performance of the device on a gel phantom. The tests indicate that the device may be able to be useful in a clinical setting, though certain challenges are described, which will require future work for the device before it can be used in the clinical setting. v Preface This work was completed by Michael Kudla-Hooper. Deidre Batchelar provided guidance and vision throughout the project, as well as significant feedback for research activities. Danielle Anderson provided valuable research feedback throughout the project. Dr.âs Francois Bachand, Jocelyn Moore, and Juanita Crook each provided treatment plan feedback and practical clinical guidance. Ethics approval was obtained from the UBC BC Cancer Research Ethics Board for use of anonymized patient information, REB Number H19-00723. Figure 3.1 is reprinted with permission of AON3D. vi Table of Contents Abstract ................................................................................................................................................. iii Lay Summary ........................................................................................................................................ iv Preface .................................................................................................................................................... v Table of Contents .................................................................................................................................. vi List of Tables....................................................................................................................................... viii List of Figures ....................................................................................................................................... ix List of Acronyms................................................................................................................................... xi Acknowledgements .............................................................................................................................. xii Dedication ........................................................................................................................................... xiii Introduction .................................................................................................................... 1 Chapter 1:1.1 Vaginal Cancers and Their Treatment ................................................................................... 1 1.2 Interstitial High Dose Rate Brachytherapy Treatment for Vaginal Cancers .......................... 2 Clinical HDR Brachytherapy ......................................................................................... 2 1.2.1 Limitations of Interstitial Brachytherapy for Gynecological Cancers ........................... 4 1.2.21.3 Patient Specific Cylinder Templates â A Novel Approach .................................................... 6 1.4 Thesis Scope ........................................................................................................................... 7 Chapter 2: Background ................................................................................................... 7 1.4.1 Chapter 3: Materials and Methods ................................................................................. 7 1.4.2 Chapter 4: Results and Discussion ................................................................................. 8 1.4.3 Chapter 5: Future Work .................................................................................................. 8 1.4.4 Background .................................................................................................................... 9 Chapter 2:2.1 High Dose Rate Brachytherapy Physics ................................................................................. 9 Ionizing Radiation .......................................................................................................... 9 2.1.12.2 Radioactive Decay ............................................................................................................... 10 2.3 Interactions of Radiation with Matter .................................................................................. 13 Radiation Dose ............................................................................................................. 14 2.3.12.4 Radiation Therapy ................................................................................................................ 16 Principles of Radiation Therapy ................................................................................... 16 2.4.1 High Dose Rate Brachytherapy for Gynecological Cancers ........................................ 17 2.4.2 Imaging for HDR Brachytherapy ................................................................................. 20 2.4.3 Patient Experience for Interstitial HDRBT .................................................................. 21 2.4.42.5 3D Printing ........................................................................................................................... 22 Fused Deposition Modeling ......................................................................................... 22 2.5.1 3D Printing for Medical Applications .......................................................................... 24 2.5.22.6 Application Programming Interfaces ................................................................................... 25 Eclipse Scripting Application Programming Interface................................................. 25 2.6.1 Solidworks Application Programming Interface .......................................................... 25 2.6.2 Materials and Methods ................................................................................................. 26 Chapter 3:3.1 Material Selection ................................................................................................................ 26 Materials Requirements ................................................................................................ 26 3.1.1 Materials Survey and Material Selection ..................................................................... 27 3.1.23.2 3D Printer Selection ............................................................................................................. 28 3D Printer Requirements .............................................................................................. 28 3.2.1 Comparison of Commercially Available 3D Printers .................................................. 28 3.2.2 3D Printer Selection ..................................................................................................... 29 3.2.33.3 Cylinder Template Design ................................................................................................... 29 Cylinder Template Design Requirements .................................................................... 30 3.3.1vii PSCT Design Details .................................................................................................... 33 3.3.23.4 Code ..................................................................................................................................... 35 Code Design Requirements .......................................................................................... 35 3.4.1 ESAPI Cylinder Information Exporter ......................................................................... 37 3.4.2 Cylinder Applicator Creator ......................................................................................... 40 3.4.3 Cylinder Applicator Source Position Exporter (CASPE) ............................................. 42 3.4.4 Cylinder Applicator Source Position Comparator (CASPC) ....................................... 43 3.4.5 Summary ...................................................................................................................... 44 3.4.63.5 Geometric and Insertion Validation of 3D Printed PSCTâs ................................................. 45 Experimental Design .................................................................................................... 47 3.5.13.6 Chapter Summary ................................................................................................................. 51 Materials Selection ....................................................................................................... 51 3.6.1 3D Printer Selection ..................................................................................................... 51 3.6.2 Cylinder Applicator Design ......................................................................................... 52 3.6.3 Code ............................................................................................................................. 52 3.6.4 Validation Testing ........................................................................................................ 52 3.6.5 Results and Discussion ................................................................................................. 54 Chapter 4:4.1 Results .................................................................................................................................. 54 Dosimetry Assessment ................................................................................................. 54 4.1.1 Caliper Measurements .................................................................................................. 58 4.1.2 Geometric Accuracy Assessment ................................................................................. 58 4.1.34.2 Discussion ............................................................................................................................ 59 Treatment Planning with the PSCT .............................................................................. 59 4.2.1 3D Printer Efficacy....................................................................................................... 59 4.2.2 Insertion Inaccuracy Effects on Treatment Quality ..................................................... 59 4.2.34.3 Conclusion............................................................................................................................ 60 Future Work ................................................................................................................. 62 Chapter 5:5.1 Catheter Trajectory Assessment in Tissue Representative Phantom ................................... 62 5.2 Dosimetric Characterization of 3D Printed PEEK materials ............................................... 63 5.3 Software Development ......................................................................................................... 64 5.4 Workflow Development ....................................................................................................... 64 5.5 Quality Assurance Procedure Development......................................................................... 64 5.6 Other Applicators ................................................................................................................. 65 Bibliography ......................................................................................................................................... 66 Appendix A: High Temperature 3D Printer Comparison .................................................................... 68 Appendix B: ESAPI Cylinder Information Exporter Code .................................................................. 69 Appendix C: Cylinder Applicator Creator ........................................................................................... 79 Appendix D: Cylinder Applicator Source Position Exporter (CASPE) Code ................................... 108 Appendix E: Cylinder Applicator Source Position Comparator (CASPC) Code ............................... 119 viii List of Tables Table 1: Test Patient 1 selected plan dosimetry values for the patients actual treated plan, the PSCT pre-plan, inserted plan, and re-optimized treatment plan. Prescribed dose per fraction is 800cGy for 4 fractions. ............................................................................................................................................... 55 Table 2: Test Patient 2 selected plan dosimetry values for the patientsâ actual treated plan, the PSCT pre-plan, inserted plan, and re-optimized treatment plan. Prescribed dose per fraction is 600cGy for 4 fractions. ............................................................................................................................................... 56 Table 3: Test patient 1 inserted and re-optimized plan comparisons to treated plan. .......................... 56 Table 4: Test patient 2 inserted and re-optimized plan comparisons to treated plan. .......................... 56 Table 5: Test patient 1 inserted and re-optimized plan comparisons to preplan. ................................. 57 Table 6: Test patient 2 inserted and re-optimized plan comparisons to preplan. ................................. 57 Table 7: For each 3D printed PSCT, the diameter was measured in three places and the overall length is measured. The measured values are all within 0.8mm. .................................................................... 58 Table 8: The estimated source position displacement for each PSCT tested is determined by the digitization of the final catheter position after insertion, compared to the plan position. .................... 58 Table 9: The number of interstitial and intracavitary catheters, total catheters, and total interstitial length are shown. Notably, the PSCT plans resulted in decreased numbers of catheters, and total interstitial length................................................................................................................................... 58 ix List of Figures Figure 1.1: Computed Tomography scan of pelvic anatomy. The rectum is shown in reddish-brown, sigmoid bowels in yellow, bladder in green, small bowel in purple. A treatment volume is shown in blue. A: Coronal view. B: Sagittal view. ................................................................................................ 2 Figure 1.2: Example of a cylindrical applicator with a single channel. ................................................. 3 Figure 1.3: A: Flexible interstitial catheter with locking collet. B: Locking Collet screw, used to tighten a catheter to a locking template. The collet bore compresses the catheter slightly as the collet is tightened into a template. ................................................................................................................... 3 Figure 1.4: Perineal Grid Template mounted on cylinder shaped rectal US device (described below). An interstitial catheter is inserted into the template. A: End View. B: Top View. C: Isometric View. . 4 Figure 1.5: CT (described below) image of the pelvic region of a female patient. An interstitial freehand catheter and a cylindrical applicator have been inserted into vaginal wall and vaginal cavity, respectively. The catheter can be seen diverging from the side of the applicator into an interstitial location. .................................................................................................................................................. 5 Figure 1.6: CT image of an example interstitial brachytherapy treatment. GTV, HRCTV, and 100% Isodose contours are shown in dark blue, light blue, and red, respectively. Green and pink arrows represent interstitial catheters. The top of the vaginal vault is not able to be sufficiently covered even with the combined use of freehand interstitial catheters and intracavitary applicators. ......................... 6 Figure 2.1: The types of radiation and their subcategories. In this chapter, electrons and gamma rays are discussed. Adapted from [15]. ........................................................................................................ 10 Figure 2.2: Decay scheme for Ir-192 into Pt-192 by beta minus decay and to Os-192 by electron capture. ................................................................................................................................................. 12 Figure 2.3: Common Photon Interactions with matter. Subscript terminology: i and f represent initial and final photons respectively, and the numbers 1, 2, and 3 represent the Compton, Photoelectric, and Raleigh effects, respectively. ............................................................................................................... 14 Figure 2.4: Example IR-192 Brachytherapy source used with an HDR Afterloader. Dimensions are approximate. ......................................................................................................................................... 17 Figure 2.5: Commercial HDRBT Afterloader. Source channels are shown on the front of the unit. .. 18 Figure 2.6: A: An MRI scan slice of the pelvic region with a vaginal cylinder applicator inserted. B: A CT scan of the same patient. The CT scan has poorer soft tissue contrast, but improved applicator contrast, as compared to the MRI......................................................................................................... 20 Figure 2.7: A: Commercial US trolley with image display. B: Paddle shaped US transducer - side view. C: Paddle shaped US transducer - end view ............................................................................... 21 Figure 2.8: Treatment workflow for HDR Interstitial Brachytherapy for Vaginally Recurrent Endometrial Cancer at BC Cancer â Kelowna. .................................................................................... 22 Figure 2.9: A: 3D printing of a cylinder model. B: Magnified section showing individual layers. Each layer is ~0.3mm in height. .................................................................................................................... 23 Figure 3.1: AON - M2 3D Printer by AON3D. Reprinted with permission of AON3D. .................... 29 Figure 3.2: Example Drawings of Patient Specific Cylindrical Template ........................................... 31 Figure 3.3: The GUI for the Cylinder Applicator Exporter. ................................................................ 38 Figure 3.4: Cylinder Applicator Creator GUI ...................................................................................... 41 Figure 3.5: GUI for CASPC ................................................................................................................. 44 Figure 3.6: Current Freehand Interstitial Catheter and Cylinder HDR Brachytherapy Workflow ...... 46 Figure 3.7: Proposed PSCT HDR Brachytherapy Workflow............................................................... 47 Figure 3.8: Patient 1âs treated interstitial treatment plan. Blue shows HRCTV. Red shows HRCTV D90. Green/Pink shows the catheters. .................................................................................................. 48 Figure 3.9: Patient 2âs treated interstitial treatment plan. .................................................................... 48 Figure 3.10: General workflow of the A: treatment planning. B: CAD modelling, C: 3D printing, D: 3D print validation, and E: insertion of catheters into the PSCT in gel. .............................................. 50 x Figure 4.1: A and B: Patient 1âs cylinder and freehand interstitial treatment plan, A-P and Axial views respectively. C and D: Patient 1âs interstitial BT PSCT preplan, A-P and Axial views respectively. HRCTV contours are shown in light blue and the 100% Isodose line is shown in red. Interstitial needles are visible on the CT imagery, and are digitized in green and pink. ..................... 54 Figure 4.2: A and B: Patient 2âs cylinder and freehand interstitial treatment plan, A-P and Axial views respectively. C and D: Patient 2âs interstitial BT PSCT preplan, A-P and Axial views respectively. HRCTV contours are shown in light blue and the 100% Isodose line is shown in red. Interstitial needles are visible on the CT imagery, and are digitized in green and pink. ..................... 55 xi List of Acronyms 3D Three Dimensional ABS Acrylonitrile Butadiene Styrene API Application Programming Interface BC British Columbia BT Brachytherapy C# C-Sharp (Programming Language) CAD Computer Assisted Drawing CASPC Cylindrical Applicator Source Position Comparator CASPE Cylindrical Applicator Source Position Exporter CT Computed Tomography D2cm3 Minimum Dose to the Maximally Irradiated 2cm3 of a Volume D90 Dose to 90% of a Volume EBRT External Beam Radiation Therapy ESAPI Eclipse Scripting API FDM Fused Deposition Modelling FFF Fused Filament Fabrication GTV Gross Tumour Volume GUI Graphical User Interface HDR High Dose Rate HRCTV High Risk Clinical Target Volume IBT Interstitial Brachytherapy IR-192 Iridium-192 MIFU Manufacturerâs Instructions for Use MRI Magnetic Resonance Imaging OAR Organ at Risk OR Operating Room PC Polycarbonate PDD Percent Depth Dose PDF Portable Document Format (filetype extension) PEEK Polyether Ether Ketone PLA Polylactic Acid PEI Polyetherimide PPSU Polyphenylsulfone PSCT Patient Specific Cylindrical Template QA Quality Assurance SLDPRT Solidworks Part File (filetype extension) STL Standard Tessellation Language US Ultrasound V100 Volume Receiving 100% of the Prescribed Dose XML Extensible Markup Language (filetype extension) xii Acknowledgements I would like to thank my family for all their continuous support. Thank you to my supervisor, Deidre, for all of our brainstorming conversations, for allowing me to pursue this research largely on my own terms, for the constant encouragement, and for keeping me on track. Iâd like to thank the UBCO Medical Physics group members for their openness to discuss ideas, help with problems, and give excellent feedback and advice. This work would also have not been possible without the participation of too many BC Cancer staff to count, in particular Dr. Francois Bachand, and Dr. Jocelyn Moore. Finally I thank my classmates, particularly Claire, Ramie, and Paul for their help, long conversations, and for keeping this process fun. xiii Dedication To my family. 1 Introduction Chapter 1:1.1 Vaginal Cancers and Their Treatment Cancers of the vagina include primary vaginal cancer and vaginal metastases. Primary vaginal cancer is defined as having arisen solely from the vagina. Vaginal metastases constitute the majority of vaginal malignancies and mostly come from the cervix, endometrium, or ovary, though they can come from the breast, rectum, pancreas, and other sites. Whether primary vaginal cancer or a metastasis, the malignancy can occur anywhere in the vagina [1]. Indications of gynecological cancers can include vaginal bleeding, unusual vaginal discharge, pelvic pain, dyspareunia, and post-coital bleeding [2]. Common vaginal cancers include recurrent endometrial cancer and primary vaginal cancer [3]. Endometrial cancers are typically treated by hysterectomy. While this treatment is intended to be curative, depending on the stage, the cancer will recur in up to 30% of patients [4]. This recurrence is commonly located in the vagina. Treatment options depend on the stage of the tumour; surgery and radiation therapy are known to be effective in the early stages, and radiation therapy alone is the primary treatment for later stages. Surgical interventions are commonly performed for early stage vaginal cancer, by a local excision of the tumour, total vaginectomy, and/or lymphadenectomy, depending on the case. These procedures may require vaginal reconstruction [1]. Chemotherapy is considered a standard treatment option for very early stage vaginal cancers, but is less common. Radiation therapy can be in the form of external beam radiation therapy (EBRT), or brachytherapy (BT). External beam radiation therapy involves the use of high energy photons or electrons generated outside of the patient and directed towards the treatment site. Brachytherapy is the placement of radioactive materials near or within the tumour. Intracavitary brachytherapy is the placement of the radiation source within an anatomical cavity, such as the vagina. Interstitial brachytherapy is the placement of the radiation source directly within tissue. Radiation therapy is a standard treatment for vaginal cancers for stage 1 and beyond, where a combination of external beam radiation therapy and brachytherapy or brachytherapy alone, is used [1]. Unfortunately, it is often difficult to determine differences in disease control rates for these treatment methods for vaginal cancer, as many have yet to be directly compared in randomized trials, and due to differences in patient selection, local expertise, and staging determinations. Further, local expertise often drives treatment options, as proficiency in both surgery and brachytherapy requires substantial expertise. 2 1.2 Interstitial High Dose Rate Brachytherapy Treatment for Vaginal Cancers High Dose Rate Brachytherapy (HDRBT) is used to treat a number of gynecological cancers, most frequently cervical, vaginal, and recurrent endometrial cancer [5]. These cancer types require accurate and repeatable treatments, as many nearby organs are at risk of severe damage or failure if they receive too high a dose [6], [7]. These organs include the rectum, sigmoid bowel, bladder, and small bowel (Figure 1.1). Patients identified as having these cancers will undergo a treatment process similar to that described in Section 1.2.1. Interstitial HDRBT treatment of the vagina is a treatment which relies on a multidisciplinary team of Oncologists, Medical Physicists, Radiation Therapists, Medical Imaging Technologists, Nurses, and Anesthesiologists. Multiple imaging systems are used for tumour and organ identification and treatment, and there are multiple tools and methods by which the treatment of these tumours is achieved. Clinical HDR Brachytherapy 1.2.11.2.1.1 Applicators for HDRBT Various intracavitary applicators (devices used to guide HDRBT sources to treatment locations, for predetermined amounts of âdwellâ times) are commercially available to facilitate HDRBT treatment within the vagina, cervix, and endometrium. Tools such as the Cylinder, Miami, Tandem and Ovoid/Ring applicators, and Bubble applicators [8] are used around the world. Varian and Elekta [9] are the major commercial suppliers in this market. These applicators come in many shapes and sizes, but are generally shaped so as to conform to the cavity geometry. Intracavitary HDRBT of the vagina is most often accomplished using a cylinder âstumpâ applicator (Figure 1.2). These applicators have Figure 1.1: Computed Tomography scan of pelvic anatomy. The rectum is shown in reddish-brown, sigmoid bowels in yellow, bladder in green, small bowel in purple. A treatment volume is shown in blue. A: Coronal view. B: Sagittal view. A B 3 only one longitudinal source channel, and therefore can only be used to deliver a dose distribution which is symmetric about the central channel. Alternatively, multi-channel cylinder applicators allow for non-symmetric dose distributions. Cylindrical intracavitary applicators are advantageous because they are simple to place, keeping operating room (OR) times low. When used as the only treatment applicators, cylinder applicators can be placed directly in the HDRBT treatment room, without the need of for anaesthetic. Interstitial catheter applicators, or catheters (Figure 1.3), are used when intracavitary applicators alone provide insufficient coverage of the treatment region, or would deliver unacceptable doses to OARs. These catheters can be inserted either via a grid template based method (Figure 1.4) or by freehand insertion (Figure 1.5). The grid template is used to guide a set of interstitial catheters through the perineum and into or very close to the tumour tissue. Interstitial catheters can also be inserted freehand, that is without template guidance, in cases where no suitable template exists, such as when the size of existing templates is not suitable or if the intended catheter paths are not perpendicular to the grid face. Freehand catheter placement involves the oncologist visualizing the tumour and placing the catheters into the tumour tissue from within the vaginal wall (Figure 1.5). Interstitial catheter insertion procedures are typically guided by some type of imaging, such as transrectal or transabdominal Ultrasound (US). Catheters are run through a locking template and locked, for example, using locking collets (Figure 1.3). Following insertion, the template is secured to Figure 1.2: Example of a cylindrical applicator with a single channel. A B Figure 1.3: A: Flexible interstitial catheter with locking collet. B: Locking Collet screw, used to tighten a catheter to a locking template. The collet bore compresses the catheter slightly as the collet is tightened into a template. 4 the patient, and if necessary, any intracavitary applicators will be inserted. In practice, a combination of both interstitial catheters and intracavitary applicators can be used for difficult treatments where intracavitary applicators alone will not suffice. This allows the operator to only place the interstitial catheters which are absolutely necessary, retaining the benefits of the ease of intracavitary applicator insertion. Limitations of Interstitial Brachytherapy for Gynecological Cancers 1.2.2While the devices mentioned above often provide clinically acceptable dose coverage, they have limitations. The main limitation of cylindrical applicators for HDRBT of the vagina is that they are unable to deliver a highly conformal dose distribution [10], [11]. This comes from a number of geometrical limitations of the device. Since the sources are located nearby but not within the tumour, and the dose distribution is symmetric, the dwell times of any given source position must be higher than that of an interstitial source position, thus increasing the dose to the whole region. Treating the central portion of the vaginal cavity for women who have had a total hysterectomy is also difficult. In this case, the intestines rest just above the vagina, and thus prescription-level doses to the top of the vagina from a cylindrical applicator result in high doses to the intestines as well. With current applicators, this limits the amount of dose that clinicians are willing to deliver to this area, which can result in insufficient dose coverage of the tumour to limit OAR toxicity. Figure 1.6 shows a CT image A B C Figure 1.4: Perineal Grid Template mounted on cylinder shaped rectal US device (described below). An interstitial catheter is inserted into the template. A: End View. B: Top View. C: Isometric View. 5 of a patientâs treatment plan. The HRCTV is unable to be adequately covered by the prescription dose. This is shown as the 100% isodose line (a contour representing where the dose is 100% of the prescription dose, inside the contour being higher in dose, and outside the contour being lower in dose) does not surround the HRCTV contour at the top of the vaginal vault. For treatments requiring IBT, freehand and interstitial template guided methods can provide increased conformal dose coverage [11], though the procedures can be daunting to attempt, and require practice to gain surgical proficiency. Freehand interstitial catheters require a very high level of operator expertise and confidence. Template based approaches are much easier to perform than freehand approaches, but they can result in increased interstitial catheter length, which is more invasive, more uncomfortable for the patient, and may result in increased trauma, such as bleeding. It is also well known that interstitial catheters tend to deflect in tissue, and this deflection increases with inserted length. Difficulty in repeatability of catheter placement can result in unpredictable day-to-day variations in catheter positioning and thus target coverage. Catheter locations can be verified and adjusted with Catheter tip extends into tissue Catheter enters vagina along intracavitary cylinder applicator Figure 1.5: CT (described below) image of the pelvic region of a female patient. An interstitial freehand catheter and a cylindrical applicator have been inserted into vaginal wall and vaginal cavity, respectively. The catheter can be seen diverging from the side of the applicator into an interstitial location. 6 feedback from US guidance, but with limited success. Further, all interstitial catheter-based HDRBT involves a risk of patient trauma and discomfort. Due to the uncertainties of interstitial catheter placement there is no guarantee that excellent target volume coverage can be achieved. These uncertainties can also result in doses to Organs at Risk (OARs) which are higher than or very close to recommended limits. Often a high number of catheters and long insertion lengths (either through the perineum or vaginal wall) are necessary to deliver adequately conformal coverage using current methods. 1.3 Patient Specific Cylinder Templates â A Novel Approach 3D printed, patient specific interstitial template rings have been created by other groups for the treatment of cervical cancer [12]. The novel device, the Patient Specific Cylinder Template (PSCT), is designed to allow the care team to pre-plan interstitial catheter orientations and insert them to their pre-planned positions in an easy, repeatable manner for the treatment of vaginal cancers. If pre-operative planning is reliably achieved in the patient, this could result in improved tumour dose coverage with lower doses to OARs. This is advantageous as the complications to OARs are highly dependent on dose delivered to the organ [13]. Test plans created using the PSCT have resulted in comparable or improved treatment plans, resulting in increased doses to High Risk Control Tumour Volumes (HRCTV) such as volume receiving 100% of dose (V100%) and the dose to 90% of the volume (D90%). The rese plans also maintained OAR doses, such as minimum dose to the maximally Figure 1.6: CT image of an example interstitial brachytherapy treatment. GTV, HRCTV, and 100% Isodose contours are shown in dark blue, light blue, and red, respectively. Green and pink arrows represent interstitial catheters. The top of the vaginal vault is not able to be sufficiently covered even with the combined use of freehand interstitial catheters and intracavitary applicators. HRCTV (light blue) is not sufficiently covered by 100% isodose (red) 7 irradiated 2 cm3 (D2cm3) within limits. Initial data suggests that these templates are capable of guiding catheters to preplanned positions in gel models per oncologist feedback. The current design and workflow can be improved upon, as these results are only based on simplified preliminary tests. In addition, the total length and number of interstitial catheters in many cases is substantially reduced, which could potentially improve patient comfort and OR time. These 3D printable patient specific applicators provide increased flexibility over current commercial applicators, allowing radiation dose distributions to be achieved similar to those obtained through use of freehand interstitial catheters, but without requiring the same skill level required to achieve freehand placement of such catheters. The innovation also includes a partially automated design and manufacturing workflow to create PSCTs useful for the treatment of cancer by brachytherapy. 1.4 Thesis Scope This thesis is organized to describe in detail work which has been done to develop a patient specific cylindrical template for interstitial gynecological brachytherapy, and a software and clinical workflow which facilitates the manufacture of this template to be used within a clinic. The next chapters describe in detail the background of the research, the materials and methods of the research, the results, and concluding thoughts. Chapter 2: Background 1.4.1Having introduced the major relevant topics of this thesis, the next chapter describes in detail the relevant physics and clinical practices of radiation therapy generally, focusing on high dose rate brachytherapy, 3D printing fundamentals, high temperature 3D printing, the applications used for this project, and the major considerations of the project. This section is intended to give the reader sufficient background on the relevant technologies and disciplines used in this project, and to serve as a reference while reading later sections. Chapter 3: Materials and Methods 1.4.2Once the background for the project is described, the Materials and Methods chapter describes the main body of work completed during this project. The chapter is organized in a manner which outlines the thought process used to make design decisions, sorted by the technologies developed, and then the tests used to validate these technologies. This allows for the major design decisions such as materials selection, 3D printer selection, template design, code development, and testing, to be described as independent subprojects. 8 Chapter 4: Results and Discussion 1.4.3The results and discussion chapter presents the current capabilities of the technologies developed, and presents the results of the tests conducted. Discussion topics including future directions, existing limitations of the solution, and proposed mitigations, are covered. Chapter 5: Future Work 1.4.4Future work is focused on moving the project to a clinical trial. This includes sterilization validation of the PSCT, dosimetric characterization of PEEK materials, and testing of the template on phantoms . which are mechanically and geometrically similar to patient anatomy 9 Background Chapter 2:This project intends to improve upon a specific type of medical intervention, bringing together a diverse set of technologies and sub-fields. In this chapter, the necessary background information of radiation therapy physics for High Dose Rate Brachytherapy (HDRBT), the treatment techniques for HDRBT for gynecological cancers, three-dimensional (3D) printing in medicine, and scripting applications used for the project are introduced. 2.1 High Dose Rate Brachytherapy Physics Radiation Therapy (RT) Physics is a sub-field of physics including the types and properties of ionizing radiation which can be used in radiation therapy, a commonly used cancer treatment [14]. In this section, certain types of radiation, relevant interactions of this radiation with matter, radioactive decay, and a brief description of radiation dose are described. The intent of this section is to give a brief background to the fundamental physics principles of HDRBT. Ionizing Radiation 2.1.1Radiation can be divided into two subcategories: Ionizing Radiation and Non-Ionizing Radiation (Figure 2.1). Ionizing Radiation is radiation which has enough energy to cause an ionization of tightly bound electrons from an atom. Non-Ionizing Radiation is any type of radiation with energy below this threshold [15]. For the purposes of this work, only Ionizing Radiation relevant to HDRBT is introduced. 10 2.2 Radioactive Decay Radioactive decay is a naturally occurring process in which an unstable parent nucleus transforms into one or more daughter nuclei, while emitting some type of radiation [15]. The energy involved in a decay event is dependent on the parent and daughter nuclei, which determine the radiated particles and decay type. This energy is imparted to the charged and uncharged daughter products as kinetic energy, and/or to electromagnetic radiation such as X-rays, gamma rays, and others. Emitted radiation can be useful for various medical applications, including treatment of cancer, i.e. radiation therapy [15]. For HDRBT applications, it is important that the radioactive sources be useful for as long a period of time as possible, for economic reasons. For this reason, the half-life of a radioactive source is an important metric for source selection. The half-life of a source is the amount of time that it will take for fifty percent of the parent material to have decayed into daughter products. A longer half-life is preferable for HDRBT materials, so as to minimize the number of radioactive source replacements and disposals. Other important considerations include the energies and types of radiation emitted, cost of manufacture of the source, radiation protection requirements, that the radiated products are not toxic, and high specific activity (number of decays per second per kilogram). Figure 2.1: The types of radiation and their subcategories. In this chapter, electrons and gamma rays are discussed. Adapted from [15]. 11 Currently, Iridium â 192 (Ir-192) is the most common isotope used as the radioactive source for HDRBT. Below, the types of radioactive decay relevant to Ir-192 are discussed. Electron Capture Electron capture is the capture of a shell electron by an atomic nucleus, causing a proton to neutron transformation. Thus, the atomic number of the daughter nucleus will be one less than the parent nucleus, and the atomic mass number will remain the same [15]. The generic equation is:  +  â   +  + 2.1 where A is the mass number, Z is the atomic number, is the parent element,  is an electron,  is the daughter element,  is a neutrino, and  is a photon. Beta Minus Decay Beta minus decay occurs when a nucleus transforms a neutron into a proton, emitting an electron and an antineutrino. The atomic number of the daughter nucleus will be one greater than the parent nucleus, and the atomic mass number remains the same [15]. The generic equation is:  â  +   +  + 2.2 where Ì  represents an antineutrino. Gamma Ray ( -ray) Emissions Gamma Ray emissions, or nuclear de-excitation gamma decays, can occur following (but are often included as part of) radioactive decays, as described above. In the case of both the electron capture and beta minus decay events described above, immediately following the decay event, the daughter nuclei are unstable. A series of energy level structure changes will occur very quickly (on the order of 10-12s after these events), each resulting in the emission of a -ray. The generic equation for the -decays is: â â  + +  2.3 where â is the daughter nucleus of the previous radioactive decay (electron capture or beta minus in this case), which is also the parent nucleus for this decay.  is the daughter nucleus for the  decay,  represents the gamma ray, and  represents the decay energy of this emission. The energy is imparted both into the -ray and into the daughter nucleus as a kinetic recoil energy. In particular, Ir-192 radioactive decays result in a high number of gamma ray radiation events [16]. 12 Atomic Electron Energy Level Transitions Electrons are bound to nuclei in discrete energy levels. Often, electrons move from one energy level to another. An electron may jump from a lower energy level to a higher level via an energy input by some incident particle or radiation, and may move to a lower energy level by emission of a photon, called characteristic radiation [15]. Since atomic electrons (electrons bound to atoms) are more stable at lower energy states, an electron shell arrangement which is in an unstable, higher energy state will emit these photons in order to transition to a lower, more stable state. Thus, a series of shell electron rearrangements can occur which emit a series of usually high energy photons, as well as result in a final, more stable atom. Characteristic radiation is common after many radioactive decay events, as daughter products tend to de-energize into more stable states. Iridium-192 Decay for HDRBT Iridium-192 has a half-life of 73.83 days, and decays by electron capture decay modes (~5% of all Ir-192 decays), and beta minus decay modes (~95%). Electrons are emitted from the HDRBT source with a kinetic energy range of 0 to 0.668 MeV [5]. After either of these decay modes occurs, a series of nuclear particle rearrangements occurs, emitting a series of photons. Many photons are emitted along both decay modes, with an energy range of 0.136 to 1.379 MeV with an effective energy of 0.38 MeV [15], [16]. The final products are Osmium-192 and Platinum-192, from the electron capture and beta minus decay modes, respectively (Figure 2.2). Figure 2.2: Decay scheme for Ir-192 into Pt-192 by beta minus decay and to Os-192 by electron capture. 13 2.3 Interactions of Radiation with Matter Photons and electrons interact with matter through a number of different interaction mechanisms. These interactions result in atomic energy changes, often causing the emission of charged particles from the atom, which results in the ionization of the atom [15]. These ionized atoms and emitted charged particles can go on to create chemical chain reactions, potentially resulting in DNA damage, which can cause cell death [17]. Below are discussed the interactions of radiation with matter which contribute most to dose deposition for Ir-192 based HDRBT. Compton Effect The Compton effect (Figure 2.3, interaction 1) occurs when a high energy incident photon interacts with a loosely bound orbital electron [15]. This results in the emission of an electron and a photon from the atom. The energy of the incident photon is imparted to the system. The emitted electron and photon share the energy of the incident photon in the form of kinetic energy. In theoretical calculations, the binding energy of the electron to the atom is taken to be zero. Photoelectric Effect The photoelectric effect (Figure 2.3, interaction 2) occurs when a photon interacts with an atom, its energy is absorbed by the atom, and an orbital electron is ejected from the atom [15]. The ejected electron will have a kinetic energy equal to the energy of the incident photon, minus the binding energy of the electron. These emitted electrons can go to be involved in further interactions (see Coulomb Scattering) Raleigh Scattering Raleigh scattering(Figure 2.3, interaction 3) occurs when a photon interacts with the whole atom, causing electrons to gain energy, briefly change energy levels, and the move back to their original energy level, emitting a photon of the same energy as the incident photon at a different angle to the incident photon [15]. Coulomb Scattering Charged particles such as electrons experience scattering with nuclei and orbital electrons via the Coulomb force when they travel through or near atoms. These interactions are generally sorted into three different collision types: hard, soft, and radiation. Hard collisions of charged particles with atoms occur when a charged particleâs impact parameter, b (roughly the perpendicular distance between the charged particleâs direction vector, and the atoms nucleus), is approximately the same as the impacted atoms classical atomic radius, a. A soft collisions occurs when b is much greater than a, and a radiation collision occurs when the b is much smaller than a. For hard collisions, it is possible 14 for the incident electron to impact a shell electron of the atom, ejecting it. This creates an ion pair (the negatively charged electron and the positively charged atom) which can subsequently interact together or with other subatomic particles, atoms, and molecules [15]. Radiation Dose 2.3.1Definition of Dose As mentioned above, when radiation particles interact with atoms a transfer of energy happens, which often results in further radiation and ionizations. These radiated particles further interact with other atoms in the medium. Ionizations can trigger cascading chemical reactions, which result in damaging effects to the cell, importantly DNA damage, which can result in cell death. This is the fundamental physical process by which radiation is used to kill cancer cells [17]. The amount of energy which a particle imparts to a system relates to the amount of resultant DNA damage. This energy is related to one of the most important measures in radiation therapy. Absorbed Figure 2.3: Common Photon Interactions with matter. Subscript terminology: i and f represent initial and final photons respectively, and the numbers 1, 2, and 3 represent the Compton, Photoelectric, and Raleigh effects, respectively. 15 dose, colloquially referred to as dose, is defined as the amount of energy deposited by radiation to a unit of mass [15]. Dose is measured in Grays (Gy), which is defined as one Joule (J) per kilogram (kg). A dose quantity is the prescribed treatment to a tumour in radiation therapy and is also used to set OAR limits. The amount of dose which is prescribed to any patient is referenced while creating treatment plans for that patient, and while coverage of the target by the prescribed dose is sought for treatment, treatment planners must also consider OAR specific dose limits [5]. Dose Calculation in HDR Brachytherapy In order to calculate the dose to a particular point or volume of interest, the contribution of the source at each source position must be accounted for. The international standard for this calculation is based on the AAPM Radiation Therapy Committee Task Group No. 43 formalism [18]. This report presents the equations and physical quantities required for calculation of brachytherapy dose. In order to perform the dose calculation, important physical and relative quantities must be determined: Air Kerma Source Strength , is measured in units  where 1 = 1 !" â$. Standard values for individual brachytherapy sources are typically provided by the supplier. The dose rate constant %, is the dose rate per unit air kerma strength at 1cm along the transverse axis of the source, with units of â$ $. The geometry factor (', )) with units !" is used to account for the fact that photon fluence falloff with distance and direction depends on the distribution of radioactive material in the source. The unitless anisotropy factor +(', )) accounts for the anisotropy of dose relative to dose on the transverse axis of the source. The radial dose function ,(') accounts for the depth dependence of dose in a scattering medium along the transverse axis of the source. From these quantities, the dose rate (-. (', ))), in units of â$ is computed [18] as: /. (0, 1) = 2 â 34 â 5(0,1)56 ,789â :(0, 1) â ;(0) 2.4 Approximating the source as a point source results in a simplified version of this equation: /. (0) = 2 â 34 â ;(0)â<=>(0)08 2.5 where ?@A(') is the ratio of the dose rate at a distance r, averaged with respect to solid angle, to the dose rate on the transverse axis. Finally, the dose from a given position is calculated: 16 / = /. â B 2.6 Where C is the amount of time the source spends at a certain position, measured in hours, and -. is either of the dose rates calculated above. 2.4 Radiation Therapy The discovery of x-rays, radioactivity, and radium in the late 1890âs has led to various medical treatment and diagnosis subspecialties including radiology and radiation therapy, and medical physics as a sub-discipline of physics. Over the subsequent decades, these and related phenomena have allowed treatment specialists to both image and treat malignant cancers, improving patient outcomes [19], [20]. Principles of Radiation Therapy 2.4.1How Radiation Kills Cells Cancer is a group of diseases, defined by the uncontrolled proliferation of mutated cells in the body. These cells cause damage by competing for resources and destroying nearby tissues, often including major organs. Additionally, these cells can, if not treated early, spread to other parts of the body in a process known as metastasis. Cancer treatments, generally speaking, attempt to remove, damage, or kill these groups of cells, or tumours. Radiation therapy is used to damage and destroy tumour cells by depositing a dose of energy from ionizing radiation (in the form of electrons, photons, or protons) within these cells. Ionizing radiation interactions cause ionized molecules which can cause molecular chain reactions through chemical changes leading to the breaking of chemical bonds, including DNA breaks, which can cause damage to and/or death of the cell. Unfortunately, both tumorous and normal tissues are damaged via interactions with ionizing radiation [21]. Preventing Damage to Normal Tissues There are a number of ways to minimize the impact of radiation therapy on normal tissues while maximizing the impact on tumour tissues. For example, different tissue and tumour cell types have different responses to radiation. Having multiple treatments delivered at specified time intervals, or fractionation, can allow for improved tumour treatment with decreased impact on the normal tissue [21]. Fractionation is successful when normal tissue can repair proportionally faster than tumour tissue between treatment fractions. Treatment planning and delivery techniques also allow for geometrical variation in dose delivery, which can be used to selectively deliver dose to treatment volumes while limiting dose to OARs. 17 Treatment Planning Treatment planning is the process through which the parameters required to deliver radiation preferentially to the tumour while protecting surrounding normal tissue are determined. Imaging information is used to delineate tumours and critical structures by the treatment planner. In HDRBT for gynecological cancers, the gross tumour volume (GTV) is typically first delineated, upon which an additional margin is added to create the high-risk clinical target volume (HRCTV). The HRCTV represents the GTV, plus an estimate of additional tissue to be treated, which is at a high risk of being malignant, but not confirmed by images. The treatment plan is then created using a model of the radiation delivery system to combine radiation source delivery configurations to compose a comprehensive simulation of doses to target volumes and critical structures. For each patient, the treatment plan is customized dependent on the treatment volume and OAR geometries. High Dose Rate Brachytherapy for Gynecological Cancers 2.4.2High Dose Rate Brachytherapy involves placing highly radioactive sources next to or within a tumour volume to deliver a localized dose of radiation [5]. The most common HDRBT source material used is Ir-192 [15]. High Dose Rate Brachytherapy sources (Figure 2.4) for Ir-192 based HDRBT are on the order of 4mm in length and 1mm in diameter, are approximately cylindrical in shape, and are welded to a guide wire [5]. The source(s) are transited to planned positions via this guide wire which linearly extends the source to within the patient through channels within applicators or needle-like catheters. Figure 2.4: Example IR-192 Brachytherapy source used with an HDR Afterloader. Dimensions are approximate. 18 When not being used for treatment, the source is retracted into a shielded storage compartment in a treatment unit called a remote afterloader (Figure 2.5) [5]. For treatment, one or more applicators are inserted into the tumour tissue or a nearby body cavity. The brachytherapy afterloader moves the HDR source through each applicator to preplanned positions for preplanned amounts of time for each position in order to deliver the intended dose to the region [5]. Commercial afterloaders contain up to 40 channels which can be connected to corresponding guide tubes which in turn are connected to catheters and applicator transit channels. For treatment, the source is transited to planned positions via a stepper motor in the afterloader, through guide tubes to the applicators. The afterloader is computer controlled, so that source positions and dwell times can be preplanned in brachytherapy treatment planning software. 2.4.2.1 Physical Exam and Applicator Insertion On the treatment day, the patient is anaesthetized, positioned in dorsal lithotomy, and a physical exam is performed by the by the oncologist. This exam is used to affirm the position of the tumour. Additional guidance can be provided by trans-abdominal, trans-vaginal, or trans-rectal US imaging. Once the position, size, and shape of the tumour is confirmed by the oncologist, the template and/or applicator(s) selected for the treatment will be inserted. 2.4.2.2 Post-Operative Imaging Once the insertion procedure is complete, it is necessary to verify the positioning of the applicators and/or templates, in order to create a treatment plan based on their positioning. The patient will undergo a Computed Tomography (CT) scan, and these images may be aligned, or registered, to magnetic resonance (MR) images. The MR images are either acquired with the implant in place, if magnetic resonance imaging (MRI) compatible applicators are used, or preoperatively otherwise. Pre-operative MR images are taken with an intracavitary cylinder in place to simulate the treatment position, in the case when interstitial catheters are used along with an intracavitary cylinder for treatment. Figure 2.5: Commercial HDRBT Afterloader. Source channels are shown on the front of the unit. 19 2.4.2.3 Treatment Planning for HDR Brachytherapy Based on both the CT (used to visualize the applicator and organs) and MRI (which will best visualize the tumour [22]), a treatment plan for the patient will be developed. The treatment plan is fundamentally a set of positions and dwell times for the HDR source within the applicator and templates. During plan creation, planners attempt to deliver the prescription dose to the target volume (usually to the HRCTV), while keeping organ doses below acceptable limits. A brachytherapy treatment planning system (TPS) is a program which allows the user to view patient images, identify patient anatomy (tumour and organs) and treatment applicators, plan dwell positions and dwell times for brachytherapy treatment, and export the treatment plan to the afterloader system. Treatment planning for HDRBT is commenced once an applicator and/or interstitial catheters are fixed in the patient. For cylinder applicator based methods, the applicator is identified on the patient images. The applicator treatment channels, and/or the interstitial catheters, are identified and digitized in the TPS by identifying their locations on the images and creating a digital representation the channel. Since the applicator channels are what the HDR source will be transiting through, it is important to digitize their position accurately. Once all treatment channels are identified (either the applicator channels or interstitial catheters) the position of HDR sources and their individual dwell times at each position are planned. Typically, a standardized spacing of HDR source positions within the channel/catheter is used. The dwell time for each position can be âforward plannedâ by manually varying the dwell time for each source position in order to result in a desired dose to the tumour, while reducing doses to OARs. Optimization algorithms are increasingly common, such as geometric optimization [5] and inverse planned simulated annealing (IPSA) [23], which can determine source dwell times in order to satisfy a set of constraints input by the user. These constraints are typically in the form of dose-volume relations. Commonly used treatment planning goals for various structures (organ or tumour, or treatment volume) are: volume receiving 100% of dose (V100%), minimum dose to the maximally irradiated 2 cm3 (D2cm3), and the dose to 90% of the volume (D90%). Once the positions of the treatment channels are identified and an acceptable set of source positions and dwell times is determined, the treatment plan is digitally transferred to the treatment unit. 2.4.2.4 Treatment A treatment plan is imported to the HDRBT Remote Afterloader console, and the patient is positioned in the brachytherapy treatment room. The catheter(s), and/or applicators are connected to the afterloader via guide tubes, and the treatment is delivered to the patient. For treatment days where 20 multiple fractions are delivered, the applicators typically remain inserted between treatments. A typical interstitial treatment regimen is 2-4 treatments, over the course of two separate days. Imaging for HDR Brachytherapy 2.4.3Magnetic Resonance Imaging Magnetic resonance imaging (MRI) is a magnetic field based imaging method which uses position, phase, and frequency sequenced magnetic signals to create a response in tissue which can be read by specialized receiver coils [24]. Clinically, MRI images offer high contrast between tissue types (Figure 2.6). This is advantageous for the identification and delineation of tumour and OAR structures, as they are more easily identified as compared to the other imaging technologies introduced below [25]. A disadvantage of MRI is that protection measures must be in place to prevent any magnetic or ferromagnetic materials from being in the scanner or even in the room in which the MRI machine is housed [24]. MRI imaging systems are also expensive, meaning that they have limited or no availability, depending on the location. In the most advanced vaginal interstitial brachytherapy treatment workflows, MRI is used to image the patient on the treatment day, allowing for clinicians to easily identify the tumour and OARs [25]. Computed Tomography Computed tomography (Figure 2.6B) is an x-ray based imaging technique which relies on the variation of tissue attenuation of x-rays to create one or more image slices over a volume of interest [24]. Since most soft tissues in the body have similar electron densities and attenuate diagnostic x-rays similarly, soft tissue contrast in CT is poorer than MRI, whereas the difference between bone and soft tissue are more pronounced. 3D CT image datasets can be acquired in sub-second timeframes, and while they do not result in the same tissue contrast as MRI, they provide improved visualization of applicator materials, such as plastics [24]. In addition, metallic surgical instrumentation may be scanned using CT. For these reasons, CT imaging is commonly used after A B Figure 2.6: A: An MRI scan slice of the pelvic region with a vaginal cylinder applicator inserted. B: A CT scan of the same patient. The CT scan has poorer soft tissue contrast, but improved applicator contrast, as compared to the MRI. 21 applicator insertion for vaginal HDRBT, allowing for straightforward post-insertion digitization of applicators [26]. Ultrasound Imaging Ultrasound images are created using high frequency (inaudible) sound waves which are projected into a medium by piezoelectric crystals in the US transducers. The sound waves reflect off of various structures in the medium, and received by the piezoelectric crystals on the device [24]. Based on the speed of sound in the material and the reflection times of individual signals, an image of the medium can be computed. US imaging systems are commonly integrated on trolleys with a display (Figure 2.7A), unlike an MRI or CT. For this reason, as well as the lack of ionizing radiation from US (such as in the case of CT) and the ability to use metallic object in the nearby vicinity (unlike MRI) US is commonly used in operating rooms for vaginal HDRBT applicator insertions. For HDRBT, US transducers are typically of either a cylindrical shape (Figure 1.4) used trans-vaginally or trans-rectally, or of a linear or curvilinear paddle shape (Figure 2.7 B&C) used transabdominally. US imaging systems are used in operating rooms to provide visual feedback during the placement of vaginal HDRBT applicators. Patient Experience for Interstitial HDRBT 2.4.4Vaginally recurrent endometrial cancer is treated with HDRBT [26]. A sample treatment workflow for vaginally recurrent endometrial cancer requiring interstitial brachytherapy (IBT) is shown in Figure 2.8 and is described below. A B C Figure 2.7: A: Commercial US trolley with image display. B: Paddle shaped US transducer - side view. C: Paddle shaped US transducer - end view 22 On or before treatment day, the patient will undergo an MRI scan with an applicator inserted to reflect patient anatomy at treatment. The MRI scan is used to identify the patient tumour and organs. On treatment day the patient is taken to the operating room and general anaesthetic is induced. A physical examination is then completed, where the oncologist will physically identify and verify the tumour size and shape in the patient. Due to the differences in mechanical properties between the tumour and vaginal tissue, this can be done by feel. Once the physical examination is completed, the patient will have an applicator and interstitial catheters inserted in the operating room. With the applicator and catheters in place, the patient will undergo a CT scan in order to verify the final locations of the applicator and catheter paths. The resultant CT images will be registered to the previously acquired MRI images, and applicator and catheter channels will be digitized in the planning system. A treatment plan is created and approved for the patient and the patient will undergo the HDRBT treatment. At BC Cancer - Kelowna, these treatments will be fractionated 4 times over the course of 2 separate treatment days, with each treatment day separated by 2 â 7 days. The per-treatment (fraction) dose is on the order of 600 cGy. 2.5 3D Printing While most automated manufacturing processes such as CNC mills and lathes are subtractive, in that they remove material from a starting volume, 3D printing, or additive manufacturing, only adds material until the final part is formed. This allows for materials savings, the elimination of custom tooling and employee manufacturing time, and the ability to form highly complex geometries, traditionally impossible or very difficult to manufacture. 3D printing has become increasingly popular as both a prototype and end-use manufacturing method for a number of industries, including automotive, space, healthcare, and many others [27]. In healthcare settings, 3D printing has become useful in the development of custom surgical tools, immobilization devices, external bolus for radiation therapy, and many other uses, though its adoption is still in the early stages [27], [28]. An introduction to the type of 3D printing used for this project, and considerations for 3D printing in medicine follows. Fused Deposition Modeling 2.5.1Fused Deposition Modeling (FDM) (Figure 2.9) is a type of 3D printing which uses a continuously extruded bead of thermoplastic to create a thin slice of material (for example, in an X-Y plane), Figure 2.8: Treatment workflow for HDR Interstitial Brachytherapy for Vaginally Recurrent Endometrial Cancer at BC Cancer â Kelowna. 23 representing a cross section with a small thickness of the designed part. In a slice-by-slice (layer-by-layer) manner, the final part is created by printing layers typically uniformly spaced in the third dimension (for example, the Z direction.) The final part exhibits the layered nature of this manufacturing process, as each print layer is visible on the exterior (Figure 2.9) [27]. A number of factors affect the accuracy, smoothness, and strength of the final printed part [29]. The temperature of the print nozzle is related to the temperature at which the 3D print material will be heated to as it is deposited. Too cool of print nozzles can result in material gaps and too hot of nozzles results in too much spread of the material on the bed, or burning the material. Some commercial systems include nozzle-integrated fluid based heat exchanger systems intended to improve temperature homogeneity throughout the nozzle. The temperature of the print bed affects how well the first layer of material adheres to the bed. Poor bed adhesion can result in warpage of the final 3D printed model, since as individual layers cool, they shrink and exhibit a stress on nearby layers. The layer height of each individual layer directly relates to the smoothness of the final part, since the outer edge of each bead is curved. The infill percentage relates to the percentage of volume filled with material within the final part. A part printed with an infill percentage less than one hundred percent will contain internal, patterned voids, which allow for material and weight Figure 2.9: A: 3D printing of a cylinder model. B: Magnified section showing individual layers. Each layer is ~0.3mm in height. A B Build Plate Print Nozzle Visible Print Layers 24 savings. Infill percentage can be varied in order to take advantage of weight and strength trade-offs, and to save prototyping costs. The relative humidity of the storage conditions of 3D print materials can affect their final print performance. Most 3D printing material manufacturers have humidity storage recommendations [27]. High Temperature Fused Deposition Modeling Many high temperature, high strength, 3D printable thermoplastics (often called âengineering thermoplasticsâ) are commercially available, though they are significantly more expensive 3D printing materials than traditional lower temperature, lower strength 3D printing materials such as Acrylonitrile Butadiene Styrene (ABS) or Polylactic Acid (PLA) . These materials include Polyether Ether Ketone (PEEK), polyetherimide (PEI), and others. One advantage of using these materials is the fact that they are already used for intracavitary applicators, and their commonplace acceptance as a steam sterilizable manufacturing material for surgical tools [30]. 3D Printing for Medical Applications 2.5.2Three dimensional printing of custom surgical and other clinical tools for medical applications has existed since the mid 1990âs [27]. Since that time, many hospitals, clinics, and cancer centers have developed their own in-house 3D printing services [27]. In response, the 3D printing industry and academia has developed a number of clinically important offerings, including sterile 3D printing [30] [31] and custom software for medical applications of 3D printing [32] [33]. Although this industry is growing quickly, there remain some important concerns in the field that can act as barriers to entry for many clinics. Sterilization For devices used in surgical applications, sterilization is required in order to ensure the safety of the patient. In most medical centers, sterilization of reusable and in-house manufactured devices is achieved by Ethylene Oxide sterilization or by pressurized steam sterilization in an autoclave device, and the stringency of prescriptive guidelines varies by region. In order to have a 3D printable applicator available for clinical use in the operating room in British Columbia, Canada, for example, these devices must be able to be sterilized, and the ability for a given device to be sterilizable must be independently validated [35]. Complicating this requirement, is that only certain materials are known to be compatible or can withstand a given sterilization method, and for high temperature 3D printing materials, sterilization validation tests have not been done or are not published. 25 Reliability and Repeatability Patient specific surgical tools created in the clinic must be reliably manufactured if they are to be directly used in the operating room with confidence on a day-to-day basis. Due to the adolescent state of the 3D printed custom surgical tools field, no standards exist for acceptance testing end-use surgical tools, meaning clinics must develop their own acceptance testing procedures. A holistic manufacturing approach must be adopted in order to address the specific concerns and trade-offs associated with an individual clinicâs 3D printing needs. 2.6 Application Programming Interfaces An application programming interface (API) is a set of software tools and communication protocols which allows a programmer to build and access software [36]. Two APIs were used for this project, the Eclipse Scripting API (ESAPI) (Varian Medical Systems, Palo Alto, CA, USA) and the Solidworks API (Dassault Systèmes, Vélizy-Villacoublay â France). ESAPI and the Solidworks API are sets of reference files which may be accessed by custom scripts to access and manipulate data in their respective programs. Eclipse Scripting Application Programming Interface 2.6.1ESAPI allows developers to write custom scripts which can access treatment planning information in the Eclipse treatment planning system. These scripts can be run as standalone applications or as scripts within the Eclipse planning system. ESAPI can be used to access most parameters within the treatment planning system, though writing of variables to the system is only allowed in non-clinical research versions of the software, to ensure that undeliverable or potentially dangerous treatments are not delivered to patients. Solidworks Application Programming Interface 2.6.2The Solidworks API allows developers to write programs which can open the Solidworks application and create and edit 3D models. The API contains hundreds of accessible functions, such as creating lines, extrusions, measuring parameters, etc. The API is particularly useful for the creation of many slightly different models, with minor variations. Whereas these models would take a long time to create manually, many can be created in a short time using the API. 26 Materials and Methods Chapter 3:This chapter discusses the materials and methods used to develop a workflow which automates design and manufacture of patient specific applicators for interstitial vaginal brachytherapy. The rationale for the 3D printing materials used, the 3D printer selected, the baseline design for the patient specific applicators, the custom code written for the project, as well as validation testing experiments are discussed. 3.1 Material Selection Materials Requirements 3.1.1There are a number of important factors which affect the selection of a suitable material for manufacturing patient specific templates. What follows is the list of materials requirements initially created for the PSCT, and the underlying rationale for these requirements. Sterilization Sterilization of in-house manufactured devices intended for brachytherapy procedures is a requirement of BC Cancer â Kelowna, as guided by the BC Ministry of Health [35]. Sterilization services for BC Cancer â Kelowna are accomplished using an autoclave with a nominal temperature of 132°C. The material selected needed to be both sterilizable by steam and able to withstand steam sterilization temperatures and pressures. 3D Printable Patient specific templates have non-trivial geometries and the most straightforward means of manufacturing these within BC Cancer â Kelowna is via 3D printing. Thus, although there are many materials that can withstand autoclave conditions, it was also necessary that the material be 3D printable. Familiarity BC Cancer â Kelowna has experience creating and using in-house manufactured devices for brachytherapy. These devices have undergone a sterilization validation procedure, which is used to provide instructions to sterilization staff in a Manufacturerâs Instructions for Use (MIFU) document. To minimize the differences in sterilization procedures between devices currently manufactured in house and the custom cylindrical template, it was deemed preferable to use sterilization procedures and materials that are similar to those used currently. 27 Water Equivalence It is also important that the material selected be near water equivalent with respect to electron and photon dose deposition at Iridium â 192 energies. This is an important characteristic in ensuring that the software used to calculate dose to the target and organ at risk volumes remains as accurate as possible, as current clinical treatment planning software for brachytherapy assumes water equivalence throughout the calculation volume. Materials Cost The materials cost for this project was not considered. While other centers or groups may consider the materials cost as an important factor for a clinical implementation, the similarity of the material to others used at BC Cancer Kelowna, and the materialâs steam sterilizablility were overriding concerns in this case. Materials Survey and Material Selection 3.1.2A survey of commercially available 3D printable materials was conducted. Polyether Ether Ketone (PEEK) was selected, as it has a relatively high heat deflection temperature of 160C [37], is 3D printable, has an existing track record for 3D printed devices in medicine [27], and is familiar to the clinicians and staff involved with in-house manufactured devices at BC Cancer - Kelowna. Other thermoplastics were considered, such as Polyetherimide (PEI), Polyphenylsulfone (PPSU) and Polycarbonate (PC). It is hypothesized that 3D printed PEEK will have similar dosimetric qualities to that of water. Although commercially available applicators are manufactured from PEEK, the author is unaware of any published tests on the dosimetric qualities of PEEK. Further, the dosimetric effect of 3D printing this material as compared to traditional manufacturing methods is unknown. Nevertheless, the applicators currently used at BC Cancer â Kelowna are manufactured using PEEK, so dosimetric differences between these applicators and the PSCT are expected to be small. Work to explore these concerns is ongoing. Polyether Ether Ketone is the material selected for this project, though it is likely not the most cost effective, nor a necessary selection for other clinics wishing to implement this workflow. Each institutionâs choice would be guided by their experience, 3D printer, and sterilization requirements. 28 3.2 3D Printer Selection 3D Printer Requirements 3.2.1The approach to the selection of a 3D printer was to first list a number of important requirements relevant to the manufacture of PSCTs, then to do a market search to find potential 3D printers which satisfy some or all of these requirements, and then to use a decision matrix to determine which printers would be best suited to the task. High Temperature Given that PEEK was selected as the material of choice for this project, the 3D printer selected for the project needed to be PEEK compatible. The melting temperature of PEEK is 343°C [38], meaning that the print nozzle needed to be able to achieve temperatures above this value. In addition, the print bed and chamber needed to be able to withstand the chamber temperatures required to achieve quality bed adhesion and print quality. Print Volume For the purposes of comparison between candidate 3D printers, the longest PSCT to be printed would be on the order of 300mm in length, and the bed area should to be of similar dimensions. While there were not fixed minimum dimensions for the printer, these suffice as rough guidelines. For the purpose of future possible functionalities for this printer, larger print volumes were preferred. Minimum Layer Height In sample PSCT print testing using the MakerBot Replicator 2 (MakerBot Industries, Brooklyn, NY) 3D printer, a layer height of 0.1mm or less was found to be necessary to result in a template which could be judged as sufficiently smooth for clinical purposes. Larger layer height values result in rough, jagged print models which would not conform to common medical device design aesthetics and ergonomics. Reputable Manufacturer As the 3D printer will be used to accomplish clinical tasks, it was necessary that the device and manufacturer have a proven track record. Manufacturer device and support reliability are necessary for a device used in a clinical environment, as machine downtime, poor print quality, and maintenance expenses can negatively affect patient care, clinical efficiency, and device functionality. Affordable The cost of the selected printer needed to fit within the budget for this project. Comparison of Commercially Available 3D Printers 3.2.229 A search for commercially available PEEK 3D printers utilizing information from 3D printing blogs, market reviews, and research articles was conducted. Technical documents were used to collect specifications and compare available 3D printers so that a selection of 3D printers could shortlisted. 3D Printer Selection 3.2.3After market research and an engineering matrix comparison (Appendix A), discussions with other Canadian medical professionals proficient in 3D printing, and phone interviews with manufacturers, the AON 3D (Montreal) M2 3D printer was selected, and purchased. The AON-M2 3D prints using Fused Filament Fabrication (FFF) technology, has a 454 x 454 x 640mm build volume, and can print layer heights as small as 0.05mm. It can print most commercially available FFF/FDM 3D printing materials, including PEEK [39]. Similar to the material selection process for this project, the reader should note that this 3D printer was not the only viable option, and possibly not the most cost effective. Factors such as the competency and availability of the manufacturer for spare parts and repairs, customer reviews, and applicability to other projects within the centre played an important role in selection of this particular 3D printer. While other 3D printers may be able to offer similar print quality for PEEK as the AONâM2, the robustness, ease of use, and reputation of the AON-M2 3D printer is particularly attractive for our purposed, at this price point. The tests conducted for this thesis (described later) were completed on the Makerbot Replicator 2. Future work will be conducted using PEEK on the AON-M2. 3.3 Cylinder Template Design The overall goal for the PSCT is to deliver highly conformal treatments to the vagina by integrating preplanned catheter path geometries into a cylindrical template. This facilitates accurate catheter guidance to intended intra-template and interstitial treatment locations. To accomplish this, a detailed design process needed to be defined in order to develop robust and reliable template designs. First, a set of design requirements was established, and then a device that meets or exceeds these Figure 3.1: AON - M2 3D Printer by AON3D. Reprinted with permission of AON3D. 30 requirements was designed in consultation with Physicists and Radiation Oncologists at BC Cancer â Kelowna. This section explains the design process and final design of the PSCT, including the manner in which each cylinder is customized. Cylinder Template Design Requirements 3.3.1In order to create a successful template for the clinic, a number of important design requirements that motivated the design choices for the PSCT were identified. These are minimum specifications which the design needed to meet in order to be considered successful. The requirements set forth measurable and/or testable design and manufacturing goals which can be directly assessed. The following list details each of these requirements, and how each requirement is satisfied by the design. Requirement 1: Orientable It must be possible to orient the template within the vagina (roll and pitch), and it should be possible to validate this orientation. The PSCT is 3D printed with two small notches on the outer cylinder face, at the base of the template (see Figure 3.2). These notches are always located at 12:00 and 6:00 on the base of the template. This way, the operator can use a level, if necessary, to orient the ârollâ position of the template. The template is visually checked after printing to ensure that the notches are at the correct position, and easily identifiable. Operator placement competency is the current proposed method by which the cylinder pitch angle and orientation are established. Whether or not this can be accurately reproduced is an ongoing point of research. Requirement 2: Identifiable catheter guide bores The catheter guide bores must be clearly identifiable by the operator during the surgical procedure. 31 The catheter guide bores will be identified using a patient specific operating room (OR) guide sheet. The guide sheet includes a printout of the base face of the template, with numbered holes. This allows the operator to determine the correct hole in which to insert each catheter. An alternative to this method is to have the holes numbered directly on the template; however, placing the numbers on the face of the template automatically can be difficult if 2 or more holes are clustered, as the numbering can be confusing. Also, the quality of small, 3D printed numbers is often unreliable. In addition, body and surgical fluids could make these numbers difficult to read. Having a guide is a simple, clean solution. To ensure that the catheter guide bores are identifiable in the OR, the guide sheet and printed model are visually checked for coincidence as a part of the manufacturing process. Requirement 3: As little resistance as possible There must be as little resistance felt as possible by the operator when inserting a catheter through the guide bore. Figure 3.2: Example Drawings of Patient Specific Cylindrical Template 32 This requirement is satisfied by several mitigations. First, the printed layer height is as small as possible to minimise the likelihood of the catheter tip catching on a layer of printed material. The default guide bore diameter is also set to allow smooth transit of the catheter through the guide bore. A âtest blockâ which has a number of guide bores printed in it, with varying diameters, can be printed to assess which diameter suits the catheter best. In addition, the 3D printer can be tuned to print the intended diameter within a given accuracy tolerance. To ensure that this requirement is met, each guide bore is cleaned and tested before use. Requirement 4: Guide bores must be a reasonable diameter The guide bore must be an appropriate diameter to limit catheter deflection in tissue, while allowing smooth transit of the catheter through the template. The guide bore diameter is selected according to the operatorsâ preference. The default guide bore diameter has been selected using an internal test block experiment but may be altered by the user in the software (described later). The guide bore is tested during the manufacturing process by running a catheter through it. The guide bore may be cleaned or deburred by use of a metal pipe cleaner before being sent for sterilization. Requirement 5: Manufacturing technique The template must be 3D printable. 3D printing techniques including support structures (certainly internal supports) and infill percentages less than 100% may not be used. Requirement 6: Patient/Couch fixable It must be possible to mount the template to either hip straps or to couch mounted template holders. Strap loops on the base of the applicator body are intended to allow for the applicator to be fixed. The loops are tested during the manufacturing process to ensure that the straps are able to run through the loops. Requirement 7: As smooth as possible The template must be 3D printed with a smooth enough surface to be sterilizable inside and out, as well as provide an aesthetic which will integrate well with existing operating room devices. The applicator is 3D printed with the smallest reasonable layer height to allow for as smooth a surface as possible. This is typically less than 0.1mm. An ongoing project of this work will be to assess what the largest reasonable layer height is for the applicator, as small layer heights take longer to print. For now, the smallest available layer height is recommended. 33 The applicatorsâ smoothness will be visually inspected by the clinician responsible for the applicator quality assurance. Requirement 8: Curvature limited The curvature of the guide bore is limited by default to a minimum radius of 13mm, which is the minimum allowable curvature of BC Cancer â Kelownaâs Varian Gamma Medplus iX afterloader [40]. This limit is, however, variable by the user. As there is no direct method of measuring the curvature of the guide bore, the ability to transmit the catheter through the guide bore is used as a proxy during manufacturing. In addition, the afterloader unit always checks each catheter with a dummy source before the real source is inserted into the catheter. This serves as a double check for the curvature limit. Requirement 9: Similar to existing templates The template should be similar in material, look and feel, and interface to existing templates, which minimizes manufacturing, sterilization, and surgical process change. Requirement 10: Parametric design The user should be able to alter template design variables to allow for dimensional design variations. The applicator creator software allows the user to change all of the major variables of the applicator. These options are detailed in the code description. PSCT Design Details 3.3.2The PSCT design is similar in shape and use to existing cylinder applicators currently on the market, though the design includes a number of unique features in order to ensure that catheters can transit along any pre-planned path, that catheters can be inserted interstitially guided by the template, and that all design requirements are satisfied. The design details of the patient specific cylindrical template are described in this section. Technical drawings of an example template are shown in Figure 3.2. Cylindrical Shape The template body is generally of a cylindrical shape, allowing for smooth insertion into the vagina. The cylindrical shape provides similar operational and aesthetic quality as that of existing commercial applicators used for vaginal HDRBT. Diameter and length variability allows the cylinder to be sized so as to appropriately fit each patientâs anatomy. The template is designed to extend outside the vagina to allow for manipulation and fixation by the operator. 34 Rounded Top The rounded top of the template allows the cylinder to be easily inserted into the vagina. The rounding is of the same radius as the cylinder by default to create a dome top, but it is conceivable that an operator may prefer a radius less than this, so that option can be allowed in future software iterations. Chamfers Chamfers at various regions on the template provide both a nicer aesthetic for the device, allow for easier catheter insertion, and allow a collet (see below) to be used to lock the catheter into the template. The collet and internal hole chamfers are designed so that the collet will pinch the catheter once the collet has been threaded in to a certain depth. These are an existing product used at BC Cancer â Kelowna for interstitial perineal catheter templates. Counter-bores The counter bores in the template allow for threads to be tapped directly after printing. This allows for catheters to be locked into position using custom collets manufactured by BC Cancer â Kelowna. Threaded Catheter Guide Bore The catheter paths are calculated by the custom software based on clinically planned catheter positions and are defined as a circle extruded along this curved path to create the guide bore. Both the curve profile diameter and the minimum allowable curvature are variable by the user, though there are default values. At the base of the applicator the guide bore is tapered at a depth of 6mm. This base section is also hand tapped to be compatible with in-house manufactured locking collets. Locking Collet The locking collets are used to lock the catheter into the PSCT once the catheter has been inserted to the desired depth by pinching the catheter. Mounting Loops Mounting loops are included on the template to allow for attachment to a template fixation belt. Orientation Notches The orientation notches are located at the 12:00 and 6:00 locations on the bottom of the template, and denote the positioning of the template as intended in the treatment plan. The notches are used by the operator to ensure that the template is at the correct rotational positioning. 35 3.4 Code Scripts and standalone applications were written for this project. These provide automation in the creation of 3D printable patient specific applicators, and for assessing the accuracy of implanted applicators. ESAPI was used to access patient treatment plan information such as patient ID and brachytherapy catheter geometry information. The Solidworks API was used to first programmatically instantiate an instance of the Solidworks (Dassault Systèmes, Vélizy-Villacoublay â France) 3D modelling program in the background, then create a model of the PSCT using processed information from ESAPI, and finally save it in a 3D printable format (STL). The following sections describe the design requirements used to guide code development, how those requirements were satisfied, general code outline for each script, screenshots of the graphical user interfaces (GUIs), and the user operational workflow of the code. Code Design Requirements 3.4.1The code requirements were selected by the team to set goals for the code design and as a metric for successful implementation. In order to show how the design criteria are satisfied, a brief explanation of how the requirement was satisfied is also given. Requirement 1: Ability to generate complex 3D models from patient plan The main purpose of the scripts is to automate the design of the PSCT. The code was needed to be able to take data from the Eclipse Planning System (using ESAPI), to manipulate the data, and to generate and save a 3D printable STL model. Requirement 2: Intuitive The user interface and operation of the scripts should be simple to use. The interface and operation of the scripts and applications are relatively simple. Training on the software will be brief and is easily explained by the user guides. Care has been taken to minimize the number of user inputs while allowing for customization. How this model generation works, and the relevant outputs, are described in later sections. Requirement 3: Minimum necessary user input The code needed to be as automated as possible in order to maximise workflow efficiency and minimize operational complexity. Other than interfacing with the information exporter and the cylinder creator applications (described later), the user has little to do once a plan is created. The scripts and applications do all export, 36 saving, calculations, and modelling automatically, though the user has options to customize these operations, as well as the final model. Requirement 4: Check for catheter guide bore intersections and limits Code is needed to ensure both that no paths intersect and that the paths do not violate curvature limits. In order to test that the treatment plan intended by the program does not include intersecting catheters, the code does an exhaustive Euclidean distance search between all source positions and curve shape coordinates to ensure that the catheter and source positions do not intersect. Requirement 5: Update the user This code gives the user updates on the code progress, informs the user of any errors, and provides details of the errors. The user is notified that the calculation is ongoing by a progress percentage. If there is an intersection, the user is notified as to where any intersections are. The user is then given the option to re-plan or to continue with the calculation. Requirement 6: Automated and intuitive file management The code should manage each calculation independently and not overwrite any existing information so that any potential error analysis can be completed retroactively. The file structure is organized by each individual export, within a patientâs name directory and plan subdirectory. This way, if a user wishes to compare multiple similar plans for the same treatment, they will not overwrite. The 3D model files are saved to the same file location as the transfer file used to create the 3D model. Two programs written to export and compare a patientâs PSCT treatment plans, Cylinder Applicator Source Position Exporter (CASPE) and Cylinder Applicator Source Position Comparator (CASPC), both save their exports to the patient folder within CASPE and CASPC subdirectories, respectively. Requirement 7: Automated Generation of Log File A log file, with information relevant to diagnosing potential problems, is created for each run of the script. The log file includes patient name, catheter positions source positions, coordinate system transformations, source position check results, error results, and locations of errors (such as a pair of source positions which are too close together). 37 Requirement 8: Automated Generation of Operating Room Reference Sheet This script needed to generate a PDF file that provides a map of the catheter numbering and catheter insertion lengths. The Cylinder Applicator OR Reference File is generated by the ESAPI Cylinder Exporter. The file includes the patient and plan information, a table with the planned insertion lengths for each catheter, and a base map of the cylinder applicator showing the numbered catheter hole pattern. This is useful for the operatorâs reference in the OR to ensure the proper catheter holes and insertion lengths are used. ESAPI Cylinder Information Exporter 3.4.2The purpose of this script is to export and check the cylinder and patient plan information from Eclipse. At BC Cancer - Kelowna, custom scripts are run from the Eclipse drop-down menu Tools>>Scripts interface. For consistency, the ESAPI Cylinder Information Exporter was written to be run this way as well. ESAPI interfacing software is commonly achieved using C# scripts and applications, for which reference documentation is available [41]. The ESAPI Cylinder Information Exporter script has been written to allow the user to export important information relevant to the creation of a Patient Specific Cylindrical Applicator model to a file which will be accessible to the user. In addition, the script completes a number of checks and calculations important to the design of the applicator. This section provides an outline of the ESAPI Cylinder Information Exporter code, its functions, and its outputs. 3.4.2.1 Graphical User Interface The graphical user interface of the ESAPI Cylinder Information Exporter is designed to be simple and user friendly, while still allowing for design modification. As seen in Figure 3.3, the first step for the user is to identify the cylinder diameter. This is a required user input, as the patients undergo a pre-operative MRI using one of a set of standard vaginal cylinders, each with different diameters. The planner must correctly input the diameter of cylinder to be used to ensure that the patient anatomy with the applicator inserted is reflective of that in the MR images. The length of cylinder and the guide bore diameter are also adjustable. Future versions of this code will allow for additional modifications, such as providing the ability to selectively ignore warnings, guarantee that a certain catheter bore will be only an internal bore (not an interstitial catheter), or choose between a mounting 38 strap or some other mounting mechanism, such as a clamp. In Step 2, the user may select a different name and file path for the destination folder. The default directory is an internal BC Cancer Patient Specific Applicator directory. The default patient folder name is related to the patient name, plan, and the date on which the script was run. Once a satisfactory folder name is entered, the user can click on the âCreate Applicatorâ button, which executes the script. The results section of the GUI describes the current progress of the script and then provides a link to the patient folder once the calculation is complete and the files have been saved. If there are any errors in the calculation, the Results section will state the error, and provide a description of the error. The error is also shown in the log file. 3.4.2.2 Code Structure The ESAPI Cylinder Information Exporter retrieves information from the Eclipse Planning System, and prepares this information for creation of a PSCT model. As detailed below, the software exports this information from the planning system, prepares the variables necessary for creation of the cylinder, does geometry checks, exports the information to a transfer file, and creates a log file of the calculation. The user is notified of any errors and is given the opportunity to alter the plan before exporting. Once this step is complete, the plannerâs job is complete for the applicator, and the applicator 3D model is ready to be created. Get Info The Get Info code subsection retrieves patient and plan information using the ESAPI script context. A âPatientâ Class having been previously defined in the main script, an instance of the patient class is Figure 3.3: The GUI for the Cylinder Applicator Exporter. 39 instantiated, and information such as the patient and plan name, as well as source and catheter shape information, is defined. Assign Cylinder Variables The Assign Cylinder Variables code subsection takes information from the GUI that the user has set, or default values, and assigns them to a new instantiation of a âCylinderâ class object. Convert Coordinates The Convert Coordinates code subsection takes the shape information provided by ESAPI script context given in the default coordinate system of the treatment planning system, and converts it first to the user coordinate system, and then to the SolidWorks coordinate system. Create Curves The Create Curves code subsection takes the converted shape information from the Patient object and creates point-based curves which act as the catheter guide bore centerline curves for the applicator. Minimum diameter curvatures and small spacing between curve points are imposed. A spacing of about 0.3mm between curve points is necessary because SolidWorks will create a curve-fit to the points. The small spacing ensures a small error, or sagitta, in curve fit from linearity between points. Check Spacing The Check Spacing code subsection performs an exhaustive check on the curves created in the previous subsection to ensure that none of the curves will intersect with one another. If any curves are found to intersect, the code flags these two as intersecting, and logs the locations along each curve where the intersection occurs in the log file. Later, this information is conveyed to the user. Write PDF The Write PDF subsection creates a PDF which contains information including: a cylinder base drawing with each hole labeled, a table describing the insertion length of each catheter, and other relevant patient, plan, and cylinder information. Save Info All the patient and cylinder information is saved to a reference XML file in the patient custom cylinder applicator log folder. In addition, any relevant calculation and error information is saved to a text log file for debugging and reference purposes. 40 Update User The User Results section relays information relevant to the user once the calculations are complete. If the export is successful and there are no errors, the user is notified that the export is complete and a hyperlink to the folder containing the export information is provided to the user for reference. If there are errors, the error details are also provided. The user may choose to continue with the export and ignore the errors, or the user may abort the export. If the user chooses to abort, they may then tweak their design, based on the error information provided, and restart the code. Log File The log file for each export is saved in the export folder and includes log information for many of the calculations performed by the script. Transfer File The transfer file created by the Save Info code block contains a serialized XML formatted version of the patient and applicator class instances. This allows for another program to recreate these exact class instances, enabling transfer of the relevant information about a patient and PSCT between two applications. Cylinder Applicator Creator 3.4.3The Cylinder Applicator Creator functions as a converter between a set of patient specific variables related to the design of an individual PSCT, to a 3D printable model representation of that PSCT by interfacing with the Solidworks API. The SolidWorks API is a set of reference files which allow a programmer to control the SolidWorks application using C# via functions in these reference files. The SolidWorks API reference documentation is available online and locally to provide information useful to programmers intending to write code which can interface with SolidWorks [42]. Since a 3D model of the PSCT is required for 3D printing, and because 3D modelling of these applicators manually, even from template models, would be time consuming, a goal of this project was to automate the model creation. An application has been developed which uses the applicator design as described in section 3.3.2 and the transfer file created by the ESAPI Cylinder Information Exporter to create a 3D model of the PSCT using the SolidWorks API. The application can be launched from the desktop, and requires minimal user input to function. Once the 3D model design has been created for an individual patient the PSCT can be 3D printed. The following sections describe the Cylinder Applicator Creator application, outlining the functionality and code. 41 3.4.3.1 Graphical User Interface The GUI for the Cylinder Applicator Creator is quite simple (Figure 3.4). The user is required to browse to the folder in which the transfer file for a patient plan is saved. The user also has the option to rename the 3D model part name. Once the âCreate Applicatorâ button is clicked, the 3D model is created by the application. 3.4.3.2 Code Structure Get Variables The Get Variables code subsection de-serializes the transfer file in the patient plan folder. This writes the important variables relevant to the creation of the patient specific applicator. Generate Model The Generate Model subsection is where the 3D model is created. The subsection begins by instantiating an instance of the SolidWorks application in the background. Once the application is open, a series of steps including extrusion, chamfering, rounding, and path insertions is followed, resulting in the Patient Specific Cylinder Applicator 3D model. Figure 3.4: Cylinder Applicator Creator GUI 42 Once the model is created, the model is saved both as a STL and SLDPRT file type. The STL file type is used for 3D printing, and the SLDPRT file type is kept for reference in case any manual edits to the applicator design are desired. Update User The user is updated to the status of the model generation, and a link to the folder where the files were saved is provided. Cylinder Applicator Source Position Exporter (CASPE) 3.4.4An application called CASPE has been developed, which enables the user to export catheter geometry and plan information from the planning system, convert it to the Solidworks coordinate system, save the information to a transfer file, and create a log file of the calculation. Once this step is complete, the exported information may be used in CASPC to compare the catheter geometries of two plans, such as a pre-plan and post insertion plan. In order to export and manage the catheter information, a separate application from the ESAPI Cylinder Information Exporter was created. This is mainly due to the fact that CASPE application is much simpler and does not require the same intersection and other geometry checks as the ESAPI Cylinder Information Exporter, making the code much quicker to execute. The approach to the CASPE code and interface design, however, is similar. This section describes the application function and code of CASPE. 3.4.4.1 Graphical User Interface There is no GUI for this script. 3.4.4.2 Code Structure Get Info The Get Info code subsection retrieves patient and plan information using the ESAPI script context. A âPatientâ Class being previously defined in the main script, an instance of the patient class is instantiated, and information such as the patient and plan name, as well as source and shape information is defined. Assign Cylinder Variables The Assign Cylinder Variables code subsection takes information from the GUI that the user has accepted and assigns them to a new instantiation of a Cylinder class object. 43 Convert Coordinates The Convert Coordinates code subsection takes the shape information provided by ESAPI script context given in the default planning system coordinate system, and converts it first to the user coordinate system, and then to the SolidWorks coordinate system. Save Info All the patient and cylinder information is saved to a reference XML file in the patient custom cylinder applicator log folder. In addition, relevant calculation and any error information is saved to a text log file for debugging purposes. Transfer File The transfer file created by the Save Info code block contains a serialized XML formatted version of the patient and applicator class instances. This allows another program to recreate these exact class instances, effectively transferring the entire information about a patient and PSCT between two applications and having them represented in the same manner in each. This provides continuity between the different applications, improving code readability and editing ease. Cylinder Applicator Source Position Comparator (CASPC) 3.4.5An application, CASPC, has been written to compare the catheter geometries of two interstitial PSCT plans. This allows an operator to assess the geometric accuracy of individual insertions relative to the pre-planned catheter positions. Once the initial plan and final inserted catheter plan information have been exported using CASPE, CASPC compares the initial and final source positions for each catheter and determines a geometric comparison between the plan and final inserted positions. A text file with the resulting comparison statistics is saved to the patient plan folder. The CASPC application allows the user to assess the accuracy of a 3D printed applicator. This has been used to assess the performance of the workflow and manufacture in initial testing and will be useful in the future as the process is refined. In order to assess the performance of the workflow, one useful metric is the geometric error of the source positions for each catheter, and for the cylinder as a whole. Additionally, this application can be used to assess the accuracy of catheter insertions, both in vitro and in vivo. The application has already been used to assess the accuracy of plan insertions in gel phantoms and can be similarly used to assess the accuracy of patient implants (Section 3.5.1). Two plans are compared using the exported transfer files from CASPE. The CASPC software GUI, code structure, and result files are dscribed in detail below. 44 3.4.5.1 Graphical User Interface The GUI for the CASPC application is shown below (Figure 3.5). The user is prompted to select two folders which contain the transfer files for each of the plans to be compared. Once two plans are selected and the âCompareâ button is clicked, the software performs the calculations as described below. 3.4.5.2 Code Structure Get Variables The Get Variables code subsection de-serializes the transfer files in the patient plan folder. This writes the important variables relevant to the creation of the patient specific applicator for each of the two plans being compared. Compare Plans The Compare Plans code subsection calculates the average Euclidian distance differences between the two plans for each corresponding source (e.g. preplan and inserted) and computes the standard deviation in the average distance. Save Results The calculated results are formatted and saved to a new results text file in the patient folder. Update User The application window lets the user know that the calculation has been completed and provides a link to the folder location where the results file was saved. Summary 3.4.6Custom scripts and applications have been written to facilitate the design and assess the performance of Patient Specific Cylindrical Applicators. The design criteria are satisfied by this code. This provides a user-friendly workflow for the creation of PSCTs. Figure 3.5: GUI for CASPC 45 While the previous subsections show that the code satisfies design criteria, it does not show that the created cylinders perform effectively. In the following Sections, the validation testing of the Patient Specific Cylinder Applicator is described. 3.5 Geometric and Insertion Validation of 3D Printed PSCTâs It was necessary to assess what accuracy can be expected by the insertion of a catheter within the PSCT. Two new plans and custom PSCTâs were created for 2 previously treated patients and insertion was simulated on a gel phantom. A CT image set of the gel phantom was acquired and fused with the original patient images. The plan was re-optimized using the final catheter positions. A geometric comparison of the pre-planned and re-optimized dwell positions was calculated. The manufacturing and simulated surgical procedure was completed twice, in order to assess the dosimetric and geometric reproducibility of a single plan. Finally, the plan produced using the custom applicator was compared to the treated plans. In addition, various measurements were made of the major dimensions of each PSCT, in order to assess what the expected accuracy of PSCT manufacturing will be. Testing the geometric accuracy of a set of 3D printed PSCTâs and assessing the effects of any inaccuracies on patient plan dosimetry is an important step in understanding the case for the utility of the PSCT tool. This allows the operator and other clinicians to be confident in the reliability of the workflow and device at future testing of the PSCT, as the next logical step in device assessment will be in actual patients, once sterilization validation is complete. Though ideal, a comprehensive and in-depth assessment of the various potential errors associated with the current workflow would require a rigorous examination of errors and error propagation throughout the planning, manufacturing, and implant processes. In order to limit the amount of time required to perform preliminary assessment, the implant step was simulated in a static gel phantom instead of a phantom with tumour and organ volumes. This simplification results in an assessment that ignores the potential uncertainties in PSCT location and orientation, while still providing data on the applicator print quality, insertion accuracy, and the effects that these variations will have on plan dosimetry. Operator expertise and future testing will be relied upon to address potential PSCT placement location and orientation errors. Given that post-insertion CT imaging is standard for patients undergoing interstitial vaginal brachytherapy at BC Cancer â Kelowna, in this workflow the dwell positions and times for each applicator are re-planned or assessed postoperatively. This allows for the plan to be adapted according to any geometric inaccuracies in applicator manufacture, applicator placement, and catheter insertion. That said the clinicians at BC Cancer â Kelowna feel 46 that the device should be tested on a phantom which is mechanically and geometrically similar to , before testing the device on actual patients. This will be done in future work. patient anatomyA new workflow for Interstitial Gynecological HDRBT is proposed as a part of this research and development. Figure 3.7 and Figure 3.7 respectively show the current and proposed workflows for Interstitial Gynecological Brachytherapy at BC Cancer â Kelowna. In order to assess errors and problems associated with manufacturing the PSCT, each test of a PSCT for a previously treated patient followed the proposed workflow. This way the proposed workflow order and practices could be evaluated while simultaneously assessing the quality of printed applicators and the accuracy of insertions in phantom. Figure 3.6: Current Freehand Interstitial Catheter and Cylinder HDR Brachytherapy Workflow 47 In order to assess these geometries and their effects, the variables that were tested were PSCT diameter, PSCT length, PSCT guide bore diameter, and dwell position. From the inserted dwell positions, the resultant dosimetry for HRCTV and OARs could be calculated. The following subsections describe in detail the materials and methods used to assess these parameters, the results, and some concluding thoughts. Experimental Design 3.5.1Randomized Patients Each test patient used to assess the PSCT had been previously treated at BC Cancer for vaginal or vaginally recurrent endometrial cancer using intracavitary and/or interstitial BT. Thus, HRCTV and OAR contours were available for each patient. and XX show treatment planning software screenshots of the HRCTV contours, digitized interstitial needles, and treated dose distributions. The prescribed dose to the HRCTV for Patient 1 and 2 were 800cGy and 600cGy per fraction respectively. Figure 3.7: Proposed PSCT HDR Brachytherapy Workflow 48 Planning For each test patient, a new plan was created using the Eclipse planning software. The number of catheters and dwell times and positions were determined by the planner for each patient. The number of catheters allowed per PSCT is a minimum of one and no maximum. Of course, the number of guide bores is physically limited by the space available in the applicator. With the PSCT, a better plan than currently possible may be achievable, meaning higher or similar tumour dose coverage accompanied by similar or lower doses to OARs. Once each plan was approved by an oncologist, the ESAPI Cylinder Information Exporter and Cylinder Applicator Creator were used to create the sample PSCT. For the purposes of this study the planning goals were to increase the HRCTV D90 and V100, relative to the delivered treatment, while maintaining the OAR doses to clinically acceptable levels. OAR dose limits are not well defined in literature nor by governing bodies, but as a starting point the limits for cervical cancer are used: Rectum and Sigmoid = <3.9 Gy per fraction, Small Bowel < 2.3 Gy per fraction, Bladder < 5.5 Gy/per fraction. Because there is scant evidence, the trade-offs and relative importance is ultimately a clinical decision. Axial View A-P View Figure 3.8: Patient 1âs treated interstitial treatment plan. Blue shows HRCTV. Red shows HRCTV D90. Green/Pink shows the catheters. Axial View A-P View Figure 3.9: Patient 2âs treated interstitial treatment plan. 49 Pre-Plan Dosimetry Assessment Once planning was complete, a 3D dose calculation was performed, and important dosimetric quantities were recorded, including HRCTV V100 and D90 dose coverage, and OAR D2cm3. These doses represent the estimated dose that the HRCTV and OARs would receive if the treatment was executed exactly as planned, assuming no PSCT manufacturing, placement, or catheter insertion geometry inaccuracies. Manufacturing The 3D models were then printed using the MakerBot Replicator 2, with print settings of 0.1mm layer height, and 10% infill. The material used for this test was ABS. A typical print time for one PSCT was approximately 8 hours. Caliper Measurements Once sample PSCTâs were 3D printed, they were tested for dimensional accuracy. Outer diameter was measured at base, mid-length, and one centimeter before the rounded top start. Outer diameter measurements were averaged for each device. Overall length was also measured for each device. Dry Catheter Insertion Test For each sample PSCT, a catheter was passed through each guide bore to ensure that a minimum diameter sufficient to allow smooth transit of the catheter had been achieved. If a catheter did not transit through a guide bore easily, the guide bore was cleaned using a pipe cleaner and/or water and/or compressed air. A catheter needed to be able to transit each guide bore before the PSCT was used for the next step in the experiment. Phantom Creation Each phantom was created using a mixture of Knox Gelatine and water (28g Knox to 1L water). The mixture was set in a rectangular container, with the PSCT fixed perpendicular to the waterâs surface and the cylinder base plus 3-5cm of cylinder body extending out of the gel surface as seen in Figure 3.10. Catheter Insertion in Phantom Once the gelatine was set, catheters were inserted into the PSCT. Using the insertion depths as prescribed by the PSCT OR Reference Sheet, each catheter was inserted and locked using a PSCT collet. After catheter insertion, the PSCT in phantom was CT scanned. 50 CT Scanning Each PSCT and phantom was CT scanned at BC Cancer â Kelowna using a GE LightSpeed RT16 (GE Medical Systems, LLC, Waukesha, WI) CT scanner. Image Registration Each PSCT CT image set was imported into the planning software and rigidly registered to the existing patient images (MRI). The cylinder body was registered to the inserted template applicator visible on the existing MRI images. Inserted Catheter Registration A copy of each PSCT Pre-Plan was made. The catheter locations of the new plan were then adjusted to align with the imaged locations of the catheter. Inserted Pre-Plan Dosimetry Assessment Once the planned catheter positions are adjusted to the inserted positions, a 3D dose calculation was performed using the preplanned dwell times. Relevant dosimetric quantities were recorded, including HRCTV V100 and D90 coverage, and OAR D2cm3. These doses represent the estimated dose that the HRCTV and OARs would receive if the mock treatment was immediately performed without adjustment of the preplanned source position and dwell time values to account for insertion and PSCT geometric inaccuracies. Figure 3.10: General workflow of the A: treatment planning. B: CAD modelling, C: 3D printing, D: 3D print validation, and E: insertion of catheters into the PSCT in gel. A D C B E 51 Re-Optimized Plan Dosimetry Assessment Each plan was re-optimized manually on the basis of the actual catheter positions in the registered phantom. The resulting calculated doses represent the estimated dose to the HRCTV and OARs if the treatment was performed on the phantom, which models the insertion and PSCT geometric inaccuracies. Treated Pre-, Inserted and Re-Optimized PSCT Plan Comparison Each of the re-optimized plans was compared to the original treated plan for important plan characteristics: number of total catheters, number of interstitial catheters, total interstitial catheter length, HRCVT V100, HRCTV D90, Bladder D2cm3, Rectum D2cm3, Sigmoid D2cm3, and Bowel D2cm3. The treated plan value difference (as a percentage of the treated plan) was calculated for each of the pre-, inserted, and re-optimized plans. Pre-, Inserted and Re-Optimized PSCT Plan Comparison Similar to above, the pre-plan value difference (as a percentage of the pre-plan) was calculated for each of the inserted and re-optimized plans. Geometric Accuracy Assessment The CASPE and CASPC applications were used to compare the inserted position of each catheter to the original preplan. This provides a comparison of the overall combined geometric accuracy of catheter insertion in the phantom and 3D printing, as it affects the final catheter position. 3.6 Chapter Summary Materials Selection 3.6.1The material selected for the PSCT needed to be sterilizable, 3D printable, similar to common medical materials and dosimetrically water equivalent. In order to select a material which satisfied these requirements a market survey was conducted to compare the available materials. Factors including cost, ease of use, and other factors were also considered. PEEK, a popular engineering thermoplastic, has been provisionally selected for the PSCT. While other materials may be acceptable for this project, PEEK is a common plastic used in medical applications, is familiar to BC Cancer â Kelowna staff, is increasingly popular as a 3D printing plastic, and is assumed to be water equivalent in BC Cancer Kelownaâs treatment planning practices. 3D Printer Selection 3.6.2As BC Cancer â Kelowna did not have a 3D printer capable of manufacturing using PEEK, a capable 3D printer was needed for the later stages of the project. A survey and trade-off comparison of 52 commercially available, PEEK-compatible 3D printers was conducted and a 3D printer which best satisfied printer quality, capability, cost, and clinical concerns was selected. The AON-M2 3D printer from AON was selected and purchased. This printer will allow for excellent PSCT print quality and reliability, and is of sufficient quality and size to be used for many other 3D print projects at BC Cancer â Kelowna. Cylinder Applicator Design 3.6.3The design requirements of the PSCT were detailed, and were defined before initiating the design process so that the applicator would satisfy any and all clinical requirements. The applicator design was then completed. It is composed of a solid cylinder with a rounded top, catheter guide bores with counter bore holes which can later be tapped during manufacturing, and mounting loops for fixation to the patient. A reflection on the design requirements shows that they are satisfied by the applicator design. Code 3.6.4In order to automate the design and generation of a PSCT, code was written to take information from the Eclipse Planning System, manipulate that data, and generate a 3D model based on these data. There was also a need to develop scripts which would allow the user to generate a comparison between two plans, in order to assess the accuracy of inserted catheter geometries as compared to preplanned geometry. Code was written which can interface with the planning system using the Eclipse Scripting API, extract data and generate a 3D model using the Solidworks API, as well as compute various geometrical statistical values. These scripts and applications are able to extract data from a given treatment plan and generate a 3D model in STL format. This can later be 3D printed and used to guide catheter insertion. Validation Testing 3.6.5It was necessary to assess what accuracy can be expected when a catheter is inserted using the PSCT. A new plan and custom applicator were created for 2 previously treated patients and a catheter insertion was simulated in a gel phantom. A CT image set of the gel phantom was acquired and fused with the original patient CT. The plan was re-optimized using the physical catheter positions in the phantom. A geometric comparison of the pre-planned and re-optimized dwell positions was calculated. The manufacturing and simulated surgical procedure was completed twice, in order to assess the dosimetric and geometric reproducibility of a single plan. Finally, the dosimetry of the plan produced using the custom applicator was compared to the treated plans. In addition, various measurements were made of the major dimensions of each PSCT, in order to assess what the 53 expected accuracy of PSCT manufacturing will be. Remaining work includes future testing on , sterilization phantoms which are mechanically and geometrically similar to patient anatomyvalidation, and eventually a clinical trial. 54 Results and Discussion Chapter 4:4.1 Results Dosimetry Assessment 4.1.1The dosimetry assessment results for each patient test are tabulated below. For both plans, the target HRCTV V100 is 100% per fraction, the HRCTV D90 targets were 800 cGy for patient 1 and 600 cGy for patient 2, per fraction. D2cm3 limits for Bladder, Rectum, Sigmoid, and Small Bowel for Pre-Plans and Re-Plans were based on the patients treated plan. Each OAR dose was attempted to be brought as low as possible. If the D2cm3 for a given OAR was higher than the Treated Plan dose, the conditions on other OARs and the HRCTV dose-volume metrics were relaxed in order for the OAR dose to be below or within about 10% of the Treated Plan D2cm3 for that OAR. However, for patient 2, the approving oncologist preferred a plan with better treatment coverage to the HRCTV but higher doses to the OARs. C D A B Figure 4.1: A and B: Patient 1âs cylinder and freehand interstitial treatment plan, A-P and Axial views respectively. C and D: Patient 1âs interstitial BT PSCT preplan, A-P and Axial views respectively. HRCTV contours are shown in light blue and the 100% Isodose line is shown in red. Interstitial needles are visible on the CT imagery, and are digitized in green and pink. 55 Table 1: Test Patient 1 selected plan dosimetry values for the patients actual treated plan, the PSCT pre-plan, inserted plan, and re-optimized treatment plan. Prescribed dose per fraction is 800cGy for 4 fractions. Treated Plan PSCT Pre Plan Inserted Plan Inserted Plan 2 ReOp 1 ReOp 2 HRCTV V100 (%) 96 97 97 97 96 97 HRCTV D90 (cGy) 847 872 868 868 858 872 Bladder D2cm3 (cGy) 612 595 601 601 612 622 Rectum D2cm3 (cGy) 558 569 565 565 551 560 Sigmoid D2cm3 (cGy) 346 356 358 358 336 349 Small Bowel D2cm3 (cGy) 183 183 185 185 180 186 D B C A Figure 4.2: A and B: Patient 2âs cylinder and freehand interstitial treatment plan, A-P and Axial views respectively. C and D: Patient 2âs interstitial BT PSCT preplan, A-P and Axial views respectively. HRCTV contours are shown in light blue and the 100% Isodose line is shown in red. Interstitial needles are visible on the CT imagery, and are digitized in green and pink. 56 Table 2: Test Patient 2 selected plan dosimetry values for the patientsâ actual treated plan, the PSCT pre-plan, inserted plan, and re-optimized treatment plan. Prescribed dose per fraction is 600cGy for 4 fractions. Treated Plan PSCT Pre Plan Inserted Plan Inserted Plan 2 ReOp 1 ReOp 2 HRCTV V100 (%) 87 98 93 92 98 96 HRCTV D90 (cGy) 572 716 646 627 679 661 Bladder D2cm3 (cGy) 789 805 795 808 819 836 Rectum D2cm3 (cGy) 736 787 823 817 792 797 Sigmoid D2cm3 (cGy) 287 312 254 260 306 274 Small Bowel D2cm3 (cGy) 421 542 432 424 538 514 Table 3: Test patient 1 inserted and re-optimized plan comparisons to treated plan. PSCT Preplan Difference from Treated Plan (%) Inserted Plan Difference from Treated Plan (%) Inserted Plan 2 Difference from Treated Plan (%) Re-Plan 1 Difference from Treated Plan (%) Re-Plan 2 Difference from Treated Plan (%) HRCTV V100 (%) 1.0% 1.0% 1.0% 1.0% 1.0% HRCTV D90 (%) 3.0% 2.5% 2.5% 2.5% 3.0% Bladder D2cm3 (cGy) -2.8% -1.8% -1.8% -1.8% 1.6% Rectum D2cm3 (cGy) 2.0% 1.3% 1.3% 1.3% 0.4% Sigmoid D2cm3 (cGy) 2.9% 3.5% 3.5% 3.5% 0.9% Small Bowel D2cm3 (cGy) 0.0% 1.1% 1.1% 1.1% 1.6% Table 4: Test patient 2 inserted and re-optimized plan comparisons to treated plan. PSCT Preplan Difference from Treated Plan (%) Inserted Plan Difference from Treated Plan (%) Inserted Plan 2 Difference from Treated Plan (%) Re-Plan 1 Difference from Treated Plan (%) Re-Plan 2 Difference from Treated Plan (%) HRCTV V100 (%) 13.1% 7.1% 5.6% 5.6% 10.0% HRCTV D90 (%) 25.3% 13.0% 9.8% 9.8% 15.6% Bladder D2cm3 (cGy) 2.1% 0.8% 2.4% 2.4% 6.0% Rectum D2cm3 (cGy) 6.9% 11.8% 11.0% 11.0% 8.3% Sigmoid D2cm3 (cGy) 8.7% -11.5% -9.5% -9.5% -4.6% Small Bowel D2cm3 (cGy) 28.6% 2.6% 0.7% 0.7% 22.0% 57 Table 5: Test patient 1 inserted and re-optimized plan comparisons to preplan. Inserted Plan Difference from Pre Plan (%) Inserted Plan 2 Difference from Pre Plan (%) Re-Plan 1 Difference from Pre Plan (%) Re-Plan 2 Difference from Pre Plan (%) HRCTV V100 (%) 0.0% 0.0% -1.0% 0.0% HRCTV D90 (%) -0.5% -0.5% -1.6% 0.0% Bladder D2cm3 (cGy) 1.0% 1.0% 2.9% 4.5% Rectum D2cm3 (cGy) -0.7% -0.7% -3.2% -1.6% Sigmoid D2cm3 (cGy) 0.6% 0.6% -5.6% -2.0% Small Bowel D2cm3 (cGy) 1.1% 1.1% -1.6% 1.6% Table 6: Test patient 2 inserted and re-optimized plan comparisons to preplan. Inserted Plan Difference from Pre Plan (%) Inserted Plan 2 Difference from Pre Plan (%) Re-Plan 1 Difference from Pre Plan (%) Re-Plan 2 Difference from Pre Plan (%) HRCTV V100 (%) -5.3% -6.6% -0.9% -2.8% HRCTV D90 (%) -9.8% -12.4% -5.2% -7.8% Bladder D2cm3 (cGy) -1.3% 0.4% 1.8% 3.8% Rectum D2cm3 (cGy) 4.6% 3.9% 0.7% 1.3% Sigmoid D2cm3 (cGy) -18.6% -16.8% -2.1% -12.3% Small Bowel D2cm3 (cGy) -20.2% -21.7% -0.7% -5.1% 58 Caliper Measurements 4.1.2For each PSCT, three measurements were taken for the diameter (at the top, middle, and base of the applicator) and one for overall length. The results are tabulated for each PSCT below. Table 7: For each 3D printed PSCT, the diameter was measured in three places and the overall length is measured. The measured values are all within 0.8mm. Designed Diameter (mm) Diameter (mm) Designed Length (mm) Length (mm) Uncertainty (mm) Patient 1 Print 1 30.0 29.8 150.0 149.3 0.05 29.6 29.7 Patient 1 Print 2 29.7 149.3 29.9 29.9 Patient 2 Print 1 29.2 120.0 119.5 29.2 29.3 Patient 2 Print 2 29.7 119.2 29.9 29.8 Geometric Accuracy Assessment 4.1.3Geometric variations in dwell position are tabulated below. Table 8: The estimated source position displacement for each PSCT tested is determined by the digitization of the final catheter position after insertion, compared to the plan position. Average Source Position Displacement (mm) Standard Deviation (mm) Patient 1 Test 1 0.7 0.2 Patient 1 Test 2 1.3 0.2 Patient 2 Test 1 3.8 2.6 Patient 2 Test 2 7.1 5.9 Table 9: The number of interstitial and intracavitary catheters, total catheters, and total interstitial length are shown. Notably, the PSCT plans resulted in decreased numbers of catheters, and total interstitial length. Number of Interstitial Catheters Number of Intracavitary Catheters Total Catheters Total Interstitial Length (mm) Patient 1 Treated 14 1 15 1470 Patient 1 PSCT 0 9 9 0 Patient 2 Treated 9 1 10 320 Patient 2 PSCT 9 0 9 190 59 4.2 Discussion Treatment Planning with the PSCT 4.2.1The PSCT preplan dosimetry assessment provides a theoretical estimate of what dose could be deliverable to each volume of interest in the treatment area, were a PSCT used for catheter guidance. Of course, these plans are not necessarily clinically relevant because they do not represent a delivered or even necessarily deliverable dose, since the catheter insertion has not yet occurred at this point in the treatment process. What the preplan dosimetry does provide the operator is the ability to preplan the positions of the catheters based on dosimetry, which gives a pre-insertion quantitative rationale for interstitial catheter placement location. While preplanning catheter positions is technically possible with current workflows, recreating preplanned positions in the patient via freehand placed catheters is difficult, so preplanning the positions is of little practical value. The ability to create a PSCT pre-plan which is potentially superior to other catheter delivery methods provides an indication that a PSCT-delivered plan may be a preferable delivery alternative. However whether or not a PSCT-delivered plan will be superior to current methods is yet to be determined, as the extent to chich the catheters might deflect from their planned trajectory within tumour tissue is not known. 3D Printer Efficacy 4.2.2 Caliper measurements were conducted to ensure that the 3D printer could print the PSCTâs to a reasonable tolerance. Within a millimeter is acceptable for major dimensions. The caliper measurements show that the average major dimension error in printing a PSCT is well within a millimeter. While it is important to keep these variations small for consistency, some variation in length and diameter can be tolerated, but how much is not yet known. For the purposes of these tests, the accuracy of the 3D printer is adequate to reliably place the catheters within the applicator. Insertion Inaccuracy Effects on Treatment Quality 4.2.3The inserted pre-plan dosimetry assessment gives the operator the ability to assess the dosimetric implications of catheter placement errors. Notably, in this study, each of the inserted pre-plans is still preferable to the originally treated plan, meaning that an inserted pre-plan, without post-insertion dwell time optimization, is preferable for these patients, even though insertion errors exist and the source dwell times have not been re-optimized. That said, this does not mean that a pre-planned PSCT inserted into an actual patient will result in a preferable treatment, because the effects of applicator roll, pitch, and placement errors as well as effects of tissue density and pliability on interstitial catheter deflection are as yet untested. Before testing the applicator on patients, these untested variables will be assessed in phantoms which are mechanically and geometrically similar to patient anatomy.60 The re-optimized plans post-insertion represent what would be the planned treated dose to the phantom, were a delivery given. The doses estimate what the dosimetry to the target volumes and OARs may be achievable, given the preplanned catheter positions, insertion inaccuracies, post-insertion CT and re-planning. In each case, the re-optimized plan was slightly inferior than the pre-plan, though it was preferable to the patientâs actual treated plan using freehand catheter placement, thus providing a rationale to test the applicator further in a phantom which is mechanically and . geometrically similar to patient anatomyThe dosimetry assessment shows that the final, re-optimized plan dose metrics were generally well within 5% of the preplanned values, barring some anomalies. While some values were larger, this early result suggests that with further development, the PSCT will be a beneficial surgical tool. For the patient 1 test, the accuracy of catheter placement was quite good. This applicator, having no interstitial needles planned, is effectively a very similar design to the Miami Applicator (Varian Medical Systems, Palo Alto, CA). Since the 3D printing costs of one applicator using PEEK material is on the order of $100, and since the Miami Applicator costs on the order of $30000 to buy from a commercial supplier and is only certified for 100 sterilization cycles. This method provides BC Cancer an opportunity for bypassing commercial supplier chains for the Miami Applicator and similar devices, and making their own at a substantially reduced cost. A close reading of the results for Test Patient 2 () shows that the doses to the Bladder, Rectum, and the Small bowel are higher than that of Test Patient 1 (Table 1), despite having the same prescription doses. This is in large part due to the geometry differences of the GTV, HRCTV, and OARs between the two patients. Since Test Patient 2âs PSCT treatment plan included interstitial needles, the source dwell positions are closer to certain OARs. The geometric accuracy assessment shows that the combined effects of software interpolation and smoothing of catheter curves, 3D printing, and catheter insertion, can result in a range of source position errors. Efforts to minimize this error are ongoing, being addressed by development of better catheter insertion procedures, and by procuring a 3D printer with better print accuracy. 4.3 Conclusion A new workflow, software, and device for Interstitial Gynecological HDRBT is proposed as a result of this research and development. Aspects of the workflow, software, and device have been tested in order to complete a preliminary assessment of the expected changes to the current treatment workflow. The geometric accuracy of two 3D printed PSCTâs, and the resultant effects that combined 3D printing and catheter insertion inaccuracies had on the target and organ dosimetry has been tested. 61 The effects of insertion inaccuracies have been small enough produce a treatment arrangement which, with the preplanned source dwell times, is a competitive plan to the originally treated plan. Upon re-optimization, each plan was improved further. This finding suggests that this workflow could provide improved and more reliably deliverable treatment plans to actual patients, though the results do not consider applicator insertion inaccuracies. In order to be confident that a treatment plan using the PSCT will be reliably achievable, further testing on a phantom with similar mechanical properties to that of tissue is necessary. In addition, a number of future tests and developments have been described which will be necessary in order for this device and workflow to be practically realistic in a clinical setting. 62 Future Work Chapter 5:5.1 Catheter Trajectory Assessment in Tissue Representative Phantom A catheter tracking assessment in phantoms composed of materials with similar density and elasticity to that of tissue is planned. The desired outcome of this experiment is to understand the accuracy with which catheters can be inserted interstitially using the PSCT in a phantom which is mechanically . This will provide an estimate as to how accurately these and geometrically similar to patient anatomytemplates can place catheters interstitially in actual patients. The phantoms will be CT scanned with a dummy cylindrical applicator inserted, and a treatment plan will be created based on these images using a sample tumour volume imposed on the image. A PSCT will be 3D printed and a test insertion will be simulated in the phantom. Once this is complete the phantom will be rescanned with the template and catheters inserted, and the geometric variation between the inserted and planned positions of the catheters will be calculated. In addition, the resultant insertion geometry will be used to calculate the dose that would be delivered if the original dwell times were used. Following this, the dwell times will be re-optimized to compare the pre-operation treatment plan to the re-optimized inserted treatment plan. The geometric accuracy and the resultant treatment planning accuracy of interstitial brachytherapy plans inserted in a phantom using the PSCT will be assessed. These results will serve as a starting point in deciding whether or not the workflow can be used in an actual patient. In practice, the clinical team will evaluate this method relative to current clinical practice and judge whether it provides an easier or more consistent means of implant with dosimetric results that are equivalent or better than currently achievable. There are two primary concerns with this research plan. First, if a suitable phantom (model vaginal tissue density and elasticity) cannot be created or purchased, then it will be difficult to assess if the catheters will be able to extend to preplanned positions accurately in actual tissue. Commercial training models are available which claim to represent tissues accurately. Computerized Imaging Reference Systems, Inc. is one example provider, offering similar phantoms in the $1000 range. Purchase of these phantoms is budgeted for future work, but it would be more cost effective to create a simpler version, as there is some custom phantom manufacture expertise in-house at BC Cancer â Kelowna. Second, if the catheters are unable to penetrate the model tissue properly, cannot be placed accurately, or if they move the surrounding tissue too much, then this may be an indication that the catheters will not be able to properly penetrate and deliver a source accurately to the planned location 63 via the PSCT. If this is the case, some design refinement and operational limitations may be necessary. For example, if catheters are found to inadequately penetrate dense tumour tissue, a flexible internal guide can be developed to increase catheter rigidity. Similar non-flexible devices are used to assist straight guidance of longer interstitial catheters in perineal templates. Ultimately, it will be up to the clinical team to assess whether they feel comfortable moving forward to test the template in an actual patient. Promisingly, one group in Denmark has tested a similar idea in patients, without any testing in phantom first [12]. Their reported success is an indication that the approach should be feasible in a patient. 5.2 Dosimetric Characterization of 3D Printed PEEK materials The dosimetric characterization research is designed to assess the percent depth dose (PDD) of 3D printed PEEK. This test intends to understand if the 3D printed PEEK materials used in the PSCT have dosimetric characteristics similar to water. The first experiment will measure the PDD of 3D printed PEEK blocks with varying infill percentages. This experiment will consist of 3D printing a number of PEEK templates with an extruded slot in which a radiographic film may be inserted. The templates will also have a guide bore through which a radioactive source of Iridium-192 may be transmitted. The entire experimental template, except for the portion which contains the source, will be submerged in water to eliminate the potential for an air gap at the radiographic film. The Iridium-192 HDR source will be used to irradiate the device and film, after which the film will be processed to compute the dose deposited as a function of the distance from the source. The distance from the source dwell position to the radiographic film at different film locations will be known based on the 3D model of the phantom, and a PDD will be developed based these distances and the relative dose delivered to the radiographic film, as measured. This PDD will be compared to one measured using only water as a buildup material. If infill percentage influences the PDD, the infill percentage will be varied on PSCT models in order to achieve an infill percentage that matches the PDD of water most closely. The PEEK infill percentage with a closest to water, or which provides the most economical PDD, which is still acceptably close to dosimetry in water, will be chosen as the default infill percentage for the template. To the authorâs knowledge, the effect of infill percentage on the PDD has not been tested. If an effect is measured which is large enough to be dosimetrically meaningful, it may be difficult to account for 64 this without using 100 percent infill. However a large effect is not expected as the radial distance in the dose deposition fall off is dominant in HDR dosimetry. 5.3 Software Development While a proof of principle software package had been written for PSCT design automation, several improvements will be required before the software be suitable for a commercial or clinical setting, independent of the BC Cancer â Kelowna team. Improvements to the plan-checking algorithms, operating room documentation creation automation, and additional customizability for the creation of templates are necessary before the software could be deployed in a general clinical setting. Most of this work requires general programming skills, rather than scientific development, and could therefore be completed by a summer computer science student. 5.4 Workflow Development While work continues on the above research objectives, manufacturing and insertion techniques for the PSCT development will continue. This requires having each team member perform the task which they would be responsible for in an actual patient, to address problems in this workflow from plan creation through treatment delivery until the workflow is sufficiently well understood, tested, and ready to be tested on a patient. 5.5 Quality Assurance Procedure Development A quality assurance procedure will be developed and tested to ensure that 3D printed applicators are manufactured as designed. The QA activities will consist of: -A visual check for print aberrations, voids, etc. -Weighing the 3D printed applicator to quickly check that approximately the correct amount of 3D printed material has been used. -Mechanical check to ensure that the catheters run properly through each guide bore. -Mechanical measurements of the major dimensions of the PSCT. -CT scanning the 3D printed applicator to check that the infill percentage is correct. -The geometries of the catheter holes will be compared to the planned orientations on the patient plan by registering the CT scan of the PSCT to the patient plan images. 65 While most of these checks are simple to perform, the last two are more involved and some testing on the procedure may be required. QA documentation forms and procedure information will be developed for these activities. 5.6 Other Applicators Naturally, a similar workflow to the one described in this thesis can be adapted to other applicators. Promising future templates would include a patient specific tandem and ring automated design, and contour-based templates where the bulk shape of the applicator is based on a set of contours (such as a 3D contoured volume of the vaginal cavity.) Compatible 66 Bibliography [1] PDQ Adult Treatment Editorial Board, âVaginal Cancer Treatment (PDQ®): Health Professional Version,â National Cancer Institute, 2019. [Online]. Available: http://www.ncbi.nlm.nih.gov/pubmed/26389242. [Accessed: 25-Jun-2019]. [2] PDQ Adult Treatment Editorial Board, âCervical Cancer Treatment (PDQ): Health Professional Version.â [Online]. Available: https://www.cancer.gov/types/cervical/hp/cervical-treatment-pdq. [Accessed: 21-May-2019]. [3] B. W. Stewart and C. P. Wild, Eds., World Cancer Report 2014. International Agency for Research on Cancer, 2014. [4] S. A. Sohaib, S. L. Houghton, R. Meroni, A. G. Rockall, P. Blake, and R. H. Reznek, âRecurrent endometrial cancer: patterns of recurrent disease and assessment of prognosis,â Clin. Radiol., vol. 62, no. 1, pp. 28â34, 2007. [5] J. L. M. Venselaar, D. Baltas, A. S. Meigooni, and P. J. Hoskin, Eds., Comprehensive Brachytherapy: Physical and Clinical Aspects. CRC Press, 2013. [6] M. K. Bucci, A. Bevan, and M. Roach, âAdvances in radiation therapy: conventional to 3D, to IMRT, to 4D, and beyond.,â CA. Cancer J. Clin., vol. 55, no. 2, pp. 117â34, 2005. [7] Y. Lin et al., âIntensity-modulated radiation therapy for definitive treatment of cervical cancer: A meta-analysis,â Radiat. Oncol., vol. 13, no. 177, 2018. [8] Varian Medical Systems, Varian Brachytherapy Applicators and Accessories. 2011. [9] Nucleotron, âBrachytherapy Applicators and Accessories,â 2012. [Online]. Available: http://www.scrim.ma/wp-content/uploads/2016/04/applicateurs.pdf. [Accessed: 22-Apr-2019]. [10] M. Carrara et al., âComparison of different treatment planning optimization methods for vaginal HDR brachytherapy with multichannel applicators: A reduction of the high doses to the vaginal mucosa is possible,â Phys. Medica, vol. 44, pp. 58â65, Dec. 2017. [11] D. B. Paterson, S. M. Pearson, and A. N. Wilson, âIntracavitary vaginal brachytherapy using a custom balloon applicator,â J. Med. Radiat. Sci., vol. 64, no. 4, pp. 310â314, 2017. [12] J. C. Lindegaard et al., âIndividualised 3D printed vaginal template for MRI guided brachytherapy in locally advanced cervical cancer,â Radiother. Oncol., vol. 118, no. 1, pp. 173â175, 2016. [13] B. G. Sorbe, G. Horvath, H. Andersson, K. Boman, C. Lundgren, and B. Pettersson, âExternal pelvic and vaginal irradiation versus vaginal irradiation alone as postoperative therapy in medium-risk endometrial carcinoma: A prospective, randomized study - Quality-of-life analysis,â Int. J. Gynecol. Cancer, vol. 22, no. 7, pp. 1281â1288, 2012. [14] P. Price and K. Sikora, Eds., Treatment of Cancer, 6th ed. CRC Press, 2015. [15] E. B. Podgoršak, Radiation Physics for Medical Physicists, 3rd ed. Springer Nature, 2016. [16] International Atomic Energy Agency, âLive Chart of Nuclides.â [Online]. Available: https://www-nds.iaea.org/relnsd/vcharthtml/VChartHTML.html. [Accessed: 24-Jun-2019]. [17] E. J. Hall and A. J. Giaccia, Radiobiology for the Radiologist, 7th ed. Wolters Kluwer, 2012. [18] R. Nath, L. L. Anderson, G. Luxton, K. A. Weaver, J. F. Williamson, and A. S. Meigooni, âDosimetry of interstitial brachytherapy sources: Recommendations of the AAPM Radiation Therapy Committee Task Group No. 43,â Med. Phys., vol. 22, no. 2, pp. 209â233, 1995. [19] M. Lederman, âThe early history of radiotherapy: 1895-1939,â Int. J. Radiat. Oncol. Biol. Phys., vol. 7, no. 5, pp. 639â648, 1981. [20] F. Bray, J. Ferlay, I. Soerjomataram, R. L. Siegel, L. A. Torre, and A. Jemal, âGlobal cancer statistics 2018: GLOBOCAN estimates of incidence and mortality worldwide for 36 cancers in 185 countries.,â CA. Cancer J. Clin., vol. 68, no. 6, pp. 394â424, 2018. [21] M. Joiner and A. van der Kogel, Eds., Basic Clinical Radiobiology. Hodder Arnold, 2009. [22] D. Buthiau and D. Khayat, Eds., CT and MRI in Oncology. Sprinver-Verlag Berlin Heidelberg, 1998. 67 [23] J. Pouliot, D. Tremblay, J. Roy, and S. Filice, âOptimization of permanent 125I prostate implants using fast simulated annealing,â Int. J. Radiat. Oncol. Biol. Phys., 1996. [24] J. T. Bushberg, J. A. Siebert, E. M. Leidholdt Jr, J. M. Boone, J. E. M. Leidholdt, and J. M. Boone, The Essential Physics of Medical Imaging, 3rd ed. Lippincott WIlliams & Wilkins, 2012. [25] J. C. A. Dimopoulos et al., âGEC-ESTRO Recommendations from Gynaecological (GYN) GEC-ESTRO Working Group (IV): Basic principles and parameters for MR imaging within the frame of image based adaptive cervix cancer brachytherapy,â Radiother. Oncol., vol. 103, pp. 113â122, 2012. [26] W. Small et al., âAmerican Brachytherapy Society consensus guidelines for adjuvant vaginal cuff brachytherapy after hysterectomy,â Brachytherapy, vol. 11, no. 1, pp. 58â67, 2012. [27] F. J. Rybicki and G. T. Grant, Eds., 3D Printing in Medicine. Springer Nature, 2017. [28] Y. Zhao et al., âClinical applications of 3-dimensional printing in radiation therapy,â Med. Dosim., vol. 42, no. 2, pp. 150â155, 2017. [29] N. Choi, âOptimized Environment Parameters from Dimensional Accuracy for FDM-type 3D Printing System,â J. Korean Inst. Ind. Eng., vol. 44, no. 1, pp. 9â17, 2018. [30] A. Kumar, W. T. Yap, S. L. Foo, and T. K. Lee, âEffects of Sterilization Cycles on PEEK for Medical Device Application,â Bioengineering, vol. 5, no. 1, p. 18, 2018. [31] VSHAPER, âVSHAPER 500 MED,â 2019. [Online]. Available: http://vshaper.com/en/3d-printers/500-med/. [Accessed: 23-May-2019]. [32] R. Y. Neches, K. J. Flynn, L. Zaman, E. Tung, and N. Pudlo, âOn the intrinsic sterility of 3D printing,â PeerJ, vol. 4, p. e2661, 2016. [33] M. F. Haefner et al., â3D-Printed masks as a new approach for immobilization in radiotherapy - a study of positioning accuracy,â Oncotarget, vol. 9, no. 5, pp. 6490â6498, 2018. [34] bccResearch, â3D Printing Software: Global Markets to 2023,â 2018. [35] British Columbia Ministry of Health, âBest Practice Guidelines For Cleaning, Disinfection and Sterilization of Critical and Semi-critical Medical Devices In BC Health Authorities.â 2011. [36] D. Chandler and R. Munday, A Dictionary of Media and Communication. 2011. [37] T. E. Attwood, P. C. Dawson, J. L. Freeman, L. R. J. Hoy, J. B. Rose, and P. A. Staniland, âSynthesis and properties of polyaryletherketones,â Polymer (Guildf)., vol. 22, no. August, pp. 1096â1103, 1981. [38] www.3dxtech.com, âThermax Peek 3D Print Filament,â 2019. [Online]. Available: https://www.3dxtech.com/thermax-peek-3d-printing-filament-natural/. [Accessed: 06-May-2019]. [39] AON3D, âThe AON-M2 Industrial 3D Printer,â 2019. [Online]. Available: https://www.aon3d.com/aon-m2-industrial-3d-printer/. [Accessed: 06-May-2019]. [40] Varian Medical Systems, âGammaMedplus iX, 3/24 iX Afterloaders Feature Sheet.â Palo Alto, CA, 2014. [41] Varian Medical Systems, âEclipse Scripting API Reference Guide.â Palo Alto, CA, 2015. [42] solidworks.com, âSolidworks API Help,â 2019. [Online]. Available: http://help.solidworks.com/2019/english/api/sldworksapiprogguide/welcome.htm. [Accessed: 06-May-2019]. 68 Appendix A: High Temperature 3D Printer Comparison 69 Appendix B: ESAPI Cylinder Information Exporter Code using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.Xml.Serialization; using SolidWorks.Interop.sldworks; using SolidWorks.Interop.swconst; namespace Applicator_Creator { #region Classes /// /// Patient Info contains all information about a patient. /// public class PatientInfo { public string PatientName; public string PatientID; // needed for save file name? public string PlanID; // public double OriginX; public double OriginY; public double OriginZ; public double shift; public List<PlanCatheter> CathList; public CylinderApplicator Applicator; } /// /// Plan Catherter will contain the plan information related to an individual catheter /// public class PlanCatheter { public int CathNumber; public int NumSeeds; public List<Seed> SeedList; public List<double[]> CathShape; } /// /// Seed contains the information about an individual seed. /// public class Seed { public double[] SeedPosition; public int SeedNumber; } 70 /// /// CylinderApplicator contains all the information about an individual cylinder applicator /// public class CylinderApplicator { public int NumCaths; public List<Curve> CurveList; //list of all the curves in a single cylinder applicator... public List<double[]> LastPointList; public List<List<double[]>> FirstThreeList; public List<List<double[]>> SeedPointsList; public List<double[]> FacePointList; public double CylinderLength; public double CylinderOD; public double GuideTubeID; public double FilletRadius; public double TubeOffset; public double TubeID; public double M4DrillIDforTap; public double M4DrillDepthforTap; public double M4ThreadMajorDiameter; } /// /// Curve contains the information for one single curve. /// public class Curve { public List<double[]> CathPath; //represents the xyz coordinates of the catheter path. public double DX; //start position in X-dir public double DZ; public static int CompareByY(double[] p1, double[] p2) { return p1[1].CompareTo(p2[1]); } } #endregion public class Program { #region Notes /* This program will allow the user to create a brachytherapy applicator using exported information from Eclipse (done using an eclipse plugin). A GUI will open, which will allow the user to select which patient to make the applicator for. The user will also be prompted to select the diameter and length of the applicator and the the type of applicator (cylinder to start) To Do: 1. GUI: -a. Browser which allows you to select the patient which you would like to use -b. Option to select applicator type -c. Diameter Selection (if cylinder) -d. Length Selection (if cylinder) -e. Length Tandem 71 -f. Diameter Tandem -e. "Generate Model" Button 2. Import - Import the patient data from where it was saved on the drive. - Define a new PatientInfo. 2. Math a. Shift Coordinates b. Write Curves c. Write Design File 3. Solidworks: a. Update full code to generate a cylinder b. Check Model c. Export to STL d. Save in Appropriate Folder */ #endregion #region Main -- Done /// /// The main entry point for the application. /// [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form1()); } #endregion #region Execute -- Done /// /// Everything that happens once the Create Applicator button is pressed. /// public void Execute(string filename, string filepath) { // Instantiate PatientInfo, a class native to this program. See below for Definition PatientInfo Patient1 = new PatientInfo(); #region Set Pathname ////Pathname for code used at BCCA string pathname = System.IO.Path.Combine(filepath, "PatientShiftCoordinates.txt"); ////Pathname used for my computer //string pathname = @"omitted filepath"; #endregion #region Get and Set Variables Required Patient1 = GetVariables(filepath); //Patient1.Applicator.CylinderOD = Convert.ToDouble(Diameter); //Patient1.Applicator.CylinderLength = Convert.ToDouble(Length); //Patient1.Applicator.GuideTubeID = Convert.ToDouble(GuideTubeDiameter); //using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) //{ 72 // file.WriteLine("Got XML Variables"); // file.WriteLine("Number of Catheters: " + Patient1.Applicator.CurveList.Count()); //} #endregion #region Design and Save Solidworks Model GenerateModel(Patient1, filepath, pathname); #endregion #region Check Model //CheckModel(); Not sure how to do this. Perhaps it is redundant since the user is required to set up the model to print on the 3d printer and is required to click print. Since they do these tasks manually, it may be incumbent on them to check the model using SW or using the 3d printing setup software. For now we will not create anything to view. Ideally, i suppose, we could generate a dicom file which would be overlaid on the patient and plan imagery. This way, the planed printed applicator could be easily compared to the planned seed placement. #endregion #region Update User //UpdateUser(); #endregion #region New Or Close //NewOrClose(); #endregion } #endregion #region Get Variables from XML File -- Done public PatientInfo GetVariables(string filepath) { // Deserialize using XML Serializer to get Patient. string xmlpath = System.IO.Path.Combine(filepath, "transfer.xml"); PatientInfo Patient1 = new PatientInfo(); XmlSerializer xs = new XmlSerializer(typeof(PatientInfo)); using (var sr = new StreamReader(xmlpath)) { Patient1 = (PatientInfo)xs.Deserialize(sr); } return Patient1; } #endregion #region Generate Model - Done public interface ISketchManager { }; //public interface IPartDoc { }; public void GenerateModel(PatientInfo Patient, string filepath, string pathname) { #region 1. Get Solidworks Going -- Done //Done SketchManager skManager; ModelDoc2 swDoc = null; PartDoc swPart = null; DrawingDoc swDrawing = null; AssemblyDoc swAssembly = null; ModelDocExtension swModelDocExt = default(ModelDocExtension); SelectionMgr swSelectionMgr = default(SelectionMgr); 73 Feature swFeature = default(Feature); FreePointCurveFeatureData swFreePointCurveFeatureData = default(FreePointCurveFeatureData); bool boolstatus; int longstatus = 0; int longwarnings = 0; bool status = false; int nbrPoints = 0; double[] pointArray = null; int i = 0; SldWorks swApp = new SldWorks(); swApp.Visible = false; swDoc = (ModelDoc2)swApp.NewDocument(@"C:ProgramDataSOLIDWORKSSOLIDWORKS 2018 emplatesMBDpart 0251mm to 1000mm.prtdot", 0, 0, 0); swApp.ActivateDoc2("Part1", false, ref longstatus); ModelView myModelView = null; myModelView = (ModelView)swDoc.ActiveView; myModelView.FrameState = ((int)(swWindowState_e.swWindowMaximized)); #endregion #region 2. Create Cylinder Body -- Done // Create a Circle boolstatus = swDoc.Extension.SelectByID2("Top Plane", "PLANE", 0, 0, 0, false, 0, null, 0); swDoc.SketchManager.InsertSketch(true); swDoc.ClearSelection2(true); SketchSegment skSegment = null; skSegment = swDoc.SketchManager.CreateCircleByRadius(Patient.shift/1000, -Patient.shift/1000, 0, Patient.Applicator.CylinderOD/2/1000); // y-value is negative because of how SW orients the create circle reference frame relative to the global frame. Globally, this represents (x,y,z) = (shift,0,shift). swDoc.ClearSelection2(true); swDoc.SketchManager.InsertSketch(true); // Extrude the Cylinder swDoc.ShowNamedView2("*Trimetric", 8); swDoc.ViewZoomtofit2(); swDoc.SketchManager.InsertSketch(true); Feature myFeature = null; myFeature = ((Feature)(swDoc.FeatureManager.FeatureExtrusion3(true, false, false, 0, 0, Patient.Applicator.CylinderLength/1000, 0, false, false, false, false, 0, 0, false, false, false, false, true, true, true, 0, 0, false))); swDoc.ISelectionManager.EnableContourSelection = false; boolstatus = swDoc.DeSelectByID("Boss-Extrude1", "BODYFEATURE", 0, 0, 0); object swMathUtils = null; swMathUtils = swApp.GetMathUtility(); #endregion #region 3. Create Dome Top -- Done //ModelView swModelView = null; //swModelView = ((ModelView)(swDoc.ActiveView)); //swModelView.RollBy(0); swDoc.ClearSelection2(true); //boolstatus = swPart.GetEntityByName(""); 74 //boolstatus = swDoc.Extension.SelectByID2("Boss-Extrude1", "PLANE", 0, 0, 0, true, 1, null, 0); boolstatus = swDoc.Extension.SelectByRay(Patient.shift/1000, Patient.Applicator.CylinderLength/1000, Patient.shift/1000, 1, 0, 1, 0.001, 1, true, 1, 0); //Select the top edge to put the dome on. We do this by finding the first edge that intersects with a cylinder defined by a ray and a radius. The ray goes from the center of the top of the cylinder, and then outwards, the radius is 1mm. This is the least complicated way of doing this. Trust me. Array radiiArray0 = null; double[] radiis0 = new double[0]; Array dist2Array0 = null; double[] dists20 = new double[0]; Array conicRhosArray0 = null; double[] coniRhos0 = new double[0]; Array setBackArray0 = null; double[] setBacks0 = new double[0]; Array pointArray0 = null; double[] points0 = new double[0]; Array pointDist2Array0 = null; double[] pointsDist20 = new double[0]; Array pointRhoArray0 = null; double[] pointsRhos0 = new double[0]; radiiArray0 = radiis0; dist2Array0 = dists20; conicRhosArray0 = coniRhos0; setBackArray0 = setBacks0; pointArray0 = points0; pointDist2Array0 = pointsDist20; pointRhoArray0 = pointsRhos0; myFeature = ((Feature)(swDoc.FeatureManager.FeatureFillet3(195, Patient.Applicator.CylinderOD/2/1000, 0, 0, 0, 0, 0, radiiArray0, dist2Array0, conicRhosArray0, setBackArray0, pointArray0, pointDist2Array0, pointRhoArray0))); #endregion #region 4. Create Base Chamfer -- Done swDoc.ClearSelection2(true); double basechamferwidth = 0.001; boolstatus = swDoc.Extension.SelectByRay(Patient.shift/1000, 0, Patient.shift/1000, 1, 0, 1, 0.001, 1, true, 1, 0); //Same as selection of dome top edge myFeature = ((Feature)(swDoc.FeatureManager.InsertFeatureChamfer(6, 1, basechamferwidth, 45*Math.PI/180, 0, 0, 0, 0))); //1mm chamfer. #endregion #region Create Leveling Tabs //swDoc.SketchManager.InsertSketch(true); //swDoc.ClearSelection2(true); //skSegment = swDoc.SketchManager.CreateLine(-0.013489, -0.027632, 0, -0.013489, -0.030427, 0); ////swDoc.ClearSelection2(true); //skSegment = swDoc.SketchManager.CreateLine(-0.016299, -0.027632, 0, -0.016299, -0.030427, 0); ////swDoc.ClearSelection2(true); //skSegment = swDoc.SketchManager.CreateArc(Patient.shift / 1000, -Patient.shift / 1000, 0, -0.016299, -0.030427, 0, -0.016299, -0.030427, 0,-1); 75 ////swDoc.ClearSelection2(true); ////skSegment = swDoc.SketchManager.CreateLine(-0.013489, -0.027632, 0, -0.016299, -0.027632, 0); ////swDoc.ClearSelection2(true); //swDoc.SketchManager.InsertSketch(true); //boolstatus = swDoc.Extension.SelectByID2("Sketch11", "SKETCH", 0, 0, 0, false, 0, null, 0); //myFeature = swDoc.FeatureManager.FeatureExtrusion2(true, false, true, 0, 0, 0.01, 0.01, false, false, false, false, 0.017453292519943334, 0.017453292519943334, false, false, false, false, true, true, true, 0, 0, false); //swDoc.ISelectionManager.EnableContourSelection = false; //swDoc.ActivateSelectedFeature(); //boolstatus = swDoc.Extension.SelectByRay(0.029342707282523861, 0.000982209302605952, 0.010811656723408447, -0.31708541216004343, 0.94683835592556542, -0.05435042910104787, 0.00018307115613639969, 1, true, 1, 0); //swDoc.ClearSelection2(true); //boolstatus = swDoc.Extension.SelectByID2("Boss-Extrude3", "BODYFEATURE", 0, 0, 0, false, 4, null, 0); //boolstatus = swDoc.Extension.SelectByRay(0.029342707282523861, 0.000982209302605952, 0.010811656723408447, -0.31708541216004343, 0.94683835592556542, -0.05435042910104787, 0.00018307115613639969, 1, true, 1, 0); //myFeature = swDoc.FeatureManager.FeatureCircularPattern5(2, 6.2831853071796, false, "NULL", false, true, false, false, false, false, 1, 0.26179938779915, "NULL", false); //swDoc.ClearSelection2(true); #endregion #region 5. Create M4 Major Cut Profile for Each Hole -- Done foreach (Curve hole in Patient.Applicator.CurveList) { swDoc.ClearSelection2(true); boolstatus = swDoc.Extension.SelectByRay(Patient.shift / 1000, -1, (Patient.shift / 1000 - Patient.Applicator.CylinderOD/2/1000 + basechamferwidth + 0.0005), 0, 1, 0, 0.001, 2, false, 0, 0); //Here we are selecting the bottom face of the cylinder, but we need to make sure that one of the faces of the cuts are not selected. Therefore, we will select the face just beside the edge of the cylinder where there will be no hole. swDoc.SketchManager.InsertSketch(true); swDoc.ClearSelection2(true); skSegment = ((swDoc.SketchManager.CreateCircleByRadius(hole.CathPath[0][0]/1000, hole.CathPath[0][2] / 1000, 0, Patient.Applicator.M4DrillIDforTap/2/1000))); swDoc.ClearSelection2(true); swDoc.SketchManager.InsertSketch(true); myFeature = swDoc.FeatureManager.FeatureCut4(true, false, false, 0, 0, Patient.Applicator.M4DrillDepthforTap/1000, 0.1, false, false, false, false, 0.017453292519943334, 0.017453292519943334, false, false, false, false, false, true, true, true, true, false, 0, 0, false, false); swDoc.ISelectionManager.EnableContourSelection = false; } #endregion #region 6. Create Curve for Each Hole -- Done //Insert free point curve feature int count = 1; foreach (var curve in Patient.Applicator.CurveList) 76 { #region Debug Start Curve Insertion using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) { file.WriteLine("Creating Curve # " + count + ":"); } #endregion swDoc.InsertCurveFileBegin(); foreach (var point in curve.CathPath) { status = swDoc.InsertCurveFilePoint(point[0]/1000, point[1]/1000, point[2]/1000); } status = swDoc.InsertCurveFileEnd(); #region Check that the Curve was successfully created if (status == true) { using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) { file.WriteLine("Curve # " + count + " Created Successfully."); } } else { using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) { file.WriteLine("Curve # " + count + " Creation Failed."); } } #endregion //Now extrude the selected hole: swDoc.ClearSelection2(true); string curvestring = "Curve"; string curveistring = curvestring+count; boolstatus = swDoc.Extension.SelectByID2(curveistring, "REFERENCECURVES", 0, 0, 0, false, 4, null, 0); Feature swFeat = null; FeatureManager swFeatMgr = null; swFeatMgr = ((FeatureManager)(swDoc.FeatureManager)); SweepFeatureData swFeatData = null; swFeatData = ((SweepFeatureData)(swFeatMgr.CreateDefinition(((int)(swFeatureNameID_e.swFmSweepCut))))); swFeatData.CircularProfileDiameter = Patient.Applicator.GuideTubeID/1000; swFeatData.SetTwistAngle(0); swFeatData.SetWallThickness(true, 0); swFeatData.CircularProfile = true; swFeat = ((Feature)(swFeatMgr.CreateFeature(swFeatData))); count++; 77 swDoc.ClearSelection2(true); } #endregion #region 7. Create Upper Chamfer for Each Hole -- Done double chamferwidth = (Patient.Applicator.M4DrillIDforTap - Patient.Applicator.GuideTubeID) / 2 / 1000; foreach (var curve in Patient.Applicator.CurveList) { swDoc.ClearSelection2(true); boolstatus = swDoc.Extension.SelectByRay(curve.CathPath[0][0]/1000, Patient.Applicator.M4DrillDepthforTap/1000, curve.CathPath[0][2]/1000, 1, 0, 0, 0.00001, 1, true, 4096, 0); myFeature = null; myFeature = swDoc.FeatureManager.InsertFeatureChamfer(6, 1, chamferwidth, 0.78539816339745, 0, 0, 0, 0); } #endregion #region 8. Create Lower Chamfer for Each Hole -- Done chamferwidth = 0.0002; foreach (var curve in Patient.Applicator.CurveList) { swDoc.ClearSelection2(true); boolstatus = swDoc.Extension.SelectByRay(curve.CathPath[0][0] / 1000, -Patient.Applicator.M4DrillIDforTap/2/1000, curve.CathPath[0][2] / 1000, 1, 1, 0, 0.0001, 1, true, 4096, 0); //Debug.WriteLine(boolstatus); myFeature = null; myFeature = swDoc.FeatureManager.InsertFeatureChamfer(6, 1, chamferwidth, 0.78539816339745, 0, 0, 0, 0); } #endregion #region 9. Create Thread for Each Hole -- Optional (Currently Commented) foreach (var curve in Patient.Applicator.CurveList) { ////select the circles //Feature swFeat = null; //FeatureManager swFeatMgr = null; //swDoc.ClearSelection2(true); //boolstatus = swDoc.Extension.SelectByRay(curve.CathPath[0][0] / 1000, -Patient.Applicator.M4DrillIDforTap / 2 / 1000 + chamferwidth, curve.CathPath[0][2] / 1000, 1, 1, 0, 0.0001, 1, true, 4194304, 0); // possibly make the mark = 1. //// Thread Variables Assigned //swFeatMgr = ((FeatureManager)(swDoc.FeatureManager)); //ThreadFeatureData swFeatData = null; //swFeatData = ((ThreadFeatureData)(swFeatMgr.CreateDefinition(((int)(swFeatureNameID_e.swFmSweepThread))))); //swFeatData.InitializeThreadData(); //swFeatData.BlindDepth = 0.01000000000000000021; 78 //swFeatData.EndConditionOffsetReverse = true; //swFeatData.EndConditionOffsetDistance = 0.001000000000000000021; //swFeatData.OffsetDistance = 0.001000000000000000021; //swFeatData.Revolutions = 14.28571428571428648; //swFeatData.Type = @"C:ProgramDataSolidWorksSOLIDWORKS 2019 hread profilesMetric Tap.SLDLFP"; //swFeatData.Diameter = 0.003300000000000001283; //swFeatData.Pitch = 0.0006999999999999999929; //swFeatData.Size = "M4x0.7"; //// Create the thread //swFeat = ((Feature)(swFeatMgr.CreateFeature(swFeatData))); //swDoc.ClearSelection2(true); } #endregion #region 10. Save Part and Generate STL -- Done #region For my PC //Save the model using the user generated name, etc. //longstatus = swDoc.SaveAs3("omitted filepath", 0, 2); //Save the model as an STL using the user generated name, etc. //longstatus = swDoc.SaveAs3("omitted filepath ", 0, 0); #endregion #region For BCCA PC swDoc.ClearSelection2(true); //Save the model using the user generated name, etc. string sldsavepath = System.IO.Path.Combine(filepath, "SOLIDWORKS FILE.SLDPRT"); longstatus = swDoc.SaveAs3(sldsavepath, 0, 2); //Save the model as an STL using the user generated name, etc. string stlsavepath = System.IO.Path.Combine(filepath, "STL FILE FOR PRINTER.STL"); longstatus = swDoc.SaveAs3(stlsavepath, 0, 0); #endregion #endregion swApp.Visible = true; } #endregion } } 79 Appendix C: Cylinder Applicator Creator /* Header * An outline of the steps required to convert a Brachyvision plan to a printable STL is as follows: Step 1: Get Brachytherapy Applicator Information From BrachyVision Step 2: Assign Cylinder Variables based on Applicator Info Step 3: Convert Dicom Coordinate System to Cylinder Coordinate System Step 4: Write Cylinder Variables to SW Design File Step 5: Update/Resave SW file (is this possible?) Step 6: Export SW file as STL to file Step 7: Return to the user the STL name and filepath */ using System; // These are all libraries we are using.. using System.Linq; using System.Text; using System.Threading; using System.Windows; using System.Collections.Generic; using VMS.TPS.Common.Model.API; //includes PlanSetup and BrachyPlanSetup using VMS.TPS.Common.Model.Types; using System.Drawing; using System.Text.RegularExpressions; using System.IO; using System.Xml.Serialization; using System.Diagnostics; using Microsoft.Office.Interop.Excel; using System.Windows.Forms; using SolidWorks.Interop.sldworks; using SolidWorks.Interop.swconst; using System.Runtime.InteropServices; using System.Runtime.InteropServices.ComTypes; using Microsoft; using Microsoft.Win32; using System.ComponentModel; using System.Threading.Tasks; using System.Windows.Threading; //declare a namespace which our program will run in. namespace WPFTemplate // This is our "namespace", which declared the scope of this document, and organize the script. Variables defined within this namespace are global within it, but not outside it. { //define the script public class in the VMS.TPS namespace #region Classes #region PatientInfo /// /// Patient Info contains all information about a patient. /// public class PatientInfo { public string PatientName; public string PatientID; 80 public string PlanID; public double OriginX; public double OriginY; public double OriginZ; public List<PlanCatheter> CathList; public CylinderApplicator Applicator; public double shift; } #endregion #region PlanCatheter /// /// Plan Catherter will contain the plan information related to an individual catheter /// public class PlanCatheter { public int CathNumber; public int NumSeeds; public List<Seed> SeedList; public List<double[]> CathShape; } #endregion #region Seed /// /// Seed contains the information about an individual seed. /// public class Seed { public double[] SeedPosition; public int SeedNumber; } #endregion #region CylinderApplicator /// /// CylinderApplicator contains all the information about an individual cylinder applicator /// public class CylinderApplicator { public int NumCaths; public List<Curve> CurveList; //list of all the curves in a single cylinderapplicator... public List<double[]> LastPointList; public List<List<double[]>> FirstThreeList; public List<List<double[]>> SeedPointsList; public List<double[]> FacePointList; public double CylinderLength; public double CylinderOD; public double GuideTubeID; public double FilletRadius; public double TubeOffset; public double TubeID; public double M4DrillIDforTap; public double M4DrillDepthforTap; 81 public double M4ThreadMajorDiameter; public double maxgap; } #endregion #region Curve /// /// Curve contains the information for one single curve. /// public class Curve { public List<double[]> CathPath; //represents the xyz coordinates of the catheter path. public double DX; //start position in X-dir public double DZ; public static int CompareByY(double[] p1, double[] p2) { return p1[1].CompareTo(p2[1]); } } #endregion #endregion public class XScript // a class is a type that is basically a blueprint that defines a set of data, actions, or methods public means it can be accessed without restrictions { #region Execute public void Execute(ScriptContext context) { // The ESAPI worker needs to be created in the main thread var esapiWorker = new EsapiWorker(context); // This new queue of tasks will prevent the script // for exiting until the new window is closed DispatcherFrame frame = new DispatcherFrame(); RunOnNewStaThread(() => { // This method won't return until the window is closed InitializeAndStartMainWindow(esapiWorker, context); // End the queue so that the script can exit frame.Continue = false; }); // Start the new queue, waiting until the window is closed Dispatcher.PushFrame(frame); //OpenForm(context); } #endregion #region RunOnNewStaThread private void RunOnNewStaThread(System.Action a) { a(); 82 } #endregion #region InitializeAndStartMainWindow private void InitializeAndStartMainWindow(EsapiWorker esapiWorker, ScriptContext context) { var viewModel = new ViewModel(esapiWorker, context); Form1 mainwindow = new Form1(viewModel); mainwindow.ShowDialog(); } #endregion } public class datatobind // interface between View and ViewModel. { } public class ViewModel { #region EsapiWorker and ViewModel EsapiWorker worker; ScriptContext context; public ViewModel(EsapiWorker inworker, ScriptContext context) { this.worker = inworker; this.context = context; } public string status { get; set; } public void BindData() // called by window constructor in GUI thread, initializes viewModel with data from Patient in context { } #endregion public ScriptContext Context { get { return context; } } #region Execute2 -- Where the fun happens. public void Execute2(string filename, string Diameter, string Length, string GuideTubeDiameter, string filepath) { worker.Run(context => { #region Setup string pathname = System.IO.Path.Combine(filepath, "PatientShiftCoordinates.txt"); File.WriteAllText(pathname, String.Empty); //clear the file from previous data (delete this line if you want the data appended). #endregion #region GetInfo PatientInfo Patient1 = new PatientInfo(); Patient1 = GetInfo(context, pathname); 83 #endregion #region AssignCylinderVariables AssignCylinderVariables(Patient1, pathname); #endregion #region Get and Set Variables Required //Patient1 = GetVariables(filepath); try { Patient1.Applicator.CylinderOD = Convert.ToDouble(Diameter); } catch { } Patient1.Applicator.CylinderLength = Convert.ToDouble(Length); Patient1.Applicator.GuideTubeID = Convert.ToDouble(GuideTubeDiameter); #endregion #region Convert Coordinates ConvertCoordinates(Patient1, pathname); #endregion #region Create Curves CreateCurves(Patient1, pathname); #endregion #region CheckSeedVariables bool pass = CheckSpacing(Patient1, pathname); // if (pass == false) // { // //Report back to the gui the problems curves // } #endregion #region Save Info to XML SaveToXML(Patient1, pathname); #endregion #region Update User //worker.ReportProgress(100); #endregion #region Write PDF WritePDF(Patient1, pathname); #endregion #region New Or Close //NewOrClose(); #endregion }); } #endregion 84 #region GetInfo /// /// The GetInfo method retrieves all relavent information to the rest of the script from the planning system files, using the ESAPI. Variables such as the Cylinder Length, Number of Catheters, Catheter Geometries, Seed Positions, and the User Coordinate Systems are retrieved. /// /// /// <returns></returns> public PatientInfo GetInfo(ScriptContext context, string pathname) { #region Initialize Patient and Variables //Write the Patient and User Origin information to variables. PatientInfo Patient1 = new PatientInfo(); Patient1.PatientName = context.Patient.Name; Patient1.PatientID = context.Patient.Id; Patient1.PlanID = context.PlanSetup.Id; Patient1.OriginX = context.Image.UserOrigin.x; Patient1.OriginY = context.Image.UserOrigin.y; Patient1.OriginZ = context.Image.UserOrigin.z; Patient1.CathList = new List<PlanCatheter>(); Patient1.shift = 15; //mm #endregion #region Prep Log File // Loop through the catheters and seeds and write the values to the script. //Clear the pathname file //File.WriteAllText(pathname, String.Empty); //clear the file from previous data (delete this line if you want the data appended). //using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) //{ // file.WriteLine("Custom Cylinder Creation Log File"); // file.WriteLine(); // file.WriteLine("Eclipse Source Positions:"); //} #endregion #region Assign Seed and Shape Values // int cathcount = 0; using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) { file.WriteLine("Assigning Shape"); } foreach (var cath in context.BrachyPlanSetup.Catheters) { 85 #region Prep Temporary Catheter //cath.ChannelNumber; //catheter channel number (integer) //cath.ApplicatorLength; // Total length of catheter from tip to treatment unit (double) PlanCatheter tempCath = new PlanCatheter(); //tempCath.SeedList = new List<Seed>(); tempCath.CathShape = new List<double[]>(); //using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) //{ // cathcount++; // file.WriteLine("Source Positions for Catheter # " + cathcount); //} #endregion #region Assign Seed Positions to Temporary Catheter - Obsolete //foreach (SourcePosition sp in cath.SourcePositions) //{ #region Get Seed Position/Rotation Info - Obsolete //double[,] temppos = sp.Transform; ///* 4x4 matrix, 4x3 rotation matrix & 4x1 translation matrix, bottom row is scaling and is always 0,0,0,1. Transform is actually the 4x4 transformation matrix itself, not a command. remember that for any x.y -> y is a property of x. The [,] means that we creating a matrix (or something like that) which is an x,y or 2D format. This is why we use it for the transformation matrix. not we can loop through the j's and the i's and write each variable to file. //*/ //// Patient1.Catheter Catheter1 = new PatientInfo.Patient1.Catheter(); ////Create the seed variable //Seed tempSeed = new Seed(); //tempSeed.SeedPosition = new double[3]; //for (int i = 0; i < 3; i++) // hard coded 4 would be better to get the size //{ // tempSeed.SeedPosition[i] = temppos[i, 3]; //} //tempCath.SeedList.Add(tempSeed); #endregion #region Write Stuff to LogFile - Obsolete //using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) //{ // file.WriteLine("Rotation:"); // for (int i = 0; i < 4; i++) // hard coded 4 would be better to get the size // { // file.Write(temppos[0, i] + " "); // } // file.WriteLine(); // for (int i = 0; i < 4; i++) // hard coded 4 would be better to get the size // { 86 // file.Write(temppos[1, i] + " "); // } // file.WriteLine(); // for (int i = 0; i < 4; i++) // hard coded 4 would be better to get the size // { // file.Write(temppos[2, i] + " "); // } // file.WriteLine(); // file.WriteLine("Position:"); // for (int i = 0; i < 4; i++) // hard coded 4 would be better to get the size // { // file.Write(temppos[3, i] + " "); // } // file.WriteLine(); // file.WriteLine("Position:"); // for (int i = 0; i < 3; i++) // hard coded 4 would be better to get the size // { // file.Write(tempSeed.SeedPosition[i] + " "); // } // file.WriteLine(); //} #endregion //} #endregion #region Assign Shape Values to Temporary Catheter /* The first catheter needs to be straight, and it needs to run down the center of the applicator, but the rotation is relative to the planning coordinate system. To do the rotation shift correctly, we can either do a rotation relative to the planning system, or relative to the user coordinate system. Since the applicator is brought in and sort of defines the user coordinate system, it would probably be best to simple align the coordniate systems to the applicator. To do this we would need to align the coordinates given by the planning system and rotate them either in the planning frame or in the user frame. I suppose that we will also need to rotate the reference frame as well. */ #region Build the CathShape Info foreach (VVector vv in cath.Shape) { double[] tempshapepos = new double[3]; tempshapepos[0] = vv.x; tempshapepos[1] = vv.y; tempshapepos[2] = vv.z; tempCath.CathShape.Add(tempshapepos); } #endregion #region Write Cathshape to LogFile - Obsolete 87 //using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) //{ // file.WriteLine("Catheter Shape:"); // foreach (double[] position in tempCath.CathShape) // { // file.Write(position[0] + " " + position[1] + " " + position[2]); // file.WriteLine(); // } //} #endregion #endregion #region Assign Temporary Catheter to Cathlist/Patient Patient1.CathList.Add(tempCath); //using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) //{ // file.WriteLine(); //} #endregion } #endregion return Patient1; } #endregion #region AssignCylinderVariables /// /// The AssignCylinderVariables method /// /// /// /// <returns></returns> public void AssignCylinderVariables(PatientInfo Patient1, string pathname) { CylinderApplicator Applicator = new CylinderApplicator(); Applicator.NumCaths = Patient1.CathList.Count; Applicator.CylinderLength = 120; Applicator.CylinderOD = 30; Applicator.GuideTubeID = 4; Applicator.FilletRadius = 0.5; Applicator.TubeOffset = 10; Applicator.TubeID = 2.8; Applicator.M4DrillIDforTap = 3.3; Applicator.M4ThreadMajorDiameter = 4; Applicator.M4DrillDepthforTap = 1.5 * Applicator.M4ThreadMajorDiameter; Patient1.Applicator = Applicator; 88 Patient1.Applicator.maxgap = 3; //TODO: Add suppression states based on NumCaths (might just need to add this to the WriteCylinderVariables method. I can do a little calc for how many cells in a row to write a "S" for supressing a variable which would be created to supress the irrelavent geometries. //Keep for now but this here below is probably not needed. using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) { file.WriteLine("Number of Catheters = " + Applicator.NumCaths); file.WriteLine("Cylinder Length = " + Applicator.CylinderLength); file.WriteLine("Cylinder OD = " + Applicator.CylinderOD); file.WriteLine("Guide Tube ID = " + Applicator.GuideTubeID); file.WriteLine("Fillet Radius = " + Applicator.FilletRadius); file.WriteLine("Tube Offset = " + Applicator.TubeOffset); file.WriteLine("Tube ID = " + Applicator.TubeID); file.WriteLine("Drill ID for Tap = " + Applicator.M4DrillIDforTap); file.WriteLine("Drill Depth for Tap = " + Applicator.M4DrillDepthforTap); file.WriteLine("Thread Major Diameter = " + Applicator.M4ThreadMajorDiameter); } } #endregion #region Shift Coordinates to SW -- Done public void ConvertCoordinates(PatientInfo Patient, string pathname) { //Only works properly if there is a central channel //The other program doesn't do any shifts //Shift # 1 //The Planning System coordinate system has a translation shift to the User Coordinate System. I think that the User Coordinate System coordinates just need to be added to the Planning System coordinates in order to shift everything properly. Probably everything should be shifted before creating the full curves. We'll shift all the information from the planning system. We'll create a new instance of the Patient here, and call it PatientShifted. This will keep the Patient1 information available for debug and reference reasons. //Shift # 3 - Rotation //The first catheter needs to be straight, and it needs to run down the center of the applicator, but the rotation is relative to the planning coordinate system. // To do the rotation shift correctly, we can either do a rotation relative to the planning system, or relative to the user coordinate system. // Since the applicator is brought in and sort of defines the user coordinate system, it would probably be best to simple align the applicator to the user coordinate system once all the shifts are complete. To do this we would need to rotate the applicator relative to the user coordinate system, by calculating the angle of the applicator relative to the user coordinate system and then rotating all the points of the entire system the using probably a rotation matrix. //Shift # 2 //The Coordinate System in the SW file is such that the base face of the cylinder is 15mm from origin in the x and z directions, and is 0mm in the y direction. //For the User Coordinate System in the planning software, the cylinder tip is at the origin, with the cylinder body falling in the negative z direction. 89 //The User Coordinate System X and Y will be the SW X and Z coordinates, and there will have to be a 15mm shift in each of these directions. We will need to ADD 15mm to the User Coordinate System X and Y coordinate systems to properly translate them to where the SW X and Z coordinates are. The Z coordinate system in the User Coordinate System will have to have the cylinder length added to it, and then the Z location becomes equal to the Y location in SW. #region Shift Seeds - Obsolete #region Shift to User Coord System - Obsolete ////Shift the Planning System Coordinate System to the User Coordinate System //using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) //{ // file.WriteLine("User Origin Shift"); //} //int cathcount = 0; //foreach (var cath in Patient.CathList) //{ // using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) // { // cathcount++; // file.WriteLine("Source Positions for Catheter # " + cathcount); // } // foreach (var seed in cath.SeedList) // { // seed.SeedPosition[0] -= Patient.OriginX; // seed.SeedPosition[1] -= Patient.OriginY; // seed.SeedPosition[2] -= Patient.OriginZ; // using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) // { // file.Write(seed.SeedPosition[0] + " "); // file.Write(seed.SeedPosition[1] + " "); // file.Write(seed.SeedPosition[2] + " "); // file.WriteLine(); // } // } // using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) // { // file.WriteLine(); // } //} #endregion #region Rotate Coord System - Obsolete #region Step 1: Get Centerline Channel Angles Relative to User Coordinate System - Obsolete 90 //Get the Initial points //double[] point1 = Patient.CathList[0].SeedList[0].SeedPosition; //double[] point2 = Patient.CathList[0].SeedList[1].SeedPosition; ////Calculate the Y-axis rotation angle of the centerline channel relative to 0. //double x1 = point1[0]; //double z1 = point1[2]; //double x2 = point2[0]; //double z2 = point2[2]; //double thetaY = -(Math.Atan2(z2 - z1, x2 - x1) + Math.PI / 2); ////Calculate the X-axis rotation angle of the centerline channel relative to 0. //double y1 = point1[1]; //double y2 = point2[1]; //double thetaX = -(Math.Atan2(z2 - z1, y2 - y1) + Math.PI / 2); //using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) //{ // file.WriteLine("ThetaY"); // file.WriteLine(thetaY); // file.WriteLine(thetaY * 180 / Math.PI); // file.WriteLine("ThetaX"); // file.WriteLine(thetaX); // file.WriteLine(thetaX * 180 / Math.PI); //} #endregion #region Step 2: Rotate Applicator to SW Coord System - Obsolete //using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) //{ // file.WriteLine("Rotation Shift"); //} //double xi; //double yi; //double zi; //cathcount = 0; //foreach (var cath in Patient.CathList) //{ // using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) // { // cathcount++; // file.WriteLine("Source Positions for Catheter # " + cathcount); // } // foreach (var seed in cath.SeedList) // { // xi = seed.SeedPosition[0]; // zi = seed.SeedPosition[2]; 91 // //Rotate points about Y // seed.SeedPosition[0] = xi * Math.Cos(thetaY) - zi * Math.Sin(thetaY); // seed.SeedPosition[2] = xi * Math.Sin(thetaY) + zi * Math.Cos(thetaY); // yi = seed.SeedPosition[1]; // zi = seed.SeedPosition[2]; // //Rotate points about X // seed.SeedPosition[1] = yi * Math.Cos(thetaX) - zi * Math.Sin(thetaX); // seed.SeedPosition[2] = yi * Math.Sin(thetaX) + zi * Math.Cos(thetaX); // using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) // { // file.Write(seed.SeedPosition[0] + " "); // file.Write(seed.SeedPosition[1] + " "); // file.Write(seed.SeedPosition[2] + " "); // file.WriteLine(); // } // } // using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) // { // file.WriteLine(); // } //} #endregion #endregion #region Shift to SW Coord System - Obsolete ////Shift the User Coordinate System to the SW Coordinate System //using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) //{ // file.WriteLine("Solidworks Coordinate Shift"); //} //int cathcount2 = 0; //foreach (var cath in Patient.CathList) //{ // using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) // { // cathcount2++; // file.WriteLine("Source Positions for Catheter # " + cathcount2); // } // foreach (var seed in cath.SeedList) // { // double tempDouble = seed.SeedPosition[1]; 92 // seed.SeedPosition[1] = seed.SeedPosition[2]; // seed.SeedPosition[2] = tempDouble; // //Shift the x and z // seed.SeedPosition[0] += Patient.shift; // seed.SeedPosition[2] += Patient.shift; // //Shift the y // seed.SeedPosition[1] += Patient.Applicator.CylinderLength; // using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) // { // file.Write(seed.SeedPosition[0] + " "); // file.Write(seed.SeedPosition[1] + " "); // file.Write(seed.SeedPosition[2] + " "); // file.WriteLine(); // } // } // using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) // { // file.WriteLine(); // } //} #endregion #endregion #region Shift Catheter Shape #region Shift to User Coordinate System //("Shape" is the points which define the lines which the seeds follow in Eclipse) using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) { file.WriteLine("Shape Catheter Shift"); } int cathcount = 0; foreach (var cath in Patient.CathList) { using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) { cathcount++; file.WriteLine("Source Positions for Catheter # " + cathcount); } foreach (double[] shape in cath.CathShape) { shape[0] -= Patient.OriginX; shape[1] -= Patient.OriginY; 93 shape[2] -= Patient.OriginZ; using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) { file.Write(shape[0] + " "); file.Write(shape[1] + " "); file.Write(shape[2] + " "); file.WriteLine(); } } using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) { file.WriteLine(); } } #endregion #region Rotate Coord System #region Step 1: Get Centerline Channel Angles Relative to User Coordinate System - Obsolete //Get the Initial points double[] point1 = Patient.CathList[0].CathShape[0]; double[] point2 = Patient.CathList[0].CathShape[1]; //Calculate the Y-axis rotation angle of the centerline channel relative to 0. double x1 = point1[0]; double z1 = point1[2]; double x2 = point2[0]; double z2 = point2[2]; double thetaY = -(Math.Atan2(z2 - z1, x2 - x1) + Math.PI / 2); //Calculate the X-axis rotation angle of the centerline channel relative to 0. double y1 = point1[1]; double y2 = point2[1]; double thetaX = -(Math.Atan2(z2 - z1, y2 - y1) + Math.PI / 2); using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) { file.WriteLine("ThetaY"); file.WriteLine(thetaY); file.WriteLine(thetaY * 180 / Math.PI); file.WriteLine("ThetaX"); file.WriteLine(thetaX); file.WriteLine(thetaX * 180 / Math.PI); } 94 #endregion #region Step 2: Rotate Applicator to SW Coord System using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) { file.WriteLine("Rotation Shift of Shape Information"); } cathcount = 0; foreach (var cath in Patient.CathList) { using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) { cathcount++; file.WriteLine("Shape Positions for Catheter # " + cathcount); } foreach (double[] shapepoint in cath.CathShape) { double xi = shapepoint[0]; double zi = shapepoint[2]; //Rotate points about Y shapepoint[0] = xi * Math.Cos(thetaY) - zi * Math.Sin(thetaY); shapepoint[2] = xi * Math.Sin(thetaY) + zi * Math.Cos(thetaY); double yi = shapepoint[1]; zi = shapepoint[2]; //Rotate points about X shapepoint[1] = yi * Math.Cos(thetaX) - zi * Math.Sin(thetaX); shapepoint[2] = yi * Math.Sin(thetaX) + zi * Math.Cos(thetaX); using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) { file.Write(shapepoint[0] + " "); file.Write(shapepoint[1] + " "); file.Write(shapepoint[2] + " "); file.WriteLine(); } } using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) { file.WriteLine(); } } #endregion 95 #endregion #region Shift to SW Coord System //Shift the User Coordinate System to the SW Coordinate System using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) { file.WriteLine("Solidworks Coordinate Shift"); } int cathcount2 = 0; foreach (var cath in Patient.CathList) { using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) { cathcount2++; file.WriteLine("Shape Positions for Catheter # " + cathcount2); } foreach (double[] shapepoint in cath.CathShape) { double tempDouble = shapepoint[1]; shapepoint[1] = shapepoint[2]; shapepoint[2] = -tempDouble; //the SW Z direction is defined negative to the Eclipse Z direction //Shift the x and z shapepoint[0] += Patient.shift; shapepoint[2] += Patient.shift; //Shift the y shapepoint[1] += Patient.Applicator.CylinderLength; using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) { file.Write(shapepoint[0] + " "); file.Write(shapepoint[1] + " "); file.Write(shapepoint[2] + " "); file.WriteLine(); } } using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) { file.WriteLine(); } } #endregion #endregion } 96 #endregion #region CreateCurves -- Done /// /// Create Curves creates the coordinate intersections file for every point which the extrusuion curve for the catheter will run through. /// There are a number of philosophies which can guide how we might go about this. /// Design method #1: /// In this method we would use the closest possible position on the extrusion face to the last (lowest, or closest to the HDR unit) seed position in the catheter. In this manner, we have designed a catheter path which is relatively simple. *** If we require the user to have the catheter to be relatively vertical, then we can have paths which are very very simple. We could even have the user position the end of the path on the opposite side of the cylinder from that catheters final trajectory. /// Step 1: Determine the closest point to the bottom seed on the extrusion face. Create a list of all the bottom points to use in the design file. /// Step 2: Check that none of the paths are too close to each other. If so, return an error to the user. /// Step 3: Check that none of the extrusion face points are too close to each other. If so, move both of them a bit away from each other. Iterate until all conditions are satisfied. /// Step 4: Iterate through 2 until all conditions are satisfied. /// Step 5: Save all the trajectories to the curve files, don't forget to add the bottom point and 2 points just above it to ensure that the hole is straight when the catheter enters the tube. /// Step 6: Profit. /// /// /// /// public void CreateCurves(PatientInfo Patient, string pathname) { #region Prep Starting Points for Curve //Determine where the bottom of the cylinder will be, in the y-coordinate. double ycoordcylinderface = 0; //Determine where the first point (in the y-coord) of a Curve will be, based on the applicator face position, and the drill depth. double CurveStartY = ycoordcylinderface; //Come up with a list of all the start positions of all the catheters, based on the last positions of all the shape information //Create a list of all the last seeds... Patient.Applicator.LastPointList = new List<double[]>(); foreach (var cath in Patient.CathList) { double[] lastpoint = cath.CathShape.Last(); Patient.Applicator.LastPointList.Add(lastpoint); } //Bring the lastpoint positions down to the Curve Start position, and add two points above it so the line is straight. //Also create the facepoints for the location of the drill holes. Patient.Applicator.FirstThreeList = new List<List<double[]>>(); Patient.Applicator.FacePointList = new List<double[]>(); 97 //create the firstthreelist and the facepointlist foreach (var lastpoint in Patient.Applicator.LastPointList) { //Bring the lastpoint down to become the first point (of the curve) using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) { double[] firstpoint = new double[3]; firstpoint[0] = lastpoint[0]; firstpoint[1] = CurveStartY; firstpoint[2] = lastpoint[2]; double[] secondpoint = new double[3]; secondpoint[0] = firstpoint[0]; secondpoint[1] = firstpoint[1] + 5; secondpoint[2] = firstpoint[2]; double[] thirdpoint = new double[3]; thirdpoint[0] = firstpoint[0]; thirdpoint[1] = firstpoint[1] + 10; thirdpoint[2] = firstpoint[2]; //Bring the lastpoint down to also become the face point. double[] facepoint = new double[3]; facepoint[0] = lastpoint[0]; facepoint[1] = CurveStartY; facepoint[2] = lastpoint[2]; //Create a list of the first 3 points List<double[]> firstthree = new List<double[]>(); firstthree.Add(firstpoint); firstthree.Add(secondpoint); firstthree.Add(thirdpoint); //Add the temp arrays to their proper lists Patient.Applicator.FirstThreeList.Add(firstthree); Patient.Applicator.FacePointList.Add(facepoint); } } #endregion #region Prep the Seedlist for the Curve - Obsolete ////Flip the seedlists... //foreach (var cath in Patient.CathList) //{ // cath.SeedList.Reverse(); //} #endregion #region Prep the ShapeList for the Curve //Flip the shapelists... 98 foreach (var cath in Patient.CathList) { cath.CathShape.Reverse(); } #endregion #region Create the Curves #region Create Curve List Patient.Applicator.CurveList = new List<Curve>(); #endregion #region Create Curves and Add Them to the Curve List //For each catheter, create a new curve, add the first three and then the list of seeds (now reversed) to the curve. Add each curve to the applicator curvelist. for (int i = 0; i < Patient.CathList.Count(); i++) { #region Create Temp Curve and Add Points //create a temporary curve Curve curve = new Curve(); curve.CathPath = new List<double[]>(); //First add the facepoints foreach (var fp in Patient.Applicator.FirstThreeList[i]) { curve.CathPath.Add(fp); } //next add the shapepoints foreach (var shp in Patient.CathList[i].CathShape) { curve.CathPath.Add(shp); } //next add the seedpoints - Obsolete //foreach (var sp in Patient.CathList[i].SeedList) //{ // curve.CathPath.Add(sp.SeedPosition); //} #endregion #region Sort the Curve by Ascending Y (Really should sort by shape ordering) // *** Note that this isn't really the best way do this, as it limits the user to making curves which always increase in the Y direction. A more robust method would be to use the shape points as a sort of "template", and fit the seed points within the shape section it was drawn. This could be done, for example, by checking that all three of the seed point coordinates are within the coordinates of the bounding shape point coordinates, AND that the slope to the point from the first shape point is the same (or within limits) as the slope to the second shape point from the first shape point. This takes a lot of computation though, so I'm not really sure if it's necessary. 99 //sort the curve in order of ascending y (y is the longitudinal direction of the cylinder in our Solidworks coordinate system) curve.CathPath.Sort(Curve.CompareByY); #endregion #region Delete Useless Points From the Curve //Delete any Points that are below 0 in Y (shape points that are outside (below) the cylinder) //Initiate a list to track which points to remove List<double[]> deletelist = new List<double[]>(); //Determine which points to delete foreach (double[] cathpoint in curve.CathPath) { if (cathpoint[1] < 0) { deletelist.Add(cathpoint); } } //Delete the specified points foreach (double[] deletepoint in deletelist) { curve.CathPath.Remove(deletepoint); } #endregion #region Write the Curve before interpolation to the log file //using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) //{ // file.WriteLine("Catheter Curve # " + (i + 1) + " before interpolation"); //} //foreach (var point in curve.CathPath) //{ // using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) // { // file.Write(point[0] + " "); // file.Write(point[1] + " "); // file.Write(point[2] + " "); // file.WriteLine(); // } //} //using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) //{ // file.WriteLine(); //} #endregion #region Interpolate -- Add Extra Points into the Curve if Needed 100 //using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) //{ // file.WriteLine(); // file.WriteLine("Interpolating curve # " + (i + 1) + " # of Points to Check:" + (curve.CathPath.Count() - 1)); //} #region Setup //Create a list of points with the point index and the number of points to add between them (1 for every 3mm of gap) //double maxgap = 3; List<int[]> insertlist = new List<int[]>(); #endregion #region Find where to add extra points for (int j = 0; j < curve.CathPath.Count() - 1; j++) { double x1 = curve.CathPath[j][0]; double y1 = curve.CathPath[j][1]; double z1 = curve.CathPath[j][2]; double x2 = curve.CathPath[j + 1][0]; double y2 = curve.CathPath[j + 1][1]; double z2 = curve.CathPath[j + 1][2]; double dist = Math.Pow(Math.Pow(x2 - x1, 2) + Math.Pow(y2 - y1, 2) + Math.Pow(z2 - z1, 2), 0.5); //using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) //{ // file.WriteLine("Checking Dist # " + j + ": " + dist); //} if (dist > Patient.Applicator.maxgap) { int[] tempinsert = new int[2]; tempinsert[0] = j; tempinsert[1] = Convert.ToInt32(Math.Round(dist / Patient.Applicator.maxgap)) - 1; if (tempinsert[1] > 0) { insertlist.Add(tempinsert); #region Debug Check # of points to add //using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) //{ // file.WriteLine("# of Points to Add: " + tempinsert[1]); //} 101 #endregion } } } //using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) //{ // file.WriteLine(); //} #endregion #region Add the extra points needed int index = 0; int totalpointsadded = 0; if (insertlist.Count() > 0) { //using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) //{ // file.WriteLine("Inserting points into Curve # " + (i + 1)); //} //for every point in insertlist foreach (int[] insertpointid in insertlist) //rememebr that insertpoint id is an array int[2] comprised of: 1: the index of the initial point where the distance was too large, and 2: the number of points to add { index = insertpointid[0] + totalpointsadded; //Create the double[] to insert //for how ever many points we said needed to be inserted before for (int j = 0; j < insertpointid[1]; j++) { //Make our temp point equal to the point that needs some filler points ahead of it: //double[] cathpoint = curve.CathPath[insertpointid[0]]; double[] cathpoint = curve.CathPath[index]; double[] vect = new double[3]; double[] insertpoint = new double[3]; //Now simply alter the values of the point to be along the line between this point and the next point: int k = index; double x1 = curve.CathPath[k][0]; double y1 = curve.CathPath[k][1]; double z1 = curve.CathPath[k][2]; double x2 = curve.CathPath[k + 1][0]; double y2 = curve.CathPath[k + 1][1]; double z2 = curve.CathPath[k + 1][2]; 102 double dist = Math.Pow(Math.Pow(x2 - x1, 2) + Math.Pow(y2 - y1, 2) + Math.Pow(z2 - z1, 2), 0.5); vect[0] = (x2 - x1) / dist; vect[1] = (y2 - y1) / dist; vect[2] = (z2 - z1) / dist; insertpoint[0] = cathpoint[0] + vect[0] * Patient.Applicator.maxgap * (j + 1); insertpoint[1] = cathpoint[1] + vect[1] * Patient.Applicator.maxgap * (j + 1); insertpoint[2] = cathpoint[2] + vect[2] * Patient.Applicator.maxgap * (j + 1); //Since the first index of insertpoint represents the index of the point in the curvelist, we want to insert the points after that point and before the next one. curve.CathPath.Insert(index + j + 1, insertpoint); //using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) //{ // file.WriteLine("Inserted " + insertpoint[0] + "," + insertpoint[1] + "," + insertpoint[2] + " at position " + (index + j + 1)); //} totalpointsadded++; } } #region Debug Check # of points added //using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) //{ // file.WriteLine("Curve # " + (i + 1) + ": # of Points Added: " + totalpointsadded); //} #endregion } #endregion #endregion #region Add Point to List of Curves //Add this curve to the curvelist Patient.Applicator.CurveList.Add(curve); #endregion #region Write the Curve after interpolation to the log file using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) { file.WriteLine("Catheter Curve # " + (i + 1) + " after interpolation"); } foreach (var point in curve.CathPath) { using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) { 103 file.Write(point[0] + " "); file.Write(point[1] + " "); file.Write(point[2] + " "); file.WriteLine(); } } using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) { file.WriteLine(); } #endregion } #endregion #endregion #region Write Curve to LogFile //int cathcount2 = 0; //foreach (var curve in Patient.Applicator.CurveList) //{ // using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) // { // cathcount2++; // file.WriteLine("Points for Catheter Curve # " + cathcount2); // } // foreach (var point in curve.CathPath) // { // using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) // { // file.Write(point[0] + " "); // file.Write(point[1] + " "); // file.Write(point[2] + " "); // file.WriteLine(); // } // } // using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) // { // file.WriteLine(); // } //} #endregion } #endregion #region Check Curve Closeness /*This region checks to make sure that all the seeds in the plan are a minimum distance from all the other seed positions. This prevents future problems where the solidworks model will have path extrusion intersection issues. 104 The algorithm checks each seed point in each other catheter, and checks to make sure that the net distance between the points is greated than the minseedspacing. */ #region Check Distances Stopwatch StopWatch; public bool CheckSpacing(PatientInfo Patient1, string pathname) { StopWatch = Stopwatch.StartNew(); #region Setup double minspacing = Patient1.Applicator.GuideTubeID; // mm double minspacingbase = 7; //mm (not sure if 7 is correct) double minspacingsquared = minspacing * minspacing; double dist; double distsquared; double x1; double x2; double y1; double y2; double z1; double z2; double dx; double dy; double dz; int seedcount; int seedcount2; #endregion #region Check Catheter Spacings //For each Catheter int numcurves = Patient1.Applicator.CurveList.Count(); int failcount = 0; using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) { for (int i = 0; i < numcurves - 1; i++) //dont need to check the last curve, as it's already been checked. { seedcount = 0; //For each seed in the i-th catheter foreach (double[] seed in Patient1.Applicator.CurveList[i].CathPath) { seedcount++; for (int j = i + 1; j < numcurves; j++) { seedcount2 = 0; foreach (double[] checkseed in Patient1.Applicator.CurveList[j].CathPath) { seedcount2++; //x2 = checkseed[0]; //y2 = checkseed[1]; //z2 = checkseed[2]; dx = checkseed[0] - seed[0]; 105 dy = checkseed[1] - seed[1]; dz = checkseed[2] - seed[2]; distsquared = dx * dx + dy * dy + dz * dz; if (distsquared >= Patient1.Applicator.maxgap) { //Write the successful points to the logfile. file.WriteLine("Distance Squared: " + distsquared + " => Pass"); } else { dist = Math.Pow(distsquared, 0.5); //Add both points (catheter # && seed #) that are too close to a list. //Write the failed points to the log file file.WriteLine("Too close, at Applicator # " + i + " and " + j + ". Minimum spacing is: " + Patient1.Applicator.maxgap + " and the offending spacing is " + dist); failcount++; } } } } } } #endregion #region Fail/Pass //Return wether or not there were any failed points. bool pass = false; if (failcount == 0) { pass = true; } StopWatch.Stop(); using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) { file.WriteLine("Time to Check Closeness: " + StopWatch.Elapsed.TotalSeconds); } return pass; #endregion } #endregion #endregion #region Write PDF File public void WritePDF(PatientInfo Patient, string pathname) { using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) { int j = 0; 106 foreach (var curve in Patient.Applicator.CurveList) { double cathlength = 0; double sectionlength; double xlength = 0; double ylength = 0; double zlength = 0; var path = curve.CathPath; for (int i = 0; i < path.Count()-1;i++) { xlength = path[i+1][0] - path[i][0]; ylength = path[i + 1][1] - path[i][1]; zlength = path[i + 1][2] - path[i][2]; sectionlength = Math.Pow(xlength * xlength + ylength * ylength + zlength * zlength, 0.5); cathlength += sectionlength; } file.WriteLine("Catheter # " + (j + 1) + ": Length: " + cathlength + "mm"); j++; } } } #endregion #region SaveToXML // Saves to the Patient1 PatientInfo class instance as an XML variable. public void SaveToXML(PatientInfo Patient1, String pathname) { // Create a folder to save the xml file to: // Specify a name for your top-level folder. string folderName = @"omitted filepath"; using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) { file.WriteLine("Folder Name:"); file.WriteLine(folderName); } string pathString = System.IO.Path.Combine(folderName, Patient1.PatientName /* + " Created " + DateTime.Now.ToString()*/); using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) { file.WriteLine("Path String:"); file.WriteLine(pathString); } System.IO.Directory.CreateDirectory(pathString); using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) { file.WriteLine("Folder Created"); 107 file.WriteLine(pathString); } // Create the xml file directory string fileString = System.IO.Path.Combine(pathString, "transfer.xml"); // Save the xml file XmlSerializer xs = new XmlSerializer(typeof(PatientInfo)); TextWriter tw = new StreamWriter(fileString); xs.Serialize(tw, Patient1); } #endregion } public class EsapiWorker { private readonly ScriptContext _scriptContext; private readonly Dispatcher _dispatcher; public EsapiWorker(ScriptContext scriptContext) { _scriptContext = scriptContext; _dispatcher = Dispatcher.CurrentDispatcher; } public void Run(Action<ScriptContext> a) { _dispatcher.BeginInvoke(a, _scriptContext); } public void RunSynch(Action<ScriptContext> a) { _dispatcher.Invoke(a, _scriptContext); } } } 108 Appendix D: Cylinder Applicator Source Position Exporter (CASPE) Code using System; // These are all libraries we are using.. using System.Linq; using System.Text; using System.Threading; using System.Windows; //using System.Windows.Forms; using System.Collections.Generic; using VMS.TPS.Common.Model.API; //includes PlanSetup and BrachyPlanSetup using VMS.TPS.Common.Model.Types; using System.Drawing; using System.Text.RegularExpressions; using System.IO; using System.Xml.Serialization; using System.Diagnostics; using System.Runtime.InteropServices; using System.Runtime.InteropServices.ComTypes; using Microsoft; using Microsoft.Win32; using System.ComponentModel; using System.Threading.Tasks; //declare a namespace which our program will run in. namespace CASPE // This is our "namespace", which declared the scope of this document, and organize the script. Variables defined within this namespace are global within it, but not outside it. { //define the script public class in the VMS.TPS namespace #region Classes #region PatientInfo /// /// Patient Info contains all information about a patient. /// public class PatientInfo { public string PatientName; public string PatientID; public string PlanID; public double OriginX; public double OriginY; public double OriginZ; public List<PlanCatheter> CathList; public CylinderApplicator Applicator; public double shift; } #endregion #region PlanCatheter /// /// Plan Catherter will contain the plan information related to an individual catheter /// public class PlanCatheter { public int CathNumber; 109 public int NumSeeds; public List<Seed> SeedList; public List<double[]> CathShape; } #endregion #region Seed /// /// Seed contains the information about an individual seed. /// public class Seed { public double[] SeedPosition; public int SeedNumber; } #endregion #region CylinderApplicator /// /// CylinderApplicator contains all the information about an individual cylinder applicator /// public class CylinderApplicator { public int NumCaths; public List<Curve> CurveList; //list of all the curves in a single cylinderapplicator... public List<double[]> LastPointList; public List<List<double[]>> FirstThreeList; public List<List<double[]>> SeedPointsList; public List<double[]> FacePointList; public double CylinderLength; public double CylinderOD; public double GuideTubeID; public double FilletRadius; public double TubeOffset; public double TubeID; public double M4DrillIDforTap; public double M4DrillDepthforTap; public double M4ThreadMajorDiameter; public double maxgap; } #endregion #region Curve /// /// Curve contains the information for one single curve. /// public class Curve { public List<double[]> CathPath; //represents the xyz coordinates of the catheter path. public double DX; //start position in X-dir public double DZ; public static int CompareByY(double[] p1, double[] p2) 110 { return p1[1].CompareTo(p2[1]); } } #endregion #endregion public class XScript // a class is a type that is basically a blueprint that defines a set of data, actions, or methods public means it can be accessed without restrictions { #region Execute public void Execute(ScriptContext context) { string filepath = @"omitted filepath"; string patientpath = System.IO.Path.Combine(filepath, context.Patient.Name); string pathname = System.IO.Path.Combine(patientpath, context.BrachyPlanSetup.Id); string label = "CASPE " + Convert.ToString(context.BrachyPlanSetup.Id) + " .xml"; string xmlfilepath = System.IO.Path.Combine(patientpath, label); #region GetInfo PatientInfo Patient1 = new PatientInfo(); Patient1 = GetInfo(context, pathname); #endregion #region AssignCylinderVariables AssignCylinderVariables(Patient1, pathname); #endregion #region Convert Coordinates ConvertCoordinates(Patient1, pathname); #endregion #region Save Info to XML SaveToXML(Patient1, xmlfilepath); #endregion } #endregion #region GetInfo /// /// The GetInfo method retrieves all relavent information to the rest of the script from the planning system files, using the ESAPI. Variables such as the Cylinder Length, Number of Catheters, Catheter Geometries, Seed Positions, and the User Coordinate Systems are retrieved. /// /// /// <returns></returns> public PatientInfo GetInfo(ScriptContext context, String pathname) { #region Initialize Patient and Variables //Write the Patient and User Origin information to variables. PatientInfo Patient1 = new PatientInfo(); Patient1.PatientName = context.Patient.Name; Patient1.PatientID = context.Patient.Id; Patient1.PlanID = context.PlanSetup.Id; Patient1.OriginX = context.Image.UserOrigin.x; Patient1.OriginY = context.Image.UserOrigin.y; 111 Patient1.OriginZ = context.Image.UserOrigin.z; Patient1.CathList = new List<PlanCatheter>(); Patient1.shift = 15; //mm #endregion #region Prep Log File // Loop through the catheters and seeds and write the values to the script. //Clear the pathname file File.WriteAllText(pathname, String.Empty); //clear the file from previous data (delete this line if you want the data appended). using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // overloadedmethod(path, append, encoding) { file.WriteLine("custom cylinder creation log file"); file.WriteLine(); file.WriteLine("eclipse source positions:"); } #endregion #region Assign Seed and Shape Values // int cathcount = 0; File.WriteAllText(pathname, String.Empty); using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) { file.WriteLine("Custom Cylinder Creation Log File"); file.WriteLine(); file.WriteLine("Eclipse Source Positions:"); } foreach (var cath in context.BrachyPlanSetup.Catheters) { #region Prep Temporary Catheter //cath.ChannelNumber; //catheter channel number (integer) //cath.ApplicatorLength; // Total length of catheter from tip to treatment unit (double) PlanCatheter tempCath = new PlanCatheter(); tempCath.SeedList = new List<Seed>(); tempCath.CathShape = new List<double[]>(); //using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) //{ // cathcount++; // file.WriteLine("Source Positions for Catheter # " + cathcount); //} #endregion #region Assign Seed Positions to Temporary Catheter - Obsolete foreach (SourcePosition sp in cath.SourcePositions) { #region Get Seed Position/Rotation Info - Obsolete double[,] temppos = sp.Transform; /* 4x4 matrix, 4x3 rotation matrix & 4x1 translation matrix, bottom row is scaling and is always 0,0,0,1. Transform is actually the 4x4 transformation matrix itself, not a command. remember that for any x.y -> y is a property of x. The [,] means that we creating a matrix (or something like 112 that) which is an x,y or 2D format. This is why we use it for the transformation matrix. not we can loop through the j's and the i's and write each variable to file. */ //Patient1.Catheter Catheter1 = new PatientInfo.Patient1.Catheter(); //Create the seed variable Seed tempSeed = new Seed(); tempSeed.SeedPosition = new double[3]; for (int i = 0; i < 3; i++) // hard coded 4 would be better to get the size { tempSeed.SeedPosition[i] = temppos[i, 3]; } tempCath.SeedList.Add(tempSeed); #endregion #region Write Stuff to LogFile - Obsolete //using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) //{ // file.WriteLine("Rotation:"); // for (int i = 0; i < 4; i++) // hard coded 4 would be better to get the size // { // file.Write(temppos[0, i] + " "); // } // file.WriteLine(); // for (int i = 0; i < 4; i++) // hard coded 4 would be better to get the size // { // file.Write(temppos[1, i] + " "); // } // file.WriteLine(); // for (int i = 0; i < 4; i++) // hard coded 4 would be better to get the size // { // file.Write(temppos[2, i] + " "); // } // file.WriteLine(); // file.WriteLine("Position:"); // for (int i = 0; i < 4; i++) // hard coded 4 would be better to get the size // { // file.Write(temppos[3, i] + " "); // } // file.WriteLine(); // file.WriteLine("Position:"); // for (int i = 0; i < 3; i++) // hard coded 4 would be better to get the size // { // file.Write(tempSeed.SeedPosition[i] + " "); // } // file.WriteLine(); //} #endregion } #endregion #region Assign Shape Values to Temporary Catheter /* 113 The first catheter needs to be straight, and it needs to run down the center of the applicator, but the rotation is relative to the planning coordinate system. To do the rotation shift correctly, we can either do a rotation relative to the planning system, or relative to the user coordinate system. Since the applicator is brought in and sort of defines the user coordinate system, it would probably be best to simple align the coordniate systems to the applicator. To do this we would need to align the coordinates given by the planning system and rotate them either in the planning frame or in the user frame. I suppose that we will also need to rotate the reference frame as well. */ #region Build the CathShape Info foreach (VVector vv in cath.Shape) { double[] tempshapepos = new double[3]; tempshapepos[0] = vv.x; tempshapepos[1] = vv.y; tempshapepos[2] = vv.z; tempCath.CathShape.Add(tempshapepos); } #endregion #region Write Cathshape to LogFile - Obsolete //using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) //{ // file.WriteLine("Catheter Shape:"); // foreach (double[] position in tempCath.CathShape) // { // file.Write(position[0] + " " + position[1] + " " + position[2]); // file.WriteLine(); // } //} #endregion #endregion #region Assign Temporary Catheter to Cathlist/Patient Patient1.CathList.Add(tempCath); //using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) //{ // file.WriteLine(); //} #endregion } #endregion return Patient1; } #endregion #region AssignCylinderVariables /// /// The AssignCylinderVariables method /// /// 114 /// /// <returns></returns> public void AssignCylinderVariables(PatientInfo Patient1, string pathname) { CylinderApplicator Applicator = new CylinderApplicator(); Applicator.NumCaths = Patient1.CathList.Count; Applicator.CylinderLength = 120; Applicator.CylinderOD = 30; Applicator.GuideTubeID = 4; Applicator.FilletRadius = 0.5; Applicator.TubeOffset = 10; Applicator.TubeID = 2.8; Applicator.M4DrillIDforTap = 3.3; Applicator.M4ThreadMajorDiameter = 4; Applicator.M4DrillDepthforTap = 1.5 * Applicator.M4ThreadMajorDiameter; Patient1.Applicator = Applicator; Patient1.Applicator.maxgap = 3; //TODO: Add suppression states based on NumCaths (might just need to add this to the WriteCylinderVariables method. I can do a little calc for how many cells in a row to write a "S" for supressing a variable which would be created to supress the irrelavent geometries. //Keep for now but this here below is probably not needed. using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) { file.WriteLine("Number of Catheters = " + Applicator.NumCaths); file.WriteLine("Cylinder Length = " + Applicator.CylinderLength); file.WriteLine("Cylinder OD = " + Applicator.CylinderOD); file.WriteLine("Guide Tube ID = " + Applicator.GuideTubeID); file.WriteLine("Fillet Radius = " + Applicator.FilletRadius); file.WriteLine("Tube Offset = " + Applicator.TubeOffset); file.WriteLine("Tube ID = " + Applicator.TubeID); file.WriteLine("Drill ID for Tap = " + Applicator.M4DrillIDforTap); file.WriteLine("Drill Depth for Tap = " + Applicator.M4DrillDepthforTap); file.WriteLine("Thread Major Diameter = " + Applicator.M4ThreadMajorDiameter); } } #endregion #region Shift Coordinates to SW -- Done public void ConvertCoordinates(PatientInfo Patient, string pathname) { //Only works properly if there is a central channel //The other program doesn't do any shifts //Shift # 1 //The Planning System coordinate system has a translation shift to the User Coordinate System. I think that the User Coordinate System coordinates just need to be added to the Planning System coordinates in order to shift everything properly. Probably everything should be shifted before creating the full curves. We'll shift all the information from the planning system. We'll create a new instance of the Patient here, and call it PatientShifted. This will keep the Patient1 information available for debug and reference reasons. //Shift # 3 - Rotation 115 //The first catheter needs to be straight, and it needs to run down the center of the applicator, but the rotation is relative to the planning coordinate system. // To do the rotation shift correctly, we can either do a rotation relative to the planning system, or relative to the user coordinate system. // Since the applicator is brought in and sort of defines the user coordinate system, it would probably be best to simple align the applicator to the user coordinate system once all the shifts are complete. To do this we would need to rotate the applicator relative to the user coordinate system, by calculating the angle of the applicator relative to the user coordinate system and then rotating all the points of the entire system the using probably a rotation matrix. //Shift # 2 //The Coordinate System in the SW file is such that the base face of the cylinder is 15mm from origin in the x and z directions, and is 0mm in the y direction. //For the User Coordinate System in the planning software, the cylinder tip is at the origin, with the cylinder body falling in the negative z direction. //The User Coordinate System X and Y will be the SW X and Z coordinates, and there will have to be a 15mm shift in each of these directions. We will need to ADD 15mm to the User Coordinate System X and Y coordinate systems to properly translate them to where the SW X and Z coordinates are. The Z coordinate system in the User Coordinate System will have to have the cylinder length added to it, and then the Z location becomes equal to the Y location in SW. #region Shift Catheter Shape #region Shift to User Coordinate System //("Shape" is the points which define the lines which the seeds follow in Eclipse) using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) { file.WriteLine("Shape Catheter Shift"); } int cathcount = 0; foreach (var cath in Patient.CathList) { using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) { cathcount++; file.WriteLine("Source Positions for Catheter # " + cathcount); } foreach (double[] shape in cath.CathShape) { shape[0] -= Patient.OriginX; shape[1] -= Patient.OriginY; shape[2] -= Patient.OriginZ; using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) { file.Write(shape[0] + " "); file.Write(shape[1] + " "); file.Write(shape[2] + " "); file.WriteLine(); } } 116 using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) { file.WriteLine(); } } #endregion #region Rotate Coord System #region Step 1: Get Centerline Channel Angles Relative to User Coordinate System - Obsolete //Get the Initial points double[] point1 = Patient.CathList[0].CathShape[0]; double[] point2 = Patient.CathList[0].CathShape[1]; //Calculate the Y-axis rotation angle of the centerline channel relative to 0. double x1 = point1[0]; double z1 = point1[2]; double x2 = point2[0]; double z2 = point2[2]; double thetaY = -(Math.Atan2(z2 - z1, x2 - x1) + Math.PI / 2); //Calculate the X-axis rotation angle of the centerline channel relative to 0. double y1 = point1[1]; double y2 = point2[1]; double thetaX = -(Math.Atan2(z2 - z1, y2 - y1) + Math.PI / 2); using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) { file.WriteLine("ThetaY"); file.WriteLine(thetaY); file.WriteLine(thetaY * 180 / Math.PI); file.WriteLine("ThetaX"); file.WriteLine(thetaX); file.WriteLine(thetaX * 180 / Math.PI); } #endregion #region Step 2: Rotate Applicator to SW Coord System using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) { file.WriteLine("Rotation Shift of Shape Information"); } cathcount = 0; foreach (var cath in Patient.CathList) { using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) { cathcount++; file.WriteLine("Shape Positions for Catheter # " + cathcount); } foreach (double[] shapepoint in cath.CathShape) { 117 double xi = shapepoint[0]; double zi = shapepoint[2]; //Rotate points about Y shapepoint[0] = xi * Math.Cos(thetaY) - zi * Math.Sin(thetaY); shapepoint[2] = xi * Math.Sin(thetaY) + zi * Math.Cos(thetaY); double yi = shapepoint[1]; zi = shapepoint[2]; //Rotate points about X shapepoint[1] = yi * Math.Cos(thetaX) - zi * Math.Sin(thetaX); shapepoint[2] = yi * Math.Sin(thetaX) + zi * Math.Cos(thetaX); using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) { file.Write(shapepoint[0] + " "); file.Write(shapepoint[1] + " "); file.Write(shapepoint[2] + " "); file.WriteLine(); } } using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) { file.WriteLine(); } } #endregion #endregion #region Shift to SW Coord System //Shift the User Coordinate System to the SW Coordinate System using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) { file.WriteLine("Solidworks Coordinate Shift"); } int cathcount2 = 0; foreach (var cath in Patient.CathList) { using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) { cathcount2++; file.WriteLine("Shape Positions for Catheter # " + cathcount2); } foreach (double[] shapepoint in cath.CathShape) { double tempDouble = shapepoint[1]; shapepoint[1] = shapepoint[2]; shapepoint[2] = tempDouble; //Shift the x and z shapepoint[0] += Patient.shift; shapepoint[2] += Patient.shift; 118 //Shift the y shapepoint[1] += Patient.Applicator.CylinderLength; using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) { file.Write(shapepoint[0] + " "); file.Write(shapepoint[1] + " "); file.Write(shapepoint[2] + " "); file.WriteLine(); } } using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) { file.WriteLine(); } } #endregion #endregion } #endregion #region SaveToXML // Saves to the Patient1 PatientInfo class instance as an XML variable. public void SaveToXML(PatientInfo Patient1, string xmlfilepath) { //// Create a folder to save the xml file to: //// Specify a name for your top-level folder. //string folderName = @"omitted filepath"; //using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) //{ // file.WriteLine("Folder Name:"); // file.WriteLine(folderName); //} //// To create a string that specifies the path to a subfolder under your //// top-level folder, add a name for the subfolder to folderName. //string pathString = System.IO.Path.Combine(folderName, Patient1.PatientName /* + " Created " + DateTime.Now.ToString()*/); //using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) //{ // file.WriteLine("Path String:"); // file.WriteLine(pathString); //} //// Create the subfolder. You can verify in File Explorer that you have this //// structure in the C: drive. //// Local Disk (C:) //// Top-Level Folder //// SubFolder 119 //System.IO.Directory.CreateDirectory(pathString); //using (StreamWriter file = new StreamWriter(pathname, true, Encoding.ASCII)) // OverloadedMethod(path, append, encoding) //{ // file.WriteLine("Folder Created"); // file.WriteLine(pathString); //} // Create the xml file directory // Save the xml file XmlSerializer xs = new XmlSerializer(typeof(PatientInfo)); TextWriter tw = new StreamWriter(xmlfilepath); xs.Serialize(tw, Patient1); } #endregion } } Appendix E: Cylinder Applicator Source Position Comparator (CASPC) Code using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.Xml.Serialization; using SolidWorks.Interop.sldworks; using SolidWorks.Interop.swconst; namespace Applicator_Creator { #region Classes /// /// Patient Info contains all information about a patient. /// public class PatientInfo { public string PatientName; public string PatientID; // needed for save file name? public string PlanID; // public double OriginX; public double OriginY; public double OriginZ; public double shift; public List<PlanCatheter> CathList; public CylinderApplicator Applicator; } /// /// Plan Catherter will contain the plan information related to an individual catheter /// 120 public class PlanCatheter { public int CathNumber; public int NumSeeds; public List<Seed> SeedList; public List<double[]> CathShape; } /// /// Seed contains the information about an individual seed. /// public class Seed { public double[] SeedPosition; public int SeedNumber; } /// /// CylinderApplicator contains all the information about an individual cylinder applicator /// public class CylinderApplicator { public int NumCaths; public List<Curve> CurveList; //list of all the curves in a single cylinder applicator... public List<double[]> LastPointList; public List<List<double[]>> FirstThreeList; public List<List<double[]>> SeedPointsList; public List<double[]> FacePointList; public double CylinderLength; public double CylinderOD; public double GuideTubeID; public double FilletRadius; public double TubeOffset; public double TubeID; public double M4DrillIDforTap; public double M4DrillDepthforTap; public double M4ThreadMajorDiameter; } /// /// Curve contains the information for one single curve. /// public class Curve { public List<double[]> CathPath; //represents the xyz coordinates of the catheter path. public double DX; //start position in X-dir public double DZ; public static int CompareByY(double[] p1, double[] p2) { return p1[1].CompareTo(p2[1]); } } 121 #endregion public class Program { #region Notes #endregion #region Main -- Done /// /// The main entry point for the application. /// [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form1()); } #endregion #region Execute -- Done /// /// Everything that happens once the Create Applicator button is pressed. /// public void Execute(string filepath1, string filepath2, string folderpath) { // Instantiate PatientInfo, a class native to this program. See below for Definition PatientInfo Patient1 = new PatientInfo(); PatientInfo Patient2 = new PatientInfo(); #region Get and Set Variables Required Patient1 = GetVariables(filepath1); Patient2 = GetVariables(filepath2); #endregion #region Compare Dwell Positions ComparePlans(Patient1, Patient2, folderpath); #endregion } #endregion #region Get Variables from XML File -- Done public PatientInfo GetVariables(string filepath) { // Deserialize using XML Serializer to get Patient. //string xmlpath = System.IO.Path.Combine(filepath, ".xml"); PatientInfo Patient1 = new PatientInfo(); XmlSerializer xs = new XmlSerializer(typeof(PatientInfo)); using (var sr = new StreamReader(filepath)) { Patient1 = (PatientInfo)xs.Deserialize(sr); } return Patient1; } #endregion #region Compare Plans - Working 122 public void ComparePlans(PatientInfo Patient1, PatientInfo Patient2, string folderpath) { int cathcount = Patient1.CathList.Count(); List<double> distlist = new List<double>(); for (int i=0; i< cathcount; i++) { List<Seed> cath1 = Patient1.CathList[i].SeedList; int seedcount = cath1.Count(); List<Seed> cath2 = Patient2.CathList[i].SeedList; for (int j=0; j<seedcount; j++) { double xdist = cath1[j].SeedPosition[0] - cath2[j].SeedPosition[0]; double xdistsq = Math.Pow(xdist, 2); double ydist = cath1[j].SeedPosition[1] - cath2[j].SeedPosition[1]; double ydistsq = Math.Pow(ydist, 2); double zdist = cath1[j].SeedPosition[2] - cath2[j].SeedPosition[2]; double zdistsq = Math.Pow(zdist, 2); double dist = Math.Pow(xdistsq + ydistsq + zdistsq, 0.5); distlist.Add(dist); } } List<double> ret = CalculateStdDev(distlist); double avg = ret[0]; double std = ret[1]; string logfilepath = System.IO.Path.Combine(folderpath, "CASPC.txt"); File.WriteAllText(logfilepath, String.Empty); //clear the file from previous data (delete this line if you want the data appended). using (StreamWriter file = new StreamWriter(logfilepath, true, Encoding.ASCII)) // overloadedmethod(path, append, encoding) { file.WriteLine("Average Dist: " + avg + " mm"); file.WriteLine(); file.WriteLine("StdDev: " + std + " mm"); } } #endregion #region CalculateStdDev private List<double> CalculateStdDev(List<double> distlist) { List<double> ret = new List<double>(); if (distlist.Count() > 0) { //Compute the Average double avg = distlist.Average(); //Perform the Sum of (value-avg)_2_2 double sum = distlist.Sum(d => Math.Pow(d - avg, 2)); //Put it all together double std = Math.Sqrt((sum) / (distlist.Count() - 1)); ret.Add(avg); 123 ret.Add(std); } return ret; } #endregion } }
Thesis/Dissertation
eng
Medical Physics
Vancouver : University of British Columbia Library
Attribution-NonCommercial-NoDerivatives 4.0 International
Graduate
Custom template design and manufacture automation for interstitial gynecological brachytherapy
Text