Home

Awesome

TomoTherapy Archive Extraction Tools

by Mark Geurts mark.w.geurts@gmail.com <br>Copyright © 2015, University of Wisconsin Board of Regents

The TomoTherapy® Archive Extraction Tools are a compilation of functions that parse TomoTherapy patient archives and into MATLAB structures and arrays. In addition, a function is included which can use these variables for dose calculation. These tools are used in various applications, including exit_detector, systematic_error, and mvct_dose.

These tools use the SSH/SFTP/SCP for Matlab (v2) interface based on the Ganymed-SSH2 javalib for sending files between and executing commands on a research workstation, which has been included in this repository. Refer to the Third Party Statements for copyright information of this interface.

TomoTherapy is a registered trademark of Accuray Incorporated.

Contents

Installation and Use

To install the TomoTherapy Archive Extraction Tools, copy all MATLAB .m files and subfolders from this repository into your MATLAB path. If installing as a submodule into another git repository, execute git submodule add https://github.com/mwgeurts/tomo_extract. To configure dose calculation, see the CalcDose instructions below.

Compatibility and Requirements

The TomoTherapy Archive Extraction Tools have been validated for 4.X and 5.X patient archives using MATLAB versions 8.3 through 8.5 on Macintosh OSX 10.8 (Mountain Lion) through 10.10 (Yosemite). These tools use the javax.xml.xpath Java library and xmlread() MATLAB function for parsing archive XML files. These functions are compatible with helical and direct plans.

Tools and Examples

The following subsections describe what inputs and return variables are used, and provides examples for basic operation of each tool. For more information, refer to the documentation within the source code.

LoadImage

LoadImage() loads the reference CT and associated IVDT information from a specified TomoTherapy patient archive and plan UID. This function calls FindIVDT() to load the IVDT data.

The following variables are required for proper execution:

The following variables are returned upon succesful completion:

Below is an example of how this function is used:

path = '/path/to/archive/';
name = 'Anon_0001_patient.xml';
planUID = '1.2.826.0.1.3680043.2.200.1688035198.217.40463.657';
image = LoadImage(path, name, planUID);

LoadStructures

LoadStructures() loads transverse reference structure sets given a reference image UID and creates mask arrays for each structure. Voxels will be 1 if they are included in the structure and 0 if not. Currently partial voxel inclusion is not supported.

The following variables are required for proper execution:

The following variables are returned upon succesful completion:

Below is an example of how this function is used:

path = '/path/to/archive/';
name = 'Anon_0001_patient.xml';
planUID = '1.2.826.0.1.3680043.2.200.1688035198.217.40463.657';
image = LoadImage(path, name, planUID);
atlas = LoadAtlas('atlas.xml');
structures = LoadStructures(path, name, image, atlas);

LoadPlan

LoadPlan() loads the delivery plan from a specified TomoTherapy patient archive and plan trial UID. This data can be used to perform dose calculation via CalcDose().

The following variables are required for proper execution:

The following variables are returned upon succesful completion:

Below is an example of how this function is used:

path = '/path/to/archive/';
name = 'Anon_0001_patient.xml';
planUID = '1.2.826.0.1.3680043.2.200.1688035198.217.40463.657';
plan = LoadPlan(path, name, planUID);

LoadPlanDose

LoadPlanDose() loads the optimized dose after EOP (ie, Final Dose) for a given reference plan UID and TomoTherapy patient archive. The dose is returned as a structure.

The following variables are required for proper execution:

The following variables are returned upon succesful completion:

Below is an example of how this function is used:

path = '/path/to/archive/';
name = 'Anon_0001_patient.xml';
planUID = '1.2.826.0.1.3680043.2.200.1688035198.217.40463.657';
dose = LoadPlanDose(path, name, planUID);

LoadDailyQA

LoadDailyQA() parses a TomoTherapy Transit Dose DICOM RT object or patient archive XML file for procedure return data and derives various calibration parameters. See below for more details on the parameters returned.

The following variables are required for proper execution:

The following structure fields are returned upon succesful completion:

Below is an example of how this function is used:

path = '/path/to/archive/';
name = 'Daily_QA_patient.xml';
dailyqa = LoadDailyQA(path, name, 9000, 531, 528, 0); 

LoadStaticCouchQA

LoadStaticCouchQA() searches a TomoTherapy machine archive (given by the name and path input variables) for static couch QA procedures. If more than one is found, it prompts the user to select one to load (using listdlg call) and reads the exit detector data into the return variable detdata. If no static couch QA procedures are found, the user is prompted to select a DICOM RT transit dose file. Note, TomoDirect DICOM RT transit dose files are not currently supported.

The following variables are required for proper execution:

The following variables are returned upon succesful completion:

Below is an example of how this function is used:

% Load Daily QA data (channel calibration)
path = '/path/to/archive/';
name = 'Daily_QA_patient.xml';
dailyqa = LoadDailyQA(path, name, 9000, 531, 528, 0); 
 
% Load Static Couch QA data
path = '/path/to/archive/';
name = 'Static_Couch_QA_patient.xml';
[machine, planUID, detdata, tau] = LoadStaticCouchQA(path, name, 27, ...
    dailyqa.channelCal, 643); 

FindIVDT

