def test_artifacts_with_qi2(): # 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
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
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_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)
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
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
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