Università degli Studi di Torino
Facoltà di Scienze Matematiche, Fisiche e Naturali
Corso di Laurea in Fisica



TESI DI LAUREA


SVILUPPO E IMPLEMENTAZIONE IN C++ DI ALGORITMI PER IL CALCOLO DI PIANI DI TRATTAMENTO IN ADROTERAPIA







Candidato: Giovanni Nicco





Anno Accademico 1999/2000

Indice

1  Basi fisiche, chimiche e biologiche della radioterapia
    1.1  Interazione della radiazione con la materia
        1.1.1  Particelle cariche pesanti
        1.1.2  Emissione di elettroni e formazione della traccia
        1.1.3  Perdita di energia per gli elettroni
        1.1.4  Fotoni
        1.1.5  Neutroni
    1.2  Reazioni chimiche e biologiche conseguenti alla ionizzazione
        1.2.1  Effetti radiochimici
        1.2.2  Danni al DNA
        1.2.3  Risposta biologica
2  Radioterapia
    2.1  Grandezze radioterapiche di base
    2.2  Le basi della radioterapia
    2.3  Radioterapia convenzionale
    2.4  Adroterapia
    2.5  Piani di trattamento in Adroterapia
    2.6  Immagini diagnostiche
    2.7  Tomografia Computerizzata
    2.8  Distribuzione della dose
    2.9  Sistemi di distribuzione attiva del fascio
3  Il programma ANCOD2: gli oggetti
    3.1  Descrizione degli obiettivi
    3.2  Architettura del programma
    3.3  Oggetti e Metodi
        3.3.1  Cenni di C++
        3.3.2  REALdef
        3.3.3  SystemOfUnits
        3.3.4  int3Vector
        3.3.5  Hep3Vector
        3.3.6  Line
        3.3.7  GridBox
        3.3.8  Rijk
        3.3.9  R1R1
        3.3.10  RiRjR1
        3.3.11  cRUN
        3.3.12  cPAW
        3.3.13  Il file makefile
4  Il programma ANCOD2: le procedure ed i risultati
    4.1  La procedura farSource
        4.1.1  Descrizione sommaria
        4.1.2  Descrizione dettagliata
    4.2  Dosi teoriche rilasciate dal piano di trattamento prodotto
    4.3  Utilizzo di ANCOD2 nella valutazione del SOBP in acqua per ioni carbonio
Bibliografia
Indice immagini
Introduzione


Questo lavoro di testi é stato svolto presso il gruppo TERA dell'universitá degli studi di Torino, e la locale sezione INFN. Il progetto TERA (TErapia con Radiazione Adronica) venne promosso nel 1991 con lo scopo di portare in Italia nuove efficaci tecniche di radioterapia con utilizzo di protoni, neutroni e ioni leggeri. La sezione INFN di Torino partecipa alla collaborazione TERA con varie attivitá:
Il contributo della tesi é stato quello di migliorare e portare il programma per la stesura di piani di trattamento da un linguaggio procedure-oriented (FORTRAN) a un linguaggio Object-Oriented (C++). Tale passaggio ha lo scopo di allineare il codice verso l'attuale orientamento nel computing e riorganizzarlo secondo i dettami dell'Object Oriented Programming ( strutturazione della informazione e modularizzazione effettiva del codice). Per quanto concerne il miglioramento si é invece proposto un nuovo algoritmo per il calcolo delle fluenze e aperto il programma alla lettura di due nuovi formati di file CT (Computerized Tomograph): quello CART, usato dalla macchina per le TAC del centro IRCC ( Istituto per la Ricerca e la Cura del Cancro) di Candiolo e quello DICOM (standard molto comune per lo scambio di immagini mediche).
Nel capitolo 1 vengono descritti i processi di interazione della radiazione con la materia che sono inerenti alla radioterapia. Vengono quindi descritti alcuni aspetti biologici di questo tipo di interazione.
Nel capitolo 2 si forniscono informazioni sulla radioterapia partendo dalle principali grandezze radioterapiche fino ad arrivare alle modalitá di pianificazione e rilascio di dose al paziente.
Nel capitolo 3 si descrivono le classi e gli oggetti approntati per supportare le costituenti del problema del calcolo di un piano di trattamento.
Nel capitolo 4 viene presentata la prima delle procedure che faranno uso dei metodi e delle classi descritte nel terzo capitolo (quella relativa a sorgenti poste molto lontano dal bersaglio), oltre alla descrizione dettagliata del programma sono illustrati anche i risultati con esso ottenuti.
Ringraziamenti


Ringrazio Teresa e mia madre per avermi sostenuto per il lavoro di cui questa tesi rappresenta la parte finale.
Ringrazio inoltre tutti i compagni/colleghi con i quali ho diviso questi ultimi mesi etc..

Capitolo 1
Basi fisiche, chimiche e biologiche della radioterapia

Il passaggio di particelle dotate di massa o fotoni attraverso la materia provoca, a seguito di interazioni elettromagnetiche o nucleari, rilascio di energia e mutazioni chimico fisiche all'interno della materia stessa. In un organismo, tali mutazioni, possono indurre alterazioni fisiologiche cioé modifiche del funzionamento delle componenti cellulari, delle cellule e dell'intero organismo. L'arco di conoscenze necessario per riunire causa-effetto spazia perció dalla interazione radiazione-materia alle reazioni chimiche connesse fino alla risposta biologica e fisiologica dell'organismo. Verranno qui di seguito prese in considerazione le principali nozioni necessarie per percorrere, non troppo in dettaglio, tale arco di conoscenze.

1.1  Interazione della radiazione con la materia

Le radiazioni [1] si distinguono in due gruppi: La maggior parte della interazione tra particelle cariche e materiale é caratterizzata da processi elettromagnetici dovuti all'interazione tra il campo elettromagnetico della particella incidente e quello degli elettroni e dei nuclei atomici del mezzo in cui si muove. Una parte minore (ma sempre piú rilevante alle alte energie) della interazione é invece quella nucleare responsabile della frammentazione dei nuclei e quindi delle code dei picchi di Bragg (paragrafo 1.1.1). Per quanto riguarda la parte elettromagnetica si distinguono: Le prime comportano perdita continua di energia da parte della particella incidente attraverso ionizzazione ed eccitazione del mezzo. Gli elettroni emessi dal processo di ionizzazione hanno inizialmente grandi energie cinetiche e sono pertanto a loro volta particelle ionizzanti dette raggi d : in pratica sono i responsabili della ripartizione della energia persa dalla particella primaria nel mezzo. Le collisioni elastiche, viceversa, danno luogo a cambiamenti di direzione del moto del proiettile ma senza perdite apprezzabili di energia. L'effetto aumenta con il diminuire della massa della particella incidente ed &#"Calling ghostscript to convert zImages/fig5.EPSF to zImages/fig5.EPSF.gif , please wait ..." 233; quindi particolarmente rilevante per particelle leggere (elettroni) che urtando contro i nuclei della materia vengono diffuse ad angoli anche molto grandi, cambiando bruscamente direzione ed emettendo di conseguenza radiazione di frenamento. Questa diversa dinamica nelle collisioni suggerisce di separare lo studio delle particelle cariche leggere (elettroni) da quello delle particelle cariche pesanti (quelle aventi massa maggiore di quella dell'elettrone).
Rilascio di energia
Si definisce stopping power [2] il valor medio della perdita di energia per unitá di percorso. Esso dipende dalla velocitá e dalla carica della particella ionizzante nonché (linearmente) dalla densitá del mezzo attraversato. In un contesto biologico si preferisce tuttavia usare il LET (Linear Energy Transfer) che rappresenta la stessa quantitá ma nell'acqua cioé a densitá fissata r = 1 gm/cm3 e che si misura solitamente in keV/ mm.
Un'altra misura della perdita di energia molto comune é il potere frenante massico che elimina la dipendenza dal mezzo dividendo lo stopping power per la densitá del mezzo stesso ( si esprime solitamente in [(MeVcm2)/(gm)] ).

1.1.1  Particelle cariche pesanti

La perdita di energia delle particelle cariche pesanti é causata dalla interazione Coulombiana con gli elettroni degli atomi bersaglio (electron stopping) o con il loro potenziale nucleare (nuclear stopping). I range di energia propri di questi due processi sono indicati in fig. 1.1.

 

Figure 1.1: Rappresentazione schematica dei processi di perdita di energia per una particella carica pesante.

 

Si puó notare che a basse energie predomina il nuclear stopping mentre per tutte le altre energie é l'electron stopping che causa la perdita di energia. La intensitá della interazione dipende dalla velocitá e dalla carica. Nel caso degli ioni tuttavia bisogna considerare la carica media efficace la quale dipende a sua volta dalla velocitá. Gli elettroni del proiettile aventi una velocitá orbitale minore di quella del proiettile vengono infatti strappati via nelle collisioni, di conseguenza il numero di elettroni rimanenti, e quindi la carica effettiva, sono funzione della velocitá del proiettile. A velocitá medie molto elevate tutti gli elettroni possono essere rimossi e la carica dello ione eguaglia il suo numero atomico. Col decrescere della velocitá gli elettroni vengono prelevati dal materiale bersaglio e la carica effettiva del proiettile diminuisce. La carica efficace é espressa dalla formula empirica di Barkas [2]:
Zeff = Zprt (| 1 - exp(-125 bztrg2/3 )

)

"Calling ghostscript to convert zImages/fig11.EPSF to zImages/fig11.EPSF.gif , please wait ..." "Calling ghostscript to convert zImages/fig10.EPSF to zImages/fig10.EPSF.gif , please wait ..."

In fig 1.2 sono illustrati i valori di Zeff in funzione della energia specifica (energia per unitá di massa atomica; solitamente espressa in MeV/u) della particella proiettile.

 

Figure 1.2: Carica efficace secondo la formula di Barkas in funzione della energia specifica.

 

Si puó notare che per energie specifiche maggiori di 10 MeV tutti e sei gli elettroni del carbonio sono strappati via.
La regione del nuclear stopping sebbene ad alta efficacia biologica in quanto i nuclei possono essere sbalzati fuori dai propri legami molecolari e, nella fattispecie, anche dal DNA, non risulta tuttavia significativa perché accade solo a bassissime energie e in regioni di spazio limitate. La regione dell'electron stopping é invece quella i cui effetti biologici sono predominanti e viene descritta dalla formula di Bethe-Bloch:
 dE

dx
=  4 pe2 Zeff2 N ztrg

mev2
ln  mv2

I0ztrg
+ rel. terms
dove

In fig. 1.3 vengono comparati valori teorici (Bethe-Bloch) ed empirici della perdita di energia (potere frenante massico) in funzione della energia specifica e dalla particella incidente:

 

Figure 1.3: Comparazione tra la perdita di energia misurata con quella teorica in funzione della energia specifica.

 

 

Si puó notare che il massimo rilascio di energia, per esempio degli ioni carbonio é a circa 9 MeV cm2/mg equivalenti ad un LET di 900 KeV/mm e che lo stesso LET puó essere ottenuto a differenti energie specifiche muovendosi ai due lati del massimo; a questo medesimo LET, tu"Calling ghostscript to convert zImages/fig9.EPSF to zImages/fig9.EPSF.gif , please wait ..." ttavia corrispondono efficacie biologiche differenti: questo significa che il LET in se stesso non é un parametro completo per la determinazione della efficacia biologica.

Range

Dalle curve di perdita di energia (dE/dx) si possono ottenere le quantitá inverse (dx/dE) e, per integrazione su tutta l'energia rilasciabile, il range che la particella percorre all'interno del mezzo:
R =
E0

0 
 dx

dE
dE

Essendo dE/dx un valore "medio" anche R risulta avere una dispersione s che definisce il parametro di straggling a:={2s}. In pratica viene definito range medio la distanza per la quale il numero di particelle iniziale si é ridotto del 50% e straggling la FWHM (Full Width Half Maximum) della gaussiana che ne rappresenta la dispersione come si puó vedere in fig. 1.4 dove sono rappresentate due curve: la curva integrale che descrive l'andamento del numero di particelle ancora presenti ad una profonditá x e la curva differenziale che mostra il numero di particelle il cui cammino é pari alla profonditá x in ascissa.

 

Figure 1.4: Curva integrale e differenziale dei percorsi di particelle cariche pesanti nella materia.

 

 

I range calcolati o misurati vengono di solito raccolti in tabelle reperibili in letteratura, é comunque possibile calcolare i range per generiche particelle pesanti sfruttando il fatto che il range é fattorizzabile in termini di M (massa della particella), Z (carica) ed una funzione dipendente solo dalla velocitá f(b):
Rp(b)=  Mp

Zp2
f(b)

Rx(b)=  Mx

Zx2
f(b)

Rx(b)=  zp2Mx

Zx2Mp
Rp(b)

Picco di Bragg

Graficando la perdita di energia di una particella carica pesante in funzione della profonditá si osserva un plateu che parte dal punto di entrata nel materiale ed arriva fino a pochi cm dal range della particella dove comincia a crescere per poi avere un picco la cui larghezza é di pochi mm cui segue un secondo plateu con valori molto piú bassi come si puó vedere in figura 1.5

Figure 1.5: Densitá di ionizzazione in funzione della profonditá. La curva tratteggiata rappresenta il contributo dei frammenti nucleari.

 

 

Tale picco viene detto picco di Bragg ed il suo notevolissimo valore terapeutico fu per primo intuito da Bob Wilson il quale face notare in un articolo degli ultimi anni '40 che protoni usati a scopo terapeutico avrebbero interrotto la loro loro traettoria sul target senza provocare danni ai tessuti retrostanti. Nella fig. 1.5 si nota un rilascio di energia anche oltre il range: ció é legato al fatto che il range si riferisce solo agli ioni primari ma esistono ioni secondari (prodotti di reazione della frammentazione) con numero atomico piú piccolo e quindi range maggiore. La struttura delle curve di Bragg si puó comprendere sulla base della fig. 1.3: ad alte energie il deposito di energia é piccolo e le particelle proseguono nella loro traettoria producendo una densitá di ionizzazione bassa e pressoché costante; quando le particelle sono state rallentate ad energie specifiche significativamente inferiori a 100MeV/u la perdita di energia cresce rapidamente diminuendo ulteriormente la velocitá in una reazione positiva che frena la particella in pochi mm raggiungendo un LET di proporzioni anche 6:1 rispetto al plateu di entrata.

1.1.2  Emissione di elettroni e formazione della traccia

