def test_artifacts_no_qi2():

    import os
    import pickle
    import pkg_resources as p

    import numpy.testing as nt

    from qap.spatial_qc import artifacts
    from qap.qap_utils import load_image, load_mask

    anat_reorient = p.resource_filename("qap", os.path.join(test_sub_dir, \
                                        "anat_reorient.nii.gz"))
                                   
    head_mask = p.resource_filename("qap", os.path.join(test_sub_dir, \
                                    "qap_head_mask.nii.gz"))

    bg_mask = p.resource_filename("qap", os.path.join(test_sub_dir, \
                                  "anat_bg_mask.nii.gz"))

    anat_data = load_image(anat_reorient)
    mask_data = load_mask(head_mask, anat_reorient)
    bg_data = load_mask(bg_mask, anat_reorient)

    art_out = artifacts(anat_data, mask_data, bg_data, calculate_qi2=False)

    nt.assert_almost_equal(art_out[0], 0.10064793870393487, decimal=4)
def test_fber():

    import os
    import pickle
    import pkg_resources as p
    
    import numpy.testing as nt

    from qap.spatial_qc import fber
    from qap.qap_utils import load_image, load_mask

    anat_reorient = p.resource_filename("qap", os.path.join(test_sub_dir, \
                                        "anat_reorient.nii.gz"))
                                   
    head_mask = p.resource_filename("qap", os.path.join(test_sub_dir, \
                                    "qap_head_mask.nii.gz"))

    skull_only_mask = p.resource_filename("qap", os.path.join(test_sub_dir, \
                                          "skull_only_mask.nii.gz"))

    anat_data = load_image(anat_reorient)
    mask_data = load_mask(head_mask, anat_reorient)
    bg_data = 1 - mask_data

    head_data = load_mask(skull_only_mask, anat_reorient)

    fber_out = fber(anat_data, head_data, bg_data)

    nt.assert_almost_equal(fber_out, 341.72165992685609, decimal=4)
예제 #3
0
def test_artifacts_no_qi2():

    import os
    import pickle
    import pkg_resources as p

    from qap.spatial_qc import artifacts
    from qap.qap_utils import load_image, load_mask

    anat_reorient = p.resource_filename("qap", os.path.join(test_sub_dir, \
                                        "anat_1", \
                                        "anatomical_reorient", \
                                        "mprage_resample.nii.gz"))
                                   
    head_mask = p.resource_filename("qap", os.path.join(test_sub_dir, \
                                    "anat_1", \
                                    "qap_head_mask", \
                                    "mprage_resample_thresh_maths_maths_" \
                                    "maths.nii.gz"))

    anat_data = load_image(anat_reorient)
    mask_data = load_mask(head_mask, anat_reorient)

    art_out = artifacts(anat_data, mask_data, calculate_qi2=False)

    assert art_out == (0.06788309163289169, None)
예제 #4
0
def test_artifacts():

    ''' this will fail until the code in 'if calculate_qi2' is updated '''

    import os
    import pickle
    import pkg_resources as p

    from qap.spatial_qc import artifacts
    from qap.qap_utils import load_image, load_mask

    anat_reorient = p.resource_filename("qap", os.path.join(test_sub_dir, \
                                        "anat_1", \
                                        "anatomical_reorient", \
                                        "mprage_resample.nii.gz"))
                                   
    head_mask = p.resource_filename("qap", os.path.join(test_sub_dir, \
                                    "anat_1", \
                                    "qap_head_mask", \
                                    "mprage_resample_thresh_maths_maths_" \
                                    "maths.nii.gz"))

    anat_data = load_image(anat_reorient)
    mask_data = load_mask(head_mask, anat_reorient)

    art_out = artifacts(anat_data, mask_data, calculate_qi2=True)

    ''' not the actual expected output, needs verification '''
    assert art_out == 0
예제 #5
0
def test_ghost_direction():

    import os
    import pickle
    import pkg_resources as p
    
    from qap.spatial_qc import ghost_direction
    from qap.qap_utils import load_image, load_mask

    mean_epi = p.resource_filename("qap", os.path.join(test_sub_dir, \
                                   "rest_1", \
                                   "mean_functional", \
                                   "rest_calc_tshift_resample_volreg_" \
                                   "tstat.nii.gz"))
                                   
    func_brain_mask = p.resource_filename("qap", os.path.join(test_sub_dir, \
                                          "rest_1", \
                                          "functional_brain_mask", \
                                          "rest_calc_tshift_resample_volreg" \
                                          "_mask.nii.gz"))

    mean_epi_data = load_image(mean_epi)
    funcmask_data = load_mask(func_brain_mask, mean_epi)

    gsr_out_x = ghost_direction(mean_epi_data, funcmask_data, "x")
    gsr_out_y = ghost_direction(mean_epi_data, funcmask_data, "y")
    gsr_out_z = ghost_direction(mean_epi_data, funcmask_data, "z")

    gsr_out_all = (gsr_out_x, gsr_out_y, gsr_out_z)

    print gsr_out_all

    assert gsr_out_all == (-0.013489312, 0.016911652, 0.080058813)
