#############################################################
# dicomrename.py von onkelpaul.de
#
# Benennt DICOM-Dateien in einem Verzeichnis so um, dass sie
# Seriennummer und Bildnummer im Dateinamen enthalten:
#
# > python dicomrename.py ./DICOM/abcd/efgh -p -d
# 
#   ABCDEF --> 011-0123-Anonymous_Male-ABCDEF
#
# Also Serie 11, Bild 123 von Patient Anonymous_Male.
#
# Die Option -p haengt den Patientennamen an den neuen
# Dateinamen an, die Option -d den alten Dateinamen.
# Die Option -r dreht die Reihenfolge um.
#############################################################
#
# ACHTUNG: Dateien werden nicht kopiert, sondern umbenannt!
#
#############################################################

print "DICOM-Serien umbenennen"
import sys
import os
import dicom

# Wenn kein Verzeichnis angegeben, in dem aktuellen Verzeichnis '.' suchen:
# Erster Parameter ist der Name des Scripts, also sys.argv[0].
if len(sys.argv) == 1:
  path = "."
else:
  path = sys.argv[1]

# Damit es egal ist, ob man zum Schluss einen / (oder \ bei Windows) eingegeben hat:
# Letztes Zeichen ist path[-1], os.sep ist je nach Linux oder Windows / oder \.
# path[:-1] gibt den String vor dem letzten Zeichen, also ggf. ohne os.sep.
if path[-1] == os.sep:
  path = path[:-1]
print "Verzeichnis " + path

# Hole alle Dateien aus dem Verzeichnis:
dicomfiles = [f for f in os.listdir(path) if os.path.isfile(os.path.join(path, f))]

# Jetzt Dateien, die wirklich DICOM sind, zaehlen:
# Wir brauchen die Anzahl, wenn die Reihenfolge umgedreht werden soll.
anzahl = 0
for old_name in dicomfiles:
  try:
    ds = dicom.read_file(path + os.sep + old_name)
    anzahl = anzahl + 1
  except dicom.errors.InvalidDicomError:
    if not old_name[0] == '.': # versteckte Dateien ignorieren
      print old_name + ' IST KEIN DICOM-FILE'
print str(anzahl) + " DICOM-Dateien gefunden"

# Und jetzt werden alle Dateien darauf geprueft, ob sie DICOM sind.
for old_name in dicomfiles:
  try:
    ds = dicom.read_file(path + os.sep + old_name)
    name = ds.PatientsName.family_name
    serie = str(ds.SeriesNumber.numerator)
    
    # Reihenfolge umdrehen?
    if '-r' in sys.argv:
      instance = str(anzahl - ds.InstanceNumber.numerator)
    else:
      instance = str(ds.InstanceNumber.numerator)
      
    # Soll der Patientenname Teil des neuen Namens werden?
    if '-p' in sys.argv:
      add_pat_name = '-' + name.replace(' ', '_')
    else:
      add_pat_name = ''

    # Soll der alte Dateiname Teil des neuen Namens werden?
    if '-d' in sys.argv:
      add_file_name = '-' + old_name
    else:
      add_file_name = ''

    # Fuehrende Nullen fuer Seriennummer auf drei Stellen und Bildnummer auf 4 Stellen. 
    # Damit wird erreicht, dass die Dateisortierung hinterher klappt. Ansonsten 
    # gaebe es bei 11 Dateien sowas wie 1, 10, 11, 2, 3...
    new_name = serie.zfill(3) + '-' + instance.zfill(4) + add_pat_name + add_file_name
    print path + os.sep + old_name + ' --> ' + path + os.sep + new_name
    os.rename(path + os.sep + old_name, path + os.sep + new_name)
  except dicom.errors.InvalidDicomError:
    if not old_name[0] == '.': # versteckte Dateien ignorieren
      print old_name + ' IST KEIN DICOM-FILE'