Per energie specifiche maggiori di 1MeV/u (regione dell'electron stopping) l'energia persa dai primari é quasi totalmente trasferita agli elettroni. In base all'energia iniziale dello ione si ha fra il 65-75% dell'energia rilasciata trasformata in energia cinetica degli elettroni, 15-25% necessaria per la loro ionizzazione ed il rimanente 5-15% viene consumato in eccitazione elettronica. In accordo a questa distribuzione la maggior parte degli elettroni sono liberati dai loro legami atomici e dissipano la loro energia cinetica ad una certa distanza dalla collisione primaria (fig. 1.6) formando cosí una traccia di ionizzazione attorno alla traettoria del proiettile.

 

Figure 1.6: Scattering di elettroni a 5 keV iniettati in x=0 0 in direzione z.

 

 

Gli elettroni secondari hanno quindi scattering elastici ed anelastici. Gli scatter elastici non dissipano praticamente energia ma determinano la distribuzione angolare degli elettroni; quelli anelastici vanno distinti in energia: A basse energie ( E < 20 eV ) gli elettroni secondari non generano praticamente ionizzazione ma si limitano ad eccitare gli atomi del materiale attraversato. A maggiori energie domina invece la ionizzazione e tale rilascio di "Calling ghostscript to convert zImages/fig3.EPSF to zImages/fig3.EPSF.gif , please wait ..." "Calling ghostscript to convert zImages/fig4.EPSF to zImages/fig4.EPSF.gif , please wait ..." energia ha un massimo tra i 70 ed i 200 keV, per questo motivo elettroni altamente energetici diventano maggiormente reattivi a livello biologico (dove contano le ionizzazioni) quando vengono rallentati ad energie di poche centinaia di eV. L'energia media trasferita negli eventi di ionizzazione é largamente indipendente dalla energia degli elettroni e vale tra i 15 e 20 eV.
La combinazione del trasporto e del rilascio di energia degli elettroni consente a codici Montecarlo di calcolare con ottima verosimiglianza le tracce lasciate da ioni nella materia. Un esempio di tali tracce é illustrato in fig. 1.7 .

 

Figure 1.7: Comparazione tra le tracce di un protone e di uno ione carbonio entrambi con energia specifica di 1 MeV/u, in mezzo é rappresentata schematicamente la struttura del DNA: lo ione carbonio produce una maggiore densitá di ionizzazione causando danni piú elevati al DNA.

 

 

In linea di principio dovrebbe essere possibile predirre il danno biologico mediante la comparazione della struttura della traccia con la geometria del DNA, in pratica molti sforzi in tale direzione hanno manifestato la insufficienza delle attuali capacitá dei computer nell'eseguire calcoli cosí complessi. É stata comunque evidenziato, sia a livello sperimentale che con codici montecarlo l'andamento 1/r2 per il rilascio radiale di energia degli elettroni attorno alla traccia, tali risultati sono comunemente accettati tranne per distanze molto piccole (hard-core di alto rilascio di energia) come indicato in fig. 1.8.

Figure 1.8: Distribuzione radiale della dose attorno alla traccia di una particella: la dose decresce come 1/r2 su vari ordini di grandezza della distanza radiale.

 

 

1.1.3  Perdita di energia per gli elettroni

La perdita di energia differisce da quella delle particelle cariche pesanti per due motivi: il fatto che l'elettrone incidente sia identico a quello urtato (che deve essere tenuto in computo nel calcolo quantistico) ed il fatto che l'elettrone incidente subisce grosse deviazioni a causa della sua piccola massa (che comporta irraggiamento per radiazione da frenamento di particella carica bremsstrahlung). La perdita di energia si esprime perció in due termini:
 dE

dX
=
 dE

dX



ion 
+
 dE

dX



brem 
Il primo termine vale:
-
 dE

dX



ion 
=  2 pNA e4

me v2
r
ln
 me v2

22 I

+  1

2

per gli elettroni non relativistici (v << c), e
-
 dE

dX



ion 
=  2 pNA e4

me v2
r
ln
 2 me g[ 3/2] v2

I

-  1

2
ln (b)+  1

16
+  C

Z
-  d

2

per gli elettroni relativistici.
Il secondo termine vale:

-
 dE

dx



brem 
=  E

X0
dove
 1

X0
=  4Z(Z+1)NA

137 A
re2ln  183

Z1/3
con
re=  e2

me c2
raggio classico dell'elettrone.
X0 é detta lunghezza di radiazione del materiale attraversato e rappresenta lo spessore di materia che riduce, mediamente, l'energia dell'elettrone di un fattore e:
< E > = E0 e-x/X0
La perdita di energia per bremsstrahlung cresce con la energia e diventa predominante alle alte energie; il rapporto fra le due perdite di energia é dato da
 (dE/dx)brem

(dE/dx)ion
=  Z E

580 MeV
Si usa definire, per ogni materiale, una energia critica al di sopra della quale il contributo dovuto all'irraggiamento diventa quello piú grande, tale energia si "Calling ghostscript to convert zImages/fig6.EPSF to zImages/fig6.EPSF.gif , please wait ..." "Calling ghostscript to convert zImages/fig7.EPSF to zImages/fig7.EPSF.gif , please wait ..." puó leggere all'intersezione delle due curve illustrate nella fig. 1.9 e vale:

Figure 1.9: Contributi delle due modalitá di perdita di energia di elettroni in funzione della loro energia.

 

 


Ec =  580

Z
MeV
A causa delle molte deviazioni subite da un elettrone nell'attraversare un mezzo (fig. 1.10) , non é possibile definire propriamente un percorso compiuto se non in termini di distanza media di allontanamento dal punto iniziale ( practical range ). Il suo valore é descritto dalla seguente formula semiempirica:
Rp = 0.71 E1.72 g/cm2
con E espresso in MeV.

Figure 1.10: Traettoria di un elettrone all'interno della materia e practical range.

 

 

1.1.4  Fotoni

In base alla energia e al mezzo attraversato i raggi X e g innescano vari tipi di processi: i più importanti sono l'effetto fotoelettrico, l'effetto Compton e la produzione di coppie, meno importanti sono invece la diffusione coerente (o Rayleigh) e l'effetto fotonucleare.
Effetto fotoelettrico   L'effetto fotoelettrico consiste nell'urto tra un fotone ed un atomo, con assorbimento del fotone ed emissione di un elettrone di energia Ee- pari alla differenza tra l'energia del fotone hn e l'energia di legame dell'elettrone Eb:
g+ A A+ + e-
Ee- = Eg - Eb
La sezione d'urto sf per effetto fotoelettrico dipende da Z5 ed ha una soglia energetica pari a 300 keV.
Per Eb << hn << mec2 e per elettroni nella shell K di un atomo con numero atomico Z si può usare la sezione d'urto:

sph=42sTa4Z5
 mec2

hn

[ 7/2]

 
dove n è la frequenza del fotone, h la costante di Planck, a è la costante di struttura fine, sT la sezione d'urto classica di Thomson(8pr2e/3), me la massa dell'elettrone e c la velocità della luce nel vuoto.
Il processo fotoelettrico è dominante alle basse energie (hn < 0.5 MeV) e negli elementi pesanti, per i quali è ancora apprezzabile ad energie di 4-5 MeV.
Effetto Compton   Consiste nell'interazione tra un fotone ed un elettrone libero, a patto che l'energia del fotone sia molto maggiore dell'energia di legame dell'elettrone hn >> Eb.
L'espressione analitica per la sezione d'urto  è di Klein e Nishina:

sC=pre2  1

e


1-  2(e+1)

e2

ln( 2e+1) +  1

2
+  4

e
-  1

2( 2e+1) 2

con e = [(hn)/(mec2)] e re il raggio classico dell'elettrone.
L'effetto Compton domina per energie comprese tra 0.8 e 4 MeV.
Creazione di coppie   Avviene nel campo coulombiano di un nucleo o di un elettrone e consiste nella trasformazione dell'energia di un fotone in una coppia elettrone-positrone.
Per 1 << [(hn)/(mec2)] << [ 1/(aZ[ 1/3])] si può usare la sezione d'urto:

spc=are2Z2
 28

9
ln
 2hn

mec2

-  218

27

e per [(hn)/(mec2)] >> [ 1/(aZ[ 1/3])], tenendo conto dell'effetto di screening:

spc=are2Z2
 28

9
ln
 183

Z[ 1/3]

-  218

27

Il processo avviene per hn 3 mec2 ed è dominante per energie superiori a 5 MeV.
Sezione d'urto totale  
A partire dai processi precedenti si può definire una sezione d'urto totale per l'interazione dei fotoni data dalla somma delle sezioni d'urto parziali:
stot=sph+sC+spc
di cui è mostrato un andamento in figura 1.11.

Figure 1.11: Sezione d'urto totale e contributi dei differenti processi per fotoni in carbonio, in funzione dell'energia. ( sp.e.:effetto fotoelettrico, scoherent: diffusione coerente, sincoherent: diffusione Compton, kn: produzione di coppie nel campo nucleare, ke: produzione di coppie nel campo degli elettroni, snuc: assorbimento fotonucleare )

 

 

 

L'assorbimento di fotoni nel mezzo ha un andamento esponenziale e il numero N di fotoni che non hanno subito interazioni in una distanza l è:

N=N0e-m·l
dove N0 è il numero iniziale di fotoni e il coefficiente di attenuazione lineare è definito come:

m = r  NA

A
stot
con r densità e A numero di massa dell'assorbitore; NA è il numero di Avogadro.

1.1.5  Neutroni

I neutroni, non dotati di carica elettrica, non sono soggetti ad interazioni coulombiane con elettroni e nuclei della materia. Essi costituiscono comunque una radiazione indirettamente ionizzante perché interagiscono con i nuclei della materia che attraversano tramite la forza nucleare forte producendo particelle ionizzanti. Queste reazioni sono eventi rari in quanto avvengono solo quando il neutrone dista meno di 10-15 m dal nucleo. La legge di attenuazione di un fascio sottile di neutroni monoenergetici é simile a quella dei fotoni nel senso che vengono anch'essi attenuati esponenzialmente tramite un coefficiente di attenuazione lineare.
I neutroni termici ( E < 0.1 eV ) interagiscono con i nuclei atomici dai quali vengono "catturati"; il nucleo poi si diseccita emettendo un fotone. La probabilitá di cattura neutronica aumenta al diminuire della energia del neutrone e varia considerevolmente a seconda del materiale assorbente. La sezione d'urto é grande per elementi quali l'idrogeno, il boro ed il litio.
I neutroni veloci (1 MeV < E < 150 MeV) subiscono principalmente urti elastici con i nuclei, vale a dire che tutta l'energia persa dal neutrone é trasformata in energia cinetica del nucleo ("moderazione" dei neutroni). Il massimo trasferimento di energia si ha quando l'urto é frontale e il nucleo ha piú o meno la stessa massa del neutrone, cioé quando il bersaglio é un protone. Poiché il tessuto biologico é ricco di idrogeno, il passaggio di neutroni veloci in esso é caratterizzato in grandissima parte da questo tipo di interazione che produce protoni di rimbalzo di energia uguale a quella del neutrone incidente, i quali causano ionizzazione ed eccitazione negli atomi e nelle molecole del mezzo. Altri danni al tessuto vivente sono causati dalle collisioni dei neutroni con i nuclei di carbonio, ossigeno ed azoto.
Neutroni di energia intermedia interagiscono mediante entrambi i processi, di cattura e di urto elastico.
Altre due interazioni da ricordare sono gli urti anelastici e gli urti non-elastici. Nei primi il neutrone viene catturato dal nucleo e in seguito riemesso con una energia minore e produzione di un fotone. Questo processo si verifica solo se il neutrone ha una energia almeno di 1 MeV, necessaria ad eccitare il nucleo. Gli urti non-elastici si differenziano dai precedenti perché dopo la cattura neutronica la particella emessa non é il neutrone ma una particella carica. Queste collisioni hanno luogo per energie superiori a 5 MeV e la loro probabilitá di verificarsi cresce all'aumentare dell'energia. Infine, per neutroni con energia superiore a 100 MeV si puó avere la spallazione , cioé la frammentazione del nucleo urtato in piú parti.

1.2  Reazioni chimiche e biologiche conseguenti alla ionizzazione

1.2.1  Effetti radiochimici

Le radiazioni ionizzanti producono all'interno della materia atomi e molecole ionizzati o eccitati. Dal momento che un organismo vivente é compostoi al 70-85% di acqua [3] i processi piú probabili avvengono su di essa:
(radiolisi)
H2O radiazione
\leadsto
 
H2O++e-
(eccitazione)
(eccitazione) H2O radiazione
\leadsto
 
H2O*
Le tre specie, H2O+, H2O* ed e- si diffondono nel mezzo e danno luogo seguenti fenomeni:

H2O++H2O H3O++OH

H2O*



H2O++e-
H+OH
H2+O
"Calling ghostscript to convert zImages/elsolvat.EPSF to zImages/elsolvat.EPSF.gif , please wait ..."
L'elettrone prodotto da H2+O, una volta rallentato, si dispone al centro di quattro molecole d'acqua prende il nome di elettrone acquoso e costituisce una specie chimica molto reattiva. Una sua particolare reazione é:
H2O+eaq- H2O-
Anche la molecola H2O- (come la H2O+) é instabile:
H2O- H+OH-
Dopo ~ 10-11 sec dal passaggio della radiazione ionizzante rimangono quattro specie chimicamente attive H3O+,OH,H ed eaq-. (fig. 1.12)
Di cui:
H3O+ + e-aq H+H2O
Rimangono percó i seguenti radicali liberi:
OH: radicale ossidrile
H : radicale idrogeno
eaq: elettrone acquoso
Tali radicali sono molto reattivi poiché pur essendo elettronicamente neutri tendono ad accoppiare l'elettrone spaiato con un altro simile di un altro radicale, oppure ad eliminare l'elettrone con un processo di trasferimento. Inoltre essi possono interagire con molecole organiche RH (dove R sono componenti della molecola ed H un atomo di idrogeno) formando radicali secondari:

Figure 1.12: Specie reattive prodotte nella radiolisi dell'acqua: a) elettrone acquoso o solvatato eaq-, b) radicale idrogeno H, c) ione idrogeno H+, d) radicale idrossile OH, e) ione idrossile OH-.

 

 


RH+OH R+H2O

RH+H R+H2
Entrambi questi radicali liberi (primari o secondari) possono interagire con molecole biologicamente significative provocando il cosiddetto danno radiobiologico indiretto.
Piú raramente si ha viceversa un danno radiobiologico diretto quando le molecole organiche RH subiscono l'azione diretta della radiazione.
RH radiazione
\leadsto
 
RH++e- R+H++e-
I radicali liberi interagiscono anche con molecole di ossigeno originando altri radicali liberi dannosi; in presenza di ossigeno si ha pertanto un aumento del danno biologico conseguente al passaggio di radiazioneeffetto ossigeno.
O2+H HO2

O2+e- O2-

O2-+H+ HO2
Inoltre l'ossigeno puó anche interagire con altri radicali liberi:
R+O2 RO2

RO2+RH RO2H+R

1.2.2  Danni al DNA

Il nucleo della cellula si é dimostrato centinaia di volte piú sensibile all'attacco dei radicali liberi prodotti dal passaggio di radiazione. Tali radicali non si spostano molto dal luogo in cui sono stati prodotti a causa della loro elevata reattivitá, se reagiscono col DNA vuole pertanto dire che essi sono stati prodotti in sua stretta prossimitá. I danni che possono provocare sono i seguenti:
Cancellazione di una base (Bd: base deletion): una base è rimossa dal nucleotide;
Alterazione di uno zucchero (Sa: sugar alteration): cambiamento delle proprietà chimiche del desossiribosio;
Alterazione di una base (Ba: base alteration): cambiamento delle proprietà chimiche di una base organica (A,T,G o C);
Appaiamento erroneo di base (Mb: mismatched base): viene alterato il naturale accoppiamento tra basi A-T e G-C.
Rottura di catena (Sb: strand break): rottura del legame covalente tra lo zucchero desossiribosio e i gruppi fosfato;

1.2.3  Risposta biologica

L'esito dei danni prodotti al DNA rispetto alla vita della cellula dipende dalla fase del ciclo cellulare in cui essi intervengono ( G1 maturazione della cellula,G0 quite ,S sintesi di nuovo materiale cromosomico ,G2 preparazione alla mitosi,M mitosi ) e dalla capacitá della cellula stessa di riparare il proprio genoma. In ogni caso vi sono delle proteine sensori che riscontrano il danno subito ed inviano uno dei tre seguenti segnali cellulari:
Arresto del ciclo cellulare   Il ciclo cellulare viene interdetto ed in tal modo si inibisce la capacitá di duplicazione delle cellule.
Apoptosi   Questo processo determina la morte cellulare senza tuttavia innescare processi infiammatori tipici della necrosi, questa é infatti la via geneticamente programmata di suicidio cellulare al fine di garantire all'organismo il rinnovo delle sue cellule.
Riparazione   Se uno dei due lati della doppia elica del DNA viene individuato come "errato" una proteina é capace di risintetizzarlo per "complemento" al lato opposto considerato integro. Questo processo di riparazione non si puó innescare se si ha una doppia rottura di catena (DSB double strand break) in questo caso infatti la proteina riparatrice non riesce a portare a termine il suo lavoro.
I DSB differiscono quindi dagli SB (single strand break) proprio perché non possono essere riparati, questo é il motivo per cui radiazioni ad elevata densitá di ionizzazione (alto LET), le quali hanno maggiore probabilitá di realizzare due danni vicini tra loro (fig. 2.2) risultano biologicamente piú distruttive (o efficaci nella prospettiva della radioterapia).

Capitolo 2
Radioterapia

2.1  Grandezze radioterapiche di base

Dose

Una prima misura della quantitá di radiazione assorbita da un tessuto é la densitá di energia media e rilasciata dalle particelle ionizzanti in una massa infinitesima rdV tendente a zero [4]
D=
lim
dV 0 
 e

rdV
Nel Sistema Internazionale la sua unità di misura é [ Jkg-1 ] cui viene dato il nome di Gray [ Gy ] . Un sottomultiplo del Gy é il rad=10-2Gy.

Dose equivalente

In radioprotezione (che si distingue dalla radioterapia per le basse dosi trattate) si usa la grandezza dose equivalente che tiene conto della dannosità di ogni specifica radiazione mediante un fattore di peso per la radiazione wr. La dose equivalente in un tessuto T é data dalla espressione:
HT=

r=radiazione 
wr DT,r
La sua unità di misura nel Sistema Internazionale sarebbe anch'essa il Gray ma per ricordare che è stata moltiplicata per un fattore di peso wr adimensionale prende il nome di Sievert [Sv].

Dose efficace

Sempre nell'ambito della radioprotezione si tiene conto anche della maggiore o minore sensibilità alla radiazione da parte di un tessuto tramite un fattore di peso per i tessuti wT con T indice del tessuto. Si ottiene una grandezza che serve a dare una stima del danno totale subito da un individuo a seguito di una esposizione a radiazione:
E=

T=tessuto 
wT HT

RBE

Nella radioterapia viceversa (alte dosi) la "dannosità" del tipo di radiazione prende il nome di "efficacia" intesa come capacità di arrecare danno alle cellule. Per quantificarla si usa una misura relativa facendo riferimento ad una ben precisa radiazione campione (indicata con il pedice g ): si definisce efficacia biologica relativa (RBE,Relative Biological Effectiveness) l'espressione:

RBEr=  Dg

Dr
Dove Dg è la dose necessaria per produrre lo stesso danno prodotto dalla dose Dr di un'altra radiazione (indicata con il pedice r ). (Se occorre il doppio di dose di radiazione convenzionale (Dg = 2Dr) allora RBE=2 ). In pratica si usa mettere in relazione il valore della RBE direttamente con il LET (giá definito nel primo capitolo ma che verrá ripreso nel prossimo paragrafo) della radiazione non convenzionale perchè è fondamentalmente da questo che l'efficacia biologica di una radiazione dipende. In fig. 2.1
Figure 2.1: Rappresentazione dei dati sperimentali (ottenuti su varie linee cellulari) della dipendenza della RBE dal LET. I segmenti p,C,Ne indicano i LET ottenibili con protoni, ioni carbonio e ioni neon.
si puó notare come all'aumentare del LET vi sia una crescita dell'RBE (poiché aumenta la concentrazione di ionizzazione e quindi la probabilitá di un DSB (double strand break: doppia rottura dell'elica del DNA, non riparabile); col progressivo aumentare del LET tuttavia si ha uno sovrappiú di rilascio di energia che, mentre non aumenta il danno diminuisce tuttavia il numero di luoghi in cui tale rilascio avviene a causa della maggiore dissipazione di energia.

LET

La quantità di energia trasferita dalla particella direttamente o indirettamente ionizzante nella unità di spazio determina la distribuzione della ionizzazione e delle eccitazioni all'interno del materiale biologico e la dannosità (RBE) della radiazione stessa. Si definisce LET (Linear Energy Transfer) la quantità:
LET=  dE

dx
dove dE è l'energia media trasferita al mezzo dalla particella nel percorrere un tratto dx nel suo interno. Nella tabella 2.1 sono presentati i valori del LET delle principali radiazioni usate in radioterapia. [5]
Particella Carica Energia(MeV) LET(keV/mm)
Elettrone -1 0.01 2.3
0.1 0.42
1 0.25
Fotone 0 1.17-1.33 0.2 2
(g del 60Co )
Protone +1 2 16
+2 8
+5 4
+10 0.4
a +2 5 95
Neutrone 0 5 3-30
Ione carbonio C+6 6 10MeV/u 170
250MeV/u 14
Table 2.1: LET di radiazioni e particelle ionizzanti interessanti in radioterapia
In fig. 2.2 "Calling ghostscript to convert zImages/dna.EPSF to zImages/dna.EPSF.gif , please wait ..." "Calling ghostscript to convert zImages/p13.EPSF to zImages/p13.EPSF.gif , please wait ..." "Calling ghostscript to convert zImages/t5.EPSF to zImages/t5.EPSF.gif , please wait ..." si possono confrontare le dimensioni delle tracce di varie particelle rispetto a quelle del DNA: è evidente come per particelle ad alto LET (come la particella a in questione vi sia una più elevata possibilità di doppia rottura dell'elica del DNA con conseguente maggiore efficacia biologica.
Figure 2.2: Rappresentazione schematica del DNA e delle tracce di un elettrone e di una particella a che lo attraversano.

OER

Esistono vari fattori chimici che influenzano l'effetto biologico delle radiazioni, tra questi il principale è certamente l'effetto ossigeno . La presenza di ossigeno molecolare (O2) aumenta di molto il danno subito dalle cellule (fig. 2.3).
Figure 2.3: Percentuale di sopravvivenza per cellule irradiate in presenza o in assenza di O2; con i punti A,B,C viene illustrato graficamente il significato della quantitá OER. L'inserto illustra la radiosensibilitá in funzione della pressione parziale di O2.
Per ottenere un determinato effetto biologico in tessuti carenti di ossigeno (come il nucleo di un tumore) è necessaria una dose di radiazione maggiore poichè sono meno della metà sensibili alle radiazioni [6]. Viceversa in tessuti ben ossigenati è sufficiente una dose minore di radiazione. Questo constatazione empirica ha tre spiegazioni:
- La presenza di ossigeno causa un aumento della produzione di radicali liberi.
- L'ossigeno molecolare ha una elevata affinità elettronica e tende perciò a reagire con gli elettroni liberati dalla ionizzazione ritardandone la ricombinazione e aumentando la probabilità da parte dell'elettrone di causare danni.
- La mancanza di ossigeno tra un irraggiamento e l'altro di un trattamento frazionato diminuisce la capacità di recupero da parte delle cellule danneggiate.
Quantitativamente l'effetto ossigeno si esprime tramite la quantità OER (Oxigen Enhancement Ratio), definito come il rapporto tra la dose richiesta per arrecare un certo danno ad una cellula in condizione ipossica rispetto ad una condizione di normale ossigenazione:
OER=  D

D0
Dove D é la dose necessaria per produrre un effetto nel tessuto reale e D0 é la dose che produrrebbe lo stesso effetto se il tessuto fosse completamente ossigenato in aria a pressione normale. In fig. 2.4
Figure 2.4: OER in funzione del LET per vari tipi di radiazioni e per varie linee cellulari.Sono indicati i range di LET raggiungibili per particelle interessanti in radioterapia.
si può notare come l'OER vari in funzione del LET.

2.2  Le basi della radioterapia

Si utilizza la radioterapia per distruggere un tumore localizzato facendogli assorbire una dose di radiazioni tale da ucciderne le cellule. Talvolta si opera anche sui p"Calling ghostscript to convert zImages/t3.EPSF to zImages/t3.EPSF.gif , please wait ..." "Calling ghostscript to convert zImages/t7.EPSF to zImages/t7.EPSF.gif , please wait ..." "Calling ghostscript to convert zImages/doprofot.EPSF to zImages/doprofot.EPSF.gif , please wait ..." ossibili cammini di diffusione del tumore per impedire che proliferi altrove. Fondamentale in entrambi i casi é il fatto che le cellule tumorali risultino mediamente piú vulnerabili alla radiazione di quelle sane e questo garantisce uno spazio di lavoro (in termini di dose) muovendosi all'interno del quale é possibile arrecare un danno fatale al tumore ma sopportabile per le altre cellule. Tale spazio é stimabile dalle curve dose-effetto (fig. 2.5).
Figure 2.5: Curve dose-effetto: (A) tessuti tumorali (B) tessuti sani. Si definisce rapporto terapeutico la quantitá D2/D1 dove D2 e D1 sono le dosi che hanno una probabilitá pari al 50% di provocare rispettivamente complicazioni ai tessuti sani e controllo sul tumore.
In tale figura si puó osservare che per una dose corrispondente ad una probabilitá prossima al 100% di controllo sul tumore (linea A) si ha anche una probabilitá molto (troppo) elevata di ottenere danni ai tessuti sani. Per questo motivo il radioterapista sceglie di solito una dose tale da non salire oltre il 50% di probabilitá di avere danni sui tessuti sani, per come si presentano queste curve questo significa anche avere solo il 50% di probabilitá di controllo del tumore.
Se tuttavia si riesce ad avere una buona selettivitá balistica o conformitá nel senso che si riesce ad irradiare quasi unicamente il tumore allora (sempre facendo riferimento alla fig. 2.5) non si ha piú una unica linea orizzontale rappresentate la dose assorbita ma una coppia di linee una per la dose assorbita dal tumore (che fará riferimento alla curva (A) ) ed una per la dose assorbita dal tessuto sano (che fará riferimento alla curva (B) ).
Con l'utilizzo di adroni si riesce ad ottenere un aumento della probabilitá di cura di un tumore in quanto la dose assorbita é piú concentrata nei tessuti tumorali di quanto si riesce, viceversa ad ottenere con elettroni o fotoni (questo per le giá citate caratteristiche del picco di Bragg che verranno comunque riprese in seguito).

2.3  Radioterapia convenzionale

Inizialmente la radioterapia si praticava usando come sorgenti di radiazione dei radioisotopi come il cobalto, oggi si preferisce usare acceleratori lineari di elettroni i quali possono produrre direttamente fasci di elettroni monoenergetici o (frenando gli elettroni su bersagli ad alta densitá) fasci di fotoni caratterizzati da un spettro continuo di energie con energia massima corrispondente a quella degli elettroni. Nelle figure 2.6 e 2.7 sono visualizzati il rilascio di energia in acqua rispettivamente di elettroni e di fotoni.
Figure 2.6: Curve dose-profonditá in acqua per fasci di elettroni di energia compresa tra 4.5 e 21 MeV.
Figure 2.7: Curve dose-profonditá in acqua per fasci di fotoni aventi energie massime per energie comprese tra 6 e 25 MeV.

Elettroni

I fasci di elettroni hanno un percorso massimo all'interno del tessuto (che é circa uguale (in cm) alla metá della energia iniziale espressa in MeV), al di lá del quale si ha una coda di bassa intensitá dovuta ai fotoni di bremsstrahlung.
Per questo tipo di rilascio di energia gli elettroni sono adatti per il trattamento di tumori superficiali o al massimo a qualche centrimetro sottopelle.

Fotoni

I fasci di fotoni sono viceversa caratterizzati da un assorbimento di tipo esponenziale decrescente preceduto da un massimo che non va oltre i 4 cm per fotoni anche parecchio energetici (25 MeV).
Il loro utilizzo é particolarmente indicato per tumori "profondi" situati a molti centimetri dalla cute. Per irraggiare in modo selettivo tali bersagli sono state sviluppate tecniche sofisticate, che implicano la necessitá di utilizzare piú fasci che entrano in punti diversi del corpo ma che sono tutti focalizzati sul centro del tumore.
Per realizzare questo tipo di trattamento occorre che l'intero acceleratore lineare di elettroni ruoti attorno a un punto fisso nello spazio (isocentro) in modo da potere utilizzare qualsiasi punto d'entrata del fascio prestabilito rispetto al paziente. Un modo per "conformare" il fascio al tumore é inoltre quello di frapporre degli ostacoli tra la sorgente ed il bersaglio in modo da far pervenire specifiche dosi in ogni punto di questo. In tal senso oggi si usano degli "ostacoli" la cui forma varia dinamicamente risparmiando in tempo e costi di realizzazione rispetto gli obsoleti "ostacoli" a forma fissa. Tali oggetti dinamici vengono chiamati "multileaf collimators" (collimatori a molte foglie) in quanto sono costituiti da parallelepipedi di metallo pesante che si muovono scorrendo uno sull'altro per mezzo di motori e si frappongono al fascio realizzandone la modulazione in intensitá.

2.4  Adroterapia

Per adroterapia si intende la radioterapia praticata con particelle composte da quark: neutroni, protoni, ioni.

Neutroni

Per quanto riguarda i neutroni, il loro rilascio di energia in acqua é molto simile a quello dei fotoni e risultano particolarmente utili solo in quanto il boro ha le due seguenti proprietá:
1) si fissa su alcuni tessuti tumorali.
2) interagisce con neutroni termici liberando particelle a ad alto LET che rilasciano localmente tutta la loro energia.
Tali proprietá consentono di realizzare la boroterapia che consiste appunto nel fare in modo che il boro si fissi sul tessuto tumorale in questione il quale viene poi irradiato con neutroni termici scatenando una reazione che libera particelle a che rilasciano dose esattamente la dove tale dose é necessaria. Il rilascio di energia per i neutroni é visualizzato in fig. 2.8 insieme a quello di elettroni, fotoni e protoni.
Figure 2.8: Curva dose-profonditá per fotoni,(da una sorgente di cobalto e da un acceleratore lineare da 8 MeV), neutroni e protoni. Per ogni fascio viene indicata la distanza "sorgente pelle" ("Source to Skin Deep").

Protoni

Le curve dose-profonditá per i protoni (2.8) di"Calling ghostscript to convert zImages/t13.EPSF to zImages/t13.EPSF.gif , please wait ..." "Calling ghostscript to convert zImages/t14.EPSF to zImages/t14.EPSF.gif , please wait ..." fferiscono [7] fortemente da quelle delle altre radiazioni finora analizzate in quanto i protoni (e le particelle cariche pesanti in generale) rilasciano le dosi piú elevate alla fine del loro percorso nei tessuti dando luogo al "picco di Bragg" giá esaminato nel primo capitolo. Per i protoni quindi la dose superficiale é bassa rispetto a quella assorbita nella regione del picco, diversamente da quanto succede per fotoni e neutroni.
La profonditá del picco di Bragg varia con l'energia iniziale dei protoni: modulandola opportunamente é possibile ottenere un plateu nella curva dose-profonditá detto SOBP (Spread-out Bragg Peak; picco di Bragg allargato) illustrato in fig. 2.9.
Figure 2.9: Picco di Bragg allargato (SOBP) per fasci di protoni e ioni.
Con un plateu di questo tipo si riesce ad evitare moltissima dose al tessuto sano (praticamente vi é un rilascio di dose nullo oltre il bersaglio), tuttavia si puó fare ancora di meglio con ioni leggeri in quanto, come si puó notare in fig. 2.9 la dose rilasciata prima del picco é molto piú bassa man mano che la particella carica diventa piú pesante.

Ioni leggeri

Gli ioni leggeri consentono quindi una buona "conformazione" della dose anche se presentano i seguenti problemi:
1) realizzare un acceleratore di ioni é piú complesso che realizzarne uno per soli protoni.
2) man mano che la massa dello ione aumenta si presenta il fenomeno della frammentazione giá visto nel primo capitolo che provoca il rilascio di dose anche oltre il picco di Bragg (code) come si puó vedere in fig. 2.9 . In pratica ha senso solo usare ioni non piú pesanti dell'ossigeno.
Il grandissimo vantaggio di usare l'adroterapia al posto della terapia tradizionale (fotoni, elettroni) appare evidente in fig. 2.10,
Figure 2.10: Confronto tra le distribuzioni di dose di fasci di protoni e di elettroni su un bersaglio (rappresentato dal cerchio).
in essa viene quantificata la qualitá del trattamento conforme ottenuta con un fascio di protoni allargato comparando le curve di isodose con quelle dovute ad un fascio di elettroni.