def test_summary_mask():

    import os
    import pickle
    import pkg_resources as p

    from qap.spatial_qc import summary_mask
    from qap.qap_utils import load_image, load_mask

    anat_reorient = p.resource_filename("qap", os.path.join(test_sub_dir, \
                                        "anat_1", \
                                        "anatomical_reorient", \
                                        "mprage_resample.nii.gz"))
                                   
    head_mask = p.resource_filename("qap", os.path.join(test_sub_dir, \
                                    "anat_1", \
                                    "qap_head_mask", \
                                    "mprage_resample_thresh_maths_maths_" \
                                    "maths.nii.gz"))

    anat_data = load_image(anat_reorient)
    mask_data = load_mask(head_mask, anat_reorient)

    summary_tuple = summary_mask(anat_data, mask_data)

    assert summary_tuple == (252.25360846882191, 288.84526666983822, 6449165)
def test_fber():

    import os
    import pickle
    import pkg_resources as p
    
    from qap.spatial_qc import fber
    from qap.qap_utils import load_image, load_mask

    anat_reorient = p.resource_filename("qap", os.path.join(test_sub_dir, \
                                        "anat_1", \
                                        "anatomical_reorient", \
                                        "mprage_resample.nii.gz"))
                                   
    head_mask = p.resource_filename("qap", os.path.join(test_sub_dir, \
                                    "anat_1", \
                                    "qap_head_mask", \
                                    "mprage_resample_thresh_maths_maths_" \
                                    "maths.nii.gz"))

    anat_data = load_image(anat_reorient)
    mask_data = load_mask(head_mask, anat_reorient)     

    fber_out = fber(anat_data, mask_data)

    assert fber_out == 539.65627087395478
def test_ghost_direction():

    import os
    import pkg_resources as p
    
    import numpy.testing as nt

    from qap.spatial_qc import ghost_direction
    from qap.qap_utils import load_image, load_mask

    mean_epi = p.resource_filename("qap", os.path.join(test_sub_dir, \
                                   "mean_functional.nii.gz"))
                                   
    func_brain_mask = p.resource_filename("qap", os.path.join(test_sub_dir, \
                                          "functional_brain_mask" \
                                          ".nii.gz"))

    mean_epi_data = load_image(mean_epi)
    funcmask_data = load_mask(func_brain_mask, mean_epi)

    gsr_out_x = ghost_direction(mean_epi_data, funcmask_data, "x")
    gsr_out_y = ghost_direction(mean_epi_data, funcmask_data, "y")
    gsr_out_z = ghost_direction(mean_epi_data, funcmask_data, "z")

    gsr_out_all = (gsr_out_x, gsr_out_y, gsr_out_z)

    nt.assert_almost_equal(gsr_out_all[0], -0.018987976014614105, decimal=4)
    nt.assert_almost_equal(gsr_out_all[1], 0.020795321092009544, decimal=4)
    nt.assert_almost_equal(gsr_out_all[2], 0.06708560138940811, decimal=4)  
예제 #9
0
def qap_functional_spatial(mean_epi,
                           func_brain_mask,
                           direction,
                           subject_id,
                           session_id,
                           scan_id,
                           site_name=None,
                           out_vox=True):

    import os
    import sys

    from qap.spatial_qc import summary_mask, snr, fber, efc, fwhm, \
        ghost_direction
    from qap.qap_utils import load_image, load_mask

    # Load the data
    anat_data = load_image(mean_epi)
    fg_mask = load_mask(func_brain_mask, mean_epi)
    bg_mask = 1 - fg_mask

    # Initialize QC
    qc = dict(subject=subject_id, session=session_id, scan=scan_id)

    if site_name:
        qc['site'] = site_name

    # FBER
    qc['fber'] = fber(anat_data, fg_mask)

    # EFC
    qc['efc'] = efc(anat_data)

    # Smoothness in voxels
    tmp = fwhm(mean_epi, func_brain_mask, out_vox=out_vox)
    qc['fwhm_x'], qc['fwhm_y'], qc['fwhm_z'], qc['fwhm'] = tmp

    # Ghosting
    if (direction == "all"):
        qc['ghost_x'] = ghost_direction(anat_data, fg_mask, "x")
        qc['ghost_y'] = ghost_direction(anat_data, fg_mask, "y")
        qc['ghost_z'] = ghost_direction(anat_data, fg_mask, "z")

    else:
        qc['ghost_%s' % direction] = ghost_direction(anat_data, fg_mask,
                                                     direction)

    # Summary Measures
    qc['fg_mean'], qc['fg_std'], qc['fg_size'] = summary_mask(
        anat_data, fg_mask)
    qc['bg_mean'], qc['bg_std'], qc['bg_size'] = summary_mask(
        anat_data, bg_mask)

    qc['snr'] = None

    # SNR
    qc['snr'] = snr(qc['fg_mean'], qc['bg_std'])
    return qc
