def ffx( maskImages, effectImages, varianceImages, resultImage=None): """ Computation of the fixed effecst statistics Parameters ---------- maskImages, string or list of strings the paths of one or several masks when several masks, the half thresholding heuristic is used effectImages, list of strings the paths ofthe effect images varianceImages, list of strings the paths of the associated variance images resultImage=None, string, path of the result images Returns ------- the computed values """ # fixme : check that the images have same referntial # fixme : check that mask_Images is a list if len(effectImages)!=len(varianceImages): raise ValueError, 'Not the correct number of images' tiny = 1.e-15 nsubj = len(effectImages) mask = intersect_masks(maskImages, None, threshold=0.5, cc=True) effects = [] variance = [] for s in range(nsubj): rbeta = load(effectImages[s]) beta = rbeta.get_data()[mask>0] rbeta = load(varianceImages[s]) varbeta = rbeta.get_data()[mask>0] effects.append(beta) variance.append(varbeta) effects = np.array(effects) variance = np.array(variance) effects[np.isnan(effects)] = 0 effects[np.isnan(variance)] = 0 variance[np.isnan(variance)] = tiny variance[variance==0] = tiny t = effects/np.sqrt(variance) t = t.mean(0)*np.sqrt(nsubj) #t = np.sum(effects/variance,0)/np.sum(1.0/np.sqrt(variance),0) nim = load(effectImages[0]) affine = nim.get_affine() tmap = np.zeros(nim.get_shape()) tmap[mask>0] = t tImage = Nifti1Image(tmap, affine) if resultImage!=None: save(tImage, resultImage) return tmap
def ffx_from_stat( maskImages, statImages, resultImage=None): """ Computation of the fixed effects statistics from statistic Parameters ---------- maskImages, string or list of strings the paths of one or several masks when several masks, the half thresholding heuristic is used statImages, list of strings the paths ofthe statitsic images resultImage=None, string, path of the result images Returns ------- the computed values """ # fixme : check that the images have same referntial # fixme : check that mask_Images is a list nsubj = len(statImages) mask = intersect_masks(maskImages, None, threshold=0.5, cc=True) t = [] for s in range(nsubj): rbeta = load(statImages[s]) beta = rbeta.get_data()[mask>0] t.append(beta) t = np.array(t) t[np.isnan(t)] = 0 t = t.mean(0)*np.sqrt(nsubj) nim = load(statImages[0]) affine = nim.get_affine() tmap = np.zeros(nim.get_shape()) tmap[mask>0] = t tImage = Nifti1Image(tmap, affine) if resultImage!=None: save(tImage,resultImage) return tmap
def mask_parcellation(mask_images, nb_parcel, output_image=None): """ Performs the parcellation of a certain mask Parameters ---------- mask_images: list of strings, paths of the mask images that define the common space. nb_parcel: int, number of desired parcels output_image: string, optional path of the output image Returns ------- wim: Nifti1Imagine instance, the resulting parcellation """ from nipy.neurospin.utils.mask import intersect_masks # compute the group mask affine = load(mask_images[0]).get_affine() shape = load(mask_images[0]).get_shape() mask = intersect_masks(mask_images, threshold=0)>0 ijk = np.where(mask) ijk = np.array(ijk).T nvox = ijk.shape[0] # Get and cluster coordinates ijk = np.hstack((ijk,np.ones((nvox,1)))) coord = np.dot(ijk, affine.T)[:,:3] cent, tlabs, J = kmeans(coord, nb_parcel) # Write the results label = -np.ones(shape) label[mask]= tlabs wim = Nifti1Image(label, affine) wim.get_header()['descrip'] = 'Label image in %d parcels'%nb_parcel if output_image is not None: save(wim, output_image) return wim
import nipy.neurospin.group.onesample as fos import nipy.neurospin.graph.graph as fg import mixed_effects_stat as mes ################################################################ # first define paths etc. ################################################################ subj = ['s12069', 's12300', 's12401', 's12431', 's12508', 's12532', 's12539', 's12562','s12590', 's12635', 's12636', 's12898', 's12081', 's12165', 's12207', 's12344', 's12352', 's12370', 's12381', 's12405', 's12414', 's12432'] nsubj = len(subj) db_path = '/data/home/virgile/virgile_internship' mask_images = [op.join(db_path,"%s/fMRI/default_acquisition/Minf/mask.nii") % s for s in subj] # create the mask mask = intersect_masks(mask_images, output_filename=None, threshold=0.5, cc=True) affine = load(mask_images[0]).get_affine() grp_mask = Nifti1Image(mask, load(mask_images[0]).get_affine()) ijk = np.array(np.where(mask)).T nvox = np.sum(mask) # output dir b_smooth = True if b_smooth: print "smoothed data" threshold_path = 'volume_threshold_smooth.con' swd = '/data/home/virgile/virgile_internship/group_analysis/smoothed_FWHM5' else: print "unsmoothed data" threshold_path = 'volume_threshold.con' swd = '/data/home/virgile/virgile_internship/group_analysis/smoothed_FWHM0'
def group_reproducibility_metrics( mask_images, contrast_images, variance_images, thresholds, ngroups, method, cluster_threshold=10, number_of_samples=10, sigma=6., do_clusters=True, do_voxels=True, do_peaks=True, swap=False): """ Main function to perform reproducibility analysis, including nifti1 io Parameters ---------- threshold: list or 1-d array, the thresholds to be tested Returns ------- cluster_rep_results: dictionary, results of cluster-level reproducibility analysi voxel_rep_results: dictionary, results of voxel-level reproducibility analysis peak_rep_results: dictionary, results of peak-level reproducibility analysis """ from nipy.io.imageformats import load, save, Nifti1Image from nipy.neurospin.utils.mask import intersect_masks if ((len(variance_images)==0) & (method is not 'crfx')): raise ValueError, 'Variance images are necessary' nsubj = len(contrast_images) # compute the group mask affine = load(mask_images[0]).get_affine() mask = intersect_masks(mask_images, threshold=0)>0 grp_mask = Nifti1Image(mask, affine) xyz = np.where(mask) xyz = np.array(xyz).T nvox = xyz.shape[0] # read the data group_con = [] group_var = [] for s in range(nsubj): group_con.append(load(contrast_images[s]).get_data()[mask]) if len(variance_images)>0: group_var.append(load(variance_images[s]).get_data()[mask]) group_con = np.squeeze(np.array(group_con)).T group_con[np.isnan(group_con)] = 0 if len(variance_images)>0: group_var = np.squeeze(np.array(group_var)).T group_var[np.isnan(group_var)] = 0 group_var = np.maximum(group_var, 1.e-15) # perform the analysis voxel_rep_results = {} cluster_rep_results = {} peak_rep_results = {} for ng in ngroups: if do_voxels: voxel_rep_results.update({ng:{}}) if do_clusters: cluster_rep_results.update({ng:{}}) if do_peaks: peak_rep_results.update({ng:{}}) for th in thresholds: kappa = [] cls = [] pk = [] kwargs={'threshold':th, 'csize':cluster_threshold} for i in range(number_of_samples): if do_voxels: kappa.append(voxel_reproducibility( group_con, group_var, grp_mask, ng, method, swap, **kwargs)) if do_clusters: cls.append(cluster_reproducibility( group_con, group_var, grp_mask, ng, sigma, method, swap, **kwargs)) if do_peaks: pk.append(peak_reproducibility( group_con, group_var, grp_mask, ng, sigma, method, swap, **kwargs)) if do_voxels: voxel_rep_results[ng].update({th: np.array(kappa)}) if do_clusters: cluster_rep_results[ng].update({th:np.array(cls)}) if do_peaks: peak_rep_results[ng].update({th:np.array(cls)}) return voxel_rep_results, cluster_rep_results, peak_rep_results
def make_bsa_image_with_output_paths(mask_images, betas, denspath, crpath, theta=3., dmax= 5., ths=0, thq=0.5, smin=0, method='simple'): """ Deprecated : will be removed soon idem make_bsa_image but paths of the output are set explictly. Moreover the segmented regions are written in one single image """ # Sanity check if len(mask_images)!=len(betas): print len(mask_images),len(betas) raise ValueError,"the number of masks and activation images\ should be the same" nsubj = len(mask_images) # Read the referential information nim = load(mask_images[0]) ref_dim = nim.get_shape() affine = nim.get_affine() # Read the masks and compute the "intersection" mask = intersect_masks(mask_images) xyz = np.array(np.where(mask)).T nvox = xyz.shape[0] # create the field strcture that encodes image topology Fbeta = ff.Field(nvox) Fbeta.from_3d_grid(xyz.astype(np.int),18) # Get coordinates in mm xyz = np.hstack((xyz,np.ones((nvox,1)))) coord = np.dot(xyz,affine.T)[:,:3] xyz = xyz.astype(np.int) # read the functional images lbeta = [] for s in range(nsubj): rbeta = load(betas[s]) beta = rbeta.get_data() beta = beta[mask] lbeta.append(beta) lbeta = np.array(lbeta).T lbeta = np.reshape(lbeta,(nvox,nsubj)) # launch the method g0 = 1.0/(np.absolute(np.linalg.det(affine))*nvox) bdensity = 1 crmap = np.zeros(nvox) p = np.zeros(nvox) AF = None BF = [None for s in range(nsubj)] if method=='ipmi': crmap,AF,BF,p = bsa.compute_BSA_ipmi(Fbeta, lbeta, coord, dmax, xyz[:,:3], affine, ref_dim, thq, smin, ths, theta, g0, bdensity) if method=='dev': crmap,AF,BF,p = bsa.compute_BSA_dev (Fbeta, lbeta, coord, dmax, xyz[:,:3], affine, ref_dim, thq, smin,ths, theta, g0, bdensity,verbose=1) if method=='simple': crmap,AF,BF,p = bsa.compute_BSA_simple (Fbeta, lbeta, coord, dmax, xyz[:,:3], affine, ref_dim, thq, smin, ths, theta, g0, verbose=0) if method=='simple_quick': crmap,AF,BF,co_clust = bsa.compute_BSA_simple_quick (Fbeta, lbeta, coord, dmax, xyz[:,:3], affine, ref_dim, thq, smin, ths, theta, g0, verbose=0) density = np.zeros(nvox) crmap = AF.map_label(coord,0.95,dmax) if method=='loo': crmap,AF,BF,p = bsa.compute_BSA_loo (Fbeta, lbeta, coord, dmax, xyz[:,:3], affine, ref_dim, thq, smin,ths, theta, g0, verbose=0) # Write the results Label = -2*np.ones(ref_dim,'int16') Label[mask] = crmap.astype('i') wim = Nifti1Image (Label, affine) wim.get_header()['descrip'] = 'group Level labels from bsa procedure' save(wim, crpath) density = np.zeros(ref_dim) density[mask] = p wim = Nifti1Image (density, affine) wim.get_header()['descrip'] = 'group-level spatial density of active regions' save(wim, denspath) if AF==None: default_idx = 0 else: default_idx = AF.k+2 # write everything in one image wdim = (ref_dim[0], ref_dim[1], ref_dim[2], nsubj+1) Label = -2*np.ones(wdim,'int16') Label[mask,0] = crmap.astype(np.int) for s in range(nsubj): Label[mask,s+1]=-1 if BF[s]!=None: nls = BF[s].get_roi_feature('label') nls[nls==-1] = default_idx for k in range(BF[s].k): xyzk = BF[s].xyz[k].T Label[xyzk[0],xyzk[1],xyzk[2],s+1] = nls[k] wim = Nifti1Image (Label, affine) wim.get_header()['descrip'] = 'group Level and individual labels\ from bsa procedure' save(wim, crpath) return AF,BF, maxc
def make_bsa_image(mask_images, betas, theta=3., dmax= 5., ths=0, thq=0.5, smin=0, swd="/tmp/", method='simple', subj_id=None, nbeta='default', densPath=None, crPath=None, verbose=0): """ main function for performing bsa on a set of images. It creates the some output images in the given directory Parameters ------------ mask_images: A list of image paths that yield binary images, one for each subject the number os subjects, nsubj, is taken as len(mask_images) betas: A list of image paths that yields the activation images, one for each subject theta=3., threshold used to ignore all the image data that si below dmax=5., prior width of the spatial model; corresponds to multi-subject uncertainty ths=0: threshold on the representativity measure of the obtained regions thq=0.5: p-value of the representativity test: test = p(representativity>ths)>thq smin=0: minimal size (in voxels) of the extracted blobs smaller blobs are merged into larger ones swd='/tmp': writedir method='simple': applied region detection method; to be chose among 'simple', 'dev','ipmi' subj_id=None: list of strings, identifiers of the subjects. by default it is range(nsubj) nbeta='default', string, identifier of the contrast densPath=None, string, path of the output density image if False, no image is written if None, the path is computed from swd, nbeta crPath=None, string, path of the (4D) output label image if False, no ime is written if None, many images are written, with paths computed from swd, subj_id and nbeta Returns ------- AF: an nipy.neurospin.spatial_models.structural_bfls.landmark_regions instance that describes the structures found at the group level None is returned if nothing has been found significant at the group level BF : a list of nipy.neurospin.spatial_models.hroi.Nroi instances (one per subject) that describe the individual coounterpart of AF if method=='loo', the output is different: mll, float, the average likelihood of the data under H1 after cross validation ll0, float the log-likelihood of the data under the global null fixme: unique mask should be allowed """ # Sanity check if len(mask_images)!=len(betas): raise ValueError,"the number of masks and activation images\ should be the same" nsubj = len(mask_images) if subj_id==None: subj_id = [str[i] for i in range(nsubj)] # Read the referential information nim = load(mask_images[0]) ref_dim = nim.get_shape() affine = nim.get_affine() # Read the masks and compute the "intersection" mask = intersect_masks(mask_images) xyz = np.array(np.where(mask)).T nvox = xyz.shape[0] # create the field strcture that encodes image topology Fbeta = ff.Field(nvox) Fbeta.from_3d_grid(xyz.astype(np.int),18) # Get coordinates in mm xyz = np.hstack((xyz,np.ones((nvox,1)))) coord = np.dot(xyz,affine.T)[:,:3] xyz = xyz.astype(np.int) # read the functional images lbeta = [] for s in range(nsubj): rbeta = load(betas[s]) beta = rbeta.get_data() beta = beta[mask] lbeta.append(beta) lbeta = np.array(lbeta).T # launch the method g0 = 1.0/(np.absolute(np.linalg.det(affine))*nvox) bdensity = 1 crmap = np.zeros(nvox) p = np.zeros(nvox) AF = None BF = [None for s in range(nsubj)] if method=='ipmi': crmap,AF,BF,p = bsa.compute_BSA_ipmi(Fbeta, lbeta, coord, dmax, xyz[:,:3], affine, ref_dim, thq, smin, ths, theta, g0, bdensity, verbose=verbose) if method=='dev': crmap,AF,BF,p = bsa.compute_BSA_dev (Fbeta, lbeta, coord, dmax, xyz[:,:3], affine, ref_dim, thq, smin,ths, theta, g0, bdensity, verbose=verbose) if method=='simple': crmap,AF,BF,p = bsa.compute_BSA_simple (Fbeta, lbeta, coord, dmax, xyz[:,:3], affine, ref_dim, thq, smin, ths, theta, g0, verbose=verbose) if method=='simple_quick': crmap,AF,BF,co_clust = bsa.compute_BSA_simple_quick(Fbeta, lbeta, coord, dmax, xyz[:,:3], affine, ref_dim, thq, smin, ths, theta, g0, verbose=verbose) density = np.zeros(nvox) crmap = AF.map_label(coord,0.95,dmax) if method=='loo': mll, ll0 = bsa.compute_BSA_loo (Fbeta, lbeta, coord, dmax, xyz[:,:3], affine, ref_dim, thq, smin,ths, theta, g0, verbose=verbose) return mll, ll0 # Write the results as images # the spatial density image if densPath != False: density = np.zeros(ref_dim) density[mask] = p wim = Nifti1Image (density, affine) wim.get_header()['descrip'] = 'group-level spatial density of active regions' if densPath==None: densPath = op.join(swd,"density_%s.nii"%nbeta) save(wim, densPath) if crPath==False: return AF, BF if AF==None: default_idx = 0 else: default_idx = AF.k+2 if crPath==None: # write a 3D image for group-level labels crPath = op.join(swd,"CR_%s.nii"%nbeta) Label = -2*np.ones(ref_dim,'int16') Label[mask] = crmap wim = Nifti1Image (Label, affine) wim.get_header()['descrip'] = 'group Level labels from bsa procedure' save(wim, crPath) #write 3d images for the subjects for s in range(nsubj): LabelImage = op.join(swd,"AR_s%s_%s.nii"%(subj_id[s],nbeta)) Label = -2*np.ones(ref_dim,'int16') Label[mask]=-1 if BF[s]!=None: nls = BF[s].get_roi_feature('label') nls[nls==-1] = default_idx for k in range(BF[s].k): xyzk = BF[s].xyz[k].T Label[xyzk[0],xyzk[1],xyzk[2]] = nls[k] wim = Nifti1Image (Label, affine) wim.get_header()['descrip'] = 'Individual label image from bsa procedure' save(wim, LabelImage) else: # write everything in a single 4D image wdim = (ref_dim[0], ref_dim[1], ref_dim[2], nsubj+1) Label = -2*np.ones(wdim,'int16') Label[mask,0] = crmap for s in range(nsubj): Label[mask,s+1]=-1 if BF[s]!=None: nls = BF[s].get_roi_feature('label') nls[nls==-1] = default_idx for k in range(BF[s].k): xyzk = BF[s].xyz[k].T Label[xyzk[0],xyzk[1],xyzk[2],s+1] = nls[k] wim = Nifti1Image (Label, affine) wim.get_header()['descrip'] = 'group Level and individual labels\ from bsa procedure' save(wim, crPath) return AF,BF
get_data_light.getIt() nsubj = 12 subj_id = range(nsubj) nbeta = 29 data_dir = op.expanduser(op.join("~", ".nipy", "tests", "data", "group_t_images")) mask_images = [op.join(data_dir, "mask_subj%02d.nii" % n) for n in range(nsubj)] stat_images = [op.join(data_dir, "spmT_%04d_subj_%02d.nii" % (nbeta, n)) for n in range(nsubj)] contrast_images = [op.join(data_dir, "con_%04d_subj_%02d.nii" % (nbeta, n)) for n in range(nsubj)] swd = tempfile.mkdtemp("image") ################################################################################ # Make a group mask mask = intersect_masks(mask_images) > 0 xyz = np.where(mask) xyz = np.array(xyz).T nvox = xyz.shape[0] ################################################################################ # Load the functional images # Load the betas Functional = [] VarFunctional = [] tiny = 1.0e-15 for s in range(nsubj): beta = [] varbeta = [] rbeta = load(contrast_images[s])