-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathdicomsort.sh
executable file
·142 lines (123 loc) · 4.39 KB
/
dicomsort.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#!/bin/bash
#############
#This script use the afni programs dicom_hdr and dicom_hinfo to read header information,
#reads the information and then renames and sorts the files alphabetically, optionally
#creating subdirectories for each series. AFNI must be installed locally for
#this script to work
#Written by Michael Worden
#Updated 02/07/2024 to add support for optionally creating subject and series
#subdirectories
#Updated 03/15/2024 to name subdirectories by Series Description instead of Protocol Name
#############
set -euo pipefail
#defaults
sourcedir='./'
destdir='renamed'
tempfile='/tmp/dicomsort.tmp'
rename=0
recurse=1
usesubdir=0
subdir=''
useseqdir=0
seqdir=''
#DICOM field tags
snumtag='0020,0011' #series number
anumtag='0020,0012' #acquisition number
inumtag='0020,0013' #instance number
nametag='0010,0010' #patient name
idtag='0010,0020' #patient ID
sdesctag='0008,103e' #protocol name
usage='Usage: dicomsort [-r] [-d destdir] [-s sourcedir] [-i] [-q] [-n] [-h]'
helptxt="dicom sort is a script to sort rename dicom files in alphabetical order according to\n\
series and slice number. AFNI must be installed on the local computer to use dicomsort."
#process command line options
while getopts ":rd:s:iqnh" options; do
case $options in
r ) rename=1;;
d ) destdir=$OPTARG;;
s ) sourcedir=$OPTARG;;
i ) usesubdir=1;;
q ) useseqdir=1;;
n ) recurse=0;;
h ) echo "$usage";;
\? ) echo "$usage"
echo -e "$helptxt"
# echo "dicom sort is a script to sort rename dicom files in alphabetical"
# echo "order according to series and slice number. "
echo "Options:"
echo "-r: rename files. Default is to copy."
echo "-d: destination directoroy. Default is ./renamed ."
echo "-s: source directory. Default is current directory"
echo "-i: put files in a directory named by the subjectID."
echo "-q: put files in separate sub-directories for each sequence."
echo "-n: don't recursively descend into subdirectories."
echo "-?: print this help message."
echo "-h: print brief usage message."
exit 1;;
* ) echo "$usage"
exit 1;;
esac
done
#check to see if the destdir exists and create it if not
if [ -d "$destdir" ]; then
echo Destination directory exists
else
echo Creating "$destdir"
mkdir "$destdir"
fi
targdir="$destdir"
echo "Procecessing..."
#build a list of all the non-hidden files in the target directory
if [ "$recurse" -eq 1 ]; then
files=$(find "$sourcedir" -type f ! -name ".*" ! -iname "DICOMDIR")
else
files=$(find "$sourcedir" -type f -maxdepth 1 ! -name ".*" ! -iname "DICOMDIR")
fi
for f in $files;
do
echo "$f"
#We are only using dicom_hdr to recognize dicom files now. This seems clunky
#and could probably be sped up in the future. All valid dicom files should have
#the text DICM at offset 0x80 and we could just look for that in the future but
#this is okay for now
dicom_hdr "$f" > "$tempfile"
# make sure it's a dicom file
if grep 'ERROR:' "$tempfile"; then
continue
fi
# Now using dicom_hinfo to get specific tags instead of dicom_hdr and grep
snum=$(dicom_hinfo -tag "$snumtag" -no_name "$f")
anum=$(dicom_hinfo -tag "$anumtag" -no_name "$f")
if [ "$anum" = "null" ]; then
anum=0
fi
inum=$(dicom_hinfo -tag "$inumtag" -no_name "$f")
#If we want to use the the subject ID as an enclosing directory, check to see if
#it exists and create it if not
if [ "$usesubdir" -eq 1 ]; then
subdir=$(dicom_hinfo -tag "$nametag" -no_name "$f")
targdir="$destdir"/"$subdir"
mkdir -p "${targdir}"
fi
#If we want to use subdirectories for each series, check to see if
#it exists for the current series and create it if not. The series name
#should be prepended with a series number in case there are multiple
#series with the same sequence name.
if [ "$useseqdir" -eq 1 ]; then
seqdir=$(dicom_hinfo -tag "$sdesctag" -no_name "$f")
serpre=$(printf "%02.0f_" "$snum")
targdir="$destdir"/"$subdir"/"$serpre$seqdir"
mkdir -p "${targdir}"
fi
targfile=$(printf "%s/dcmS%04.0fA%04.0fI%04.0f\n" "$targdir" "$snum" "$anum" "$inum")
echo "Series ${snum}, Acquisition ${anum}, Instance ${inum}"
if [ "$rename" -eq 1 ]; then
echo RENAMING "$f" to "$targfile"
mv "$f" "$targfile"
else
echo COPYING "$f" to "$targfile"
cp "$f" "$targfile"
fi
done
rm "$tempfile"
echo dicomsort Complete