Beispiel #1
0
def get_transformation(path_volume, path_reference_volume, path_transfo,
                       path_inverse):
    volume = aims.read(path_volume)
    reference_volume = aims.read(path_reference_volume)
    header = volume.header()
    header_ref = reference_volume.header()
    transfo_vol_to_mni = aims.AffineTransformation3d(
        header["transformations"][0])
    transfo_reference_to_mni = aims.AffineTransformation3d(
        header_ref["transformations"][0])
    final_transfo = transfo_reference_to_mni.inverse() * transfo_vol_to_mni
    inverse = final_transfo.inverse()
    aims.write(final_transfo, path_transfo)
    aims.write(inverse, path_inverse)
    pass
Beispiel #2
0
def peaks_as_spheres(path_peaks_volume, path_spheres, radius=2):
    """
    Represent peaks as spheres centered on peaks location and of radius radius
    :param path_peaks_volume: path of the boolean volume with peaks
    :param path_spheres: path of the mesh (spheres) representing the peaks
    :param radius: radius (in mm) of the spheres used for display
    :return:
    """
    volume = aims.read(path_peaks_volume)
    data = np.array(volume)[..., 0]

    voxel_size = volume.header()['voxel_size'] + [1]
    scaling = aims.AffineTransformation3d()
    scaling.fromMatrix(np.diag(voxel_size))
    peaks_vol_coord = np.transpose(np.vstack(np.where(data != 0)))
    centers = [aims.Point3df(p) for p in peaks_vol_coord]
    print(len(centers))

    for i, center in enumerate(centers):
        center = scaling.transform(center)
        sphere = aims.SurfaceGenerator.sphere(center, radius,300)
        if i == 0:
            spheres = sphere
        else:
            aims.SurfaceManip.meshMerge(spheres, sphere)
    aims.write(spheres, path_spheres)
def execution(self, context):
    tr = aims.AffineTransformation3d()
    for t in self.MNI_transform_chain:
        ti = aims.read(t.fullPath())
        tr = ti * tr
    #context.write('transform:', tr)
    vol = aims.read(self.volume.fullPath())
    trl = vol.header().get('transformations', [])
    refl = vol.header().get('referentials', [])

    rname = aims.StandardReferentials.mniTemplateReferential()
    if rname in refl:
        trl[refl.index(rname)] = tr.toVector()
    elif len(trl) < 2:
        #else:
        trl.append(tr.toVector())
        refl.append(rname)
    else:
        trl = [list(trl[0]), list(tr.toVector())] \
            + [list(t) for t in list(trl)[1:]]
        refl = [refl[0], rname] + list(refl)[1:]
    # context.write('now:', refl, trl)
    vol.header()['referentials'] = refl
    vol.header()['transformations'] = trl
    context.write('new header:', vol.header())
    aims.write(vol, self.output_volume.fullPath())
    self.output_volume.readAndUpdateMinf()
    tm = registration.getTransformationManager()
    tm.copyReferential(self.volume,
                       self.output_volume,
                       copy_transformations=False)
Beispiel #4
0
def execution( self, context):
    bvals, bvecs = read_bvals_bvecs(self.bvals.fullPath(), self.bvecs.fullPath())
    if self.round_bvals:
        context.write("Rouding bvalues to : useful for shell based models")
        bvals = np.round(bvals,-2)
    try:
        minf = self.diffusion_data.minf()
        t = minf['storage_to_memory']
    except KeyError:
        context.write("No storage_to_memory field in the  minf file associated to the volume, using the one of the header of the volume")
        dwi = aims.read(self.diffusion_data.fullPath())
        header = dwi.header()
        t = header['storage_to_memory']
    finally:
        try :
            t1 = aims.AffineTransformation3d(t).toMatrix()
            aff = np.diag(t1)[:-1]
            affine = np.diag(aff)
        except:
            context.write("Warning!: there is no storage to memory matrix, I assume bvecs have an RAS (Nifti convention) orientation")
            affine = -1.0*np.eye(3)

    context.write("The following transformation is going to be applied:", affine)
    bvecs = np.dot(bvecs, np.transpose(affine))
    context.write("Transforming bvecs coordinate from storage to Aims referential")


    gtab = gradient_table(bvals, bvecs,b0_threshold=self.b0_threshold)
    dump(gtab, self.gradient_table.fullPath(), compress=9)

    #Handling metadata
    self.gradient_table.setMinf('rounded_bvals', self.round_bvals)
    self.gradient_table.setMinf('bvalues_uuid', self.bvals.uuid())
    self.gradient_table.setMinf('bvectors_uuid',self.bvecs.uuid())
