123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183 |
- #!/usr/bin/python3
- '''
- created on Wed 19th 2020
- author: Christian Olaf Haeusler
- '''
- from glob import glob
- import argparse
- import os
- import re
- import subprocess
- SUBMIT_CONTENT = [
- '# auto-generate file (generate_1st_level_design.py) -- do not modify!',
- 'universe = vanilla',
- 'output = condor_logs/$(CLUSTER).$(PROCESS).out',
- 'error = condor_logs/$(CLUSTER).$(PROCESS).err',
- 'log = condor_logs/$(CLUSTER).$(PROCESS).log',
- 'getenv = True',
- 'request_cpus = 1',
- 'request_memory = 5000',
- 'should_transfer_files = NO',
- 'transfer_executable = False',
- 'initialdir = /data/project/studyforrest_ppa',
- 'executable = $ENV(FSLDIR)/bin/feat',
- '',
- ]
- def parse_arguments():
- '''
- '''
- parser = argparse.ArgumentParser(
- description='rename and copy the auditory \
- confound files to onset directories')
- parser.add_argument('-fmri',
- default='inputs/studyforrest-data-aligned/sub-01/in_bold3Tp2/sub-01_task-aomovie_run-1_bold.nii.gz',
- help='example 4d fmri file/path from sub-01')
- parser.add_argument('-design',
- default='code/1st-lvl_audio-ppa-grp.fsf',
- help='the design template (for sub-01)')
- args = parser.parse_args()
- fmriEx = args.fmri
- designFile = args.design
- return fmriEx, designFile
- # main program #
- if __name__ == "__main__":
- # prepare the header for the condor .submit file
- submit_content = [line + '\n' for line in SUBMIT_CONTENT]
- # with launch_ipdb_on_exception():
- # call FSL first
- os.system('. /etc/fsl/5.0/fsl.sh')
- fmri_example, design_file = parse_arguments()
- # for 3T data input
- if 'sub-01' in fmri_example:
- subjs_pattern = fmri_example.replace('sub-01', 'sub-*')
- # search for subjects
- pathes = sorted(glob(subjs_pattern))
- subjs = [re.search(r'sub-\d{2}', path) for path in pathes]
- subjs = [int(subj.group()[-2:]) for subj in subjs]
- # filter out sub-10 that is not in intersection of subjects for
- # both movie and audio-description (missing in audio-description)
- if 10 in subjs:
- subjs.remove(10)
- runs_pattern = fmri_example.replace('run-1', 'run-*')
- pathes = sorted(glob(runs_pattern))
- runs = [re.search(r'run-\d', path) for path in pathes]
- runs = [(run.group()) for run in runs]
- runs = [int(run[-1]) for run in runs]
- else:
- print('subject string not found')
- # open design file
- with open(design_file, 'r') as f:
- lines = f.readlines()
- # use the design file as template
- template = [line.strip() for line in lines]
- for sub in subjs:
- sub = str(sub)
- print('\nsub', sub)
- for run in runs:
- run = str(run)
- print('run', run)
- # number of fmri volumes for current run
- fmri_file = fmri_example.replace('sub-01', 'sub-' + sub.zfill(2))
- fmri_file = fmri_file.replace('run-1', 'run-' + run)
- info = subprocess.check_output('fslinfo %s' % fmri_file, shell=True)
- dim4 = info.split()[9]
- vol = str(dim4).split("'")[1]
- design_file_content = []
- for lineNo, line in enumerate(template):
- if 'sub-01' in line or 'run-1' in line:
- line = line.replace('sub-01', 'sub-' + sub.zfill(2))
- line = line.replace('run-1', 'run-' + run)
- # correct bold_dico_moco.txt (motion correction for audio data)
- elif 'sub001' in line or 'run001' in line:
- line = line.replace('sub001', 'sub' + sub.zfill(3))
- line = line.replace('run001', 'run' + run.zfill(3))
- elif 'set fmri(npts) ' in line:
- line_splitted = line.split()
- line_splitted[-1] = ' ' + vol
- line = ' '.join(line_splitted)
- elif 'set fmri(evtitle' in line:
- # check for the corresponding EV3 file
- # it's name comes always 31 lines later in the file
- ev = line.split('"')[1]
- ev_file_line = template[lineNo + 31]
- ev_file = ev_file_line.split('"')[1]
- ev_file = ev_file.replace('sub-01', 'sub-' + sub.zfill(2))
- ev_file = ev_file.replace('run-1', 'run-' + run)
- if os.path.isfile(ev_file):
- with open(ev_file, 'r') as f:
- content = f.readlines()
- length = len(content)
- # check the length of the event onset file
- # use canonical HRF if it contains lines/events
- if length > 0:
- fmri_shape = '3'
- # use 0 regressor otherwise
- else:
- fmri_shape = '10'
- print('no events in', ev_file)
- print('choosing null events for ev %s' % ev)
- else:
- print('could not find', ev_file)
- fmri_shape = '10'
- print('choosing null events for ev %s' % ev)
- elif 'set fmri(shape' in line:
- line_splitted = line.split()
- line_splitted[-1] = fmri_shape
- line = ' '.join(line_splitted)
- design_file_content.append(line)
- design_file_content = [line + '\n' for line in design_file_content]
- # writing
- fsl_design = os.path.basename(design_file).split('.')[0]
- analysis = fsl_design.split('lvl_')[1]
- out_name = 'run-%s_1st_%s.fsf' % (run, analysis)
- out_path = os.path.join('sub-' + sub.zfill(2), out_name)
- try:
- with open(out_path, 'w') as the_file:
- the_file.writelines(design_file_content)
- submit_arg = 'arguments = sub-%s/%s\nqueue\n' % (sub.zfill(2), out_name)
- submit_content.append(submit_arg)
- except IOError:
- print(sub, 'is not in intersection of movie and audio-description')
- # write the condor_submit file
- submit_name = 'compute_1st-lvl_%s.submit' % analysis
- submit_path = os.path.join(os.path.dirname(design_file), submit_name)
- with open(submit_path, 'w') as the_file:
- the_file.writelines(submit_content)
- os.makedirs('condor_logs', exist_ok=True)
|