FindIVDT() searches for the IVDT associated with a daily image, reference image, or machine. If 'MVCT', the calibration UID provided is searched for in the machine archive, and the corresponding IVDT is returned. If 'TomoPlan', the IVDT UID is the correct value, the IVDT is loaded for that value. If 'TomoMachine', the machine archive is parsed for the most recent imaging equipment and the UID is returned.

The following variables are required for proper execution:

The following variables are returned upon succesful completion:

Below is an example of how this function is used:

path = '/path/to/archive/';
id = '1.2.826.0.1.3680043.2.200.1693609359.434.30969.2213';
ivdt = FindIVDT(path, id, 'TomoPlan');

FindMVCTScanLengths

FindMVCTScanLengths() searches a TomoTherapy patient archive for patient plans with associated MVCT procedures, and returns a list of procedure UIDs and start/end scan positions, organized by plan type.

The following variables are required for proper execution:

The following variable is returned upon succesful completion:

Below is an example of how this function is used:

path = '/path/to/archive/';
name = 'Anon_0001_patient.xml';
scans = FindMVCTScanLengths(path, name);

FindPlans

FindPlans() loads all delivery plan trial UIDs from a specified TomoTherapy patient archive. Only approved Helical, non-DQA plans are returned.

The following variables are required for proper execution:

The following variable is returned upon succesful completion:

Below is an example of how this function is used:

path = '/path/to/archive/';
name = 'Anon_0001_patient.xml';
plans = FindPlans(path, name);

CalcDose

CalcDose reads in a patient CT and delivery plan, generate a set of inputs that can be passed to the TomoTherapy Standalone Dose Calculator, and executes the dose calculation either locally or remotely.

This function will first attempt to calculate dose locally, if available (the system must support the which command). If not found, the dose calculator inputs will be copied to a remote computation server via SCP and sadose/gpusadose executed via an initiated SSH connection.

To change the connection information for the remote computation server, create a file named config.txt in the working directory with the following content (an example is provided with this repository):

  REMOTE_CALC_SERVER = ipaddress
  REMOTE_CALC_USER = username
  REMOTE_CALC_PASS = password

The first argument is the server DNS name (or IP address), while the second and third are the username and password, respectively. This user account must have SSH access rights, rights to execute sadose/gpusadose, and finally read/write access to the temp directory. Note, this function assumes that the remote computation server is unix-based.

Following execution, the CT image, folder, and SSH connection variables are persisted, such that CalcDose may be executed again with only a new plan input argument.

Dose calculation will natively compute the dose at the CT resolution. However, if the number of image data elements is greater than 4e7, the dose will be downsampled by a factor of two. The calculated dose will be downsampled (from the CT image resolution) by this factor in the IECX and IECY directions, then upsampled (using nearest neighbor interpolation) back to the original CT resolution following calculation. To speed up calculation, the dose can be further downsampled by adjusting the downsample variable declaration in the code below, where downsample must be an even divisor of the CT dimensions (1, 2, 4, etc).

Contact Accuray Incorporated to see if your research workstation includes the TomoTherapy Standalone Dose Calculator.

The following variables are required for proper execution:

The following variables are returned upon succesful completion:

Below are examples of how this function is used:

% Test if dose calculation is available (returns 0 or 1)
flag = CalcDose();

% Calculate dose, passing image, plan, and model folder inputs
dose = CalcDose(image, plan, modelfolder);

% Calculate dose on same image as above, using modified plan modplan
dose = CalcDose(modplan);

% Calculate dose again, but using sadose rather than gpusadose
dose = CalcDose(image, modplan, modelfolder, 1);

ParseDetData

ParseDetData() is a function that extracts the dose1, dose2, and detector data from a compressed TomoTherapy Detector Data file (detdata.dat). This function will display a progress bar while it loads (unless MATLAB was executed with the -nodisplay, -nodesktop, or -noFigureWindows flags). The following terminal commands are used to download the detector data file from the DRS following delivery:

ftp drs
bin
cd /sd0a
get detData.dat
quit

The following variables are required for proper execution:

The following variables are returned upon succesful completion:

Below is an example of how this function is used:

% Parse detector data
data = ParseDetData('./Treat_3_J48_detData.dat');

% Plot the detector data
figure;
imagesc(data.detdata);

IndexLibrary

IndexLibrary scans an given directory for patient archives, storing a summary of results in the file PatientLibraryIndex.xml within the same directory. When called again, it will re-index the directory, generating a new index file. A DOM node of the library contents is also optionally returned.

The library documents the following attributes for each approved plan: approved plan trial UID, plan label, timestamp, study UID, plan UID, and archive path.

The following variables are required for proper execution:

The following variables are returned upon succesful completion:

Below is an example of how this function is used:

% Create new library index file
IndexLibrary('1.0', 'path/to/patient/archives');

% Read the resulting index as a DOM node
docNode = xmlread('PatientLibraryIndex.xml');

% Update library index, this time returning DOM node
docNode = IndexLibrary('1.0', 'path/to/patient/archives');

Event Calling

These functions optionally return execution status and error information to an Event() function. If available in the MATLAB path, Event() will be called with one or two variables: the first variable is a string containing the status information, while the second is the status classification (WARN or ERROR). If the status information is only informative, the second argument is not included. Finally, if no Event() function is available errors will still be thrown via the standard error() MATLAB function.

Third Party Statements

SSH/SFTP/SCP for Matlab (v2) <br>Copyright © 2014, David S. Freedman <br>All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

License

This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.