【BIDS】【Python封装】自动生成dcm2bids脚本并运行

简介

        BIDS全称是Brain Imaging Data Structure,是很多研究者对神经影像数据存放方式达成的一种共识,可以更方便的组织和分享数据。

          dcm2bids的主要目标是使 dicom 到 BIDS 的转换尽可能轻松。

        通过封装脚本可以轻松实现从0创建BIDS结构,将工作精力转移到最重要的config.json文件上。

使用方法

根据下方代码创建python文件。

在命令行中运行python文件并根据提示传参。

(base) rico-PowerEdge-T640:/data2/rico$ python ./20240809-getBIDS.py -h

usage: 20240809-getBIDS.py [-h] -d DATA -b BIDS -c CONFIG [-s STARTNO] [-r] [-a]

options:
  -h, --help            show this help message and exit
  -d DATA, --data DATA  元数据地址
  -b BIDS, --BIDS BIDS  BIDS目标地址
  -c CONFIG, --config CONFIG
                        BIDS配置文件地址
  -s STARTNO, --startNo STARTNO
                        被试起始编号(默认是0001)
  -r, --autoRunBash     需要自动执行脚本
  -a, --addSub          增量增加并不从头开始

命令运行完毕后会生成两个文件,一个是bash脚本文件,另一个是被试文件夹和sub-编码的映射关系csv文件。

如果想让程序生成脚本后自动执行,需要在命令中添加 -r 选项。

 python ./runBIDS.py -d ./DCM-DATA/ -b ./BIDSrESULT -c ./config.json -r

重构模式

        重构模式指的是从0开始创建BIDS文件,包括创建目标文件夹、初始化BIDS结构和构建BIDS文件。适用于数据集的第一次创建。默认被试编号从1开始依次编码。

增量模式

        增量模式指的是在原本的BIDS文件基础上增加新的被试信息。该步骤不包括建目标文件夹、初始化BIDS结构,直接构建新被试的图像信息并添加到现有的BIDS文件中。必须指定被试继续从几号开始编码。增量模式下可以继续编写原始的映射关系csv文件。

        使用 -a来开启增量模式。开启后必须同时给定 -s 选项输入被试起始编号(比如已经有5个被试在BIDS中,如果想要继续添加被试,应该传递 -s 6)

 python ./runBIDS.py -d ./DCM-DATA/ -b ./BIDSrESULT -c ./config.json -r -a -s 6

详细代码

# @Describe   :自动生成BIDS脚本
# @File       :20240809-getBIDS.py
# @FilePath   : I:\20230725_MCCRA\MyCode\python\20240809-getBIDS.py
# @IDE        : PyCharm
# @Author     :Rico
# @CreateDate :2024/8/9 11:43
# @university : shandong jianzhu university
import os
import pandas as pd
import subprocess
import argparse
import time
'''
运行前务必阅读以下注意事项:
1.提供一个文件元数据地址,根据文件夹中的子文件夹自动生成对应的脚本运行。
2.仅限一层子文件夹!!!!
3.默认一个子文件夹中包含的数据是一个被试的。
4.默认自动执行脚本。
5.!!!!!增量模式必须指定被试起始编号,否则默认从1开始覆盖!!!!!
6.!!!!!默认自动覆盖重新生成BIDS!!!!!
7.!!!!!默认初始化BIDS数据库的时候覆盖掉BIDSPath中的文件!!!!
'''
parser = argparse.ArgumentParser()
# 元数据地址
parser.add_argument('-d','--data', type=str, required=True, default=None, help='元数据地址' )
# BIDS目标地址
parser.add_argument('-b','--BIDS', type=str, required=True,default=None, help='BIDS目标地址')
#BIDS配置文件地址
parser.add_argument('-c','--config', type=str,required=True, default=None, help='BIDS配置文件地址')
#被试起始编号(默认是1,依次)
parser.add_argument('-s','--startNo', type=int, default=1, help='被试起始编号(默认是0001)' )
#自动执行脚本还是手动执行脚本
parser.add_argument('-r','--autoRunBash', action='store_true', help='需要自动执行脚本')
#增量增加或者从头增加
parser.add_argument('-a','--addSub', action='store_true', help='增量增加并不从头开始')
args = parser.parse_args()

# 元数据地址
dataPath = args.data
# BIDS目标地址
BIDSResultPath = args.BIDS
#BIDS配置文件地址
configPath = args.config
#被试起始编号(默认是1,依次)
subjectNo = args.startNo
#自动执行脚本还是手动执行脚本
autoBash = args.autoRunBash
#增量执行脚本
addSub = args.addSub