2.5  Piani di trattamento in Adroterapia

Si é visto come gli adroni offrano il vantaggio di una distribuzione di dose in profonditá con un massimo pronunciato alla fine della traettoria rispetto alla deposizione esponenziale dei fotoni o del massimo molto allargato degli elettroni, in questo modo essi consentono un terapia conformazionale di elevata precisione.
Tale precisione consente di adattare molto bene la distribuzione della dose alla forma del volume bersaglio, diminuendo nel contempo la dose ricevuta dai tessuti sani e risparmiando gli organi critici.
Il piano di trattamento radioterapico deve essere pianificato tenendo conto di una serie di parametri multidisciplinari che vanno dalla diagnostica, alla radiomedicina passando per i limiti tecnologici e le problematiche fisiche e biologiche relative alle modalitá di rilascio della dose.
In generale, schematicamente, abbiamo le seguenti fasi:
  1. Acquisizione di informazioni diagnostiche (CT,PET,NMR,altri reperti).

  2. Individuazione del volume bersaglio e degli organi a rischio limitrofi.

  3. Scelta delle dosi e delle modalitá di rilascio (tipo di radioterapia, posizione delle sorgenti, eventuale utilizzo di collimatori)

  4. Elaborazione del piano di trattamento secondo una delle seguenti modalitá:
    • direct planning Valutazione diretta del piano di trattamento con metodo prova e riprova.

    • inverse planning Elaborazione automatica di un piano di trattamento attraverso algoritmi di inversione.

  5. Simulazione e visualizzazione tridimensionale della distribuzione di dose ottenuta.

2.6  Immagini diagnostiche

I dati di partenza per la formulazione di un piano di trattamento sono costituiti da immagini diagnostiche ottenute con diverse tecniche. Esse infatti , oltre a fornire un mezzo per la valutazione dal punto di vista clinico dell'estensione e della collocazione della lesione, contengono anche l'informazione relativa all'anatomia tridimensionale del paziente. Quest'ultima informazione svolge un ruolo importantissimo nella stesura del TP(Treatment Planning) , poiché consente di valutare l'eventuale presenza di organi e/o strutture a rischio nelle vicinanze del tumore, e di tracciare quindi i contorni del volume bersaglio e di quelli circostanti, oltre a permettere la scelta delle caratteristiche del fascio e della geometria di irraggiamento piú opportune.
Le immagini diagnostiche contengono inoltre anche l'informazione relativa alla distribuzione spaziale della densitá all'interno del corpo del paziente, che, una volta convertita in una mappa dei poteri frenanti massici in acqua, é alla base dei calcoli dosimetrici per la stesura del TP.
E' importante sottolineare la necessitá di disporre di un set di immagini diagnostiche del paziente nella posizione di irraggiamento, per disporre di una simulazione di trattamento il piú possibile aderente alla realtá, completo di tutti i dati necessari per l'individuazione della lesione e per il posizionamento del paziente sul lettino o sulla sedia di trattamento (clip chirurgiche,segni tatuati sulla pelle, ecc.). Quest'ultima esigenza é legata alla possibilitá, sempre piú diffusa, di ottenere immagini radiografiche ricostruite a partire dalle immagini diagnostiche di partenza, che possono essere comparate con delle radiografie effettuate in sala di trattamento durante ciascuna sessione di terapia, allo scopo di garantire un'adeguata riproducibilitá del posizionamento del paziente.

