Inicio > Informática Médica > Un ejemplo de aplicación de Eclipse Scripting API para la automatización en la verificación de planificaciones de radioterapia

Un ejemplo de aplicación de Eclipse Scripting API para la automatización en la verificación de planificaciones de radioterapia

Un ejemplo de aplicación de Eclipse Scripting API para la automatización en la verificación de planificaciones de radioterapia

En este trabajo se describe un programa escrito en C# que hace uso de Eclipse Scripting API para acceder a varios datos y parámetros de una planificación de radioterapia externa realizada con el sistema de planificación de tratamientos Eclipse.

Alejandro Barranco López1, Daniel Nogueira Souto2, Álvaro Boria Alegre3 y Luis Sopeña Sanz4

1Facultativo Especialista de Área de Radiofísica Hospitalaria. PhD en Física, MSc en Astrofísica, Física de Partículas y Cosmología. Lugar de trabajo: H.C.U. Lozano Blesa (Zaragoza). [email protected]

2Médico Interno Residente de Medicina Nuclear. Lugar de trabajo: H.C.U. Lozano Blesa (Zaragoza).

3Facultativo Especialista de Área de Radiodiagnóstico. Máster en Iniciación a la Investigación en Medicina. Lugar de trabajo: Hospital San Jorge (Huesca).

4Facultativo Especialista de Área de Oncología Radioterápica. Máster Internacional de Oncología Clínica. Máster en Radiocirugía y Radioterapia Estereotáxica. Máster en Oncología Intervencionista. Lugar de trabajo: H.C.U. Lozano Blesa (Zaragoza).

3/30/20

Resumen

 En este trabajo se describe un programa escrito en C# que hace uso de Eclipse Scripting API para acceder a varios datos y parámetros de una planificación de radioterapia externa realizada con el sistema de planificación de tratamientos Eclipse. Este programa o script tiene como finalidad mostrar toda una colección de ejemplos de los diferentes usos de la API de Eclipse. En particular, los ejemplos mostrados se usan para automatizar tareas de verificación de los planes de radioterapia calculados.

Palabras clave — ESAPI, Eclipse, radioterapia.

Abstract

 In this paper we describe a C# program making use of Eclipse Scripting API to access several data and parameters of an external radiotherapy planning computed with the Eclipse treatment planning system. This program or script has the aim of showing a collection of examples of different uses of the Eclipse API. In particular, the examples shown are used to automate verification tasks for the computed radiotherapy plans.

Key words — ESAPI, Eclipse, radiotherapy.

1  Introducción

Actualmente, un proceso de radioterapia externa incluye una etapa de planificación del tratamiento en la que se hace uso de programas de ordenador llamados sistemas de planificación de tratamiento (TPS, por sus siglas en inglés). A esta etapa le sigue otra en la que se verifica la planificación resultante, como medida de seguridad. Normalmente, la primera de estas dos etapas la suele realizar un dosimetrista y la verificación la realiza un especialista en Radiofísica. Por tanto, ambas etapas están sujetas al error humano, aunque con la etapa de verificación estos errores quedan reducidos. Sin embargo, con las herramientas de las tecnologías de información podríamos automatizar estos procesos ahorrando tiempo y reduciendo el factor humano en los posibles errores. Por eso, en este trabajo se presenta un ejemplo de aplicación de lo anterior. Muchos TPS actuales llevan incorporadas herramientas de scripting que permiten obtener y/o modificar información del TPS de manera programática. Este es el caso del sistema de planificación de Varian Medical Systems, Eclipse, que incorpora una interfaz de programación de aplicaciones (ESAPI, por sus siglas en inglés), de la que ya se ha hablado en [1]. Hemos usado, por tanto, dicha herramienta de scripting para automatizar el proceso de verificación de las planificaciones de radioterapia externa.

2  Material

Las diferentes herramientas que se han usado para este trabajo son:

Sistema de Planificación de Tratamientos Eclipse: Como ya hemos comentado, se ha hecho uso del TPS Eclipse (versión 15.6) de Varian Medical Systems.

Interfaz de Programación de Aplicaciones de Eclipse, ESAPI: Es el conjunto de clases, objetos, funciones…del lenguaje de programación C#.NET a través de las cuales podemos escribir programas o scripts para obtener o modificar información de Eclipse [2, 3]. En particular, ESAPI ofrece dos modos a la hora de utilizar los programas desarrollados con ella, de forma standalone, lo que vendría a ser un ejecutable individual; o integrados en la propia interfaz de Eclipse. Es en este último modo en el que se ha trabajado.

