Beispiel #1
0
    def __init__(self, dataset_dir, overwrite=False):

        print('Initializing BIDS dataset directory tree in %s' % dataset_dir)

        self.bids_dir = dataset_dir
        self.derivatives_dir = os.path.join(dataset_dir, 'derivatives')
        self.sourcedata_dir = os.path.join(dataset_dir, 'sourcedata')
        self.code_dir = os.path.join(dataset_dir, 'code')
        self.work_dir = os.path.join(dataset_dir, 'work')

        bio.safe_mkdir(self.derivatives_dir)
        bio.safe_mkdir(self.sourcedata_dir)
        bio.safe_mkdir(self.code_dir)
        bio.safe_mkdir(self.work_dir)

        self.translator_file = os.path.join(self.code_dir, 'Protocol_Translator.json')

        print('Creating required file templates')

        # README file
        self.readme_file = os.path.join(dataset_dir, 'README')
        with open(self.readme_file, 'w') as fd:
            fd.writelines('Useful information about this dataset\n')

        # CHANGES changelog file
        self.changes_file = os.path.join(dataset_dir, 'CHANGES')
        with open(self.changes_file, 'w') as fd:
            fd.writelines(['1.0.0 YYYY-MM-DD\n', ' - Initial release\n'])

        # Create template JSON dataset description (must comply with BIDS 1.2 spec)
        self.datadesc_json = os.path.join(self.bids_dir, 'dataset_description.json')
        meta_dict = dict({
            'Name': 'Descriptive name for this dataset',
            'BIDSVersion': '1.2',
            'License': 'This data is made available under the Creative Commons BY-SA 4.0 International License.',
            'Authors': ['First Author', 'Second Author'],
            'Acknowledgments': 'Thanks to everyone for all your help',
            'HowToAcknowledge': 'Please cite: Author AB, Seminal Paper Title, High Impact Journal, 2019',
            'Funding': ['First Grant', 'Second Grant'],
            'ReferencesAndLinks': ['A Reference', 'Another Reference', 'A Link'],
            'DatasetDOI': '10.0.1.2/abcd.10'
        })
        bio.write_json(self.datadesc_json, meta_dict, overwrite)

        # Create participants JSON file defining columns in participants.tsv
        # See
        self.participants_json = os.path.join(self.bids_dir, 'participants.json')
        meta_dict = dict({
            'age': {
                'Description': 'Age of participant',
                'Units': 'years'
            },
            'sex': {
                'Description': 'Sex of participant',
                'Levels': {
                    'M': 'male',
                    'F': 'female',
                    'T': 'transgender'
                }
            },
            'group': {
                'Description': 'participant group assignment'
            },
        })
        bio.write_json(self.participants_json, meta_dict, overwrite)

        # Create .bidsignore file to skip work/ during validation
        self.ignore_file = os.path.join(dataset_dir, '.bidsignore')
        with open(self.ignore_file, 'w') as fd:
            fd.writelines('work/\n')