def qap_functional_spatial(
    mean_epi, func_brain_mask, direction, subject_id, session_id, scan_id, site_name=None, out_vox=True
):

    import os
    import sys

    from qap.spatial_qc import summary_mask, snr, fber, efc, fwhm, ghost_direction
    from qap.qap_utils import load_image, load_mask

    # Load the data
    anat_data = load_image(mean_epi)
    fg_mask = load_mask(func_brain_mask, mean_epi)
    bg_mask = 1 - fg_mask

    # Initialize QC
    qc = dict()

    qc["subject"] = subject_id

    qc["session"] = session_id

    qc["scan"] = scan_id

    if site_name:
        qc["site"] = site_name

    # FBER
    qc["fber"] = fber(anat_data, fg_mask)

    # EFC
    qc["efc"] = efc(anat_data)

    # Smoothness in voxels
    tmp = fwhm(mean_epi, func_brain_mask, out_vox=out_vox)
    qc["fwhm_x"], qc["fwhm_y"], qc["fwhm_z"], qc["fwhm"] = tmp

    # Ghosting
    if direction == "all":
        qc["ghost_x"] = ghost_direction(anat_data, fg_mask, "x")
        qc["ghost_y"] = ghost_direction(anat_data, fg_mask, "y")
        qc["ghost_z"] = ghost_direction(anat_data, fg_mask, "z")

    else:
        qc["ghost_%s" % direction] = ghost_direction(anat_data, fg_mask, direction)

    # Summary Measures
    qc["fg_mean"], qc["fg_std"], qc["fg_size"] = summary_mask(anat_data, fg_mask)
    qc["bg_mean"], qc["bg_std"], qc["bg_size"] = summary_mask(anat_data, bg_mask)

    qc["snr"] = None

    # SNR
    qc["snr"] = snr(qc["fg_mean"], qc["bg_std"])

    return qc
예제 #11
0
def test_summary_mask():

    import os
    import pickle
    import pkg_resources as p

    from qap.spatial_qc import summary_mask
    from qap.qap_utils import load_image, load_mask

    anat_reorient = p.resource_filename("qap", os.path.join(test_sub_dir, \
                                        "anat_reorient.nii.gz"))

    head_mask = p.resource_filename("qap", os.path.join(test_sub_dir, \
                                    "qap_head_mask.nii.gz"))

    anat_data = load_image(anat_reorient)
    mask_data = load_mask(head_mask, anat_reorient)

    summary_tuple = summary_mask(anat_data, mask_data)

    assert int(summary_tuple[0]) == 230
    assert int(summary_tuple[1]) == 233
    assert int(summary_tuple[2]) == 157221
def test_summary_mask():

    import os
    import pickle
    import pkg_resources as p

    from qap.spatial_qc import summary_mask
    from qap.qap_utils import load_image, load_mask

    anat_reorient = p.resource_filename("qap", os.path.join(test_sub_dir, \
                                        "anat_reorient.nii.gz"))
                                   
    head_mask = p.resource_filename("qap", os.path.join(test_sub_dir, \
                                    "qap_head_mask.nii.gz"))

    anat_data = load_image(anat_reorient)
    mask_data = load_mask(head_mask, anat_reorient)

    summary_tuple = summary_mask(anat_data, mask_data)

    assert int(summary_tuple[0]) == 230
    assert int(summary_tuple[1]) == 233
    assert int(summary_tuple[2]) == 157221
