Repository: mne-tools/mne-bids

Issue:
Overwrite option Error (CTF dataset)
#### Describe the bug
Running write_raw_bids(raw, bids_path) completes successfully.
Rerunning write_raw_bids(raw, bids_path, overwrite=True) Fails

#### Steps to reproduce
import os
import os.path as op
import shutil
import mne
from mne import datasets
from mne_bids import (write_raw_bids, BIDSPath)

dpath = datasets.brainstorm.bst_auditory.data_path()
raw_fname = op.join(dpath, 'MEG/bst_auditory/S01_AEF_20131218_02.ds')

output_path = './bids_out'

raw = mne.io.read_raw_ctf(raw_fname)
raw.info['line_freq'] = 60  # specify power line frequency as required by BIDS

sub = '01'
ses = '01'
task = 'rest'
run = '01'
bids_path = BIDSPath(subject=sub, session=ses, task=task,
                     run=run, root=output_path)
if os.path.exists('./bids_out'): shutil.rmtree('./bids_out/')
os.mkdir('./bids_out')
write_raw_bids(raw, bids_path)

write_raw_bids(raw, bids_path, overwrite=True)

#### Expected results
Expect the overwrite option to overwrite the current dataset.  I expect the error to be related to the directory structure for CTF datasets compared to the single file .fif structure.

#### Actual results
Writing 'bids_out/sub-01/ses-01/meg/sub-01_ses-01_task-rest_run-01_channels.tsv'...

name	type	units	low_cutoff	high_cutoff	description	sampling_frequency	status	status_description
UDIO001	TRIG	V	0.0	1200.0	Trigger	2400.0	good	n/a
UPPT001	TRIG	V	0.0	1200.0	Trigger	2400.0	good	n/a
UTRG001	TRIG	V	0.0	1200.0	Trigger	2400.0	good	n/a
SCLK01-177	MISC	V	0.0	1200.0	Miscellaneous	2400.0	good	n/a
BG1-4408	MEGREFMAG	T	0.0	1200.0	Magnetometer Reference	2400.0	good	n/a
Copying data files to sub-01_ses-01_task-rest_run-01_meg.ds
Traceback (most recent call last):

  File "<ipython-input-2-6f496fbc8041>", line 1, in <module>
    write_raw_bids(raw, bids_path, overwrite=True)

  File "/home/jstout/miniconda3/envs/enigma/lib/python3.8/site-packages/mne_bids/write.py", line 1349, in write_raw_bids
    copyfile_ctf(raw_fname, bids_path)

  File "/home/jstout/miniconda3/envs/enigma/lib/python3.8/site-packages/mne_bids/copyfiles.py", line 156, in copyfile_ctf
    _copytree(src, dest)

  File "/home/jstout/miniconda3/envs/enigma/lib/python3.8/site-packages/mne_bids/copyfiles.py", line 35, in _copytree
    sh.copytree(src, dst, **kwargs)

  File "/home/jstout/miniconda3/envs/enigma/lib/python3.8/shutil.py", line 557, in copytree
    return _copytree(entries=entries, src=src, dst=dst, symlinks=symlinks,

  File "/home/jstout/miniconda3/envs/enigma/lib/python3.8/shutil.py", line 458, in _copytree
    os.makedirs(dst, exist_ok=dirs_exist_ok)

  File "/home/jstout/miniconda3/envs/enigma/lib/python3.8/os.py", line 223, in makedirs
    mkdir(name, mode)

FileExistsError: [Errno 17] File exists: 'bids_out/sub-01/ses-01/meg/sub-01_ses-01_task-rest_run-01_meg.ds'


#### Additional information
MNE version = 0.22
mne-bids = 0.7
OS = Linux ubuntu 18.04



Discussion:
Thanks for the report, @jstout211!

I believe the fix should be simple: we'd have to pass `dirs_exist_ok=True` to `copytree()`

Resolving patch:
diff --git a/mne_bids/write.py b/mne_bids/write.py
--- a/mne_bids/write.py
+++ b/mne_bids/write.py
@@ -1344,10 +1344,16 @@ def write_raw_bids(raw, bids_path, events_data=None,
     # create parent directories if needed
     _mkdir_p(os.path.dirname(data_path))
 
-    if os.path.exists(bids_path.fpath) and not overwrite:
-        raise FileExistsError(
-            f'"{bids_path.fpath}" already exists. '  # noqa: F821
-            'Please set overwrite to True.')
+    if os.path.exists(bids_path.fpath):
+        if overwrite:
+            if bids_path.fpath.is_dir():
+                shutil.rmtree(bids_path.fpath)
+            else:
+                bids_path.fpath.unlink()
+        else:
+            raise FileExistsError(
+                f'"{bids_path.fpath}" already exists. '  # noqa: F821
+                'Please set overwrite to True.')
 
     # If not already converting for anonymization, we may still need to do it
     # if current format not BIDS compliant


Test patch:
diff --git a/mne_bids/tests/test_write.py b/mne_bids/tests/test_write.py
--- a/mne_bids/tests/test_write.py
+++ b/mne_bids/tests/test_write.py
@@ -851,6 +851,7 @@ def test_ctf(_bids_validate, tmpdir):
     raw = _read_raw_ctf(raw_fname)
     raw.info['line_freq'] = 60
     write_raw_bids(raw, bids_path)
+    write_raw_bids(raw, bids_path, overwrite=True)  # test overwrite
 
     _bids_validate(tmpdir)
     with pytest.warns(RuntimeWarning, match='Did not find any events'):