Beispiel #2
0
def purpose_handling(bids_purpose,
                     bids_intendedfor,
                     seq_name,
                     work_nii_fname,
                     work_json_fname,
                     bids_nii_fname,
                     bids_json_fname,
                     overwrite=False):
    """
    Special handling for each image purpose (func, anat, fmap, dwi, etc)

    :param bids_purpose: str
    :param bids_intendedfor: str
    :param seq_name: str
    :param work_nii_fname: str
    :param work_json_fname: str
    :param bids_nii_fname: str
    :param bids_json_fname: str
    :param overwrite: bool
    :return:
    """

    # Init DWI sidecars
    work_bval_fname = []
    work_bvec_fname = []
    bids_bval_fname = []
    bids_bvec_fname = []

    # Load the JSON sidecar
    bids_info = bio.read_json(work_json_fname)

    if bids_purpose == 'func':

        if seq_name == 'EP':

            print('    EPI detected')
            create_events_template(bids_nii_fname, overwrite)

            # Add taskname to BIDS JSON sidecar
            bids_keys = bio.parse_bids_fname(bids_nii_fname)
            if 'task' in bids_keys:
                bids_info['TaskName'] = bids_keys['task']
            else:
                bids_info['TaskName'] = 'unknown'

    elif bids_purpose == 'fmap':

        # Add IntendedFor field if requested through protocol translator
        if 'UNASSIGNED' not in bids_intendedfor:
            bids_info['IntendedFor'] = bids_intendedfor

        # Check for MEGE vs SE-EPI fieldmap images
        # MEGE will have a 'GR' sequence, SE-EPI will have 'EP'

        print('    Identifying fieldmap image type')

        if seq_name == 'GR':

            print('    GRE detected')
            print('    Identifying magnitude and phase images')

            # Siemens: Dual gradient echo fieldmaps reconstruct to three series
            # (Requires dcm2nixx v1.0.20180404 or later for echo number suffix)
            # *--GR--<serno>_e1.<ext> : magnitude image from echo 1
            # *--GR--<serno>_e2.<ext> : magnitude image from echo 2
            # *--GR--<serno+1>_ph.<ext> : inter-echo phase difference

            # Pull dcm2niix filename info
            work_info = bio.parse_dcm2niix_fname(work_nii_fname)

            if 'e1' in work_info['Suffix']:

                print('    Echo 1 magnitude detected')

                # Replace existing contrast suffix (if any) with '_magnitude1'
                bids_nii_fname = replace_contrast(bids_nii_fname, 'magnitude1')
                bids_json_fname = []  # Do not copy sidecar

            elif 'e2' in work_info['Suffix']:

                print('    Echo 2 magnitude detected')

                # Replace existing contrast suffix (if any) with '_magnitude1'
                bids_nii_fname = replace_contrast(bids_nii_fname, 'magnitude2')
                bids_json_fname = []  # Do not copy sidecar

            elif 'ph' in work_info['Suffix']:

                print('    Interecho phase difference detected')

                # Replace existing contrast suffix (if any) with '_phasediff'
                bids_nii_fname = replace_contrast(bids_nii_fname, 'phasediff')
                bids_json_fname = replace_contrast(bids_json_fname,
                                                   'phasediff')

                # Extract TE1 and TE2 from mag and phase JSON sidecars
                te1, te2 = fmap_echotimes(work_json_fname)
                bids_info['EchoTime1'] = te1
                bids_info['EchoTime2'] = te2

            else:

                print('*   Magnitude or phase image not found - skipping')
                bids_nii_fname = []
                bids_json_fname = []

        elif seq_name == 'EP':

            print('    EPI detected')

        else:

            print('    Unrecognized fieldmap detected')
            print('    Simply copying image and sidecar to fmap directory')

    elif bids_purpose == 'anat':

        if seq_name == 'GR_IR':

            print(
                '    IR-prepared GRE detected - likely T1w MP-RAGE or equivalent'
            )

        elif seq_name == 'SE':

            print('    Spin echo detected - likely T1w or T2w anatomic image')

        elif seq_name == 'GR':

            print('    Gradient echo detected')

    elif bids_purpose == 'dwi':

        # Fill DWI bval and bvec working and source filenames
        # Non-empty filenames trigger the copy below
        work_bval_fname = str(work_json_fname.replace('.json', '.bval'))
        bids_bval_fname = str(bids_json_fname.replace('dwi.json', 'dwi.bval'))
        work_bvec_fname = str(work_json_fname.replace('.json', '.bvec'))
        bids_bvec_fname = str(bids_json_fname.replace('dwi.json', 'dwi.bvec'))

    # Populate BIDS source directory with Nifti images, JSON and DWI sidecars
    print('  Populating BIDS source directory')

    if bids_nii_fname:
        bio.safe_copy(work_nii_fname, str(bids_nii_fname), overwrite)

    if bids_json_fname:
        bio.write_json(bids_json_fname, bids_info, overwrite)

    if bids_bval_fname:
        bio.safe_copy(work_bval_fname, bids_bval_fname, overwrite)

    if bids_bvec_fname:
        bio.safe_copy(work_bvec_fname, bids_bvec_fname, overwrite)