def qap_functional_spatial(mean_epi, func_brain_mask, direction, subject_id,
                           session_id, scan_id, site_name=None, out_vox=True,
                           starter=None):
    """ Calculate the functional spatial QAP measures for a functional scan.

    - The inclusion of the starter node allows several QAP measure pipelines
      which are not dependent on one another to be executed as one pipeline.
      This allows the MultiProc Nipype plugin to efficiently manage
      resources when parallelizing.

    :type mean_epi: str
    :param mean_epi: Filepath to the mean of the functional timeseries image
                     (should be 3D).
    :type func_brain_mask: str
    :param func_brain_mask: Filepath to the binary mask defining the brain
                            within the functional image.
    :type direction: str
    :param direction: For ghost-to-signal ratio; the phase-encoding direction
                      of the image - this is often "y".
    :type subject_id: str
    :param subject_id: The participant ID.
    :type session_id: str
    :param session_id: The session ID.
    :type scan_id: str
    :param scan_id: The scan ID.
    :type site_name: str
    :param site_name: (default: None) The name of the site where the scan was
                      acquired.
    :type out_vox: bool
    :param out_vox: (default: True) For FWHM measure: output the FWHM as
                    number of voxels (otherwise as mm).
    :type starter: str
    :param starter: (default: None) If this function is being pulled into a
                    Nipype pipeline, this is the dummy input for the function
                    node.
    :rtype: dict
    :return: A dictionary mapping out the QAP measure values for the current
             participant.
    """

    from time import strftime

    import qap
    from qap.spatial_qc import summary_mask, snr, fber, efc, fwhm, \
        ghost_direction
    from qap.qap_utils import load_image, load_mask

    # Load the data
    anat_data = load_image(mean_epi)
    fg_mask = load_mask(func_brain_mask, mean_epi)
    bg_mask = 1 - fg_mask

    # FBER
    fber_out = fber(anat_data, fg_mask, bg_mask)

    # EFC
    efc_out = efc(anat_data)
    
    # Smoothness in voxels
    tmp = fwhm(mean_epi, func_brain_mask, out_vox=out_vox)
    fwhm_x, fwhm_y, fwhm_z, fwhm_out = tmp

    # Summary Measures
    fg_mean, fg_std, fg_size = summary_mask(anat_data, fg_mask)
    bg_mean, bg_std, bg_size = summary_mask(anat_data, bg_mask)

    # SNR
    snr_out = snr(fg_mean, bg_std)

    id_string = "%s %s %s" % (subject_id, session_id, scan_id)
    qc = {
            id_string:
            {
               "QAP_pipeline_id": "QAP version %s" % qap.__version__,
               "Time": strftime("%Y-%m-%d %H:%M:%S"),
               "Participant": str(subject_id),
               "Session": str(session_id),
               "Series": str(scan_id),
               "functional_spatial":
               {
                  "FBER": fber_out,
                  "EFC": efc_out,
                  "FWHM": fwhm_out,
                  "FWHM_x": fwhm_x,
                  "FWHM_y": fwhm_y,
                  "FWHM_z": fwhm_z,
                  "SNR": snr_out
               }
            }
        }

    # Ghosting
    if (direction == "all"):
        qc[id_string]["functional_spatial"]['Ghost_x'] = \
            ghost_direction(anat_data, fg_mask, "x")
        qc[id_string]["functional_spatial"]['Ghost_y'] = \
            ghost_direction(anat_data, fg_mask, "y")
        qc[id_string]["functional_spatial"]['Ghost_z'] = \
            ghost_direction(anat_data, fg_mask, "z")
    else:
        qc[id_string]["functional_spatial"]['Ghost_%s' % direction] = \
            ghost_direction(anat_data, fg_mask, direction)

    if site_name:
        qc[id_string]['Site'] = str(site_name)

    for key in qc[id_string]["functional_spatial"].keys():
        qc[id_string]["functional_spatial"][key] = \
            str(qc[id_string]["functional_spatial"][key])

    return qc
def qap_anatomical_spatial(
    anatomical_reorient,
    head_mask_path,
    anatomical_gm_mask,
    anatomical_wm_mask,
    anatomical_csf_mask,
    subject_id,
    session_id,
    scan_id,
    site_name=None,
    out_vox=True,
):

    import os
    import sys

    from qap.spatial_qc import summary_mask, snr, cnr, fber, efc, artifacts, fwhm
    from qap.qap_utils import load_image, load_mask

    # Load the data
    anat_data = load_image(anatomical_reorient)
    fg_mask = load_mask(head_mask_path, anatomical_reorient)
    bg_mask = 1 - fg_mask

    gm_mask = load_mask(anatomical_gm_mask, anatomical_reorient)
    wm_mask = load_mask(anatomical_wm_mask, anatomical_reorient)
    csf_mask = load_mask(anatomical_csf_mask, anatomical_reorient)

    # Initialize QC
    qc = dict()

    qc["subject"] = subject_id

    qc["session"] = session_id

    qc["scan"] = scan_id

    if site_name:
        qc["site"] = site_name

    # FBER
    qc["fber"] = fber(anat_data, fg_mask)

    # EFC
    qc["efc"] = efc(anat_data)

    # Artifact
    qc["qi1"], _ = artifacts(anat_data, fg_mask, calculate_qi2=False)

    # Smoothness in voxels
    tmp = fwhm(anatomical_reorient, head_mask_path, out_vox=out_vox)
    qc["fwhm_x"], qc["fwhm_y"], qc["fwhm_z"], qc["fwhm"] = tmp

    # Summary Measures
    qc["fg_mean"], qc["fg_std"], qc["fg_size"] = summary_mask(anat_data, fg_mask)
    qc["bg_mean"], qc["bg_std"], qc["bg_size"] = summary_mask(anat_data, bg_mask)

    qc["gm_mean"], qc["gm_std"], qc["gm_size"] = (None, None, None)
    qc["wm_mean"], qc["wm_std"], qc["wm_size"] = (None, None, None)
    qc["csf_mean"], qc["csf_std"], qc["csf_size"] = (None, None, None)
    qc["cnr"] = None
    qc["snr"] = None

    # More Summary Measures
    qc["gm_mean"], qc["gm_std"], qc["gm_size"] = summary_mask(anat_data, gm_mask)
    qc["wm_mean"], qc["wm_std"], qc["wm_size"] = summary_mask(anat_data, wm_mask)
    qc["csf_mean"], qc["csf_std"], qc["csf_size"] = summary_mask(anat_data, csf_mask)

    # SNR
    qc["snr"] = snr(qc["fg_mean"], qc["bg_std"])

    # CNR
    qc["cnr"] = cnr(qc["gm_mean"], qc["wm_mean"], qc["bg_std"])

    return qc