2.7  Tomografia Computerizzata

La tecnica della tomografia computerizzata non é necessariamente la fonte diagnostica principale ( esempio per patologie alla tiroide la PET 1 risulta piú valida per la valutazione dello stato fisiologico della tiroide stessa) tuttavia costituisce nella maggior parte dei casi la sorgente da cui si parte per elaborare un piano di trattamento, eventualmente coadiuvata da altre sorgenti di immagini quali la PET appunto o la NRM. 2 La CT si basa sull'assorbimento dei raggi X da parte del tessuto attraversato, tale assorbimento dipende dalla densitá elettronica del materiale che costituisce il tessuto e viene misurata da un coefficiente, detto coefficiente di assorbimento o di attenuazione lineare m. [8]
Per realizzare la CT l'orga"Calling ghostscript to convert tac.EPSF to tac.EPSF.gif , please wait ..." no in questione viene idealmente suddiviso in tante slices di spessore limitato (tipicamente circa un millimetro) , ognuna di queste viene quindi sondata individualmente utilizzando fasci di raggi X. (fig. 2.11)

Figure 2.11: Sistema di scanning per tomografia. Un fascio di raggi X passa attraverso l'oggetto e viene rivelato all'uscita. Il sistema (sorgente di raggi X - detector) scorre lungo le direzioni indicate nella figura in alto (scansione). Piú scansioni vengono effettuate a vari angoli per poter ricostruire meglio l'immagine dell'organo.

 

 

 

Ad ogni scansione viene misurata la curva di assorbimento della radiazione in funzione della posizione del sistema sorgente-detector. Si raccolgono quindi le informazioni di tutte le scansioni (sempre del medesimo piano) e tramite algoritmi abbastanza sosfisticati si risale in maniera piú o meno precisa alla densitá elettronica in ogni punto del tessuto. (La precisione aumenta col numero di scansioni ma ognuna di esse arreca un danno potenziale al paziente in quanto rilascia dose ai tessuti per cui non si puó eccedere)[9]. In maniera molto grossolana ma forse piú intuitiva si puó dire che dall'analisi delle "ombre/trasparenze" viste da piú angolazioni si puó ricostruire la forma/densitá dell'oggetto in esame. Le differenze di densitá cosí elaborate sono tali da consentire la distinzione tra un tessuto e l'altro nonch'é l'eventuale patologia di un tessuto stesso. Bisogna peró precisare che di fatto, tramite la tecnica di scansione si possono misurare unicamente i coefficienti di assorbimento m(k,E) dove k rappresenta l'identificativo di un particolare voxel e E l'energia dei raggi X utilizzati. Per passare alla densitá elettronica vera e propria bisogna calibrare (tramite scansioni a materiali noti) il sistema di acquisizione elaborando i coefficienti che legano la densitá elettronica ai coefficienti di assorbimento:
re=(A +B·m)              
 elettroni

cm3

Per rendere piú leggibili i dati raccolti sui coefficienti di assorbimento si suole peró riferirli a quelli differenza-percentuale rispetto a quelli dell'acqua moltiplicati ancora per 1000 per magnificarne la differenza [10], tali valori prendono il nome di numero di Hounsfield o numero TC:
TC(k,E)=  m(k,E) -mH2O

mH2O
·1000
L"Calling ghostscript to convert hu.eps to hu.gif , please wait ..." "Calling ghostscript to convert zImages/a246.EPSF to zImages/a246.EPSF.gif , please wait ..." a relazione tra densitá elettronica e numeri di Hounsfield differisce rispetto a quella con in coefficienti di assorbimento unicamente per i coefficienti che normalmente vengono espressi nella seguente forma:
re=(A +B·10-3·TC)·1023              
 elettroni

cm3

Dalla definizione di numero di Hounsfield si osserva che per l'aria TC=-1000, mentre per l'acqua TC=0. I valori dei numeri TC per i vari tessuti del corpo umano sono riassunti nella figura 2.12.
Figure 2.12: Distribuzione dei numeri TC per i vari tessuti del corpo umano.
Esiste infine un legame tra densitá elettronica re e densitá del materiale:
r =  A

NA·Z
re

2.8  Distribuzione della dose

Facendo riferimento alle immagini del tessuto da curare il medico fornisce le sue prescrizioni per quanto riguarda la dose che in esso va rilasciata.
Conoscendo a priori l'impossibilitá di localizzare la dose unicamente sul tumore e conoscendo inoltre i limiti delle apparecchiature a disposizione per realizzare il trattamento, il medico fornisce una richiesta di rilascio di dose che sia ragionevolmente ottenibile.
Tale richiesta viene rappresentata con delle curve di isodose (cioé contorni lungo i quali la dose assume valore costante) tracciate direttamente sull'immagine del tessuto. Con sistemi piú sofisticati, viceversa il medico puó avvalersi dell'aiuto di un computer per stilare un piano di trattamento. In fig.2.13
Figure 2.13: Curve di isodose per trattamento con protoni ad intensitá modulata.
é possibile vedere una schermata di uno di questi programmi per la elaborazione di piani di trattamento: in alto a sinistra si osservano le curve di isodose risultanti dal trattamento completo con 9 fasci di protoni. E' importante sottolineare che l'ottimizzazione della distribuzione fisica della dose non coincide con l'ottimizzazione del piano di trattamento, perché l'effetto radiobiologico é influenzato da altri parametri, quali lo schema di frazionamento e la radiosensibilitá cellulare. Per giudicare gli effetti dell'irraggiamento é dunque sempre necessario valutare anche la probabilitá di controllo del tumore(TPC) e la probabilitá di danni ai tessuuti normali (NTPC) rilevabili dalla lettura delle curve dose-effetto"Calling ghostscript to convert magn.EPSF to magn.EPSF.gif , please wait ..." "Calling ghostscript to convert rascan.EPSF to rascan.EPSF.gif , please wait ..." per i tessuti in questione.

2.9  Sistemi di distribuzione attiva del fascio

Per somministrare una dose conforme su un tumore, il metodo migliore é quello di una modulazione in intensitá del fascio non mediante bolus cioé ostacoli frapposti tra la sorgente e il bersaglio (sistemi di distribuzione passiva del fascio) ma mediante dispositivi in grado di generare fasci di energie diverse (sistemi di distribuzione attiva del fascio).
Utilizzando dei magneti disposti sul percorso del fascio é inoltre possibile modificarne la sua direzione.(fig. 2.14

Figure 2.14: Struttura schematica di un sistema a scansione magnetica.

 

 

Con l'unione delle due modulazioni é possibile, nel caso dell'adroterapia centrare il picco di Bragg in punti ben precisi del volume da trattare eseguendone una scansione tridimensionale [11].
Tale scansione puó essere di due tipi: raster o voxel (fig. 2.15).
Figure 2.15: Sistemi di scansione: a) raster b) voxel.
Con il metodo raster il fascio é continuo e si muove a zig-zag, con il metodo voxel il fascio é intermittente e situa il picco di Bragg all'interno di un volumetto che puó essere anche dell'ordine del millimetro di lato realizzando quindi un trattamento estremamente conforme al tumore stesso.
 

Capitolo 3
Il programma ANCOD2: gli oggetti

3.1  Descrizione degli obiettivi

Il programma deve essere in grado di fornire un piano di trattamento che consiste in un insieme di spot descritti da: direzione, numero di particelle, energia. Tale piano di trattamento deve essere elaborato a partire dalle seguenti cose:
  1. dalla CT che descrive gli organi da trattare

  2. dalla prescrizione del medico sulle parti da trattare e con quali dosi

  3. dalla descrizione della apparecchiatura che effettuerá il trattamento e dal posizionamento del paziente rispetto al fascio

Dal programma si vuole inoltre la visualizzazione delle dosi che con il piano di trattamento elaborato si prevede vengano rilasciate (necessariamente non identiche a quelle prescritte); tali dosi dovranno, in fase di verifica, essere convalidate con simulazioni montecarlo o sperimentali.
Fermo restando questi obiettivi il programma ha comunque molti gradi di libertá che seguono l'evolversi della situazione, per esempio:

3.2  Architettura del programma

Rispetto ad un linguaggio procedure-oriented dove l'attenzione é concentrata sul flusso di eventi che porta da un set di dati in input verso un set di dati in output [12] in un linguaggio object-oriented si cerca piuttosto di individuare le singole entitá che concorrono a costituire un contesto informativo considerando le procedure come eventi contingenti la cui plasticitá e facilitá di realizzazione sono garantite proprio da una buona disarticolazione dei dati stessi. [13] Ogni componente del contesto informativo dal quale si vogliono estrarre informazioni deve essere resa autonoma per quanto riguarda la creazione, mantenimento e richiamo. Queste componenti("Oggetti") devono poter essere scambiate tra i vari moduli delle procedure senza che vi sia altro codice che sovraintenda a ció: una matrice deve contenere in se il suo numero di elementi ed il modulo puó tranquillamente richiamarla senza preoccuparsi di cercare altrove informazioni a suo riguardo.
Questa impostazione richiede un accurato studio del contesto informativo ma consente una piú snella stesura di codice una volta che questo é stato posto in impianto.
Un 'altra caratteristica dei linguaggi object-oriented [14] é quella di consentire la creazione di nuovi "tipi" di dati. Per esempio se il programma fa uso di algebra lineare conviene creare un nuovo tipo di dato, in questo caso "matrice" e definire per esso operazioni di somma, moltiplicazione, inversione etc, in modo che il codice possa contenere istruzione del tipo
A = B + C;
A = B * C;

Dove A,B,C sono matrici.
L'introduzione di nuovi tipi facilita quindi moltissimo la stesura di codice e deve essere usata ogni volta vi sia una ragionevole probabilitá di riutilizzo nel medesimo contesto informativo [15]. Nella stesura di piani di trattamento ad esempio lo studio delle traiettorie delle particelle, della valutazione delle distanze etc, suggerisce la creazione di oggetti quali punti geometrici, linee e piani con relativi algoritmi per il calcolo delle intersezioni, delle distanze e quant'altro. L'insieme di una entitá logicamente ben delineata, unito agli algoritmi che le sono propri, costituisce una "classe". Ad esempio in questo programma é stata introdotta la classe Rijk che consente la gestione di matrici di numeri reali a 3 indici (creazione/inizializzazione, distruzione, accesso, visualizzazione, memorizzazione su file, richiamo da file, stampa).
Tutto il contesto informativo puó essere strutturato su piú livelli: si introducono entitá/tipi base per poi definire altre entitá piú complesse che ne fanno uso. L'importante, nella stesura del contesto informativo, é individuare bene i livelli gerarchici nei quali esso si struttura. Tale individuazione é tutt'altro che univoca o stabile: é opera del project manager valutare quanto tempo spendere nello studio dell'architettura e quando e quanto modificarla a fronte di imprevisti: una visione a sgrossamento iniziale seguita da approssimazioni successive sembra essere una buona strada [13] o comunque é stata quella seguita nella stesura di questo programma.

3.3  Oggetti e Metodi

Qui di seguito verranno descritti, a partire dal piú basso livello gerarchico, le classi che costituiscono il contesto informativo cui la procedura ANCOD2 fará riferimento nell'elaborazione del piano di trattamento.
La gerarchia delle classi é la seguente:
Per poter procedere nella lettura é peró opportuno aprire una breve parentesi sul C++ che consenta una comprensione, magari anche solo sommaria, delle sue principali costituenti.

3.3.1  Cenni di C++

La istruzione #include
La struttura di un programma C++ é la seguente:
#include <iostream.h> 
int main(){ 
   int i; 
   cout << ``Inserire un numero ``; 
   cin  >> i; 
   cout << ``Numero inserito = '' << i; 
   return 0; 
}