Los scripts que vamos a mostrar son pequeños fragmentos de código y, por tanto, se pueden escribir en cualquier editor de texto, ya que al ejecutarlos desde la propia interfaz de Eclipse no necesitan ser compilados. No obstante, cualquier entorno de desarrollo integrado (IDE, por sus siglas en inglés) de C# podría haber sido utilizado, ya que suelen incorporar bastantes herramientas a la hora de programar o de depurar fallos de los programas, como por ejemplo Visual Studio 12 [4], que es el que recomienda Varian.

3  Método

Así como en [1] se usaba la interfaz para Python PyESAPI, nosotros usaremos la versión original de ESAPI para programación en C#, sin embargo, el código que vamos a describir a continuación y que se muestra en el apéndice es perfectamente transformable para PyESAPI. Como ya hemos comentado, basta escribir el código que se presenta más abajo en cualquier editor de texto, guardarlo con extensión .cs y abrirlo con la herramienta de scripts de Eclipse. Cada vez que se ejecute, el programa realizará automáticamente una serie de comprobaciones acerca de la planificación seleccionada en la interfaz de Eclipse, correspondientes a la etapa de verificación.

Al final del presente trabajo aparece toda una serie de fragmentos de código que unidos en el orden en el que aparecen constituyen el script. A continuación, se describe en qué consiste cada uno de ellos, de forma que la numeración de cada descripción coincide con la figura a la que hace referencia.

  1. En el primer fragmento de código se muestra el encabezado, tras cargar una serie de bibliotecas que serán usadas por las funciones que veremos más adelante. De todas estas bibliotecas destacamos las de las líneas 9 y 10, necesarias para usar ESAPI. Como hemos mencionado más arriba, hay dos modos de trabajar con ESAPI, en el que aquí usamos, integrada en la propia interfaz de Eclipse, es necesario trabajar con un contexto, es decir, toda la información que manejemos a través de ESAPI hará referencia al contexto de Eclipse que este seleccionado en el momento de ejecutar el script. Por ejemplo, si tenemos seleccionado en Eclipse un plan, context.PlanSetup hará referencia a dicho plan, tras definir el contexto en la variable context (línea 20).
  2. En el cuerpo principal del script se comprueba primero que el contexto sea correcto, es decir, que exista un paciente y un plan seleccionado sobre el cual se recabará cierta información (líneas 1-5). En las líneas 7 y 8 se definen las variables ss y ps, que contienen el StructureSet y PlanSetup o conjunto de estructuras y plan (propiamente dicho) del contexto. En las líneas 13-26 y 32 se llaman a las diferentes funciones que definimos más adelante, las cuales devuelven una string con las alertas encontradas si las hubiera. Finalmente, en las líneas 34-41 se escriben las alertas acumuladas en la string warnings a un archivo (de ahí la necesidad de la biblioteca System.IO).

Las comprobaciones que se realizan con las diferentes funciones son:

  1. Con la función CheckCT se comprueba que el TC (tomografía computerizada) de planificación sea el último TC creado. Esto es importante para no planificar en un TC erróneo, por ejemplo, en uno de un tratamiento anterior. Obviamente habrá casos en los que esto de lugar a falsos positivos, pero simplemente se generaría una alerta y sería la persona encargada de ejecutar el script la que puede decidir si, efectivamente, es un falso positivo o la planificación se está realizando sobre un TC erróneo. En realidad, y para ser más precisos, no se busca el último TC, si no el último conjunto de estructuras contorneado.
  2. La función CheckCouch comprueba que se haya introducido la mesa de tratamiento. Para ello se comprueba que existan las estructuras CouchSurface y CouchInterior y que no estén duplicadas.
  3. CheckStructures comprueba varias cosas:

Primero, que no existan estructuras vacías (líneas 7-9).

En segundo lugar, líneas 11-21, se comprueba la correcta identificación de los órganos bilaterales. En nuestro protocolo de nomenclatura los órganos bilaterales son nombrados con _I o _D al final del nombre según sean a izquierda o a derecha. El script comprueba que no estén intercambiados, es decir, que el centro geométrico de los que se han nombrado con _I tengan mayor coordenada X que los correspondientes nombrados con _D. Tal y como está programado el script solo se tiene en cuenta el caso de un TC HFS (cabeza primero, supino), ya que, por problemas de exportación a aceleradores de otra casa comercial, se etiquetan todos los TC con dicha descripción, aunque no se hayan realizado así. Por ejemplo, para los TC que se realizan en prono el script genera un falso positivo al creer que los órganos bilaterales contorneados están intercambiados. En el caso de que no existieran dichos problemas de exportación y se generen los TC con la etiqueta correcta habría que extender el script para los casos diferentes a HFS. Para identificar si el nombre de la estructura acaba en _I o _D, se hace uso de expresiones regulares, para lo cual es necesario cargar la biblioteca System.Text.RegularExpressions.