예제 #15
0
def qap_anatomical_spatial(anatomical_reorient,
                           head_mask_path,
                           anatomical_gm_mask,
                           anatomical_wm_mask,
                           anatomical_csf_mask,
                           subject_id,
                           session_id,
                           scan_id,
                           site_name=None,
                           out_vox=True):

    import os
    import sys

    from qap.spatial_qc import summary_mask, snr, cnr, fber, efc, \
        artifacts, fwhm
    from qap.qap_utils import load_image, load_mask

    # Load the data
    anat_data = load_image(anatomical_reorient)
    fg_mask = load_mask(head_mask_path, anatomical_reorient)
    bg_mask = 1 - fg_mask

    gm_mask = load_mask(anatomical_gm_mask, anatomical_reorient)
    wm_mask = load_mask(anatomical_wm_mask, anatomical_reorient)
    csf_mask = load_mask(anatomical_csf_mask, anatomical_reorient)

    # Initialize QC
    qc = dict()

    qc['subject'] = subject_id

    qc['session'] = session_id

    qc['scan'] = scan_id

    if site_name:
        qc['site'] = site_name

    # FBER
    qc['fber'] = fber(anat_data, fg_mask)

    # EFC
    qc['efc'] = efc(anat_data)

    # Artifact
    qc['qi1'], _ = artifacts(anat_data, fg_mask, calculate_qi2=False)

    # Smoothness in voxels
    tmp = fwhm(anatomical_reorient, head_mask_path, out_vox=out_vox)
    qc['fwhm_x'], qc['fwhm_y'], qc['fwhm_z'], qc['fwhm'] = tmp

    # Summary Measures
    qc['fg_mean'], qc['fg_std'], qc['fg_size'] = summary_mask(
        anat_data, fg_mask)
    qc['bg_mean'], qc['bg_std'], qc['bg_size'] = summary_mask(
        anat_data, bg_mask)

    qc['gm_mean'], qc['gm_std'], qc['gm_size'] = (None, None, None)
    qc['wm_mean'], qc['wm_std'], qc['wm_size'] = (None, None, None)
    qc['csf_mean'], qc['csf_std'], qc['csf_size'] = (None, None, None)
    qc['cnr'] = None
    qc['snr'] = None

    # More Summary Measures
    qc['gm_mean'], qc['gm_std'], qc['gm_size'] = summary_mask(
        anat_data, gm_mask)
    qc['wm_mean'], qc['wm_std'], qc['wm_size'] = summary_mask(
        anat_data, wm_mask)
    qc['csf_mean'], qc['csf_std'], qc['csf_size'] = summary_mask(
        anat_data, csf_mask)

    # SNR
    qc['snr'] = snr(qc['fg_mean'], qc['bg_std'])

    # CNR
    qc['cnr'] = cnr(qc['gm_mean'], qc['wm_mean'], qc['bg_std'])
    return qc