Questo programma effettua un input da tastiera (cin = console input) ed un output su terminale (cout = console output).
Si noti che la prima istruzione ( # include < iostream.h > ) che di fatto viene sostituta da un precompilatore con il contenuto del file iostream.h dice al compilatore che verrá fatto uso di un set di istruzioni che concernono input ed output attraverso operatori di stream ( << e >> ) ; operatori il cui significato si evince dall'esempio stesso. Questo particolare é molto importante , infatti il compilatore C++ viene concepito come aperto: tolto un nucleo base capace di svolgere le operazioni piú elementari il resto del compilatore viene integrato da tanti moduli di cui alcuni sono standard del C++ presenti in ogni compilatore, altri sono propri dello specifico compilatore e, soprattutto si prevede che buona parte dei moduli aggiunti saranno stati creati dal programmatore stesso. Questa caratteristica, unita ad altre potenzialitá del nucleo di base che vedremo in seguito, consente la programmazione Object Oriented.
Le funzioni
Una buona regola di programmazione é la seguente: dividi e conquista: la somma delle difficoltá di un problema diviso in due é infatti dal punto di vista umano molto minore di quella dello stesso problema considerato nel suo insieme. Per riuscire a dividere un problema si utilizzano le "funzioni" dove, per funzione si intende non solo qualcosa che restituisce un numero ma anche qualcosa che effettua delle operazioni. Qui di seguito viene riportato l'esempio di dichiarazione di una funzione ("min") per trovare il minore tra due numeri ed il suo utilizzo:
int min(int a,int b) {    /* Dichiarazione */
   if( a < b ) return a;
   if( b < a ) return b;
}
#include <iostream.h> 
int main() { 
   int i,j; 
   cout << " Inserire due numeri "; 
   cin  >> i >> j; 
   cout << " Numero minore = " << min(i,j); /* Utilizzo */ 
   return 0; 
}





I file header e implementation
Nel precedente esempio dichiarazione
int min(int a,int b)

implementazione
   if( a < b ) return a;
   if( b < a ) return b;

ed utilizzo
   cout << " Numero minore = " << min(i,j);

della funzione min erano tutti e tre in uno stesso file il cui nome sarebbe potuto essere ad esempio "prova.cc". Normalmente invece queste tre parti vengono suddivise in quanto Le classi
Oltre alle funzioni si possono definire delle classi che sono delle strutture dati che hanno dei metodi che ne consentono la manipolazione. Esempio di una classe potrebbe essere quello dei numeri complessi: un numero complesso é composto da una coppia di numeri reali per la quale é definita la somma, il prodotto, la differenza ed il rapporto. La sintassi per creare una tale classe, tuttavia, non é del tutto banale e qui si presenta una classe molto piú semplice.
file unaClasse.h:
class unaClasse{
   private:
      int a;                
   public:
      void set_a(int num); 
      int get_a();         
}

file unaClasse.cc:
void unaClasse::set_a(int num)
{
   a = num;
}
int unaClasse::get_a()
{
   return a;
}


file utilizzo.cc:
#include "unaClasse.h"
#include <iostream.h>
int main(){
   unaClasse var1;
   unaClasse var2;
   var1.set_a(10);
   var2.set_a(22);
   cout << var1.get_a();
   cout << var2.get_a();
   return 0
}

Questo programma, una volta compilato ed eseguito produrrá la stampa dei numeri 10 e 22.
Per ulteriori approfondimenti sul C++ si rimanda a testi specifici di cui alcuni titoli sono indicati in bibliografia.

3.3.2  REALdef

Questo modulo definisce a priori (per questo é stato posto a "livello -1") cosa si intende per "numero reale": l'utilizzo di double garantisce maggiore precisione e velocitá di esecuzione, quello di "float", viceversa, una minore occupazione di memoria.
Tutte le classi a seguire definiranno REAL i numeri reali, dove REAL verrá sostituito da double o float a seconda di quanto contenuto in questo modulo.

3.3.3  SystemOfUnits

Questo modulo é stato ritagliato dalla librerie CLHEP ( CLasses for High Energy Physics) [17] provenienti dal CERN e consiste in una serie di definizioni di constanti. In esso sono contenute le definizioni delle unitá di misura in termini di multipli e sottomultipli di un valore scelto come fondamentale e posto uguale a 1.
Es. per le lunghezze abbiamo le seguenti definizioni:
 mm         =  1;                 
 cm         =  10    * 1 mm;      
 m          =  1000  * 1 mm;      
 micrometer =  1.e-3 * 1 mm;      
 nanometer  =  1.e-6 * 1 mm;      

Con queste definizione é quindi possibile usare istruzioni come:
thickOfDetector = 5*mm;

oppure (usando le definizioni delle energie):
enOfParticle = 5*MeV;

Tutto questo evita di dover riportare a parte le convenzioni sulle unitá di misura assunte e risulta molto chiarificativo nella lettura di codice altrui.

3.3.4  int3Vector

Questa classe serve per poter gestire come una unica entitá una terna di indici. Esempi di utilizzo sono il puntatore ad un particolare voxel, puntatore che costituisce a sua volta l'indice di un elemento della matrice contenente le densitá elettronica di tutti i voxel.
int3Vector spotVoxel=(10,2,13);
actualDensity = densityMatrix(spotVoxel);

(Nella seconda istruzione non ci si cura piú delle singole componenti del puntatore a quel voxel).

3.3.5  Hep3Vector

Come suggerisce il nome questa classe proviene dalle librerie CLHEP dalle quali peró é stata enucleata e ridotta. La fase di installazione e utilizzo delle librerie CLHEP ha infatti presentato una tale serie di problemi da suggerire di rinviare al futuro il suo completamento, questo anche in virtú del fatto che il programma avrebbe utilizzato una parte comunque molto limitata delle librerie stesse. Delle CLHEP é rimasta la sintassi del costruttore e dei metodi implementati (cioé quelli che non sono stati esclusi) in modo da garantirne un domani la compatibilitá. La classe é la versione non intera bensí reale della classe int3Vector, serve cioé a gestire terne di numeri reali (utile per esempio per i vettori nello spazio o per generici dati "tridimensionali").

3.3.6  Line

La classe Line é stata realizzata al fine di rappresentare un fascio di particelle che parte ( o passa ) da un punto e si dirige verso un altro punto. (Piú che di una linea si tratta in realtá di una linea orientata) I metodi di intersezione con i piani ortogonali agli assi consentono quindi di evidenziare la traettoria di una particella.

3.3.7  GridBox

Questa classe serve per gestire un reticolo di piani che individua un insieme di parallelepidi che vengono detti scomparti, box o voxel.
In pratica ogni elemento appartenente a questa classe si puó visualizzare come uno "scaffale" tridimensionale: quello che conta non sono i contenuti all'interno degli scomparti ma le dimensioni ed il numero degli scomparti stessi. La classe fornisce quindi indicazioni unicamente geometriche ma torna molto utile nell'identificazione e nella gestione dei volumi tipici dei piani di trattamento: TTV (ToTal Volume) e PTV (Plane of Treatment Volume). Ogni voxel ha un centro center ed uno spigolo inferiore sinistro node, in seguito si comprenderá l'importanza di tale distinzione. (Si definiscono inferiore sinistro e superiore destro i punti con coordinate algebriche rispettivamente piú piccole e piú grandi).

3.3.8  Rijk

In fortran [18] l'utilizzo di matrici a 2 o piú indici é definito in maniera univoca e definitiva dagli standard del linguaggio. In C++ viene fornito un utilizzo analogo che non risulta peró molto efficiente in quanto storicamente derivato dal C con un sistema di puntatori a puntatori che risulta lento nell'accedere ai dati. Inoltre il C non disponeva di metodi, non esistevano quindi operatori di stampa o di manipolazione delle matrici che non fossero delle funzioni a parte. Per chi vuole utilizzare matrici, o anche solo vettori, in C++ é pertanto consigliato reperire dei package giá pronti (é il caso delle CLHEP o delle Standard Template Library (STL) [19] o riscriversi delle classi ottimizzandole per il proprio tipo di utilizzo. In ANCOD2, ad esempio, a parte l'inversione non compaiono elementi di algebra matriciale e le matrici sono fondamentalmente dei contenitori a tre indici di numeri di Hounsfield, di densitá elettroniche o altro: da qui la creazione della classe Rijk.
I metodi della classe Rijk sono:

3.3.9  R1R1

Una relazione di tipo y=f(x) puó essere tabulata come un insieme di valori (xi,yi) se la funzione non é nota o se il suo calcolo risulta particolarmente pesante per il calcolatore. Questo, ad esempio, é il caso della funzione En(range) che lega un set di energie specifiche ai corrispondenti range (distanza del picco di Bragg in acqua) per protoni o ioni carbonio. La classe R1R1 serve quindi per gestire una "relazione" in senso matematico tra due insiemi di numeri reali chiamati Dom (per dominio) e Img (per immagine). É importante che i valori del dominio siano dati in ordine crescente, altrimenti alcuni metodi della classe non funzioneranno.

3.3.10  RiRjR1

Questa classe serve a gestire una relazione Ra ×Rb R. In pratica si puó visualizzare il tutto come una tabella cui ogni riga compete un valore dell'insieme Ra ed ogni colonna uno dell'insieme Rb, all'intersezione si trova il valore funzione di entrambi, per esemplificare si puó pensare di realizzare una tabella con le prime 3 potenze di alcuni numeri:
                                                                          
                                                                          
                                                                          
                                                                          
                                                                          
                                                                          
  first       first     1        2        3      (nome= "Esponente")       
  col          row                                                        
                                                                          
                                                                          
                                                                          
   2                    2        4        8                               
                                                                          
                                                                          
   3                    3        9       27                               
                                            (nome= 
                                             "PotenzeCalcolate")
   5                    5       25      125                               
                                                                          
                                                                          
  10                   10      100     1000                               
                                                                          
(nome=                                                                 
  "base")                                                          
                                                                          


La prima riga viene indicata come firstRow e le sue entrate valgono rispettivamente 1, 2 e 3. Il suo nome é "Esponente".
La prima colonna viene indicata come firstCol e le sue entrate valgono rispettivamente 2,3,4,5 e 10. Il suo nome é "Base".
Le entrate della matrice hanno anch'esse un nome: "PotenzeCalcolate". Nel caso di ANCOD2 questa classe é stata utilizzata per memorizzare il rilascio di energia per un set di 47 energie da 12 a 450 MeV (firstRow) per 351 distanze da 0 a 350 mm (firstCol).

3.3.11  cRUN

La classe cRUN serve per gestire programmi con molti dati in ingresso durante l'esecuzione. Fintanto che il programma necessita di soli due o tre dati questi possono essere forniti semplicemente da tastiera. Un esempio é il programma per il calcolo delle radici di una equazione di secondo grado che necessita unicamente dei coefficienti a, b e c.
Viceversa per un programma che ha bisogno di molti dati conviene elaborare un sistema per depositare questi dati su un file in modo che il programma li rilegga ordinatamente da solo senza doverli digitare ogni volta da tastiera. Si presentano a questo punto peró una serie di problemi:
  1. L'ordine é difficile da interpretare: modificare dieci numeri scritti uno di seguito all'altro non aiuta a ricordare il significato di ognuno di essi.

  2. Il numero di elementi da fornire in ingresso potrebbe essere variabile ed i questo caso l'ordinamento sarebbe quantomeno "complesso".

  3. In questo file non sarebbero consentiti commenti (in quanto occuperebbero il posto di un dato).

Per questi e altri motivi, in ogni luogo dove vi siano programmi sufficientemente complessi vengono realizzati dei sistemi piú o meno elaborati per passare dei dati a un programma in esecuzione. Generalmente questi sistemi sono basati su delle parole chiave che consentono di associare ogni valore alla sua specifica variabile: ogni riga del file contiene una parola chiave ed un valore e questo é quanto basta per variabili che non siano delle matrici o dei vettori. Per matrici o vettori bisogna,viceversa, insieme alla parola chiave, definire in qualche modo anche la loro dimensione e le cose si fanno un poco piú complicate. In ANCOD2 si é scelto di non passare matrici o vettori se non tramite i metodi restore visti nelle classi precedenti, per questo motivo i tipi di dati da passare saranno unicamente compresi fra i seguenti: numeri reali,numeri interi,stringhe, variabili booleane,nomi di file. Per scegliere, durante una esecuzione, di usare una matrice di tipo Rijk al posto di un'altra bisognerá pertano associare alla parola chiave "MatriceUsata" i nomi di file "MatriceA.Rijk" piuttosto che "MatriceB.Rijk". Oltre alla parola chiave ed il valore ad essa associato ogni riga del file di input conterrá anche un carattere iniziale che indica di che tipo di dato si tratta: R per numeri reali, I per numeri interi, S per stringhe, B per variabili booleane (true/false) F per nomi di file, % per righe che sono di commento. Un esempio di file per l'esecuzione si presenterá quindi cosí:
file Prova1.run

% Files per l'esecuzione e per i risultati:
F   CT_input	        /usr/ater/rossi/data/candiolo/73843748
F   energyLoss          enLoss.dat
F   graficoDosi         dosiProva22.hbook
F   TPoutputFile        TP22.dat
%
% Cose da fare o da non fare durante questa esecuzione:
B   debugON             false
B   printRunSetting     true
%
% Interi 
I   numeroIterazioni    1000
I   tipoCT              1    	
%                       (1=MOLINETTE,2= PSI, 100=GSI)
% Stringhe
S   titoloGraficoDosi   Prova22
%
% Reali
R   XofVertex           896.0
R   YofVertex           8.0
R   ZofVertex           -2000
%  (queste lunghezze sono espresse in millimetri.) 
  

Ovviamente ad ognuna delle parole chiavi a sinistra corrispondono uno o piú punti del programma che la richiamano con una sintassi consentita da una particolare struttura dati definita "Map" che consente di usare una stringa come se fosse un indice di un vettore. Tale vettore é unico per ogni tipo di dati: ( files__ Nomi di Files)
( flags__ Variabili Booleane)
( intVar__ Variabili intere)
( strVar__ Variabili stringa)
( realVar__ Variabili reali)
Segue un esempio di programma che utilizza la classe cRUN leggendo un file di dati che pilotano l'esecuzione chiamato "Prova1.run"
#include "cRUN.h"
main(){
	cRUN thisRun;
	readDataCards("Prova1.run");

	cout << files__["TPoutputFile"]
	cout << files__["graficoDosi"] ;
	cout << files__["energyLoss"]
	cout << files__["CT_input"] ;

	cout << flags__["printRunSetting"] ;
	cout << flags__["debugON"]

	cout << intVar__["numeroIterazioni"]
	cout << intVar__["tipoCT"] ;

	cout << strVar__["titoloGraficoDosi"]

	cout << realVar__["ZofVertex"] ;
	cout << realVar__["YofVertex"] ;
	cout << realVar__["ZofVertex"] ;	
}

Produce in stampa:
        TP22.dat
        dosiProva22.hbook
        enLoss.dat
        /usr/ater/rossi/data/candiolo/73843748
        true
        false
        1000
        1
        Prova22
        -2000
        8.0
        896.0

(L'ordine di alcuni dati é stato volutamente cambiato rispetto a quello del file di input per indicare che essi possono essere richiamati in qualsiasi ordine all'interno del programma). Questo programma é stato eseguito con i dati impostati nel file Prova1.run ma qualora anziché apportare continue modifiche al file Prova1.run si decida di avere predisposti piú file di esecuzione ( Prova1.run, Prova2.run,etc.) il nome del file di esecuzione potrebbe essere variabile e passato in input da tastiera prima della istruzione readDataCards():
String nomeFileEsecuzione;
cin >> nomeFileEsecuzione;
cRUN thisRun=readDataCards(nomeFileEsecuzione);

  • costruttore Questo metodo non ha parametri e predispone in memoria le mappe che serviranno ad associare i nomi delle variabili ai loro valori:
    cRUN thisRun;
    
    
    Crea sei mappe:
    ( files__ Nomi di Files)
    ( flags__ Variabili Booleane)
    ( intVar__ Variabili intere)
    ( strVar__ Variabili stringa)
    ( realVar__ Variabili reali)
    Tuttavia queste mappe sono ancora vuote e andranno riempite con i metodi di assegnazione di un valore al nome della variabile es:
    cRUN thisRun;
    thisRun.declareFile("CTinput", "23322343.dat");
    
    

  • lettura DATA CARDS La subroutine readDataCards giá vista precedentemente esegue la lettura del file di input e il conseguente riempimento delle mappe delle variabili mediante l'istruzione declare opportuna a seconda del tipo di dato trovato in ogni riga.

  • assegnazione di un valore ad una variabile Esistono cinque metodi diversi per riempire le mappe, uno per ogni tipo di variabile:
    cRUN thisRun;
    /*1*/ thisRun.declareFile("CTinput", "23322343.dat");
    /*2*/ thisRun.declareFlag("debugON", false);
    /*3*/ thisRun.declareIntVar("tipoCT", 1);
    /*4*/ thisRun.declareStrFile("titoloGraficoDosi", "prova22");
    /*5*/ thisRun.declareRealFile("XofVertex", 89.6*cm);
    
    

  • recupero del valore di una variabile Questo "metodo" in realtá consiste nel semplice richiamo di una delle cinque "mappe" con il relativo indice/nome della variabile:
    #include ``cRUN.H''
    main(){
    	cRUN thisRun;
    	readDataCards("Prova1.run");
    /*1*/	cout << files__["TPoutputFile"]
    /*2*/	cout << flags__["printRunSetting"] ;
    /*3*/	cout << intVar__["numeroIterazioni"]
    /*4*/	cout << strVar__["titoloGraficoDosi"]
    /*5*/	cout << realVar__["ZofVertex"] ;
    
    }
    
    
    I risultati di queste stampe sono giá stati presentati negli esempi precedenti.

  • stampa Questo metodo ( << ) effettua la stampa di tutte le cinque mappe con le relative coppie nome-valore.L'istruzione cout << thisRun; produrrá quindi un resoconto dei parametri che hanno regolato l'esecuzione del programma in questione.

3.3.12  cPAW

La scelta di assegnare al dispositivo software di visualizzazione (in questo caso PAW [20]) la conoscenza della classe anziché viceversa é legata alle seguenti motivazioni:
  • Avere un codice ANCOD2 che possa essere eseguito ad esempio su PC Windows non essendo vincolato a PAW (si useranno infatti altri sistemi di visualizzazione come quelli forniti nel compilatore Borland C++ Builder III).

  • Rimanendo in ambiente unix o linux usare altri dispositivi di visualizzazione come root [22] o tcl/tk [23], rispettivamente un interprete C++ con capacitá grafiche e uno script language (tcl) molto simile al linguaggio PERL con una estensione (tk) per la grafica. Le singole funzioni di questo modulo sono stati presentati ognuno nella classe di oggetti che visualizza se ne ricordano pertanto soltanto i nomi:
    • Per la classe Rijk PAWplot(),PAWplotAlongY(),PAWplotAlongZ()

    • Per la classe R1R1 PAWplot()

    • Per la classe RiRjR1 PAWplot()

3.3.13  Il file makefile

Il makefile é un file che serve per la compilazione di un programma costituito da piú moduli[16]. Tramite il comando "gmake" il sistema operativo controlla sul "makefile" (che deve specificatamente avere questo nome) quali moduli del programma sono ancora validi e quali, a causa di una qualche modifica effettuata su alcuni file di codice, devono essere ricompilati poiché o direttamente o indirettamente non hanno pi' un codice eseguibile aggiornato col codice sorgente (esempio perché usano una determinata classe che é stata modificata). La struttura del "makefile" é tale da inviduare la/le catene di dipendenze di un modulo dagli altri tramite una successione di coppie di righe:
La prima riga ("comando") consiste di un nome seguito dal carattere ":" seguito da un elenco di nomi ("dipendenze").
La seconda ("regola") deve essere iniziata da un carattere "tab" e seguita dai comandi unix che sono necessari per eseguire il "comando".
Altre righe precedute dal carattere "tab" possono seguire la seconda riga e funzionare anch'esse come "regole" nel medesimo modo. Qui di seguito é presentato un esempio di makefile che servirá ad illustarne il significato:
# (Linee precedute dal carattere diesis sono COMMENTI)

# (righe A1 A2 A3)
useR1R1: useR1R1.exe
 (tab)   echo running useR1R1
 (tab)   useR1R1.exe 

# (righe B1 B2 B3)
useR1R1.exe: useR1R1.o R1R1.o range.o
 (tab)   echo linkink useR1R1
 (tab)   cxx -o useR1R1.exe useR1R1.o R1R1.o range.o

# (righe C1 C2 C3)
useR1R1.o: useR1R1.cc
 (tab)   echo compiling useR1R1.cc
 (tab)   cxx -c useR1R1.cc

# (righe D1 D2 D3)
R1R1.o:  R1R1.cc R1R1.h
 (tab)   echo compiling R1R1.cc
 (tab)   cxx -c R1R1.cc

# (righe E1 E2 E3)
range.o: range.cc range.h
 (tab)   echo compiling range.cc
 (tab)   cxx -c range.cc


Le righe A1-A3 indicano che al comando dato da tastiera "gmake useR1R1" il computer deve eseguire l'istruzione "useR1R1.exe" a condizione che "useR1R1.exe" (dipendenza di "useR1R1") sia "aggiornato".
Le righe B1-B3 definiscono "quando" useR1R1.exe é "aggiornato": esso cessa di essere aggiornato se per qualche motivo le sue dipendenze (useR1R1.o R1R1.o range.o) o le dipendenze delle sue dipendenze (useR1R1.cc, range.cc range.h) sono state modificate.
Le righe C1-C3,E1-E3 indicano anch'esse alcune dipendenze e le regole da adottare se queste hanno subito modifiche.
Si púo sintetizzare la filosofia del makefile nel seguente modo: si deve ricostruire dal punto in cui qualcosa é stato modificato : le dipendenze indicano cosa deve essere ricostruito se una di esse é stata modificata, le regole come .

Capitolo 4
Il programma ANCOD2: le procedure ed i risultati

4.1  La procedura farSource

4.1.1  Descrizione sommaria

Il principale scopo di tutto il "contesto informativo" ANCOD2 e' quello di ottenere l'energia, le direzioni ed il numero di particelle necessario al fine di rilasciare una determinata dose sul target volume con la tecnica del voxel scanning. Sostanzialmente si tratta di:
  • conoscere le densitá presenti nel volume da trattare (fornite dalla CT)

  • elaborare le traiettorie delle particelle

  • ricostruire il percorso in acqua equivalente in base alle densitá ed alle traiettorie

  • determinare l'energia per posizionare il picco di Bragg al centro del voxel trattato

  • calcolare il rilascio di energia in ogni voxel partendo da tabelle di rilascio in acqua

  • calcolare il numero di particelle in ogni fascio in modo da avere la dose desiderata nel volume bersaglio.

Di tutte queste fasi l'ultima é la piú delicata:
Considerando che il numero di voxel trattati (e quindi il numero di fasci) puó variare da 103 a 104 e che ognuno di essi rilascia energia in un determinato numero di voxel della CT il cui numero di voxel puó variare tra 106 e 107 si ottengono facilmente matrici enormi (109 - 1011 elementi). Per risolvere questo problema si adottano degli stratagemmi per riuscire ad eliminare qualsiasi informazione non necessaria (esempio memorizzando il rilascio di energia sui soli voxel attraversati e non su una unica grande matrice contenente tutti i voxel). Questo risolve il problema della mera memorizzazione dei dati, sebbene renda meno "lineare" la visione dei dati: bisogna sequenziare i voxel attraversati con l'introduzione di nuovi "indici" che non fanno piú riferimento alla posizione dei voxel nella CT ma a quella nel vettore che li sequenzializza; occorre inoltre introdurre nuovi vettori per tenere memoria delle manipolazioni introdotte. Il problema comunque é trattabile sebbene i tempi di calcolo su queste matrici (che restano comunque di 104 - 105 elementi) sia molto elevato. In generale si presentano le seguenti scelte:
  • Inversione Globale Definendo inversione il processo del calcolo del numero di particelle (fluenze), il problema é quello di trovare i valori wb che risolvano la seguente equazione:
    Di,j,k= N

    b=1 
    (wb  dbi,j,k)
    con
    • dbi,j,k dose rilasciata da una particella del fascio (beam) b sul voxel i,j,k

    • Di,j,k la dose desiderata nel voxel {i,j,k} .

    É da notare che dbi,j,k spazia su tutti i voxel della CT sebbene solo per alcune triple i,j,k il suo valore é non nullo. Sequenzializzando le triple non nulle i,j,k con un nuovo indice v (come "v-oxel") il tutto si presenta come il seguente problema:

    dbv wb = Dv

    wb 3 0
    La cui risoluzione é complicata dalla grossa dimensione della matrice dbv e per la condizione di positivitá imposta sulle fluenze. In tal senso comunque si stanno portando avanti, studi con buoni risultati su matrici non troppo grandi con metodi di inversione iterativi.

  • Inversione Locale Se,viceversa, le condizioni geometriche sono tali che si riesca a partizionare i voxel della CT in modo che vi siano insiemi di voxel attraversati da una corrispondente partizione dei beams, allora la inversione puó avvenire a livello locale, nel senso che il calcolo delle fluenze viene circostanziato ad un ben preciso numero di voxel molto minore di quello totale e questo semplifica moltissimo le cose soprattutto se il rilascio di dose sui singoli voxel presenta una struttura tale da consentire il trattamento del problema della inversione con un metodo ad approssimazioni successive. Queste condizioni si possono ottenere
    • se la sorgente é sufficientemente lontana da apparire "all'infinito": in questo caso esistono una serie di "file" di voxel attraversati da beams che attraversano solo loro

    • se si appronta una geometria sferica con centro nella sorgente allora a q e f costanti, al variare di r si ha in maniera equivalente una "fila" di voxel. (Questa metodo richiede la traduzione della CT da un sistema di coordinate cartesiano ad un sistema di coordinate polare sferico).

La confluenza tra il metodo di inversione globale attualmente realizzato nella precedente versione di ANCOD (FORTRAN) e la nuova versione ANCOD2 (C++) deve essere ancora realizzata, cosi come si deve ancora realizzare l'approccio a geometria sferica probabilmente molto valido per sorgenti non troppo ravvicinate. La procedura farSource realizza quindi il calcolo di piani di trattamento per sorgenti all'infinito, ma grazie alla struttura ad oggetti del codice l'implementazione degli altri due metodi non dovrebbe risultare troppo onerosa.

4.1.2  Descrizione dettagliata

Load: enLoss,rangeEn,densy

Le seguenti tre istruzioni all'inizio del programma:

RiRjR1 enLoss =  Rijk_restore("/user/ater/nicco/data/enLoss.RiRjR1");
R1R1   rangeEn=  R1R1_restore("/user/ater/nicco/data/rangeEn.RiRjR1");
Rijk   enLoss =RiRjR1_restore("/user/ater/nicco/data/psiDensy.Rijk");

leggono rispettivamente:
  • enLoss Tabella contenente i rilasci di energia espressi in MeV in ogni millimetro in acqua per le particelle in questione ( in questo caso ioni carbonio). Ogni colonna di questa tabella rappresenta una energia specifica iniziale della particella ed ogni riga i rappresenta il rilascio di energia in Mev nell'i-mo millimetro.
    In fig. 4.1 sono rappresentati i rilasci di energia in ogni mm per le curve con picco di Bragg tra i 28 ed i 326 mm.
    Figure 4.1: Deposito di energia per ioni carbonio in funzione della profonditá in acqua.

  • rangeEn La tabella rangeEn serve per memorizzare la relazione tra posizione del picco di Bragg ed energia specifica della particella deducibile dalla tabella enLoss ma con un certo dispendio di calcolo, per questo tale relazione viene "fissata" in questa variabile di tipo R1R1. In realtá osservando la fig. 4.2 si puó constatare che la relazione é molto ben ricostruibile con un polinomio di terzo grado, nel programma si é comunque scelto l'utilizzo di una tabella per maggiore coerenza con i metodi di valutazione del rilascio di energia in ogni voxel (Due valori di z del picco diversi a seconda se forniti dalla interpolazione o dal loro effettivo valore in tabella avrebbero potuto creare delle incongruenze nel rilascio di energia stesso).
    Figure 4.2: Posizione del picco di Bragg in funzione della energia specifica per ioni carbonio.

  • densy La matrice densy contiene le densitá dei voxel desunte dalla CT.
    Essa puó essere letta direttamente da un file CT scritto in uno dei vari formati conosciuti dal programma oppure, ed é il caso preso in visione, "ripristinata" con il metodo restore da un file scritto nel formato ASCII previsto per i dati di tipo Rijk.
    In particolare la CT usata in questo caso é quella proveniente dall'istituto PSI la cui lettura era giá stata realizzata in FORTRAN nel programma ANCOD, si sono pertanto aggiunte alcune istruzioni per la memorizzazione della matrice letta su un file in formato .Rijk:
            open(unit=42,FILE='psiDensy.Rijk',status='unknown')
            write(42,*) 'i ','j ','k '
            write(42,*) NPIX,NPIY,NPIZ
            write(42,*) 'dataInThisFileAreInKIJorderKmovesSlowerJFaster'	
            do k=1,NPIZ
            write(42,*) 'k=',k,'###################################'
               do i=1,NPIX
                  write(42,900)( densy(i,j,k),j=1,NPIY)
               end do
            end do
            close(42)
      900   format(100(f6.3,1x))
    
    
    ed il file prodotto costituisce la sorgente CT sulla quale é stato testato il programma.
    Tale CT ha come soggetto il cranio di un paziente; é possibile vederne le prime sezioni in fig. 4.3.
    Le sezioni sono disposte con indice k crescente lungo l'altezza (piedi/capo), l'indice i sull'asse x e l'indice j sull'asse y.
    Si possono notare il palato superiore,i lobi ed il padiglione destro delle orecchie e, in generale, la forma del cranio sezionato su un piano a z costante.
    Figure 4.3: Curve di livello per le densitá della CT proveniente dal PSI.

Dichiarazione geometria dei volumi e della sorgente

Dopo aver caricato la CT e le tabelle relative al rilascio di energia le seguenti istruzioni definiscono la geometria del problema:
GridBox TTV( 0*cm,0 *cm, 0*cm,  134,1.594*mm  ,113,1.594*mm  ,98,1.594*mm );
int3Vector TGVposInsideTTV(40,40,40);
int3Vector dimOfTGV(20,20,2);
Hep3Vector source(-400*cm,8.61*cm,7.97*cm);

La prima istruzione indica al programma che il volume della CT (ToTal Volume) é posizionato al centro del sistema di riferimento adottato (0*cm,0*cm,0*cm...), ha 134*113*98 voxel ognuno di dimensione 1.594*1.594*1.549 mm.
La seconda istruzione individua la posizione del target volume rispetto al volume della CT: il voxel [0,0,0] del bersaglio coincide con il voxel[40,40,40] della CT. La terza istruzione fornisce le dimensioni del target volume in voxel: 20*20*2. L'ultima istruzione, infine, fornisce la posizione della sorgente nello spazio rispetto al sistema di riferimento della CT. Le seguenti istruzioni servono per la stampa della geometria definita:
cout<<"(All lenghts are in mm)"<< endl;
cout<<"TTV:"<< TTV << endl;
cout<< "Lower & Upper limits:"<< TTV.lowerCorner()<< " " 
                              <<TTV.higherCorner()<<endl;
cout<<"TGV:"<< TGV << endl;
cout<< "Lower & Upper limits:"<< TGV.lowerCorner()<< " " 
                              <<TVV.higherCorner()<<endl;
cout<<"Source:" << source << endl;\

e producono il seguente risultato:

(All lenghts are in mm)

TTV:
Origin          : (0,0,0)
Number of Voxels: [134,113,98]
Voxel dimensions: (1.594,1.594,1.594)
Lower & Upper limits:(0,0,0) (213.596,180.122,156.212)

TGV:
Origin          : (63.76,63.76,63.76)
Number of Voxels: [10,10,10]
Voxel dimensions: (1.594,1.594,1.594)
Lower & Upper limits:(63.76,63.76,63.76) (79.7,79.7,79.7)

Source:(-4000,86.1,79.7)


Ciclo di spot sull'intero bersaglio

Il ciclo principale del programma é quello che realizza la "scansione" del target volume: per ogni suo voxel si prevede uno spot la cui energia e intensitá sará valutata all'interno del ciclo stesso:
for( iz=0; iz<TGV.nVoxels().k();iz++){
   for( iy=0; iy<TGV.nVoxels().j();iy++){
      for( ix=0; ix< TGV.nVoxels().i()  ;ix++){
         ...
         ...
         ...
      }
   }
}

Definizione del "beam"

Viene a questo punto istituita l'entitá "beam" che sará fondamentale per lo studio della traettoria:
IX=ix+TGVposInsideTTV.i();
IY=iy+TGVposInsideTTV.j();
IZ=iz+TGVposInsideTTV.k();
spotInd = int3Vector(IX,IY,IZ);
spot    = TTV.centerPosition(spotInd);
Line beam(source,spot);

IX,IY,IZ sono gli indici del voxel sul quale é puntato lo spot rispetto al volume CT (TTV), spotInd é la versione vettore dei suddetti tre indici, spot é la posizione nello spazio del centro del voxel e beam é la linea che parte dalla sorgente (source) e passa attraverso il centro di quel voxel (spot).

Ricerca delle intersezioni

Istituita la linea-traettoria del fascio vengono ricercate le intersezioni con tutti i piani che costituiscono il volume bersaglio (a condizione che tali intersezioni esistano e non siano "all'infinito"):
BeamOrthogonalToX=false;
BeamOrthogonalToY=false;
BeamOrthogonalToZ=false;
if(abs((source.x()-spot.x()))< ParallelismLimit)BeamOrthogonalToX=true;
if(abs((source.y()-spot.y()))< ParallelismLimit)BeamOrthogonalToY=true;
if(abs((source.z()-spot.z()))< ParallelismLimit)BeamOrthogonalToZ=true;

if(!BeamOrthogonalToX){
  for(double x=TTV.lowerCorner().x();
             x<=TTV.higherCorner().x();
             x+=TTV.voxDims().x()        )
  {
    tempPoint= beam.intersectionPlaneX(x);
    if(TTV.include(tempPoint))
    {
      vect_distUintersPnt[iInters].dist=source.distance(tempPoint);
      vect_distUintersPnt[iInters].intersPnt=tempPoint;
      iInters++;
    }
  }
}

if(!BeamOrthogonalToY){....}
if(!BeamOrthogonalToZ){....}


Le prime sei istruzioni servono ad accertarsi che vi siano intersezioni: ParallelismLimit é un numero molto piccolo che garantisce che intersezioni piú distanti di 1010 mm non vengano neanche trattate, altrimenti il calcolatore andrebbe in errore da "overflow".
Accertata la condizione di "intersezioni in zona utile" (Not BeamOrthogonalTo..) si esegue il ciclo su tutti i piani del bersaglio ( for .... ) e si memorizza l'intersezione tra il beam ed il piano; tale intersezione potrebbe comunque non appartenere al volume bersaglio, per questo motivo si effettua un test prima di memorizzare definitivamente l'intersezione nell'insieme delle intersezioni trovate (vect_distUintersPnt) aggiornandone il conteggio (iInters++).
Il vettore vect_distUintersPnt contiene dei dati che sono l'unione ("U") tra la distanza dalla origine (dist) e le coordinate della intersezione (intersPnt), con tali coppie di dati sará infatti possibile ordinare tutte le intersezioni sulla base della loro distanza dall'origine ricostruendo cosí il percorso del fascio attraverso le superfici che delimitano i voxel. Le ultime due "istruzioni" stanno ad indicare che le medesime considerazioni fatte per i piani "X" vanno fatte anche per i piani "Y" e "Z".

Ordinamento delle intersezioni

L'istruzione:
sort(vect_distUintersPnt.begin(),&vect\_distUintersPnt[iInters-1])
Ordina il vettore vect_distUintersPnt sulla base di un criterio fornito in precedenza:
bool operator <(const distUintersPnt &x,const  distUintersPnt &y)
{
  return x.dist < y.dist ;
}
cioé sulla base della distanza.
Va notato che il metodo "sort" é applicabile unicamente alla classe "vector" delle STL (Standard Template Libraries) e necessita dei seguenti passaggi:
  1. Inclusione degli appositi file header
    #include <vector>
    #include <algorithm>
    #include <functional>
    	
    

  2. Definizione di un tipo chiaveOrdinatoria-dato
    struct distUintersPnt{
      double dist;
      Hep3Vector intersPnt;
    };
    	
    

  3. Dichiarazione di un vettore contenente dati del tipo appena definito
    vector<distUintersPnt> vect_distUintersPnt(NmaxIntersections);
    	
    

  4. Definizione di un criterio di ordinamento
    bool operator <(const distUintersPnt &x,const  distUintersPnt &y)
    {
      return x.dist < y.dist ;
    }
    	
    

  5. Utilizzo vero e proprio
    sort(vect_distUintersPnt.begin(),&vect_distUintersPnt[iInters-1]);
    	
    

Elaborazione e memorizzazione delle quantitá inerenti un singolo beam

In un ciclo su tutte le intersezioni del beam vengono calcolate e memorizzate le entrate dei seguenti vettori:
  • vintersInd[] Indici (rispetto al TTV) del voxel incluso tra due intersezioni.

  • vpath[] Distanza percorsa all'interno del voxel (equivalente alla differenza delle distanze dalla sorgente delle due intersezioni).

  • vWEpath[] Distanza percorsa all'interno del voxel in termini di acqua-equivalente (WE Water Equivalent), pari alla distanza percorsa moltiplicata per la densitá di quel voxel.

  • vWEpathTot[] Distanza totale (in termini di acqua-equivalente) percorsa per arrivare sino al punto di uscita dal voxel.

  • vWEspotCenter[] Distanza totale (in termini di acqua-equivalente) percorsa per arrivare sino al centro del voxel.

for(int ii=0;ii<nInters-1;ii++)
{
   middlePnt=(vect_distUintersPnt[ii].intersPnt+
              vect_distUintersPnt[ii+1].intersPnt) *0.5;
   vintersInd[ii]=TTV.insideWhichVoxel(middlePnt);
   vpath[ii]=vect_distUintersPnt[ii].intersPnt.
             distance(vect_distUintersPnt[ii+1].intersPnt);
   vWEpath[ii]=vpath[ii]*densy.get(vintersInd[ii]);
   WEpathTot+=vWEpath[ii];
   vWEpathTot[ii]=WEpathTot;
   vWEspotCenter[ii]=vWEpathTot[ii]- vWEpath[ii]/2;
   if(vintersInd[ii]==spotInd)iSPOT=ii;
}

L'ultima istruzione serve a memorizzare in quale posizione sequenziale si trova il voxel verso il quale era diretto lo spot (una volta che le intersezioni sono state ordinate).

Calcolo del rilascio di energia in ogni voxel

A questo punto del programma si conosce la posizione (in acqua-equivalente) del voxel verso il quale é diretto lo spot:
zpeak=vWEspotCenter[iSPOT];

E' quindi possibile calcolare l'energia necessaria al fine di avere un picco di Bragg in quella posizione:
E=rangeEn.linInterpolation(zpeak);

Occorre adesso stabilire quanta energia rilascerá in ogni voxel una particella avente energia E al fine di poter calcolare le fluenze.
Sorgono quindi i seguenti problemi:
  1. Elaborare una curva per il rilascio di energia in funzione di z una volta stabilito che la particella dovrá avere energia E.

  2. Utilizzando questa curva valutare il rilascio di energia tra z1 e z2 punti di entrata e di uscita (in acqua-equivalente) di ogni singolo voxel.

Per quanto concerne il primo problema si é deciso di adoperare una strategia passibile di miglioramento ma che, giá usata nella precedente versione di ANCOD, ha dato buoni risultati:
traslare una curva di Bragg con zpeak prossimo a quello cercato quel tanto che basta (in avanti o indietro) da posizionare il picco di Bragg esattamente nella z desiderata.
In pratica si assume che inserendo o togliendo un pezzo di plateu iniziale dalla curva la curva ottenuta non differisca molto da quella che ci si aspetta (fig. 4.1).
Per il secondo problema si é invece realizzata una subroutine rebinning che dato un istogramma con il numero di conteggi ed il limite destro di ogni colonna (bin) é in grado di riassestare i conteggi su una serie di limiti destro diversa (con larghezze variabili).
In questo caso anziché conteggi si tratta di MeV ma il principio é lo stesso: é come se si conoscesse il numero di pietre comprese tra una traversina e l'altra di un binario ferroviario e si volesse ricalcolare il numero di pietre qualora le traversine vengano poste in una diversa posizione. Le z presenti nella tabella enLoss rappresentano la posizione delle traversine prima del "rebinning", le z nel vettore vWEpathTot quelle dopo. La subroutine rebinning ha quattro argomenti principali: i vettori E,zE,V,zV che rappresentano le energie rilasciate prima (E) e dopo(V) il reb"Calling ghostscript to convert zImages/finale12.EPSF to zImages/finale12.EPSF.gif , please wait ..." "Calling ghostscript to convert zImages/finale13.EPSF to zImages/finale13.EPSF.gif , please wait ..." inning e le rispettive z dei bin (zE e zV).
E,zE,zV costituisco l'input della subroutine, V (Voxel) l'output.
Vi é inoltre un quinto parametro nV che indica il numero di bin del vettore in uscita. Non scendendo troppo nei particolari si puó semplicemente dire che il primo bin del vettore E sará quello che tiene conto della traslazione della curva di Bragg secondo un parametro dR che valuta appunto l'entitá di questa traslazione, il vettore zV é giá dato da vWEpathTot e la subroutine rebinning lavora su una algoritmo che si basa sul simultaneo avanzamento lungo i due sistemi di bins con calcolo della energia in base alla "proporzione di traversina" raggiunta da una parte o dall'altra.

Memorizzazione della matrice dE(beam,voxel) per la "fila" di voxel in questione

I dati relativi al rilascio di energia in ogni voxel da parte del beam corrente devono essere memorizzati per tutti i beam facenti parte della "fila" per la successiva inversione locale, in particolare se si vuole pianificare una dose costante all'interno del target volume bisogna trsformare l'energia rilasciata in ogni voxel nella relativa dose, questo viene realizzato dividendo l'energia rilasciata per la massa del volume stesso:
for(int ii=0; ii<nInters-1;ii++){
 dEvox.put(iBEAM,ii,(V[ii]*MeVtoJoule)/
          (voxVolume*densy.get(vintersInd[ii])*10E-6)   );
}
\\ 1 gm/cm3 = 10^(-3)kg/10^(3)mm3 --> *10E-6

Nel terzo argomento del metodo "put" viene realizzata la conversione da MeV/voxel a Gray: J/kg. Alla fine del ciclo sulla "fila" dEvox (dichiarata di tipo RiRjR1) conterrá il rilascio di dose sopra indicato.

Stampa dei dati relativi ad un singolo spot

Per ogni spot é possibile stampare una serie di informazioni sul beam stesso: le istruzioni
cout << "Beam =  " << beam     << endl;
cout << "spotInd " << spotInd  << endl;
cout << "spotPos " << spot     << endl;
cout << "zpeak = " << zpeak    << endl;
cout << "En = " << En << "MeV" <<endl;

Producono la seguente stampa:
Beam = from (-4000,86.1,79.7) to (64.557,64.557,64.557)
spotInd     [40,40,40]
spotPos     (64.557,64.557,64.557)
zpeak = 24.5792
En = 98.5742 MeV

Inoltre é possibile stampare le informazioni relative a tutti i voxel attraversati:
for(int ii=0; ii<nInters-1;ii++){
      cout << setw(4) << ii
           << " " << vect_distUintersPnt[ii].intersPnt
           << " " << setw(10) << vect_distUintersPnt[ii].dist
           << " " << setw(10) << vpath[ii]
           << " " << vintersInd[ii]
           << " " << setw(10) << densy.get(vintersInd[ii])
           << " " << setw(10) << vWEpath[ii]
           << " " << setw(10) << vWEpathTot[ii]
           << " " << setw(10) << D[ii]
           << " " << setw(10) << D[ii]*MeVtoJoule
           << " " << setw(10) << dEvox.get(iBEAM,ii)
           << endl;
    }

Intestazione a parte, le precedenti istruzioni producono la stampa in fig. 4.4 e fig. 4.5  .
Figure 4.4: Stampa dei risultati relativi ad un singolo spot (parte 1).
Fig"Calling ghostscript to convert zImages/fine.EPSF to zImages/fine.EPSF.gif , please wait ..." ure 4.5: Stampa dei risultati relativi ad un singolo spot (parte 2).

Calcolo della fluenza

A questo punto del programma, finito il ciclo sulla "linea", la matrice dEvox contiene il rilascio di dose in ogni voxel: occorre soltanto piú calcolare le fluenze giuste al fine di ottenere la dose desiderata (in questa caso fissata ad 1 Gray).
A tal fine la subroutine findFluence ha come parametri la matrice dEvox, la posizione del target volume all'interno della fila di voxel attraversata ( TGVposInsideTTV.i() ), la sua dimensione ( dimOfTGV.i() ) e restituisce un dato di tipo R1R1 contenente la fluenza elaborata su ogni voxel del TTV (quindi saranno tutte nulle tranne quelle nel TGV) e la dose rilasciata in quel voxel.
Le seguenti istruzioni:
R1R1 fluence = findFluence(dEvox,TGVposInsideTTV.i(),dimOfTGV.i() );
cout << fluence<< endl;

Produranno la stampa (giá intestata) della due colonne di numeri fluenza-dose della quale vengono qui riportate le sole righe dei voxel vicini al bersaglio:
0                       0.59612
0                       0.59622
0                       0.59812
0                       0.6035
0                       0.61325
0                       0.6284
0                       0.65186
0                       0.67924
0                       0.70519
0                       0.73203
0                       0.75916
0                       0.79259
0                       0.83806
0                       0.90455
1.5767e+05                    1
1.6444e+05                    1
1.963e+05                     1
1.9463e+05                    1
2.7161e+05                    1
2.8179e+05                    1
2.9948e+05                    1
3.8605e+05                    1
4.7864e+05                    1
1.4235e+06                    1
0                       0.1206
0                       0.030101
0                       0.02549
0                       0.021223
0                       0.018836
0                       0.016561
0                       0.015258
0                       0.014262
0                       0.012307
0                       0.011043
0                       0.010058
0                       0.0091796
0                       0.0084665

Si puó notare (fig. 4.6)
Figure 4.6: Energie,fluenze e dosi teoriche rilasciate per una sezione del piano di trattamento elaborato.
che la subroutine riesce a elaborare un plateu assolutamente piatto (con differenze minori del quinto decimale), va comunque evidenziato che questo é il rilascio teorico di dose mentro quello reale (ottenibile attraverso la simulazione con GEANT) potrebbe differire abbastanza a causa delle molteplici approssimazioni introdotte nel programma.

Memorizzazione del piano di trattamento completo

Ripetendo le operazioni sin qui esaminate per una "fila" di voxel su tutte le "file" facenti parte del bersaglio e memorizzando le coordinate degli spot effettuati insieme alla loro energia e alla fluenza calcolata si hanno le cinque colonne di dati che costituiscono il piano di trattamento stesso: X Y Z n E.

4.2  Dosi teoriche rilasciate dal piano di trattamento prodotto

In fig. 4.6 sono riportate le energie, le fluenze e le dosi teoriche rilasciate per una particolare sezione e per una particolare fila di voxel (iz=41,iy=41) nel piano di trattamento (con ioni carbonio) elaborato per la CT proveniente dall'istituto GSI.
Viceversa nella figura 4.7 sono visualizzate le dosi rilasciate in tut"Calling ghostscript to convert zImages/ris10.EPSF to zImages/ris10.EPSF.gif , please wait ..." "Calling ghostscript to convert zImages/WSOBP1.EPSF to zImages/WSOBP1.EPSF.gif , please wait ..." "Calling ghostscript to convert zImages/WSOBP2.EPSF to zImages/WSOBP2.EPSF.gif , please wait ..." "Calling ghostscript to convert zImages/WSOBP3.EPSF to zImages/WSOBP3.EPSF.gif , please wait ..." "Calling ghostscript to convert zImages/WSOBP4.EPSF to zImages/WSOBP4.EPSF.gif , please wait ..." te le sezioni e tutte le file con il medesimo piano di trattamento.
Figure 4.7: Dose teorica (in Gray) rilasciata dal piano di trattamento elaborato dal programma ANCOD2.

4.3  Utilizzo di ANCOD2 nella valutazione del SOBP in acqua per ioni carbonio

Il programma ANCOD2 é stato utilizzato per confermare alcuni risultati sul plateu iniziale di un SOBP (Spread Out Bragg Peak) realizzato con ioni carbonio al variare della sua profonditá massima. I risultati sono raccolti nelle figure fig. 4.8, 4.9, 4.10, 4.11 e coincidono largamente con quelli confrontati. Si puó notare che al crescere della profonditá la qualitá del plateu si deteriora fino ad assumere valori di dose maggiori di quelli nel SOBP stesso. Questo dipende dal fatto che mentre il picco di dose viene rilasciato in punti a z diverse, il plateu é sostanzialmente lo stesso (a paritá di z) per tutti gli spot e questo fa si che la dose si accumuli fino a condurre a questo risultato.
L'aggravarsi del fenomeno al crescere della profonditá del picco dipende viceversa dalla forma del rilascio di energia che alle alte energie presenta un pronunciamento iniziale seguito da una diminuizione che precede il picco vero e proprio (come si puó notare in fig. 4.1).
Figure 4.8: Fluenze e dosi calcolate per un SOBP in acqua realizzato con ioni carbonio alla profonditá di 100-150 mm.
Figure 4.9: Fluenze e dosi calcolate per un SOBP in acqua realizzato con ioni carbonio alla profonditá di 150-200 mm.
Figure 4.10: Fluenze e dosi calcolate per un SOBP in acqua realizzato con ioni carbonio alla profonditá di 200-250 mm.

Figure 4.11: Fluenze e dosi calcolate per un SOBP in acqua realizzato con ioni carbonio alla profonditá di 250-300 mm.

 

 

 

Appendice A: I file CART chapterAppendice A: I file CART

Il formato file CART per le CT

Il programma CadPlan External Beam Modeling, utilizzato dall'istituto IRCC (Istituto per la Ricerca e la Cura del Cancro) di Candiolo (To) gestisce immagini mediche provenienti da piú sorgenti con un unico formato di file chiamato CART. In questo file sono contenute informazioni riguardanti il tipo di immagine (PET,CT,NMR), le informazioni peculiari al tipo di immagine (esempio per le CT i numeri di Hounsfield) ed inoltre altre informazioni aggiunte in seguito come l'identificazione dei contorni degli organi ed il contorno del volume bersaglio. Per le CT ogni slice vienememorizzata su un singolo file il cui nome ne costituisce l'identificativo secondo le seguenti regole:
nome file = ddmmyyxxx.znn
dove
  • dd mm yy xxxz rappresentano giorno, mese, anno, sequenziale del paziente.

  • nn (0..99) numero della slice

Il file é costituito da 269 record di lunghezza costante di 512 byte il cui contenuto é il seguente:

    Record Amministrativo

  • Record 1 Contiene dati riguardanti il paziente, l'unitá diagnostica, informazioni sulla orientazione, scala e locazione delle slice, i singoli campi di questo record sono rappresentati nella tabella 4.1
    Table 4.1: Record 1
    Offset Parametro Significato Tipo
    0 FYLTYP identificativo del tipo di file = 6 Int 16 bit
    2 NSLICE numero di slices nel file = 1 Int 16 bit
    4 LENGHT numero totale di records Int 16 bit
    6 STBLK offset del primo record contenente dati Int 16 bit
    8 FLDATE data creazione file=anno*512+mese*32+giorno Int 16 bit
    10 IMORGN disp. diagn.:1000-1999=CT;-2999=NMR;-3999PETInt 16 bit
    12 ZPOS posizione relativa della slice in mm Int 16 bit
    14 NX dim. x della matrice = 256 Int 16 bit
    16 NY dim. y della matrice = 256 Int 16 bit
    18 XPXSZE dimensione fisica del pixel lungo x (*1000)Int 16 bit
    20 YPXSZE dimensione fisica del pixel lungo y (*1000)Int 16 bit
    22 DX num. righe NON memorizzate Int 16 bit
    24 DY num. colonne NON memorizzate Int 16 bit
    26 STATUS 0 se ROI non memorizzato, 1 viceversa Int 16 bit
    28 free Int 16 bit
    92 ROIBIT marker se ROI memorizzato Int 16 bit
    108 ORIENT orien.slice(0-4):ignoto,transv.,cor.,sag.,portfilm Int 16 bit
    110 PATORI orientamento del paziente Int 16 bit
    112 free Int 16 bit
    140 SEQNO numero di sequenza interno alla CT Char
    152 SCDATE data della scansione Char
    164 CTTYP tipo dispositivo diagnostico Char
    204 HSPNAM nome della clinica/ospedale Char
    244 PATID identificativo del paziente Char
    260 PATNAM nome del paziente Char
    300 CMNTS1 commenti 1 Char
    340 CMNTS2 commenti 2 Char
    380 CMNTS3 commenti 3 Char
    420 CMNTS4 commenti 4 Char
    460 REX coordinata x per slice saggitale (cm) Real 32 bit
    464 REY coordinata y per slice coronale (cm) Real 32 bit
    468 RPX REX in pixel Int 16 bit
    470 RPY REY in pixel Int 16 bit
    472 ISET_Z 1 se REZ ha dati validi Int 16 bit
    474 free Int 16 bit
    476 REZ coordinata z nel pixel centrale (riga 128) Real 32 bit
    480 free Int 16 bit

  • Record 2 Vuoto.

    Record Contorni

  • Record 3 Contiene informazioni sui contorni, in particolare il numero di punti costituenti ogni contorno.(Tab. 4.2)
    Table 4.2: Record 3
    Offset Parametro Significato Tipo
    0 nPNTS[10] Numero di pnti in ogni contorno 6 Int 8 bit
    10 CMTS1 Commenti Char
    41 IDSPWW Larghezza finestra immagine Int 8 bit
    42 IDSPWL Posizione finestra immagine Int 8 bit
    44 CMTS2 Commenti Char

  • Record 4 Coppie di coordinate per il contorno "Body" (esterno)

  • Record 5,6,7,8,9 Coppie di coordinate per le aree 1,2,3,4,5.

  • Record 10 Coppie di coordinate per il contorno "target"

  • Record 11,12,13 Coppie di coordinate per le regioni di interesse 1,2,3.

    Record Dati

  • Record 14-259 Per le CT questi record contengono i numeri di Hounsfield addizionati del valore 1000. Questi numeri sono rappresentati come interi a 16 bit considerando l'immagine come vista dai piedi del paziente partendo dallo spigolo in basso a sinistra muovendosi verso destra e poi verso l'alto.

Per quanto riguarda la calibrazione per la derivazione delle densitá elettroniche (in relazione alla densitá elettronica dell'acqua) dai numeri di Hounsfield viene adottata la seguente calibrazione:
rw;e = A0+B0*NCT   con   NCT 1100

rw;e = A1+B1*NCT   con   NCT > 1100
con
A0=0.0; B0=0.001; A1=0.572; B1=0.00048; 
In fig. 4.12 si possono osservare alcune slices di una tomografia dell'addome-bacino lette dal programma readCandiolo .
Nella visualizzazione sono state istituite poche classi di densitá per evidenziare meglio le strutture anatomiche: si possono facilmente individuare i polmoni, la cassa toracica e la spina dorsale (Le scale sull'asse X e Y sono differenti). In fig. 4.13 sono visualizzati tutti i contorni presenti nella CT, in particolare nella slice numero 30 il contorno piú marcato é quello che individua il target volume e compare unicamente nelle slice comprese tra la numero 22 e la numero 32. (fig. 4.14)
Figure 4.12: Immagini CT lette da file scritti in formato CART.
Figure 4.13: Contorni per l'individuazione degli organi e del volume da trattare.
Figure 4.14: Il volume piú marcato, al centro, é il volume da trattare.
Appendice B: I file DICOM

Lo standard per lo scambio di immagini mediche DICOM

Introduzione storica

Con l'introduzione della tomografia computerizzata (CT) e di altre modalita' di diagnostica per immagini elettroniche, nonche' con il sempre maggior utilizzo di computer nell'ambito delle applicazioni cliniche, l'American College of Radiology (ACR) ed il National Electrical Manufacturers Association (NEMA) hanno riconosciuto l'esigenza di un metodo standard per il trasferimento di immagini ed informazioni ad esse associate tra macchine realizzate da diverse industrie.
Nel 1983 l'ACR ed il NEMA hanno formato un comitato (ACR-NEMA) per sviluppare uno standard in grado di:
  • Promuovere la comunicazione di immagini digitali e correlativi dati

  • Facilitare lo sviluppo e l'espansione dell'archiviazione di immagini interfacciabili con altri strumenti di gestione dell'informazione clinica-ospedaliera

  • Consentire la creazione di data base diagnostici consultabili in rete da una larga varieta' di dispositivi.

Nel 1985 e nel 1988 l'ACR-NEMA ha pubblicato rispettivamente la versione 1.0 e 2.0 dello standard hardware, software e classificatorio delle informazioni (data elements).

Lo standard DICOM

Lo standard ACR-NEMA prende il nome DICOM (Digital Imaging and Communication in Medicine) ed attualmente e' alla version 3.0 . Esso fornisce un protocollo di comunicazione compatibile con il TCP/IP (quello usato da internet) che consente di realizzare dei veri e propri Server DICOM che sono macchine in grado di lavorare autonomamente ricevendo ed inviando file DICOM via rete. Piu' semplici ma non meno importanti sono invece i Browser DICOM che sono tool che consentono di visualizzare, editare, gestire localmente file DICOM. A grandi line, in 15 documenti ( Part1-Part15) ed in 50 supplementi ( Supp1-Supp50),reperibili al sito
http://idt.net/~dclunie/dicom-status/status.html#BaseStandard1999

si trovano tutti i formati dei dati trasmessi (spiegati dal record fino al bit) e la classificazione dei data elements. Qualora per qualche motivo il sito non fosse accessibile si riesce comunque abba stanza in fretta convergere verso questa documentazione con un motore di ricerca quale www.google.com ricercando "DICOM" (sono tutti file PDF leggibili sotto unix con il comando "gv" o sotto Windows o Mac tramite pluggin "Acrobat Reader" scaricabile da rete )

I DATA ELEMENTS

La filosofia dei DICOM files e' la seguente: Ogni DICOM file e' una collezione non ordinata di "record logici" dove ogni " record logico" e' costituito da
  • TAG : Identificativo del Data Element (sono stati catalogati parecchie centinaia di dati che vanno dalla dimensione e numero di immagini alla dose prevista per una terapia fino ai dati anagrafici del paziente ,la struttura ospedaliera la calibrazione di una CT, l'indicazione che si tratta di una PET,etc...)

  • LENGTH: Specifica che i succesivi N dati apparterranno al data element in questione (che puo' quindi essere ad ampiezza variabile)

  • DATA ELEMENT: Il dato vero e proprio.(es. 256*256 numeri di Hounsfield)

Un esempio di DICOM file e' stato prelevato dal sito:
ftp://ftp.philips.com/pub/ms/dicom/Medical_Images, i suoi contenuti sono illustrati nella pagina seguente e nella fig. 4.15  .

Posizione                 
  del      |TAG|     Lunghezza 
 byte                       --> Dato associato dal 'DICOM BROWSER' realizzato in C++ (non sono presenti tutti)    

  00]   | 0| 8| 0| 0|  (  4) -->
  12]   | 0| 8| 0| 5|  ( 10) -->
  30]   | 0| 8| 0| 8|  ( 30) --> Image Type= ORIGINAL\PRIMARY\AXIAL\VOLUME
  68]   | 0| 8| 0|16|  ( 26) --> SOP Class UID= 1.2.840.10008.5.1.4.1.1.2
 102]   | 0| 8| 0|18|  ( 48) --> SOP Instance UID= 1.3.46.670589.10.1.1.2158435922.934292566.34615.
 158]   | 0| 8| 0|20|  (  8) --> Study Date= 19990810
 174]   | 0| 8| 0|21|  (  8) -->
 190]   | 0| 8| 0|23|  (  8) --> Image Date= 19990810
 206]   | 0| 8| 0|30|  ( 14) --> Study Time= 151329.234768
 228]   | 0| 8| 0|31|  ( 14) -->
 250]   | 0| 8| 0|33|  ( 14) --> Image Time= 154139.000000
 272]   | 0| 8| 0|50|  (  0) --> Accession Number=
 280]   | 0| 8| 0|60|  (  2) --> Modality=  CT
 290]   | 0| 8| 0|70|  ( 24) --> Manufacturer= Philips Medical Systems
 322]   | 0| 8| 0|80|  ( 10) --> Institution Name= Philips CT
 340]   | 0| 8| 0|90|  (  0) --> Referring Physician's Name=
 348]   | 0| 8|10|10|  (  2) --> Station Name=
 358]   | 0| 8|10|30|  (  2) --> Study Description=
 368]   | 0| 8|10|40|  ( 10) -->
 386]   | 0| 8|10|50|  (  0) -->
 394]   | 0| 8|10|60|  (  0) -->
 402]   | 0| 8|10|90|  ( 12) --> Manufacturer's Model Name= Tomoscan CS
 422]   | 0| 8|11|40|  (110) -->
 540]   | 0|10| 0| 0|  (  4) -->
 552]   | 0|10| 0|10|  ( 22) --> Patient's Name= CT Aura-Secura^Example
 582]   | 0|10| 0|20|  ( 14) --> Patient ID= ID200631zw609
 604]   | 0|10| 0|30|  (  8) --> Patient's Birth Date= 19991213
 620]   | 0|10| 0|40|  (  2) --> Patient's Sex= M
 630]   | 0|18| 0| 0|  (  4) -->
 "Calling ghostscript to convert zImages/dic1.EPSF to zImages/dic1.EPSF.gif , please wait ..."