Beispiel #5
0
def execution(self, context):
    from soma import aims, aimsalgo
    import numpy as np
    vol = aims.read(self.image_input.fullPath())
    old_t1_to_scanner = aims.AffineTransformation3d(
        vol.header()['transformations'][0])
    new_t1 = aims.read(self.target_space_image.fullPath())
    new_t1_to_scanner = aims.AffineTransformation3d(
        new_t1.header()['transformations'][0])
    old_to_new = new_t1_to_scanner.inverse() * old_t1_to_scanner
    rsp = getattr(aims, 'ResamplerFactory_' +
                  aims.typeCode(np.asarray(vol).dtype))().getResampler(0)
    rsp.setRef(vol)
    vol_resamp = rsp.doit(old_to_new, new_t1.getSizeX(), new_t1.getSizeY(),
                          new_t1.getSizeZ(),
                          new_t1.getVoxelSize()[:3])

    aims.write(vol_resamp, self.image_output.fullPath())
    tm = registration.getTransformationManager()
    tm.copyReferential(self.target_space_image, self.image_output)
Beispiel #6
0
def build_transformation(self, trans_path, volume):
    ref_s = volume.header()['referential']
    result_tr = aims.AffineTransformation3d()
    for tr in trans_path:
        tr_o = aims.read(tr.fullPath())
        ref_s1 = tr_o.header()['source_referential']
        ref_d1 = tr_o.header()['destination_referential']
        if ref_d1 == ref_s:
            tr_o = tr_o.inverse()
            ref_s = ref_s1
        else:
            ref_s = ref_d1
        result_tr = tr_o * result_tr
    return result_tr
Beispiel #7
0
def get_aims_to_RAS_transfo(path_volume, path_transformation):
    """
    Retrieve the estimated transformation between AIMS mm and RAS mm space
    :param path_volume:
    :param path_transformation:
    :return:
    """
    vol = aims.read(path_volume)
    aims_to_RAS = aims.AffineTransformation3d(
        vol.header()["transformations"][0])
    RAS_to_aims = aims_to_RAS.inverse()
    aff = np.array(aims_to_RAS.toMatrix())
    affine = np.array(RAS_to_aims.toMatrix())
    np.save(path_transformation, affine)
    return affine
Beispiel #8
0
def execution(self, context):
    finder = aims.Finder()
    finder.check(self.read.fullPath())
    hdr = finder.header()
    dims = hdr['volume_dimension'][:3]
    vs = hdr['voxel_size'][:3]
    dims[0] += self.added_border * 2
    dims[1] += self.added_border * 2
    dims[2] += self.added_border * 2
    transfile = context.temporary('Transformation matrix')
    trans = aims.AffineTransformation3d()
    trans.setTranslation([
        self.added_border * vs[0], self.added_border * vs[1],
        self.added_border * vs[2]
    ])
    aims.write(trans, transfile.fullPath())
    cmd = [
        'AimsResample', '-t', 'n', '-i', self.read, '-o', self.write, '--dx',
        dims[0], '--dy', dims[1], '--dz', dims[2], '-m', transfile
    ]
    context.system(*cmd)
