Export DVHs to a CSV File Using Python

      10 Comments on Export DVHs to a CSV File Using Python

This blog post was inspired by a question in the Varian Developer Forum:

From File > Export > DVH in Tabular format, one can export DVH for selected structures into a single text file. I have been using the R package RadOnc to load these DVH for analysis. I have a single dummy patient containing 40 plans and I wish to write a script to export the DVH in this way for all structures in the 40 plans. I cannot find a way to do this via scripting? Any advice appreciated

I’ve never used this feature in Eclipse, so I tried it out with a few structures. First, I had to make sure that the DVHs were already in the display. To do this, I had to click on the Planning menu item, then on Show Dose Volume Histogram View.

The output file, however, is not formatted in a way that’s easily parseable. It starts with an overall header, then for each structure, contains a header including some dose statistics, followed by the DVH itself.

I would prefer a simpler file format, like CSV, where each line would contain the patient ID, course ID, plan ID, structure ID, DVH dose, and DVH volume—nothing else. This format would be easily readable by many programs, including R and Excel, although the R package that the question mentions, RadOnc, is able to read Eclipse’s format.

Here I describe a Python script that goes through every plan of a given patient, and outputs the DVH of every structure in that plan to a CSV file. For simple, data extraction scripts like these, I prefer to use Python because I feel like the code is cleaner and to the point. Also, I’m easily able to use the command-line to run the script in batch with multiple patients, if necessary. Of course, I could do this with a C# program as well, but the coding/running cycle is shorter with Python. If you haven’t used IronPython to run ESAPI scripts before, I suggest you first read my blog post ESAPI Programming with Python.

I’ve put the script on GitHub as export-dvh.

The script starts by storing the patient ID and the output file name that are given as command-line arguments. These are obtained using sys.argv, a list where the first item is the name of the script file name, and the rest are the command-line arguments.

Next, an Eclipse application object is created, and the patient is opened. I don’t check whether the returned patient is None (Python’s equivalent of null in C#), which happens when the patient can’t be opened (like if it doesn’t exist). This script, in general, doesn’t do much error checking, but it would be wise to do so.

The output file is then opened for writing and a CSV writer object is created. This script uses the csv Python package.

To get to every structure in every plan of the patient, we need to loop through every Course, every PlanSetup, and every Structure object in the patient. Inside of this triple loop, we call the GetDVHCumulativeData method, specifying absolute units and a bin width of 0.01:

According to the ESAPI documentation, this method may return null (None in Python) if the DVH cannot be calculated. For example, the plan may not have any dose. If it’s not None, we output the result using the CSV writer; otherwise, we print out an error on the standard error stream, typically the screen (see standard streams):

Finally, we dispose of the application object to free any unmanaged resourced.

To run this script, use the command-line and pass in the patient ID and the output file name:

Any errors will be output to the screen, but the actual data will be output to a file. If you have a lot of plans or structures to process, you can print out some kind of progress to the screen.

If you have a lot of patients to process, you can repeatedly run this script with a different patient ID, perhaps in a shell script that reads a list of patient IDs. Or, you can edit the script to read the patient IDs from a file.

10 thoughts on “Export DVHs to a CSV File Using Python

  1. Victor Gabriel Leandro Alves

    Hi Carlos,
    I could not imagine that it is possible to use Python for .NET package to get DVH data from Varian Eclipse database.

    I thought that only ESAPI would do the job.

    Is it possible getting optimization constrains and priorities from VMAT/IMRT planning using references to Varian API assemblies ?


    how can I find Varian’s path when referencing assemblies from a remote ARIA System (Citrix) ?

    Thank you very much.

    ps. I am following you at github.


    1. Carlos Anderson Post author

      Hi Victor,

      You’re still using ESAPI when programming in Python (specifically, IronPython). ESAPI is a .NET library, so any language compatible with the .NET framework (e.g., IronPython, F#, VB.NET) could be used to access ESAPI.

      You need to run the Python program from the machine that has the Eclipse installation. One way to find the paths to the Varian assemblies is to create a new ESAPI script with the scripting wizard, and then look at the paths it references.

      1. Victor Gabriel Leandro Alves

        Hi Carlos,

        I have taken a look at your export-dvh.py script. it seems to use pythonnet package (clr).


        Have you ever tried CPython (3.x) + pythonnet package instead of IronPython?
        I am trying to access the paths to the Varian assemblies via mapping network folder.
        I am not allowed to install python at Citrix server.

        Victor Alves

  2. J

    Hi Carlos,

    I have been using python to export dvh data from eclipse using the same method you provided in your export-dvh.py code. It has been working great, but all of a sudden the code no longer runs (with no change to the code) and I get the following error:

    Unable to cast object of type ‘VMS.TPS.Common.Model.Application’ to type ‘VMS.TPS.Common.Model.IApplication’.

    Would you have any idea as to why this happens all of a sudden and how I could possibly solve the issue?


      1. J

        Thanks for the reply. I tried switching to the 32-bit version as the other person did, but the same error persists. I also tried running both ipy64.exe and ipy.exe and there was no change.

        If you think of any other reason this would happen please let me know!

        Thanks again!


Leave a Reply

Your email address will not be published. Required fields are marked *