# @Describe  :获取当前时间
# @Author    :XUXIN
# @CreateDate:2023/3/3 14:56
def current_time():
    # 获取当前时间
    current_time = int(time.time())
    # 转换为localtime
    localtime = time.localtime(current_time)
    # 利用strftime()函数重新格式化时间
    current_time_form = time.strftime('%Y-%m-%d %H:%M:%S', localtime)
    return current_time_form

#主函数
if __name__ == '__main__':
    print("开始创建脚本")
    # 初始化文件提取报告
    catchedSampleDf = pd.DataFrame(columns=['subfoldName', 'sampleNo', 'addDate'])
    # 准备生成批量处理mask的shell脚本
    maskBash = '#!/bin/bash \n echo "开始执行BIDS转换任务任务!" \n'

    # BIDS目标地址
    #创建文件夹
    mkdir = 'mkdir -p ' + BIDSResultPath + '\n'
    maskBash = maskBash + mkdir

    #切换到conda环境
    changeConda = 'source /opt/miniconda3/etc/profile.d/conda.sh \n '+' echo "切换conda环境!" \n'+'conda activate dcm2bids  \n'
    maskBash = maskBash + changeConda

    # 读取文件地址中的所有子文件夹名称列表
    subFoldList = os.listdir(dataPath)
    if len(subFoldList) == 0 :
        print("提供源文件路径中没有被试数据,程序结束!")
    else:
        if not addSub:
            print("+++++重构模式+++++")
            #初始化BIDS数据库,默认在BIDS目标地址库中初始化 --force为默认覆盖里面的文件
            cmdTitleStr = 'echo "----初始化BIDS数据库!" \n'
            BIDScmd = 'dcm2bids_scaffold -o '+ BIDSResultPath + ' --force'
            maskBash = maskBash + " \n" + cmdTitleStr + " \n" + BIDScmd + " \n"
        else:
            print("+++++增量模式+++++")
            if subjectNo == 1:
                print("增量模式下被试编号拒绝从0001开始,请设置正确起始编号或者不要使用增量模式")
                exit(-1)
        #开始循环子文件夹
        for subFoldName in subFoldList:
            cmdTitleStr = 'echo "----开始处理' + subFoldName + '!" \n'
            cmdStr = 'dcm2bids -d '+ dataPath +'/'+ subFoldName + ' -p '+ str("{:04}".format(subjectNo)) +' -c '+ configPath +' -o '+ BIDSResultPath +' -s 1  ;'
            maskBash = maskBash + " \n" + cmdTitleStr + cmdStr + " \n"

            catchedRecord = [subFoldName, str("{:04}".format(subjectNo)), current_time()]
            # 无论如何都要追加一条提取数据记录
            catchedSampleDf = pd.concat(
                [catchedSampleDf, pd.DataFrame([catchedRecord], columns=catchedSampleDf.columns)], ignore_index=True)
            subjectNo = subjectNo + 1

        #所有文件夹处理完毕
        # 保存脚本和文件
        if addSub:
            try:
                #读取文件
                oralCsvFile = pd.read_csv('BIDS抽取文件汇总.csv')
                catchedSampleDf = pd.concat([oralCsvFile, catchedSampleDf], ignore_index=True)
            except:
                print("读取被试csv映射文件出错!请检查是否存在该文件!")
        catchedSampleDf.to_csv('BIDS抽取文件汇总.csv', header=True, encoding='utf_8_sig',index=False)
        #保存“添加mask”的bash脚本
        endCmdStr = 'echo "----数据运行完毕!" \n'
        maskBash = maskBash + " \n"  + endCmdStr + " \n"
        f = open("BIDSmaskBash.sh", "wt")
        f.write(maskBash)
        endCmdStr = 'echo "----任务执行完毕!" \n'
        f.write(endCmdStr)
        f.close()
        print("脚本创建完毕!")

        #是否自动运行脚本
        if  autoBash:
            print("开始执行脚本数据!")
            #切换到文件目录中
            ret = subprocess.call('cd ' + dataPath, shell=True)
            #调用shell修改脚本的权限
            ret = subprocess.check_output(['chmod', '+x', "BIDSmaskBash.sh"])
            #开始执行脚本
            ret = subprocess.call('./BIDSmaskBash.sh', shell=True)
            print(ret)



  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Rico只喝冰美式

研究生不易,文字换馒头

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值