Pydicom, Datenspeicherung

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
WoLF6i9
User
Beiträge: 2
Registriert: Dienstag 12. Januar 2021, 13:39

Guten Tag alle zusammen,
Ich habe erst vor ein paar Wochen mit Python angefangen und komme einfach nicht weiter ... (wär hätte es gedacht...). Ich habe vieles mittlerweile (für mich) lösen können, aber zu dem jetzigen Problem habe ich im Internet und in Foren noch nichts gefunden (vllt. Formuliere ich ja einfach die Suchanfrage immer falsch?).

Ziel des Programms:
Ich versuche momentan ein Programm zu schreiben, welches einmal pro Tag ausgeführt werden soll. Dabei soll dieses Programm alle, an diesem Tag erstellten, DICOM SR (Structured Reporting) auslesen und bestimmte Daten rausziehen. Diese sollen dann abgespeichert werden und Später in eine Datenbank exportiert werden.

Das Problem:
Mein Problem ist es Momentan, die Daten, die ich auslesen will, als Variable zu speichern und wieder abrufen zu können, da die DICOM Dateien unterschiedlich viele Datenstrukturen besitzen und ich auch nicht weiß wie viele Dateien pro Tag ausgelesen werden. Momentan habe ich es geschafft die Daten als dictionary zu speichern, bekomme es aber nicht hin diese wieder abzurufen (weiß auch nicht ob das eine gute bzw. sinnvolle Lösung ist).

Würde mich über Vorschläge bzw. Hilfestellungen freuen :).

Der Code:

Code: Alles auswählen

#####Imports#####
import pydicom
from pathlib import Path
import os
import collections
import datetime

#####dictionary#####
def erzeuge_var(ID, Organ, CTDI1, DLP1, CTDI2, DLP2, CTDI3, DLP3):
    globals()[Time.value] = ID.value ,Organ, CTDI1, DLP1, CTDI2, DLP2, CTDI3, DLP3

####Zu durchsuchenden Pfad angeben#####
now =datetime.date.today()
date = now.strftime('%Y%m%d')
destination = '/Testdaten/'+date

####Variabeln definieren#####
suffixes = []
i=0
#####Anzahl der Datein zählen#####
for root, dirs, files in os.walk(destination):  # root = Path, dirs = folders, files = files

    for file in Path(str(root)).iterdir():
            if file.stem == 'SR000000': 
                suffixes.append(file.suffix) # Für die Anzahl der gezählten Dateien
extensions = collections.Counter(suffixes)
print('\nDateien insgesamt:', len(suffixes))