Y en tercer lugar (líneas 23-32), que exista la estructura BODY y sea de tipo external. En nuestro caso, para tener en cuenta los apoyos e inmovilizadores en el cálculo de la dosis se contornean dentro de la estructura BODY y se genera otra estructura BODY_CBCT que es la que corresponde al paciente exclusivamente. Esto puede dar lugar a confusiones y que se asigne como external a la estructura BODY_CBCT lo que excluiría los apoyos del cálculo de la dosis.

  1. La función CheckMarkers comprueba que los marcadores estén bien colocados, comprobando si existen 5 en total y que al menos 3 caigan en una región de alta densidad (los que corresponderían a los perdigones, los otros dos marcadores se colocan sobre la mesa). Para comprobar si caen en una región de alta densidad se define, para cada uno de ellos, una matriz de píxeles de 4mm×4mm con el marcador en el centro, sobre el corte del TC en el que se encuentran situados. Dicha matriz debe contener al menos un píxel con densidad mayor que 1500HU (unidades Hounsfield). Comprobar que los marcadores estén bien colocados es importante porque el script, más adelante, genera un comentario de centraje con los desplazamientos que se deberán hacer al paciente una vez colocado en la camilla de tratamiento y centrado en los tatuajes, y dichos desplazamientos los calcula de la posición de los marcadores.
  2. La función CheckOrigin comprueba que el origen sobre el TC esté bien colocado, alineado con los marcadores. Para ello se determina que el marcador con menor coordenada X en valor absoluto sea menor que 1mm. Y, análogamente, para los dos marcadores con menor coordenada Y.
  3. La función CheckCentraje comprueba que en el campo de comentarios del plan haya un comentario de centraje con la siguiente estructura

Desplazamientos

Vrt: 0.0 cm

Lng: 0.0 cm

Lat: 0.0 cm

Altura Marcas: 0.0 cm

DFS 0 Marcas: 0.0 cm

Altura Isocentro: 0.0 cm

DFS 0 Isocentro: 0.0 cm

Este comentario incluye los desplazamientos que se tendrán que realizar al paciente en tratamiento para llevarlo desde el origen (centrado en tatuajes) hasta el isocentro, así como las diferentes distancias que se comprueban para ver que el paciente se ha colocado correctamente: alturas desde los tatuajes laterales a la mesa y las distancias fuente-superficie (DFS), tanto cuando el paciente está situado en el origen como cuando está situado en el isocentro.

  1. La función CheckCamposCentraje comprueba que existan los campos de colocación a 0º y 270º, que incluyan el ángulo de gantry en el nombre y que el colimador y la mesa se encuentren en 0º.
  2. La función CheckFields alerta en caso de usarse una energía con filtro. Si los campos corresponden a arcos con sentido horario deben contener SH en el nombre, y si tienen sentido antihorario SAH, en caso contrario se alerta para corregirlo. Además, se alerta también si hay campos con giros de colimador similares entre sí o cercanos a 0º (con diferencias menores a 5º). Finalmente, también se comprueba que el número de arcos en cada sentido, horario o antihorario, esté equilibrado.
  3. La función CheckTolerancias alerta en el caso de que haya algún campo sin una tabla de tolerancia asignada.
  4. La función CheckGantrySpeed comprueba que la velocidad de gantry sea constante. Esta es una recomendación de Varian, así que se comprueba que la velocidad de gantry se mantenga, en nuestro caso, en 6º/s en todos los puntos de control. Obviamente, no en todos los casos se va a poder cumplir con dicho requisito, por ejemplo, en una radiocirugía.
  5. Como índice básico de complejidad del plan se calcula el cociente entre las unidades monitor totales y los cGy por fracción. La función CheckUMcGy alerta en el caso de que dicho índice sea mayor que 4.
  6. La función CheckCalculationModel comprueba que se usa la última versión aprobada del algoritmo de Acuros, en nuestro caso Acuros_15.6.03. Obviamente, si se aprueban nuevas versiones la string de la línea 4 debe ser cambiada.
  7. La función CheckPrescription comprueba varias cosas. En las líneas 7 y 8, que exista un punto de referencia de dosis. Este punto es el que se usa para almacenar la dosis administrativa en el sistema de registro y verificación, y en él se almacenan la dosis total, dosis diaria y dosis por sesión.

En las líneas 9 y 10 se comprueba que exista una prescripción para el plan y, en particular, para algún PTV (Planning Target Volume).

En las líneas 15-29 se comprueba que la dosis de la prescripción del PTV de mayor dosis coincida con los límites de dosis que aparecen en el punto de referencia.