642]   | 0|18| 0|10|  (  4) --> Contrast/Bolus Agent= NONE
 654]   | 0|18| 0|50|  (  8) --> Slice Thickness= 5.000000
 670]   | 0|18| 0|60|  ( 10) --> KVP= 120.000000
 688]   | 0|18|10|20|  ( 18) --> Software Version(s)= CT Backend R1.1L1
 714]   | 0|18|10|30|  ( 22) -->
 744]   | 0|18|11| 0|  ( 10) -->
 762]   | 0|18|11|20|  (  8) --> Gantry/Detector Tilt= 0.000000
 778]   | 0|18|11|30|  ( 10) --> Table Height=  38.000000
 796]   | 0|18|11|50|  (  4) --> Exposure Time= 1000
 808]   | 0|18|11|51|  (  4) -->
 820]   | 0|18|11|52|  (  4) --> Exposure=  100
 832]   | 0|18|12| 0|  (  8) --> Date of Last Calibration= 19990810
 848]   | 0|18|12| 1|  ( 14) --> Time of Last Calibration= 083759.582871
 870]   | 0|18|12|10|  (  4) --> Convolution Kernel= AA0
 882]   | 0|18|51| 0|  (  4) --> Patient Position= HFS
 894]   | 0|20| 0| 0|  (  4) -->
 906]   | 0|20| 0| D|  ( 48) --> Study Instance= 1.3.46.670589.10.1.1.2158435922.934290809.23985.
 962]   | 0|20| 0| E|  ( 48) --> Series Instance= 1.3.46.670589.10.1.1.2158435922.934292556.78163.