예제 #16
0
def qap_anatomical_spatial(anatomical_reorient,
                           qap_head_mask_path,
                           whole_head_mask_path,
                           skull_mask_path,
                           anatomical_gm_mask,
                           anatomical_wm_mask,
                           anatomical_csf_mask,
                           subject_id,
                           session_id,
                           scan_id,
                           site_name=None,
                           exclude_zeroes=False,
                           out_vox=True,
                           starter=None):
    """Calculate the anatomical spatial QAP measures for an anatomical scan.

    - The exclude_zeroes flag is useful for when a large amount of zero
      values have been artificially injected into the image, for example,
      when removing the faces and ears in scans for privacy compliance
      reasons; these zeroes can artificially skew the spatial quality metric
      results and make it seem that there is far less noise or artifacts in
      the image than there really is.
    - The inclusion of the starter node allows several QAP measure pipelines
      which are not dependent on one another to be executed as one pipeline.
      This allows the MultiProc Nipype plugin to efficiently manage
      resources when parallelizing.

    :type anatomical_reorient: str
    :param anatomical_reorient: Filepath to the reoriented anatomical scan.
    :type qap_head_mask_path: str
    :param qap_head_mask_path: Filepath to mask of the head, plus the slice
                               covering the region below the nose and in
                               front of the mouth.
    :type whole_head_mask_path: str
    :param whole_head_mask_path: Filepath to mask of the entire head only (no
                                 slice in front of head).
    :type skull_mask_path: str
    :param skull_mask_path: Filepath to the mask of the upper portion of the
                            head only (the whole head mask subtracted by the
                            slice mask).
    :type anatomical_gm_mask: str
    :param anatomical_gm_mask: Filepath to the binary mask of the gray matter.
    :type anatomical_wm_mask: str
    :param anatomical_wm_mask: Filepath to the binary mask of the white
                               matter.
    :type anatomical_csf_mask: str
    :param anatomical_csf_mask: Filepath to the binary mask of the CSF.
    :type subject_id: str
    :param subject_id: The participant ID.
    :type session_id: str
    :param session_id: The session ID.
    :type scan_id: str
    :param scan_id: The scan ID.
    :type site_name: str
    :param site_name: (default: None) The name of the site where the scan was
                      acquired.
    :type exclude_zeroes: bool
    :param exclude_zeroes: (default: False) Whether or not to exclude the
                           pure zero values when defining the background mask.
    :type out_vox: bool
    :param out_vox: (default: True) For FWHM measure: output the FWHM as
                    number of voxels (otherwise as mm).
    :type starter: str
    :param starter: (default: None) If this function is being pulled into a
                    Nipype pipeline, this is the dummy input for the function
                    node.
    :rtype: dict
    :return: A dictionary mapping out the QAP measure values for the current
             participant.
    """

    from time import strftime
    import qap
    from qap.spatial_qc import summary_mask, snr, cnr, fber, efc, \
        artifacts, fwhm, cortical_contrast
    from qap.qap_utils import load_image, load_mask, \
                              create_anatomical_background_mask

    # Load the data
    anat_data = load_image(anatomical_reorient)

    fg_mask = load_mask(qap_head_mask_path, anatomical_reorient)

    # bg_mask is the inversion of the "qap_head_mask"
    bg_mask = create_anatomical_background_mask(anat_data, fg_mask,
                                                exclude_zeroes)

    whole_head_mask = load_mask(whole_head_mask_path, anatomical_reorient)
    skull_mask = load_mask(skull_mask_path, anatomical_reorient)

    gm_mask = load_mask(anatomical_gm_mask, anatomical_reorient)
    wm_mask = load_mask(anatomical_wm_mask, anatomical_reorient)
    csf_mask = load_mask(anatomical_csf_mask, anatomical_reorient)

    # FBER
    fber_out = fber(anat_data, skull_mask, bg_mask)

    # EFC
    efc_out = efc(anat_data)

    # Artifact
    qi1, _ = artifacts(anat_data, fg_mask, bg_mask, calculate_qi2=False)

    # Smoothness in voxels
    tmp = fwhm(anatomical_reorient, whole_head_mask_path, out_vox=out_vox)
    fwhm_x, fwhm_y, fwhm_z, fwhm_out = tmp

    # Summary Measures
    fg_mean, fg_std, fg_size = summary_mask(anat_data, whole_head_mask)
    bg_mean, bg_std, bg_size = summary_mask(anat_data, bg_mask)

    gm_mean, gm_std, gm_size = (None, None, None)
    wm_mean, wm_std, wm_size = (None, None, None)
    csf_mean, csf_std, csf_size = (None, None, None)

    # More Summary Measures
    gm_mean, gm_std, gm_size = summary_mask(anat_data, gm_mask)
    wm_mean, wm_std, wm_size = summary_mask(anat_data, wm_mask)
    csf_mean, csf_std, csf_size = summary_mask(anat_data, csf_mask)

    # SNR
    snr_out = snr(fg_mean, bg_std)

    # CNR
    cnr_out = cnr(gm_mean, wm_mean, bg_std)

    # Cortical contrast
    cort_out = cortical_contrast(gm_mean, wm_mean)

    id_string = "%s %s %s" % (subject_id, session_id, scan_id)
    qc = {
        id_string: {
            "QAP_pipeline_id": "QAP version %s" % qap.__version__,
            "Time": strftime("%Y-%m-%d %H:%M:%S"),
            "Participant": str(subject_id),
            "Session": str(session_id),
            "Series": str(scan_id),
            "anatomical_spatial": {
                "FBER": fber_out,
                "EFC": efc_out,
                "Qi1": qi1,
                "FWHM_x": fwhm_x,
                "FWHM_y": fwhm_y,
                "FWHM_z": fwhm_z,
                "FWHM": fwhm_out,
                "CNR": cnr_out,
                "SNR": snr_out,
                "Cortical Contrast": cort_out
            }
        }
    }

    if site_name:
        qc[id_string]['Site'] = str(site_name)

    if exclude_zeroes:
        qc[id_string]['_zeros_excluded'] = "True"

    for key in qc[id_string]["anatomical_spatial"].keys():
        qc[id_string]["anatomical_spatial"][key] = \
            str(qc[id_string]["anatomical_spatial"][key])

    return qc
