Skip to content

Commit accac90

Browse files
authored
Merge pull request #6 from Inria-Visages/multiAtlasSeg
Multi atlas seg
2 parents 26b785f + 38ecd92 commit accac90

File tree

1 file changed

+127
-0
lines changed

1 file changed

+127
-0
lines changed
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
#!python3
2+
# Warning: works only on unix-like systems, not windows where "python animaAtlasBasedBrainExtraction.py ..." has to be run
3+
4+
import sys
5+
import argparse
6+
import os
7+
import stat
8+
import subprocess
9+
10+
if sys.version_info[0] > 2:
11+
import configparser as ConfParser
12+
else:
13+
import ConfigParser as ConfParser
14+
15+
configFilePath = os.path.expanduser("~") + "/.anima/config.txt"
16+
if not os.path.exists(configFilePath):
17+
print('Please create a configuration file for Anima python scripts. Refer to the README')
18+
quit()
19+
20+
configParser = ConfParser.RawConfigParser()
21+
configParser.read(configFilePath)
22+
23+
animaDir = configParser.get("anima-scripts", 'anima')
24+
animaPyramidalBMRegistration = os.path.join(animaDir, "animaPyramidalBMRegistration")
25+
animaDenseSVFBMRegistration = os.path.join(animaDir, "animaDenseSVFBMRegistration")
26+
animaTransformSerieXmlGenerator = os.path.join(animaDir, "animaTransformSerieXmlGenerator")
27+
animaApplyTransformSerie = os.path.join(animaDir, "animaApplyTransformSerie")
28+
animaConvertImage = os.path.join(animaDir, "animaConvertImage")
29+
animaConcatenateImages = os.path.join(animaDir, "animaConcatenateImages")
30+
animaMajorityLabelVoting = os.path.join(animaDir, "animaMajorityLabelVoting")
31+
32+
# Argument parsing
33+
parser = argparse.ArgumentParser(description="Propagate and fuse segmentations from multiple atlases onto a list of subjects")
34+
35+
parser.add_argument('-i', '--image-file', required=True, type=str, help='list of anatomical images to be segmented (in txt file)')
36+
parser.add_argument('-a', '--anat-file', required=True, type=str, help='list of atlas anatomical images (in txt file)')
37+
parser.add_argument('-s', '--seg-file', required=True, type=str, help='list of atlas label images (segmentations) (in txt file)')
38+
parser.add_argument('-o', '--out-dir', required=True, type=str, help='output directory')
39+
parser.add_argument('-c', '--num-cores', type=int, default=8, help='Number of cores to run on (default: 8)')
40+
41+
args = parser.parse_args()
42+
43+
images = [line.rstrip('\n') for line in open(args.image_file)]
44+
N = len(images)
45+
anats = [line.rstrip('\n') for line in open(args.anat_file)]
46+
P = len(anats)
47+
segs = [line.rstrip('\n') for line in open(args.seg_file)]
48+
49+
if len(segs) != P:
50+
print("The number of atlas anatomical images must be equal to the number of atlas label images")
51+
exit()
52+
53+
outDir = args.out_dir
54+
if not os.path.exists(outDir):
55+
os.makedirs(outDir)
56+
if not os.path.exists(os.path.join(outDir, "err")):
57+
os.makedirs(os.path.join(outDir, "err"))
58+
if not os.path.exists(os.path.join(outDir, "out")):
59+
os.makedirs(os.path.join(outDir, "out"))
60+
if not os.path.exists(os.path.join(outDir, "registrations")):
61+
os.makedirs(os.path.join(outDir, "registrations"))
62+
if not os.path.exists(os.path.join(outDir, "segmentations")):
63+
os.makedirs(os.path.join(outDir, "segmentations"))
64+
65+
for i in range(0, N):
66+
image=images[i]
67+
68+
# Registrations
69+
70+
imagePrefix = os.path.splitext(image)[0]
71+
if os.path.splitext(image)[1] == '.gz':
72+
imagePrefix = os.path.splitext(imagePrefix)[0]
73+
imageBasename = os.path.basename(imagePrefix)
74+
75+
nCoresPhysical = int(args.num_cores / 2)
76+
77+
filename = os.path.join(outDir, "regRun_" + imageBasename)
78+
myfile = open(filename,"w")
79+
myfile.write("#!/bin/bash\n")
80+
if args.num_cores<=16:
81+
myfile.write("#OAR -l {hyperthreading=\'NO\'}/nodes=1/core=" + str(args.num_cores) + ",walltime=01:59:00\n")
82+
myfile.write("#OAR -l {hyperthreading=\'YES\'}/nodes=1/core=" + str(nCoresPhysical) + ",walltime=01:59:00\n")
83+
myfile.write("#OAR --array " + str(P) + "\n")
84+
myfile.write("#OAR -O " + os.path.join(outDir, "out" , imageBasename) + ".%jobid%.output\n")
85+
myfile.write("#OAR -E " + os.path.join(outDir, "err" , imageBasename) + ".%jobid%.error\n")
86+
myfile.write("anats=(" + " ".join(anats) + ")\n")
87+
myfile.write("segs=(" + " ".join(segs) + ")\n")
88+
myfile.write(animaPyramidalBMRegistration + " -m ${anats[$(($OAR_ARRAY_INDEX-1))]} -r " + image + " -o " + os.path.join(outDir, "registrations", imageBasename) + "_${OAR_ARRAY_INDEX}_aff.nrrd -O " + os.path.join(outDir, "registrations", imageBasename) + "_${OAR_ARRAY_INDEX}_aff_tr.txt --sp 3 --ot 2 -p 4 -l 0" + "\n" )
89+
myfile.write(animaDenseSVFBMRegistration + " -m " + os.path.join(outDir, "registrations", imageBasename) + "_${OAR_ARRAY_INDEX}_aff.nrrd -r " + image + " -o " + os.path.join(outDir, "registrations", imageBasename) + "_${OAR_ARRAY_INDEX}_diffeo.nrrd -O " + os.path.join(outDir, "registrations", imageBasename) + "_${OAR_ARRAY_INDEX}_diffeo_tr.nrrd --sr 1 -p 3 -l 0" + "\n" )
90+
myfile.write(animaTransformSerieXmlGenerator + " -i " + os.path.join(outDir, "registrations", imageBasename) + "_${OAR_ARRAY_INDEX}_aff_tr.txt -i " + os.path.join(outDir, "registrations", imageBasename) + "_${OAR_ARRAY_INDEX}_diffeo_tr.nrrd -o " + os.path.join(outDir, "registrations", imageBasename) + "_${OAR_ARRAY_INDEX}_tr.xml\n" )
91+
myfile.write(animaApplyTransformSerie + " -i ${segs[$(($OAR_ARRAY_INDEX-1))]} -g " + image + " -t " + os.path.join(outDir, "registrations", imageBasename) + "_${OAR_ARRAY_INDEX}_tr.xml" + " -o " + os.path.join(outDir, "segmentations", imageBasename) + "_${OAR_ARRAY_INDEX}_seg.nrrd -n nearest\n" )
92+
myfile.close()
93+
94+
os.chmod(filename, stat.S_IRWXU)
95+
oarRunCommand = ["oarsub","-n","reg-" + imageBasename,"-S", filename]
96+
jobsIds = []
97+
procStat = subprocess.Popen(oarRunCommand, stdout=subprocess.PIPE)
98+
for statsLine in procStat.stdout:
99+
if "OAR_JOB_ID" in statsLine:
100+
jobsIds += [statsLine.split("=")[1]]
101+
102+
# Label fusion
103+
104+
listSeg=os.path.join(outDir, "segmentations", imageBasename) + "_listSeg.txt"
105+
segFile = open(listSeg,"w")
106+
for j in range(0, P):
107+
segFile.write(os.path.join(outDir, "segmentations", imageBasename) + "_" + str(j+1) + "_seg.nrrd\n")
108+
segFile.close()
109+
110+
filename2 = os.path.join(outDir, "fuseRun_" + imageBasename)
111+
myfile2 = open(filename2,"w")
112+
myfile2.write("#!/bin/bash\n")
113+
if args.num_cores<=16:
114+
myfile2.write("#OAR -l {hyperthreading=\'NO\'}/nodes=1/core=" + str(args.num_cores) + ",walltime=01:59:00\n")
115+
myfile2.write("#OAR -l {hyperthreading=\'YES\'}/nodes=1/core=" + str(nCoresPhysical) + ",walltime=01:59:00\n")
116+
myfile2.write("#OAR -O " + os.path.join(outDir, "out" , imageBasename) + "_fusion.%jobid%.output\n")
117+
myfile2.write("#OAR -E " + os.path.join(outDir, "err" , imageBasename) + "_fusion.%jobid%.error\n")
118+
myfile2.write(animaMajorityLabelVoting + " -i " + listSeg + " -o " + os.path.join(outDir, imageBasename) + "_consensus_seg.nrrd \n")
119+
myfile2.close()
120+
121+
os.chmod(filename2, stat.S_IRWXU)
122+
oarFuseCommand = ["oarsub","-n","fusion_" + imageBasename,"-S", filename2]
123+
124+
for jobId in jobsIds:
125+
oarFuseCommand += ["-a",jobId]
126+
127+
subprocess.call(oarFuseCommand, stdout=open(os.devnull, "w"))

0 commit comments

Comments
 (0)