Beispiel #3
0
    def __init__(self, dataset_dir, overwrite=False):

        print('Initializing BIDS dataset directory tree in %s' % dataset_dir)

        self.bids_dir = dataset_dir
        self.derivatives_dir = os.path.join(dataset_dir, 'derivatives')
        self.sourcedata_dir = os.path.join(dataset_dir, 'sourcedata')
        self.code_dir = os.path.join(dataset_dir, 'code')
        self.work_dir = os.path.join(dataset_dir, 'work')

        bio.safe_mkdir(self.derivatives_dir)
        bio.safe_mkdir(self.sourcedata_dir)
        bio.safe_mkdir(self.code_dir)
        bio.safe_mkdir(self.work_dir)

        self.translator_file = os.path.join(self.code_dir,
                                            'Protocol_Translator.json')

        print('Creating required file templates')

        # README file
        self.readme_file = os.path.join(dataset_dir, 'README')
        with open(self.readme_file, 'w') as fd:
            fd.writelines('Useful information about this dataset\n')

        # CHANGES changelog file
        self.changes_file = os.path.join(dataset_dir, 'CHANGES')
        with open(self.changes_file, 'w') as fd:
            fd.writelines(['1.0.0 YYYY-MM-DD\n', ' - Initial release\n'])

        # Create template JSON dataset description (must comply with BIDS 1.2 spec)
        self.datadesc_json = os.path.join(self.bids_dir,
                                          'dataset_description.json')
        meta_dict = dict({
            'Name':
            'Descriptive name for this dataset',
            'BIDSVersion':
            '1.2',
            'License':
            'This data is made available under the Creative Commons BY-SA 4.0 International License.',
            'Authors': ['First Author', 'Second Author'],
            'Acknowledgments':
            'Thanks to everyone for all your help',
            'HowToAcknowledge':
            'Please cite: Author AB, Seminal Paper Title, High Impact Journal, 2019',
            'Funding': ['First Grant', 'Second Grant'],
            'ReferencesAndLinks':
            ['A Reference', 'Another Reference', 'A Link'],
            'DatasetDOI':
            '10.0.1.2/abcd.10'
        })
        bio.write_json(self.datadesc_json, meta_dict, overwrite)

        # Create participants JSON file defining columns in participants.tsv
        # See
        self.participants_json = os.path.join(self.bids_dir,
                                              'participants.json')
        meta_dict = dict({
            'age': {
                'Description': 'Age of participant',
                'Units': 'years'
            },
            'sex': {
                'Description': 'Sex of participant',
                'Levels': {
                    'M': 'male',
                    'F': 'female',
                    'T': 'transgender'
                }
            },
            'group': {
                'Description': 'participant group assignment'
            },
        })
        bio.write_json(self.participants_json, meta_dict, overwrite)

        # Create .bidsignore file to skip work/ during validation
        self.ignore_file = os.path.join(dataset_dir, '.bidsignore')
        with open(self.ignore_file, 'w') as fd:
            fd.writelines('work/\n')