1018]   | 0|20| 0|10|  (  0) --> Study ID=
1026]   | 0|20| 0|11|  (  2) --> Series Number= 19
1036]   | 0|20| 0|12|  (  2) --> Acquisition Number=  1
1046]   | 0|20| 0|13|  (  2) --> Instance Number=  1
1056]   | 0|20| 0|32|  ( 42) --> Image Position (Patient)=  -2.042221e+02\-1.818909e+02\-1.570000e+02
1106]   | 0|20| 0|37|  ( 78) --> Image Orientation (Patient)=  1.000000e+00\0.000000e+00\0.000000e+00\0.00000..
1192]   | 0|20| 0|52|  ( 48) --> Frame of Reference= 1.3.46.670589.10.1.1.2158435922.934292075.37016.
1248]   | 0|20|10|40|  (  0) --> Position Reference Indicator=
1256]   | 0|20|10|41|  ( 12) -->
1276]   | 0|20|40| 0|  (  0) --> Image Comments=
1284]   | 0|28| 0| 0|  (  4) -->
1296]   | 0|28| 0| 2|  (  2) --> Samples per Pixel=
1306]   | 0|28| 0| 4|  ( 12) --> Photometric Interpretation= MONOCHROME2
1326]   | 0|28| 0|10|  (  2) --> Rows= 512
1336]   | 0|28| 0|11|  (  2) --> Columns= 512
1346]   | 0|28| 0|30|  ( 26) --> Pixel Spacing=  7.105113e-01\7.105113e-01
1380]   | 0|28| 1| 0|  (  2) --> Bits Allocated=
1390]   | 0|28| 1| 1|  (  2) --> Bits Stored=
1400]   | 0|28| 1| 2|  (  2) --> High Bit=
1410]   | 0|28| 1| 3|  (  2) --> Pixel Representation=
1420]   | 0|28|10|50|  ( 26) --> Window Center=  4.000000e+01\7.000000e+01
1454]   | 0|28|10|51|  ( 26) --> Window Width=  4.000000e+02\2.000000e+02
1488]   | 0|28|10|52|  ( 12) --> Rescale Intercept= -1200.000000
1508]   | 0|28|10|53|  (  8) --> Rescale Slope= 1.000000
1524]   |7F|E0| 0| 0|  (  4) -->
1536]   |7F|E0| 0|10|(524288)--> Pixel Data=