예제 #17
0
def qap_functional_spatial(mean_epi,
                           func_brain_mask,
                           direction,
                           subject_id,
                           session_id,
                           scan_id,
                           site_name=None,
                           out_vox=True,
                           starter=None):
    """ Calculate the functional spatial QAP measures for a functional scan.

    - The inclusion of the starter node allows several QAP measure pipelines
      which are not dependent on one another to be executed as one pipeline.
      This allows the MultiProc Nipype plugin to efficiently manage
      resources when parallelizing.

    :type mean_epi: str
    :param mean_epi: Filepath to the mean of the functional timeseries image
                     (should be 3D).
    :type func_brain_mask: str
    :param func_brain_mask: Filepath to the binary mask defining the brain
                            within the functional image.
    :type direction: str
    :param direction: For ghost-to-signal ratio; the phase-encoding direction
                      of the image - this is often "y".
    :type subject_id: str
    :param subject_id: The participant ID.
    :type session_id: str
    :param session_id: The session ID.
    :type scan_id: str
    :param scan_id: The scan ID.
    :type site_name: str
    :param site_name: (default: None) The name of the site where the scan was
                      acquired.
    :type out_vox: bool
    :param out_vox: (default: True) For FWHM measure: output the FWHM as
                    number of voxels (otherwise as mm).
    :type starter: str
    :param starter: (default: None) If this function is being pulled into a
                    Nipype pipeline, this is the dummy input for the function
                    node.
    :rtype: dict
    :return: A dictionary mapping out the QAP measure values for the current
             participant.
    """

    from time import strftime

    import qap
    from qap.spatial_qc import summary_mask, snr, fber, efc, fwhm, \
        ghost_direction
    from qap.qap_utils import load_image, load_mask

    # Load the data
    anat_data = load_image(mean_epi)
    fg_mask = load_mask(func_brain_mask, mean_epi)
    bg_mask = 1 - fg_mask

    # FBER
    fber_out = fber(anat_data, fg_mask, bg_mask)

    # EFC
    efc_out = efc(anat_data)

    # Smoothness in voxels
    tmp = fwhm(mean_epi, func_brain_mask, out_vox=out_vox)
    fwhm_x, fwhm_y, fwhm_z, fwhm_out = tmp

    # Summary Measures
    fg_mean, fg_std, fg_size = summary_mask(anat_data, fg_mask)
    bg_mean, bg_std, bg_size = summary_mask(anat_data, bg_mask)

    # SNR
    snr_out = snr(fg_mean, bg_std)

    id_string = "%s %s %s" % (subject_id, session_id, scan_id)
    qc = {
        id_string: {
            "QAP_pipeline_id": "QAP version %s" % qap.__version__,
            "Time": strftime("%Y-%m-%d %H:%M:%S"),
            "Participant": str(subject_id),
            "Session": str(session_id),
            "Series": str(scan_id),
            "functional_spatial": {
                "FBER": fber_out,
                "EFC": efc_out,
                "FWHM": fwhm_out,
                "FWHM_x": fwhm_x,
                "FWHM_y": fwhm_y,
                "FWHM_z": fwhm_z,
                "SNR": snr_out
            }
        }
    }

    # Ghosting
    if (direction == "all"):
        qc[id_string]["functional_spatial"]['Ghost_x'] = \
            ghost_direction(anat_data, fg_mask, "x")
        qc[id_string]["functional_spatial"]['Ghost_y'] = \
            ghost_direction(anat_data, fg_mask, "y")
        qc[id_string]["functional_spatial"]['Ghost_z'] = \
            ghost_direction(anat_data, fg_mask, "z")
    else:
        qc[id_string]["functional_spatial"]['Ghost_%s' % direction] = \
            ghost_direction(anat_data, fg_mask, direction)

    if site_name:
        qc[id_string]['Site'] = str(site_name)

    for key in qc[id_string]["functional_spatial"].keys():
        qc[id_string]["functional_spatial"][key] = \
            str(qc[id_string]["functional_spatial"][key])

    return qc
