15
15
set_readonly ,
16
16
clear_temp_dicoms ,
17
17
seqinfo_fields ,
18
+ assure_no_file_exists ,
19
+ file_md5sum
18
20
)
19
21
from .bids import (
20
22
convert_sid_bids ,
@@ -102,15 +104,35 @@ def prep_conversion(sid, dicoms, outdir, heuristic, converter, anon_sid,
102
104
if not op .exists (idir ):
103
105
os .makedirs (idir )
104
106
105
- shutil .copy (heuristic .filename , idir )
106
107
ses_suffix = "_ses-%s" % ses if ses is not None else ""
107
108
info_file = op .join (idir , '%s%s.auto.txt' % (sid , ses_suffix ))
108
109
edit_file = op .join (idir , '%s%s.edit.txt' % (sid , ses_suffix ))
109
110
filegroup_file = op .join (idir , 'filegroup%s.json' % ses_suffix )
110
111
112
+ # if conversion table(s) do not exist -- we need to prepare them
113
+ # (the *prepare* stage in https://github.com/nipy/heudiconv/issues/134)
114
+ reuse_conversion_table = op .exists (edit_file )
115
+ # We also might need to redo it if changes in the heuristic file
116
+ # detected
117
+ # ref: https://github.com/nipy/heudiconv/issues/84#issuecomment-330048609
118
+ # for more automagical wishes
119
+ target_heuristic_filename = op .join (idir , op .basename (heuristic .filename ))
120
+ # TODO:
121
+ # 1. add a test
122
+ # 2. possibly extract into a dedicated function for easier logic flow here
123
+ # and a dedicated unittest
124
+ if not reuse_conversion_table and \
125
+ op .exists (target_heuristic_filename ) and \
126
+ file_md5sum (target_heuristic_filename ) != file_md5sum (heuristic .filename ):
127
+ reuse_conversion_table = False
128
+ lgr .info (
129
+ "Will not reuse existing conversion table files because heuristic "
130
+ "has changed"
131
+ )
132
+
111
133
# MG - maybe add an option to force rerun?
112
134
# related issue : https://github.com/nipy/heudiconv/issues/84
113
- if op . exists ( edit_file ) and overwrite :
135
+ if reuse_conversion_table :
114
136
lgr .info ("Reloading existing filegroup.json "
115
137
"because %s exists" , edit_file )
116
138
info = read_config (edit_file )
@@ -124,6 +146,8 @@ def prep_conversion(sid, dicoms, outdir, heuristic, converter, anon_sid,
124
146
else :
125
147
# TODO -- might have been done outside already!
126
148
# MG -- will have to try with both dicom template, files
149
+ assure_no_file_exists (target_heuristic_filename )
150
+ safe_copyfile (heuristic .filename , idir )
127
151
if dicoms :
128
152
seqinfo = group_dicoms_into_seqinfos (
129
153
dicoms ,
@@ -133,6 +157,8 @@ def prep_conversion(sid, dicoms, outdir, heuristic, converter, anon_sid,
133
157
seqinfo_list = list (seqinfo .keys ())
134
158
filegroup = {si .series_id : x for si , x in seqinfo .items ()}
135
159
dicominfo_file = op .join (idir , 'dicominfo%s.tsv' % ses_suffix )
160
+ # allow to overwrite even if was present under git-annex already
161
+ assure_no_file_exists (dicominfo_file )
136
162
with open (dicominfo_file , 'wt' ) as fp :
137
163
fp .write ('\t ' .join ([val for val in seqinfo_fields ]) + '\n ' )
138
164
for seq in seqinfo_list :
@@ -141,7 +167,9 @@ def prep_conversion(sid, dicoms, outdir, heuristic, converter, anon_sid,
141
167
info = heuristic .infotodict (seqinfo_list )
142
168
lgr .debug ("Writing to {}, {}, {}" .format (info_file , edit_file ,
143
169
filegroup_file ))
170
+ assure_no_file_exists (info_file )
144
171
write_config (info_file , info )
172
+ assure_no_file_exists (edit_file )
145
173
write_config (edit_file , info )
146
174
save_json (filegroup_file , filegroup )
147
175
@@ -152,7 +180,7 @@ def prep_conversion(sid, dicoms, outdir, heuristic, converter, anon_sid,
152
180
else :
153
181
tdir = op .join (anon_outdir , anon_sid )
154
182
155
- if converter != 'none' :
183
+ if converter . lower () != 'none' :
156
184
lgr .info ("Doing conversion using %s" , converter )
157
185
cinfo = conversion_info (anon_sid , tdir , info , filegroup , ses )
158
186
convert (cinfo ,
@@ -220,8 +248,8 @@ def convert(items, converter, scaninfo_suffix, custom_callable, with_prov,
220
248
os .makedirs (prefix_dirname )
221
249
222
250
for outtype in outtypes :
223
- lgr .debug ("Processing %d dicoms for output type %s" ,
224
- len (item_dicoms ), outtype )
251
+ lgr .debug ("Processing %d dicoms for output type %s. Overwrite=%s " ,
252
+ len (item_dicoms ), outtype , overwrite )
225
253
lgr .debug ("Includes the following dicoms: %s" , item_dicoms )
226
254
227
255
seqtype = op .basename (op .dirname (prefix )) if bids else None
@@ -245,7 +273,8 @@ def convert(items, converter, scaninfo_suffix, custom_callable, with_prov,
245
273
246
274
bids_outfiles = save_converted_files (res , item_dicoms , bids ,
247
275
outtype , prefix ,
248
- outname_bids )
276
+ outname_bids ,
277
+ overwrite = overwrite )
249
278
250
279
# save acquisition time information if it's BIDS
251
280
# at this point we still have acquisition date
@@ -258,11 +287,18 @@ def convert(items, converter, scaninfo_suffix, custom_callable, with_prov,
258
287
prov_files .append (prov_file )
259
288
260
289
tempdirs .rmtree (tmpdir )
290
+ else :
291
+ raise RuntimeError (
292
+ "was asked to convert into %s but destination already exists"
293
+ % (outname )
294
+ )
261
295
262
296
if len (bids_outfiles ) > 1 :
263
297
lgr .warning ("For now not embedding BIDS and info generated "
264
298
".nii.gz itself since sequence produced "
265
299
"multiple files" )
300
+ elif not bids_outfiles :
301
+ lgr .debug ("No BIDS files were produced, nothing to embed to then" )
266
302
else :
267
303
embed_metadata_from_dicoms (bids , item_dicoms , outname , outname_bids ,
268
304
prov_file , scaninfo , tempdirs , with_prov ,
@@ -330,10 +366,11 @@ def convert_dicom(item_dicoms, bids, prefix,
330
366
outfile = op .join (dicomdir , op .basename (filename ))
331
367
if not op .islink (outfile ):
332
368
# TODO: add option to enable hardlink?
333
- if symlink :
334
- os .symlink (filename , outfile )
335
- else :
336
- os .link (filename , outfile )
369
+ # if symlink:
370
+ # os.symlink(filename, outfile)
371
+ # else:
372
+ # os.link(filename, outfile)
373
+ shutil .copyfile (filename , outfile )
337
374
338
375
339
376
def nipype_convert (item_dicoms , prefix , with_prov , bids , tmpdir ):
@@ -350,7 +387,6 @@ def nipype_convert(item_dicoms, prefix, with_prov, bids, tmpdir):
350
387
convertnode .base_dir = tmpdir
351
388
convertnode .inputs .source_names = item_dicoms
352
389
convertnode .inputs .out_filename = op .basename (op .dirname (prefix ))
353
- convertnode .inputs .terminal_output = 'allatonce'
354
390
convertnode .inputs .bids_format = bids
355
391
eg = convertnode .run ()
356
392
@@ -365,7 +401,7 @@ def nipype_convert(item_dicoms, prefix, with_prov, bids, tmpdir):
365
401
return eg , prov_file
366
402
367
403
368
- def save_converted_files (res , item_dicoms , bids , outtype , prefix , outname_bids ):
404
+ def save_converted_files (res , item_dicoms , bids , outtype , prefix , outname_bids , overwrite ):
369
405
"""Copy converted files from tempdir to output directory.
370
406
Will rename files if necessary.
371
407
@@ -396,8 +432,8 @@ def save_converted_files(res, item_dicoms, bids, outtype, prefix, outname_bids):
396
432
397
433
if isdefined (res .outputs .bvecs ) and isdefined (res .outputs .bvals ):
398
434
outname_bvecs , outname_bvals = prefix + '.bvec' , prefix + '.bval'
399
- safe_copyfile (res .outputs .bvecs , outname_bvecs )
400
- safe_copyfile (res .outputs .bvals , outname_bvals )
435
+ safe_copyfile (res .outputs .bvecs , outname_bvecs , overwrite )
436
+ safe_copyfile (res .outputs .bvals , outname_bvals , overwrite )
401
437
402
438
if isinstance (res_files , list ):
403
439
# we should provide specific handling for fmap,
@@ -421,18 +457,18 @@ def save_converted_files(res, item_dicoms, bids, outtype, prefix, outname_bids):
421
457
422
458
for fl , suffix , bids_file in zip (res_files , suffixes , bids_files ):
423
459
outname = "%s%s.%s" % (prefix , suffix , outtype )
424
- safe_copyfile (fl , outname )
460
+ safe_copyfile (fl , outname , overwrite )
425
461
if bids_file :
426
462
outname_bids_file = "%s%s.json" % (prefix , suffix )
427
- safe_copyfile (bids_file , outname_bids_file )
463
+ safe_copyfile (bids_file , outname_bids_file , overwrite )
428
464
bids_outfiles .append (outname_bids_file )
429
465
# res_files is not a list
430
466
else :
431
467
outname = "{}.{}" .format (prefix , outtype )
432
- safe_copyfile (res_files , outname )
468
+ safe_copyfile (res_files , outname , overwrite )
433
469
if isdefined (res .outputs .bids ):
434
470
try :
435
- safe_copyfile (res .outputs .bids , outname_bids )
471
+ safe_copyfile (res .outputs .bids , outname_bids , overwrite )
436
472
bids_outfiles .append (outname_bids )
437
473
except TypeError as exc : ##catch lists
438
474
raise TypeError ("Multiple BIDS sidecars detected." )
0 commit comments