Beispiel #4
0
def purpose_handling(bids_purpose, bids_intendedfor, seq_name,
                     work_nii_fname, work_json_fname, bids_nii_fname, bids_json_fname,
                     overwrite=False):
    """
    Special handling for each image purpose (func, anat, fmap, dwi, etc)

    :param bids_purpose: str
    :param bids_intendedfor: str
    :param seq_name: str
    :param work_nii_fname: str
    :param work_json_fname: str
    :param bids_nii_fname: str
    :param bids_json_fname: str
    :param overwrite: bool
    :return:
    """

    # Init DWI sidecars
    work_bval_fname = []
    work_bvec_fname = []
    bids_bval_fname = []
    bids_bvec_fname = []

    # Load the JSON sidecar
    bids_info = bio.read_json(work_json_fname)

    if bids_purpose == 'func':

        if seq_name == 'EP':

            print('    EPI detected')
            create_events_template(bids_nii_fname, overwrite)

            # Add taskname to BIDS JSON sidecar
            bids_keys = bio.parse_bids_fname(bids_nii_fname)
            if 'task' in bids_keys:
                bids_info['TaskName'] = bids_keys['task']
            else:
                bids_info['TaskName'] = 'unknown'

    elif bids_purpose == 'fmap':

        # Add IntendedFor field if requested through protocol translator
        if 'UNASSIGNED' not in bids_intendedfor:
            bids_info['IntendedFor'] = bids_intendedfor

        # Check for MEGE vs SE-EPI fieldmap images
        # MEGE will have a 'GR' sequence, SE-EPI will have 'EP'

        print('    Identifying fieldmap image type')

        if seq_name == 'GR':

            print('    GRE detected')
            print('    Identifying magnitude and phase images')

            # Siemens: Dual gradient echo fieldmaps reconstruct to three series
            # (Requires dcm2nixx v1.0.20180404 or later for echo number suffix)
            # *--GR--<serno>_e1.<ext> : magnitude image from echo 1
            # *--GR--<serno>_e2.<ext> : magnitude image from echo 2
            # *--GR--<serno+1>_ph.<ext> : inter-echo phase difference

            # Pull dcm2niix filename info
            work_info = bio.parse_dcm2niix_fname(work_nii_fname)

            if 'e1' in work_info['Suffix']:

                print('    Echo 1 magnitude detected')

                # Replace existing contrast suffix (if any) with '_magnitude1'
                bids_nii_fname = replace_contrast(bids_nii_fname, 'magnitude1')
                bids_json_fname = []  # Do not copy sidecar

            elif 'e2' in work_info['Suffix']:

                print('    Echo 2 magnitude detected')

                # Replace existing contrast suffix (if any) with '_magnitude1'
                bids_nii_fname = replace_contrast(bids_nii_fname, 'magnitude2')
                bids_json_fname = []  # Do not copy sidecar

            elif 'ph' in work_info['Suffix']:

                print('    Interecho phase difference detected')

                # Replace existing contrast suffix (if any) with '_phasediff'
                bids_nii_fname = replace_contrast(bids_nii_fname, 'phasediff')
                bids_json_fname = replace_contrast(bids_json_fname, 'phasediff')

                # Extract TE1 and TE2 from mag and phase JSON sidecars
                te1, te2 = fmap_echotimes(work_json_fname)
                bids_info['EchoTime1'] = te1
                bids_info['EchoTime2'] = te2

            else:

                print('*   Magnitude or phase image not found - skipping')
                bids_nii_fname = []
                bids_json_fname = []

        elif seq_name == 'EP':

            print('    EPI detected')

        else:

            print('    Unrecognized fieldmap detected')
            print('    Simply copying image and sidecar to fmap directory')

    elif bids_purpose == 'anat':

        if seq_name == 'GR_IR':

            print('    IR-prepared GRE detected - likely T1w MP-RAGE or equivalent')

        elif seq_name == 'SE':

            print('    Spin echo detected - likely T1w or T2w anatomic image')

        elif seq_name == 'GR':

            print('    Gradient echo detected')

    elif bids_purpose == 'dwi':

        # Fill DWI bval and bvec working and source filenames
        # Non-empty filenames trigger the copy below
        work_bval_fname = str(work_json_fname.replace('.json', '.bval'))
        bids_bval_fname = str(bids_json_fname.replace('dwi.json', 'dwi.bval'))
        work_bvec_fname = str(work_json_fname.replace('.json', '.bvec'))
        bids_bvec_fname = str(bids_json_fname.replace('dwi.json', 'dwi.bvec'))

    # Populate BIDS source directory with Nifti images, JSON and DWI sidecars
    print('  Populating BIDS source directory')

    if bids_nii_fname:
        bio.safe_copy(work_nii_fname, str(bids_nii_fname), overwrite)

    if bids_json_fname:
        bio.write_json(bids_json_fname, bids_info, overwrite)

    if bids_bval_fname:
        bio.safe_copy(work_bval_fname, bids_bval_fname, overwrite)

    if bids_bvec_fname:
        bio.safe_copy(work_bvec_fname, bids_bvec_fname, overwrite)