Figure 4.15: Immagine CT letta da file in formato DICOM.

Indice Analitico (showing section)

Lista delle figure

    1.1  Rappresentazione schematica dei processi di perdita di energia per una particella carica pesante.
    1.2  Carica efficace secondo la formula di Barkas in funzione della energia specifica.
    1.3  Comparazione tra la perdita di energia misurata con quella teorica in funzione della energia specifica.
    1.4  Curva integrale e differenziale dei percorsi di particelle cariche pesanti nella materia.
    1.5  Densitá di ionizzazione in funzione della profonditá.
    1.6  Scattering in acqua di elettroni a 5 keV.
    1.7  Comparazione tra le tracce di un protone e di uno ione carbonio.
    1.8  Distribuzione radiale della dose attorno alla traccia di una particella.
    1.9  Contributi delle due modalitá di perdita di energia di elettroni in funzione della loro energia.
    1.10  Traettoria di un elettrone all'interno della materia e practical range.
    1.11  Sezione d'urto totale e contributi dei differenti processi per fotoni in carbonio, in funzione dell'energia.
    1.12  Specie reattive prodotte nella radiolisi dell'acqua.
    2.1  Rappresentazione dei dati sperimentali della dipendenza della RBE dal LET.
    2.2  Rappresentazione schematica del DNA e delle tracce di un elettrone e di una particella a che lo attraversano.
    2.3  Percentuale di sopravvivenza per cellule irradiate in presenza o in assenza di O2.
    2.4  OER in funzione del LET per vari tipi di radiazioni.
    2.5  Curve dose-effetto.
    2.6  Curve dose-profonditá per fasci di elettroni.
    2.7  Curve dose-profonditá per fasci di fotoni.
    2.8  Curve dose-profonditá per fotoni, neutroni e protoni.
    2.9  Picco di Bragg allargato (SOBP) per fasci di protoni e ioni.
    2.10  Confronto tra le distribuzioni di dose di fasci di protoni e di elettroni su un bersaglio.
    2.11  Sistema di scanning per tomografia.
    2.12  Distribuzione dei numeri TC per i vari tessuti del corpo umano.
    2.13  Curve di isodose per trattamento con protoni ad intensitá modulata.
    2.14  Struttura schematica di un sistema a scansione magnetica.
    2.15  Sistemi di scansione: a) raster b) voxel.
    4.1  Deposito di energia per ioni carbonio in funzione della profonditá in acqua.
    4.2  Posizione del picco di Bragg in funzione della energia specifica per ioni carbonio.
    4.3  Curve di livello per le densitá della CT proveniente dal PSI.
    4.4  Stampa dei risultati relativi ad un singolo spot (parte 1).
    4.5  Stampa dei risultati relativi ad un singolo spot (parte 2).
    4.6  Energie,fluenze e dosi teoriche rilasciate per una sezione del piano di trattamento elaborato.
    4.7  Dose teorica (in Gray) rilasciata dal piano di trattamento elaborato dal programma ANCOD2.
    4.8  Fluenze e dosi calcolate per un SOBP in acqua realizzato con ioni carbonio alla profonditá di 100-150 mm.
    4.9  Fluenze e dosi calcolate per un SOBP in acqua realizzato con ioni carbonio alla profonditá di 150-200 mm.
    4.10  Fluenze e dosi calcolate per un SOBP in acqua realizzato con ioni carbonio alla profonditá di 200-250 mm.
    4.11  Fluenze e dosi calcolate per un SOBP in acqua realizzato con ioni carbonio alla profonditá di 250-300 mm.
    4.12  Immagini CT lette da file scritti in formato CART.
    4.13  Contorni per l'individuazione degli organi e del volume da trattare.
    4.14  Il volume piú marcato, al centro, é il volume da trattare.
    4.15  Immagine CT letta da file in formato DICOM.

Bibliografia

[1]
E. Chiavassa, L. Ramello, E. Vercellin
Rivelatori di particelle: Appunti dalle lezioni di fisica dei neutroni
La scienza editrice-Torino 1991
[2]
U. Amaldi, B. Larsson, Y. Lemoigne
Advances in Hadrontherapy
Elsevier Science B.V. 1997
[3]
H.E. Johns and J.R. Cunningham
The Physics of Radiology
Charles and Thomas Pubblisher
Springfield,Illinois
[4]
International Commission on Radiation Unit and Measurements,
Radiations quantities,ICRU Rep.30,
Washington D.C. (1980).
[5]
U. Amaldi and Silari editors
The TERA project and the centre for oncological hadrotherapy
INFN-Ufficio Pubblicazioni
Seconda edizione (1995)
[6]
J.E. Coggle
Effetti biologici delle radiazioni
Edizioni Minerva Medica (1985)
[7]
G. Kraft
The radiobiological and physical basis for radiotherapy with protons and heavier ions
Strahlenther.Onkol. 166;10:13 (1990)
[8]
S. Webb
The physics of medical imaging
Institute of Physics Publishing, Bristol and Philadelphia (1988)
[9]
E. Hall
Radiobiology for the Radiologist
Philadelphia:J.B.Lippincott Co. (1994)
[10]
H. Barrett, W. Swindell
Radiological Imaging
Academic Press, Inc (London) (1981)
[11]
S. Webb
The physics of three-dimensional radiation therapy
Institute of Physics Publishing, Bristol and Philadelphia (1993)
[12]
Guido Buzzi-Ferraris
Dal Fortran al C++
Addison-Wesley Publishing Company Milano(1994)
[13]
Bjarne Strousstrup
The C++ Programming Language
Addison-Wesley
[14]
J.J.Barton,L.R. NackMan
Scientific and Engineering C++
Addison-Wesley Publishing Company,Inc. (1995)
[15]
Herbert Schildt
Teach Yourself C++
Osborne McGraw-Hill(1994)
[16]
R.Stallman,R.McGrath
GNU Make
Free Software Foundation (1995)
[17]
CERN
http://wwwinfo.cern.ch/asd/lhcpp/clhep/manual/userguide
[18]
A.edE. Spoletini
Il linguaggio Fortran
Franco Angeli Editore Milano (1983)
[19]
Rogue Wave
Standard C++ library
Rogue Wave Software,Corvallis Oregon US
[20]
CERN
PAW: Physic Analysis Workstation, an introductory tutorial
CERN Program Library entry Q121
[21]
J.Peek T.Reilly and M.Louvides
Unix Power Tools
Editor Tim O'Reilly Sebastopol,CA,U.S. (1994)
[22]
Root Educational Resources ad Fermilabs
http://www-pat.fnal.gov/root
[23]
J.K.Ousterhout
Tcl and the TK toolkit
Addison-Wesley Publishing Company(1994)
 

Footnotes:

1Positron Emission Tomography: tomografia ad emissione di positroni
2Nuclear Magnetic Resonance: risonanza magnetica nucleare.


File translated from TEX by TTH, version 3.22.
On 26 Mar 2003, 21:48.