def qap_anatomical_spatial(anatomical_reorient, qap_head_mask_path,
                           whole_head_mask_path, skull_mask_path,
                           anatomical_gm_mask, anatomical_wm_mask,
                           anatomical_csf_mask, subject_id, session_id,
                           scan_id, site_name=None, exclude_zeroes=False,
                           out_vox=True, starter=None):
    """Calculate the anatomical spatial QAP measures for an anatomical scan.

    - The exclude_zeroes flag is useful for when a large amount of zero
      values have been artificially injected into the image, for example,
      when removing the faces and ears in scans for privacy compliance
      reasons; these zeroes can artificially skew the spatial quality metric
      results and make it seem that there is far less noise or artifacts in
      the image than there really is.
    - The inclusion of the starter node allows several QAP measure pipelines
      which are not dependent on one another to be executed as one pipeline.
      This allows the MultiProc Nipype plugin to efficiently manage
      resources when parallelizing.

    :type anatomical_reorient: str
    :param anatomical_reorient: Filepath to the reoriented anatomical scan.
    :type qap_head_mask_path: str
    :param qap_head_mask_path: Filepath to mask of the head, plus the slice
                               covering the region below the nose and in
                               front of the mouth.
    :type whole_head_mask_path: str
    :param whole_head_mask_path: Filepath to mask of the entire head only (no
                                 slice in front of head).
    :type skull_mask_path: str
    :param skull_mask_path: Filepath to the mask of the upper portion of the
                            head only (the whole head mask subtracted by the
                            slice mask).
    :type anatomical_gm_mask: str
    :param anatomical_gm_mask: Filepath to the binary mask of the gray matter.
    :type anatomical_wm_mask: str
    :param anatomical_wm_mask: Filepath to the binary mask of the white
                               matter.
    :type anatomical_csf_mask: str
    :param anatomical_csf_mask: Filepath to the binary mask of the CSF.
    :type subject_id: str
    :param subject_id: The participant ID.
    :type session_id: str
    :param session_id: The session ID.
    :type scan_id: str
    :param scan_id: The scan ID.
    :type site_name: str
    :param site_name: (default: None) The name of the site where the scan was
                      acquired.
    :type exclude_zeroes: bool
    :param exclude_zeroes: (default: False) Whether or not to exclude the
                           pure zero values when defining the background mask.
    :type out_vox: bool
    :param out_vox: (default: True) For FWHM measure: output the FWHM as
                    number of voxels (otherwise as mm).
    :type starter: str
    :param starter: (default: None) If this function is being pulled into a
                    Nipype pipeline, this is the dummy input for the function
                    node.
    :rtype: dict
    :return: A dictionary mapping out the QAP measure values for the current
             participant.
    """

    from time import strftime
    import qap
    from qap.spatial_qc import summary_mask, snr, cnr, fber, efc, \
        artifacts, fwhm, cortical_contrast
    from qap.qap_utils import load_image, load_mask, \
                              create_anatomical_background_mask

    # Load the data
    anat_data = load_image(anatomical_reorient)

    fg_mask = load_mask(qap_head_mask_path, anatomical_reorient)

    # bg_mask is the inversion of the "qap_head_mask"
    bg_mask = create_anatomical_background_mask(anat_data, fg_mask,
        exclude_zeroes)

    whole_head_mask = load_mask(whole_head_mask_path, anatomical_reorient)
    skull_mask = load_mask(skull_mask_path, anatomical_reorient)

    gm_mask = load_mask(anatomical_gm_mask, anatomical_reorient)
    wm_mask = load_mask(anatomical_wm_mask, anatomical_reorient)
    csf_mask = load_mask(anatomical_csf_mask, anatomical_reorient)

    # FBER
    fber_out = fber(anat_data, skull_mask, bg_mask)

    # EFC
    efc_out = efc(anat_data)

    # Artifact
    qi1, _ = artifacts(anat_data, fg_mask, bg_mask, calculate_qi2=False)

    # Smoothness in voxels
    tmp = fwhm(anatomical_reorient, whole_head_mask_path, out_vox=out_vox)
    fwhm_x, fwhm_y, fwhm_z, fwhm_out = tmp

    # Summary Measures
    fg_mean, fg_std, fg_size = summary_mask(anat_data, whole_head_mask)
    bg_mean, bg_std, bg_size = summary_mask(anat_data, bg_mask)

    gm_mean, gm_std, gm_size = (None, None, None)
    wm_mean, wm_std, wm_size = (None, None, None)
    csf_mean, csf_std, csf_size = (None, None, None)

    # More Summary Measures
    gm_mean, gm_std, gm_size = summary_mask(anat_data, gm_mask)
    wm_mean, wm_std, wm_size = summary_mask(anat_data, wm_mask)
    csf_mean, csf_std, csf_size = summary_mask(anat_data, csf_mask)

    # SNR
    snr_out = snr(fg_mean, bg_std)

    # CNR
    cnr_out = cnr(gm_mean, wm_mean, bg_std)

    # Cortical contrast
    cort_out = cortical_contrast(gm_mean, wm_mean)

    id_string = "%s %s %s" % (subject_id, session_id, scan_id)
    qc = {
            id_string:
            {
               "QAP_pipeline_id": "QAP version %s" % qap.__version__,
               "Time": strftime("%Y-%m-%d %H:%M:%S"),
               "Participant": str(subject_id),
               "Session": str(session_id),
               "Series": str(scan_id),
               "anatomical_spatial":
               { 
                  "FBER": fber_out,
                  "EFC": efc_out,
                  "Qi1": qi1,
                  "FWHM_x": fwhm_x,
                  "FWHM_y": fwhm_y,
                  "FWHM_z": fwhm_z,
                  "FWHM": fwhm_out,
                  "CNR": cnr_out,
                  "SNR": snr_out,
                  "Cortical Contrast": cort_out
               }
            }
    }

    if site_name:
        qc[id_string]['Site'] = str(site_name)

    if exclude_zeroes:
        qc[id_string]['_zeros_excluded'] = "True"

    for key in qc[id_string]["anatomical_spatial"].keys():
        qc[id_string]["anatomical_spatial"][key] = \
            str(qc[id_string]["anatomical_spatial"][key])

    return qc