Beispiel #9
0
def execution(self, context):
    finder = aims.Finder()
    finder.check(self.read.fullPath())
    hdr = finder.header()
    dims = hdr['volume_dimension'][:3]
    vs = hdr['voxel_size'][:3]
    dims[0] -= self.crop_left + self.crop_right
    dims[1] -= self.crop_front + self.crop_back
    dims[2] -= self.crop_top + self.crop_bottom
    transfile = context.temporary('Transformation matrix')
    trans = aims.AffineTransformation3d()
    trans.setTranslation([
        -self.crop_right * vs[0], -self.crop_front * vs[1],
        -self.crop_top * vs[2]
    ])
    print('transfo:')
    print(trans)
    aims.write(trans, transfile.fullPath())
    cmd = [
        'AimsResample', '-t', 'n', '-i', self.read, '-o', self.write, '--dx',
        dims[0], '--dy', dims[1], '--dz', dims[2], '-m', transfile
    ]
    context.system(*cmd)
# Output file names
OUT_DIR = os.path.join(BASE_DIR, 'data/mask_without_cerebellum')
RESAMPLED_ATLAS_FILE = os.path.join(OUT_DIR, 'TD_lobe_1.5mm.nii')
RESAMPLED_MNI_FILE = os.path.join(OUT_DIR, 'MNI152_T1_1.5mm.nii')

if ~os.path.exists(OUT_DIR):
    os.makedirs(OUT_DIR)

# Converters
U8_2_S16_converter = aims.Converter(aims.Volume_U8, aims.Volume_S16)
S16_2_U8_converter = aims.Converter(aims.Volume_S16, aims.Volume_U8)

# Nearest-neighbor resampler
resp = aims.ResamplerFactory_S16().getResampler(0)
resp.setDefaultValue(-1)  # set background to -1
I = aims.AffineTransformation3d()

# Open mask and get parameters from it
mask = aims.read(MASK_FILE)
mask_header = mask.header()
VOLUME_SIZE = mask_header['volume_dimension']
VOXEL_SIZE = mask_header['voxel_size']
STOM = mask_header['storage_to_memory']

# Open atlas file & convert it
atlas = aims.read(ATLAS_FILE)
atlas_S16 = U8_2_S16_converter(atlas)