Finalmente, si la dosis por fracción es menor que 1.8Gy, se alerta de que el tratamiento puede ser hiperfraccionado (líneas 33 y 34). Y habrá que tener cuidado a la hora de establecer los límites de dosis diaria y dosis por sesión del punto de referencia.

  1. La función CheckMedula comprueba que si existe la estructura MED (correspondiente a la médula en nuestro protocolo), no sobrepase la dosis biológica equivalente de 45Gy en 30 sesiones con un α/β=3. Aunque en la siguiente función que se presenta, CheckConstraints, se comprueba que se cumple con los límites de dosis para los órganos de riesgo que aparecen en la prescripción, hemos incluido la función CheckMedula para comprobar de oficio que ciertos órganos críticos como la médula no corran ningún riesgo.

Obviamente, esta función se puede extender a otro tipo de órganos en serie de manera inmediata.

  1. Por último, aparece la función CheckConstraints. Esta función es la más compleja de todas por falta de estandarización en la nomenclatura de las prescripciones, por ello aparece aparte del resto de funciones en la figura 2. Así como la nomenclatura de las estructuras está más o menos estandarizada en las planificaciones que manejamos, no ocurre así en las prescripciones[1]. Por ello, en las líneas 11-53 se ha creado un diccionario en el que la etiqueta corresponde a la nomenclatura de la estructura en cuestión y el valor es una lista de expresiones regulares que intentarán coincidir con los órganos que aparecen en la prescripción.

En las líneas 57-88 se identifican los órganos de riesgo tal y como aparecen en la prescripción con aquellos que aparecen como estructuras, haciendo uso del diccionario creado anteriormente. También se ha tenido en cuenta que en la prescripción los órganos pueden aparecer como Contralateral o Ipsilateral y no como Derecha o Izquierda. En ese caso se identifican teniendo en cuenta la posición del PTV de mayor dosis.

Finalmente, en lo que queda de función se identifica la prescripción para cada órgano de riesgo: si esta está dada como dosis media, dosis máxima, volumen permitido para una dosis dada o viceversa, teniendo también en cuenta si las dosis y volúmenes son relativos o absolutos. Una vez identificada se busca en el histograma dosis-volumen la dosis o volumen conseguido y se compara con el requerido en la prescripción.

Aun así, dada la variabilidad en la forma de escribir las prescripciones, esta función arroja algún que otro error de vez en cuando, por lo que no estaría de más usarla dentro de una sentencia try-catch.

4  Discusión y conclusiones

Como se puede comprobar, el script está enfocado a VMAT (tratamientos de arcoterapia volumétrica), así que alguna función podría arrojar errores inesperados al aplicarse a otro tipo de tratamientos. Desde luego que como posible continuación de trabajo podría generalizarse para incluir otro tipo de tratamientos y, por supuesto, podría ser ampliado para verificar cuantos parámetros se deseen, o ser adaptado a las particularidades de cada servicio.

Hemos presentado, por tanto, un ejemplo de cómo usar la API que proporciona Eclipse para automatizar el proceso de verificación de una planificación. Con ello se ahorra tiempo y se deja lugar a menos fuentes de error. Obviamente el script presentado no está exento de posibles errores, por ello siempre tendrá que haber una verificación humana, por lo menos hasta que esté lo suficientemente comprobado. Sin embargo, es usual que después de la verificación de la planificación vengan etapas posteriores: aceptación de la planificación por parte del médico, verificación pretratamiento en el acelerador, etc. Por lo que se realiza una segunda verificación al final del proceso, quizá por otro radiofísico, y aunque se suelen verificar parámetros diferentes en ambas verificaciones al final acaba habiendo redundancias, con la consiguiente pérdida de tiempo. Con este tipo de scripts podemos mantener dicha redundancia sin apenas consumo de tiempo.

Finalmente, este trabajo también puede servir para aprender a manejar la API de Eclipse dada la gran cantidad de parámetros a los que este script accede.

[1] En la función anterior CheckMedula, se buscaba que existiera la estructura MED, en el caso de que se hubiera llamado Medula no hubiera funcionado.

Eclipse-Scripting-API

Eclipse-Scripting-API2

Referencias

[1] A. Barranco López, L. Sopeña Sanz, D. Nogueira Souto y A. Boria Alegre. Eclipse Scripting API, Pylinac y ARIA en una sola plataforma. Revista Electrónica de PortalesMedicos.com (en prensa).

[2] Varian Medical Systems. Eclipse Scripting API Reference Guide. P1021698-003-C.

[3] Varian Medical Systems. Eclipse Scripting API Online Help. P1021731-003-C.

[4] Microsoft. Visual Studio. Recuperado en febrero de 2020 de https://visualstudio.microsoft.com/.