#####Main#####
for root, dirs, files in os.walk(destination):  # root = Path, dirs = folders, files = files
    
        for file in Path(str(root)).iterdir():
            if i< len(suffixes):
                if file.stem == 'SR000000': 
                    ver=root+'/SR000000.dcm'
                    data=pydicom.dcmread(ver)  
                    try: 
                        if len(data.ContentSequence)<=12: 
                            #####Datenpfade#####
                            ID=data[0x0010, 0x0020]
                            Time=data[0x0008, 0x0030]
                            CTDI1=data.ContentSequence[9][0x0040, 0xa730][6][0x0040, 0xa730][0][0x0040, 0xa300][0][0x0040, 0xa30a]
                            CTDI1=CTDI1.value
                            mGy1=data.ContentSequence[9][0x0040, 0xa730][6][0x0040, 0xa730][0][0x0040, 0xa300][0][0x0040, 0x08ea][0][0x0008, 0x0100]
                            DLP1=data.ContentSequence[9][0x0040, 0xa730][6][0x0040, 0xa730][2][0x0040, 0xa300][0][0x0040, 0xa30a]
                            DLP1=DLP1.value
                            mGycm1=data.ContentSequence[9][0x0040, 0xa730][6][0x0040, 0xa730][2][0x0040, 0xa300][0][0x0040, 0x08ea][0][0x0008, 0x0100]
                            Organ=data[0x7005, 0x100d]
                            #####Nicht vorhandene Variablen#####
                            CTDI2=0
                            DLP2=0
                            CTDI3=0
                            DLP3=0
                            #####Unnötige Zeichen entfernen#####
                            Organ=str(Organ.value)
                            Organ=Organ.replace("b'","")
                            Organ=Organ.replace("'", "")
                            #####Variable erzeugen#####
                            erzeuge_var(ID, Organ, CTDI1, DLP1, CTDI2, DLP2, CTDI3, DLP3)
                            #####Ausgabe###
                            print("")
                            print(ID.value)
                            print(Organ)
                            print("CTDI_1", CTDI1, mGy1.value)
                            print("DLP_1", DLP1, mGycm1.value)
                            
                        elif 14>=len(data.ContentSequence)>13:
                            #####Datenpfade#####
                            ID=data[0x0010, 0x0020]
                            Time=data[0x0008, 0x0030]
                            CTDI1=data.ContentSequence[9][0x0040, 0xa730][6][0x0040, 0xa730][0][0x0040, 0xa300][0][0x0040, 0xa30a]
                            CTDI1=CTDI1.value
                            mGy1=data.ContentSequence[9][0x0040, 0xa730][6][0x0040, 0xa730][0][0x0040, 0xa300][0][0x0040, 0x08ea][0][0x0008, 0x0100]
                            DLP1=data.ContentSequence[9][0x0040, 0xa730][6][0x0040, 0xa730][2][0x0040, 0xa300][0][0x0040, 0xa30a]
                            DLP1=DLP1.value
                            mGycm1=data.ContentSequence[9][0x0040, 0xa730][6][0x0040, 0xa730][2][0x0040, 0xa300][0][0x0040, 0x08ea][0][0x0008, 0x0100]
                            
                            CTDI2=data.ContentSequence[10][0x0040, 0xa730][6][0x0040, 0xa730][0][0x0040, 0xa300][0][0x0040, 0xa30a]
                            CTDI2=CTDI2.value
                            mGy2=data.ContentSequence[10][0x0040, 0xa730][6][0x0040, 0xa730][0][0x0040, 0xa300][0][0x0040, 0x08ea][0][0x0008, 0x0100]
                            DLP2=data.ContentSequence[10][0x0040, 0xa730][6][0x0040, 0xa730][2][0x0040, 0xa300][0][0x0040, 0xa30a]
                            DLP2=DLP2.value
                            mGycm2=data.ContentSequence[10][0x0040, 0xa730][6][0x0040, 0xa730][2][0x0040, 0xa300][0][0x0040, 0x08ea][0][0x0008, 0x0100]
                            
                            CTDI3=data.ContentSequence[11][0x0040, 0xa730][6][0x0040, 0xa730][0][0x0040, 0xa300][0][0x0040, 0xa30a]
                            CTDI3=CTDI3.value
                            mGy3=data.ContentSequence[11][0x0040, 0xa730][6][0x0040, 0xa730][0][0x0040, 0xa300][0][0x0040, 0x08ea][0][0x0008, 0x0100]
                            DLP3=data.ContentSequence[11][0x0040, 0xa730][6][0x0040, 0xa730][2][0x0040, 0xa300][0][0x0040, 0xa30a]
                            DLP3=DLP3.value
                            mGycm3=data.ContentSequence[11][0x0040, 0xa730][6][0x0040, 0xa730][2][0x0040, 0xa300][0][0x0040, 0x08ea][0][0x0008, 0x0100]
                            Organ=data[0x7005, 0x100d]
                            totalDLP=data.ContentSequence[6][0x0040, 0xa730][1][0x0040, 0xa300][0][0x0040, 0xa30a]
                            mGycmtotal=data.ContentSequence[6][0x0040, 0xa730][1][0x0040, 0xa300][0][0x0040, 0x08ea][0][0x0008, 0x0100]
                            #####Unnötige Zeichen entfernen#####
                            Organ=str(Organ.value)
                            Organ=Organ.replace("b'","")
                            Organ=Organ.replace("'", "")
                            #####Variable erzeugen#####
                            erzeuge_var(ID, Organ, CTDI1, DLP1, CTDI2, DLP2, CTDI3, DLP3)
                            #####Ausgabe#####
                            print("")
                            print(ID.value)
                            print(Organ)
                            print("CTDI_1", CTDI1, mGy1.value)
                            print("DLP_1", DLP1, mGycm1.value)
                            
                            print("CTDI_2", CTDI2, mGy2.value)
                            print("DLP_2", DLP2, mGycm2.value)
                            
                            print("CTDI_3", CTDI3, mGy3.value)
                            print("DLP_3", DLP3, mGycm3.value)
                            print("Total DLP", totalDLP.value, mGycmtotal.value)
                            
                        else:
                            print("Diese Datenstruktur ist größer")
                            
                    except AttributeError:
                        print(" ")
                        print('In diesem Datensatz:"', ver, '" befinden sich nicht die erforderlichen Datensequenzen!')
                    i+=1
Der Code ist nicht der schönste und man kann bestimmt vieles besser lösen, als ich es tat, aber ich bin ein Neuling und es hat halt in dem Moment funktioniert :D.

Die Print Ausgaben sind für mich einfach um zu kontrollieren.
Vielen Dank.

Viele Grüße
WoLF6i9
Sirius3
User
Beiträge: 18274
Registriert: Sonntag 21. Oktober 2012, 17:20

