bb_UKBB_to_BIDS_converter.py 5.63 KB
Newer Older
Fidel Alfaro Almagro's avatar
Fidel Alfaro Almagro committed
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 143 144
#!/bin/env python
#
# Script name: bb_UKBB_to_BIDS_converter.py
#
# Description: Script to convert a dataset with Biobank structure into BIDS.
#
# Authors: Fidel Alfaro-Almagro, Stephen M. Smith & Mark Jenkinson
#
# Copyright 2017 University of Oxford
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

import os
import re
import glob
import json
import copy
import nibabel as nib
import bb_logging_tool as LT
import sys,argparse,os.path,shutil
import bb_general_tools.bb_path as bb_path
from subprocess import check_output

logger=None

def create_directories(subject):
   
    bidDirsFile=os.environ['BB_BIN_DIR'] + '/bb_data/BIDS_directories.json'
    with open(bidDirsFile, 'r') as f:
        directories=json.load(f)

    for directory in directories:
        directory=directory.replace("@SUBJECT@", subject)
        if not os.path.isdir(directory):
            logger.info("Creating directory " + directory)         
            os.makedirs(directory)
        else:
            logger.info("Directory " + directory + " already existed")

def create_links(subject):
    BB_to_BIDS_table_file=os.environ['BB_BIN_DIR'] + '/bb_data/UKBB_to_BIDS.json'
    with open(BB_to_BIDS_table_file, 'r') as f:
        BB_to_BIDS_table=json.load(f)

    for BB_to_BIDS_key in BB_to_BIDS_table.keys():
        if os.path.isfile(BB_to_BIDS_key):
            newName=BB_to_BIDS_table[BB_to_BIDS_key].replace("@SUBJECT@", subject)
                      
            #If the file is a nii.gz, create the link for it and the json file
            if BB_to_BIDS_key.endswith(".nii.gz"):
                os.symlink("../../../" + BB_to_BIDS_key, newName)
                logger.info("Created the symlink " + newName + " pointing to ../../../" + BB_to_BIDS_key )
                
                if os.path.isfile(BB_to_BIDS_key.replace(".nii.gz",".json")):
                    os.symlink("../../../" + BB_to_BIDS_key.replace(".nii.gz","") + ".json", newName.replace(".nii.gz",".json"))
                    logger.info("Created the symlink " + newName.replace(".nii.gz",".json") + " pointing to ../../../" + BB_to_BIDS_key.replace(".nii.gz",".json" ))
                else:
                    logger.info("There was a problem. Expected JSON file " +  BB_to_BIDS_key.replace(".nii.gz","") + ".json does not exist.")      
                
                #Including the TASK field in the task json files in bold files
                if newName.endswith("_bold.nii.gz"):
                    
                    if os.path.isfile(newName.replace(".nii.gz",".json")):
                        logger.info("Correcting the JSON file for " +  BB_to_BIDS_key.replace(".nii.gz","") + " to add the TaskName field, required in BIDS.")
                        with open(newName.replace(".nii.gz",".json"), "r") as fd:
                            jsonBold=json.load(fd)
                        
                        fileNameSections=(newName.replace(".nii.gz","")).split("_")
                        taskNameSection=[x for x in fileNameSections if "task" in x][0]
                        taskName=taskNameSection.split("-")[1]

                        jsonBold['TaskName']=taskName
                        
                        os.remove(newName.replace(".nii.gz",".json"))
                        fd=open(newName.replace(".nii.gz",".json"), "w")
                        json.dump(jsonBold,fd,sort_keys=True,indent=4)

                    #Including the events tsv file associated with the task fMRI
                    if not "rest" in newName:
                        origFile=os.environ['BB_BIN_DIR'] + '/bb_data/task-hariri_events.tsv'
                        newFile=os.environ['PWD']+ "/" + subject + "/" + newName.replace("_bold.nii.gz","_events.tsv")
                        shutil.copyfile(origFile,newFile)

            #If the file is NOT a nii.gz, create the corresponding link
            else:
                os.symlink("../../../" + BB_to_BIDS_key, newName)
                logger.info("Created the symlink " + newName + " pointing to ../../../" + BB_to_BIDS_key )
        
        else:
            logger.info("Subject " + subject + " does not have the file " + BB_to_BIDS_key + " so no link was created." )
        

def bb_UKBB_to_BIDS_converter(subject):
    logger.info("Change dir to " + subject)
    os.chdir(subject)
    create_directories(subject)
    create_links(subject)
    logger.info("BIDS conversion for subject " + subject + " is finished.")

class MyParser(argparse.ArgumentParser):
    def error(self, message):
        sys.stderr.write('error: %s\n' % message)
        self.print_help()
        sys.exit(2)

class Usage(Exception):
    def __init__(self, msg):
        self.msg = msg

def main(): 

    global logger

    parser = MyParser(description='BioBank Pipeline FILE Manager')
    parser.add_argument("subjectFolder", help='Subject Folder')
   
    argsa = parser.parse_args()

    subject = argsa.subjectFolder
    subject = subject.strip()

    if subject[-1] =='/':
        subject = subject[0:len(subject)-1]
    
    logger = LT.initLogging(__file__, subject)

    logger.info('Running UK Biobank to BIDS converter') 
    bb_UKBB_to_BIDS_converter(subject)

    LT.finishLogging(logger)
             
if __name__ == "__main__":
    main()