# Resampling
resp.setRef(atlas_S16)  # volume to resample
resampled_atlas_S16 = resp.doit(I, VOLUME_SIZE[0], VOLUME_SIZE[1],
def resample(input_image, transformation, output_vs=None, background=0,
             values=None):
    """
        Transform and resample a volume that as discret values

        Parameters
        ----------
        input_image: file
            Path to the input volume (.nii or .nii.gz file)
        transformation: file
            Linear transformation file (.trm file)
        output_vs: tuple
            Output voxel size (default: None, no resampling)
        background: int
            Background value (default: 0)
        values: []
            Array of unique values ordered by descendent priority. If not given,
            priority is set by ascendent values

        Return
        ------
        resampled_vol:
            Transformed and resampled volume
    """
    # Read inputs
    vol = aims.read(input_image)
    vol_dt = vol.__array__()

    if transformation:
        trm = aims.read(transformation)
    else:
        trm = aims.AffineTransformation3d(np.eye(4))
    inv_trm = trm.inverse()

    if output_vs:
        output_vs = np.array(output_vs)
        
        # New volume dimensions
        resampling_ratio = np.array(vol.header()['voxel_size'][:3]) / output_vs
        orig_dim = vol.header()['volume_dimension'][:3]
        new_dim = list((resampling_ratio * orig_dim).astype(int))
    else:
        output_vs = vol.header()['voxel_size'][:3]
        new_dim = vol.header()['volume_dimension'][:3]

    # Transform the background
    # Using the inverse is more straightforward and supports non-linear
    # transforms
    resampled = aims.Volume(new_dim, dtype=vol_dt.dtype)
    resampled.header()['voxel_size'] = output_vs
    # 0 order (nearest neightbours) resampling
    resampler = aimsalgo.ResamplerFactory(vol).getResampler(0)
    resampler.setDefaultValue(background)
    resampler.setRef(vol)
    resampler.resample_inv(vol, inv_trm, 0, resampled)
    resampled_dt = np.asarray(resampled)

    if values is None:
        values = sorted(np.unique(vol_dt[vol_dt != background]))
    else:
        # Reverse order as value are passed by descendent priority
        values = values[::-1]

    # Create one bucket by value (except background)
    # FIXME: Create several buckets because I didn't understood how to add
    #  several bucket to a BucketMap
    for i, v in enumerate(values):
        bck = aims.BucketMap_VOID()
        bck.setSizeXYZT(*vol.header()['voxel_size'][:3], 1.)
        bk0 = bck[0]
        for p in np.vstack(np.where(vol_dt == v)[:3]).T:
            bk0[list(p)] = v

        bck2 = aimsalgo.resampleBucket(bck, trm, inv_trm, output_vs)

        # FIXME: Could not assign the correct value with the converter.
        # Using the converter, the new_dim must incremented
        # conv = aims.Converter(intype=bck2, outtype=aims.AimsData(vol))
        # conv.convert(bck2, resampled)
        # Use a for loop instead:
        for p in bck2[0].keys():
            c = p.list()
            if c[0] < new_dim[0] and c[1] < new_dim[1] and c[2] < new_dim[2]:
                resampled_dt[c[0], c[1], c[2]] = values[i]

    return resampled
def compute_geodesic_depth_map(parameters):
    DIR_F, DIR_BV, s_id = parameters
    path_nu = os.path.join(DIR_F, s_id, 'T1w', s_id, 'mri', 'nu.mgz')
    path_nat = os.path.join(DIR_F, s_id, 'T1w', s_id, 'mri', 'orig', '001.mgz')
    nu_nii = os.path.join(DIR_BV, s_id, 'mri', 'nu.nii.gz')
    native_nii = os.path.join(DIR_BV, s_id, 'mri', 'native.nii.gz')
    outdir = os.path.dirname(nu_nii)
    if not os.path.isdir(outdir):
        os.makedirs(outdir)
    #mri_convert(path_nu, nu_nii)
    #mri_convert(path_nat, native_nii)
    path_ribbon = os.path.join(DIR_F, s_id, 'T1w', s_id, 'mri', 'ribbon.mgz')
    ribbon_nii = os.path.join(DIR_BV, s_id, 'mri', 'ribbon.nii.gz')
    #mri_convert(path_ribbon, ribbon_nii)
    for vol in [nu_nii, native_nii, ribbon_nii]:
        # Convert file to Aims format
        cmd = " ".join(['AimsFileConvert',
                        '-i %s' % vol,
                        '-o %s' % vol,
                        '-t S16'])
        print cmd
        os.system(cmd)
        
    # Replace the label in the ribbon with Morphologist expected label
    ribbon_bv = os.path.join(DIR_BV, s_id, 'mri', 'ribbon_bv.nii.gz')
    cmd = " ".join(['AimsReplaceLevel',
                    '-i %s' % ribbon_nii,
                    '-o %s' % ribbon_bv,
                    '-g 42 41 2 3',
                    '-n 100 200 200 100'])
    print cmd
    os.system(cmd)
    # Split the hemisphere and replace labels
    l_gw = os.path.join(DIR_BV, s_id, 'mri', 'Lgrey_white'+s_id+'.nii.gz')
    r_gw = os.path.join(DIR_BV, s_id, 'mri', 'Rgrey_white'+s_id+'.nii.gz')
    cmd = " ".join(['AimsReplaceLevel',
                    '-i %s' % ribbon_nii,
                    '-o %s' % l_gw,
                    '-g 42 41 2 3',
                    '-n 0 0 200 100'])
    print cmd
    os.system(cmd)
    cmd = " ".join(['AimsReplaceLevel',
                    '-i %s' % ribbon_nii,
                    '-o %s' % r_gw,
                    '-g 42 41 2 3',
                    '-n 100 200 0 0'])
    print cmd
    os.system(cmd)

    # Compute the grey/white histogram
    histo = os.path.join(DIR_BV, s_id, 'mri', 'nu_'+s_id+'.his')
    cmd = " ".join(['VipGreyStatFromClassif',
                    '-i %s' % nu_nii,
                    '-c %s' % ribbon_bv,
                    '-a %s' % histo,
                    '-g 100 -w 200'])
    print cmd
    os.system(cmd)
    # Create the hemi cortex required for the geodesic depth process
    l_hemcor = os.path.join(DIR_BV, s_id, 'mri', 'Lcortex_'+s_id+'.nii.gz')
    r_hemcor = os.path.join(DIR_BV, s_id, 'mri', 'Rcortex_'+s_id+'.nii.gz')
    for gw, hemcor in zip([l_gw, r_gw], [l_hemcor, r_hemcor]):
        cmd = " ".join(['VipHomotopic',
                        '-i %s' % nu_nii,
                        '-cl %s' % gw,
                        '-h %s' % histo+'.han',
                        '-o %s' % hemcor,
                        '-m C -w t'])
        print cmd
        os.system(cmd)

    # Freesurfer surface are in native space, but not the ribbon
    # Thus, we tranform the obtained hemicortex to the native space
    ribbon = aims.read(ribbon_nii) 
    native = aims.read(native_nii)
    s2sb = aims.AffineTransformation3d(ribbon.header()['transformations'][0])
    n2sb = aims.AffineTransformation3d(native.header()['transformations'][0])
    s2n = n2sb.inverse() * s2sb
    transfo_fs2nat = os.path.join(DIR_BV, s_id, 'mri', 'fs2nat.trm')
    aims.write(s2n, transfo_fs2nat)
    for hemcor in [l_hemcor, r_hemcor]:
        cmd = " ".join(['AimsResample',
                        '-i %s' % hemcor,
                        '-o %s' % hemcor,
                        '-m %s' % transfo_fs2nat,
                        '-t  0',
                        '-r %s' % native_nii])
        print cmd
        os.system(cmd)
    
    l_white = os.path.join(DIR_BV, s_id, 't1mri/BL/default_analysis',
                           'segmentation/mesh', s_id+'_Lwhite.gii')
    l_white_aims = os.path.join(DIR_BV, s_id, 't1mri/BL/default_analysis',
                                'segmentation/mesh', s_id+'_Lwhite_aims.gii')
    l_depth = os.path.join(DIR_BV, s_id, 't1mri/BL/default_analysis',
                           'segmentation/mesh/surface_analysis',
                           s_id+'_Lgeodesic_depth.gii')
    r_white = os.path.join(DIR_BV, s_id, 't1mri/BL/default_analysis',
                           'segmentation/mesh', s_id+'_Rwhite.gii')
    r_white_aims = os.path.join(DIR_BV, s_id, 't1mri/BL/default_analysis',
                            'segmentation/mesh', s_id+'_Rwhite_aims.gii')
    r_depth = os.path.join(DIR_BV, s_id, 't1mri/BL/default_analysis',
                           'segmentation/mesh/surface_analysis',
                           s_id+'_Rgeodesic_depth.gii')

    # Convert mesh to Aims Referential
    from freesurfer.freesurferMeshToAimsMesh import freesurferMeshToAimsMesh
    for white, white_aims in zip([l_white, r_white],
                                 [l_white_aims, r_white_aims]):
        freesurferMeshToAimsMesh(white, native_nii, white_aims)

        

    # Finally compute the geodesic depth of interest 
    for white, hemcor, depth in zip([l_white_aims, r_white_aims],
                                    [l_hemcor, r_hemcor], [l_depth, r_depth]):
            
        cmd = " ".join(['python -m brainvisa.axon.runprocess',
                        'whitemeshdepthmap',
                        white,
                        hemcor,
                        depth,
                        '10.0']) # closing_size
        print cmd
        os.system(cmd)


        # Another option is to compute the geodesic depth map in the volume
        # The code is commented below, however it performs sighlty worse
        """
Beispiel #13
0
def aims_get_transformation(src, ref):
    from soma import aims
    src3mni = aims.AffineTransformation3d(src.header()['transformations'][0])
    ref2mni = aims.AffineTransformation3d(ref.header()['transformations'][0])
    src2ref = ref2mni.inverse() * src3mni
    return src2ref