Vergiss gleich wieder dass es global, bzw globals überhaupt gibt. Damit löst man kein Problem. Du möchtest wirklich ein Wörterbuch verwenden.
Du benutzt Time in erzeuge_var, also eine globale Variable, dieser Fehler kann die nicht passieren, wenn Du alles in Funktionen packst.
Warum verwendest Du os.walk um danach ein Path-Objekt zu erzeugen. Benutze gleich Path und seine Methoden.
Was Du da mit suffixes machst, verstehe ich nicht, was ist der Sinn hinter dieser Schleife?

Code: Alles auswählen

destination = Path("/Testdaten") / f"{datetime.date.today():%Y%m%d}"
for filename in destination.rglob("SR000000.*"):
    suffixes.append(filename.suffix)
Pfade setzt man auch nicht mit + zusammen, dafür gibt es ja Path.

Variablennamen sollten aussagekräftig sein (ver was?), und werden komplett klein geschrieben.

Der Block innerhalb der for-Schleife ist dann deutlich zu lang und sollte in mehrer Funktionen verteilt werden.
Die vielen Indizes blickt niemand durch, da kann man nur hoffen, dass das alles so korrekt ist.
Die beiden if-Blöcke enthalten zum Großteil identischen Code, können also zusammengefasst werden.
Die Stringrepräsentation eines Bytes-Objekt dient nicht zur Weiterverarbeitung, sondern nur zu Debuggzwecken. Du möchtest wahrscheinlich decode benutzen.
Ein AttributeError ist eigentlich ein Programmierfehler. Da solltest Du den Bereich des Fehlers noch genauer eingrenzen.

Dieses Tuple mit 7 Elementen ist nicht die beste Art der Datenstruktur. Besser wäre ein namedtuple oder gleich eine Klasse.

Code: Alles auswählen

def get_data(was_auch_immer):
    CTDI = was_auch_immer[0][0x0040, 0xa300][0][0x0040, 0xa30a].value
    mGy = was_auch_immer[0][0x0040, 0xa300][0][0x0040, 0x08ea][0][0x0008, 0x0100].value
    DLP = was_auch_immer[2][0x0040, 0xa300][0][0x0040, 0xa30a].value
    mGycm = was_auch_immer[2][0x0040, 0xa300][0][0x0040, 0x08ea][0][0x0008, 0x0100].value
    return CTDI, mGy, DLP, mGycm

def main():
    all_data = {}
    destination = Path("/Testdaten") / f"{datetime.date.today():%Y%m%d}"
    for filename in destination.rglob("SR000000.dcm"):
        data = pydicom.dcmread(filename)
        if len(data.ContentSequence)<=12 or 13 < len(data.ContentSequence) <= 14:
            data_id = data[0x0010, 0x0020].value
            time = data[0x0008, 0x0030].value
            CTDI1, mGy1, DLP1, mGycm1 = get_data(data.ContentSequence[9][0x0040, 0xa730][6][0x0040, 0xa730])
            if len(data.ContentSequence) > 13:
                CTDI2, mGy2, DLP2, mGycm2 = get_data(data.ContentSequence[10][0x0040, 0xa730][6][0x0040, 0xa730])
                CTDI3, mGy3, DLP3, mGycm3 = get_data(data.ContentSequence[11][0x0040, 0xa730][6][0x0040, 0xa730])
            else:
                CTDI2, mGy2, DLP2, mGycm2 = 0, 0, 0, 0
                CTDI3, mGy3, DLP3, mGycm3 = 0, 0, 0, 0

            organ = data[0x7005, 0x100d].value.decode("ASCII")
            all_data[time] = (data_id, CTDI1, DLP1, CTDI2, DLP2, CTDI3, DLP3)

            print("")
            print(data_id)
            print(organ)
            print("CTDI_1", CTDI1, mGy1)
            print("DLP_1", DLP1, mGycm1)
            if len(data.ContentSequence) > 13:
            else:
                was_auch_immer = data.ContentSequence[6][0x0040, 0xa730][1][0x0040, 0xa300][0]
                totalDLP = was_auch_immer[0x0040, 0xa30a].value
                mGycmtotal = was_auch_immer[0x0040, 0x08ea][0][0x0008, 0x0100].value
                
                print("CTDI_2", CTDI2, mGy2)
                print("DLP_2", DLP2, mGycm2)
                
                print("CTDI_3", CTDI3, mGy3)
                print("DLP_3", DLP3, mGycm3)
                print("Total DLP", totalDLP, mGycmtotal)
        else:
            print("Diese Datenstruktur ist größer")
                
if __name__ == '__main__':
    main()
WoLF6i9
User
Beiträge: 2
Registriert: Dienstag 12. Januar 2021, 13:39

Vielen Dank für die schnelle und ausführliche Hilfe :). Ich brauchte zwar etwas um alles für mich vollständig nachvollziehen zu können, aber mit ein paar Veränderungen funktioniert jetzt alles einwandfrei :D!
Antworten