Ejemplo n.º 1
0
    def compute(self):
        
        all_data = self.getData('data')
        xml_header = self.getData('ISMRMRDHeader')

        header = ismrmrd.xsd.CreateFromDocument(xml_header)
        enc = header.encoding[0]

        #Parallel imaging factor
        acc_factor = 1
        if enc.parallelImaging:
            acc_factor = enc.parallelImaging.accelerationFactor.kspace_encoding_step_1
        
        # Coil combination
        print "Calculating coil images and CSM"
        coil_images = transform.transform_kspace_to_image(np.squeeze(np.mean(all_data,0)),(1,2))
        (csm,rho) = coils.calculate_csm_walsh(coil_images)
        csm_ss = np.sum(csm * np.conj(csm),0)
        csm_ss = csm_ss + 1.0*(csm_ss < np.spacing(1)).astype('float32')
        
        if acc_factor > 1:
            coil_data = np.squeeze(np.mean(all_data,0))
            
            if self.getVal('Parallel Imaging Method') == 0:
                (unmix,gmap) = grappa.calculate_grappa_unmixing(coil_data, acc_factor,csm=csm)
            elif self.getVal('Parallel Imaging Method') == 1:
                (unmix,gmap) = sense.calculate_sense_unmixing(acc_factor,csm)
            else:
                raise Exception('Unknown parallel imaging method')

        recon = np.zeros((all_data.shape[-4],all_data.shape[-2],all_data.shape[-1]), dtype=np.complex64)
        
        for r in range(0,all_data.shape[-4]):
            recon_data = transform.transform_kspace_to_image(np.squeeze(all_data[r,:,:,:]),(1,2))*np.sqrt(acc_factor)
            if acc_factor > 1:
                recon[r,:,:] = np.sum(unmix * recon_data,0)
            else:
                recon[r,:,:] = np.sum(np.conj(csm) * recon_data,0)

        print "Reconstruction done"
        
        self.setData('recon', recon)
        
        if acc_factor == 1:
            gmap = np.ones((all_data.shape[-2],all_data.shape[-1]),dtype=np.float32)
            
        self.setData('gmap',gmap)

        return 0
Ejemplo n.º 2
0
    def process(self, acq, data,*args):

        if self.buffer is None:
            # Matrix size
            eNx = self.enc.encodedSpace.matrixSize.x
            eNy = self.enc.encodedSpace.matrixSize.y
            eNz = self.enc.encodedSpace.matrixSize.z
            rNx = self.enc.reconSpace.matrixSize.x
            rNy = self.enc.reconSpace.matrixSize.y
            rNz = self.enc.reconSpace.matrixSize.z

            # Field of View
            eFOVx = self.enc.encodedSpace.fieldOfView_mm.x
            eFOVy = self.enc.encodedSpace.fieldOfView_mm.y
            eFOVz = self.enc.encodedSpace.fieldOfView_mm.z
            rFOVx = self.enc.reconSpace.fieldOfView_mm.x
            rFOVy = self.enc.reconSpace.fieldOfView_mm.y
            rFOVz = self.enc.reconSpace.fieldOfView_mm.z
        
            channels = acq.active_channels

            if data.shape[1] != rNx:
                raise("Error, Recon gadget expects data to be on correct matrix size in RO direction")
                
            if (rNz != 1):
                rasie("Error Recon Gadget only supports 2D for now")
                
            self.buffer = np.zeros((channels, rNy, rNx),dtype=np.complex64)
            self.samp_mask = np.zeros(self.buffer.shape[1:])
            self.header_proto = ismrmrd.ImageHeader()
            self.header_proto.matrix_size[0] = rNx
            self.header_proto.matrix_size[1] = rNy
            self.header_proto.matrix_size[2] = rNz
            self.header_proto.field_of_view[0] = rFOVx
            self.header_proto.field_of_view[1] = rFOVy
            self.header_proto.field_of_view[0] = rFOVz
        
        #Now put data in buffer
        line_offset = self.buffer.shape[1]/2 - self.enc.encodingLimits.kspace_encoding_step_1.center                                                                                 
        self.buffer[:,acq.idx.kspace_encode_step_1+line_offset,:] = data                                                          
        self.samp_mask[acq.idx.kspace_encode_step_1+line_offset,:] = 1
        
        #If last scan in buffer, do FFT and fill image header
        if acq.isFlagSet(ismrmrd.ACQ_LAST_IN_ENCODE_STEP1) or acq.isFlagSet(ismrmrd.ACQ_LAST_IN_SLICE):
            img_head = copy.deepcopy(self.header_proto)
            img_head.position = acq.position                                                                                                                               
            img_head.read_dir = acq.read_dir                                                                                                                               
            img_head.phase_dir = acq.phase_dir                                                                                                                             
            img_head.slice_dir = acq.slice_dir                                                                                                                             
            img_head.patient_table_position = acq.patient_table_position                                                                                                   
            img_head.acquisition_time_stamp = acq.acquisition_time_stamp                                                                                                   
            img_head.slice = acq.idx.slice
            img_head.channels = 1
            
            scale = self.samp_mask.size/(1.0*np.sum(self.samp_mask[:]));

            #We have not yet calculated unmixing coefficients
            if self.unmix is None:
                self.calib_buffer.append((img_head,self.buffer.copy()))
                self.buffer[:] = 0
                self.samp_mask[:] = 0
                
                if len(self.calib_buffer) >= self.calib_frames:
                    cal_data = np.zeros(self.calib_buffer[0][1].shape, dtype=np.complex64)
                    for c in self.calib_buffer:
                        cal_data = cal_data + c[1]
                        
                    mask = np.squeeze(np.sum(np.abs(cal_data),0))
                    mask = np.ones(mask.shape)*(np.abs(mask)>0.0)
                    target = None #cal_data[0:8,:,:]
                    
                    coil_images = transform.transform_kspace_to_image(cal_data,dim=(1,2))
                    (csm,rho) = coils.calculate_csm_walsh(coil_images)
                    
                    if self.method == 'grappa':
                        self.unmix, self.gmap = grappa.calculate_grappa_unmixing(cal_data, 
                                                                                 self.acc_factor, 
                                                                                 data_mask=mask, 
                                                                                 kernel_size=(4,5), 
                                                                                 csm=csm)
                    elif self.method == 'sense':
                        self.unmix, self.gmap = sense.calculate_sense_unmixing(self.acc_factor, csm)
                    else:
                        raise Exception('Unknown parallel imaging method: ' + str(self.method))
                        
                    for c in self.calib_buffer:
                        recon = transform.transform_kspace_to_image(c[1],dim=(1,2))*np.sqrt(scale)
                        recon = np.squeeze(np.sum(recon * self.unmix,0))
                        self.put_next(c[0], recon,*args)
                        
                return 0
                
            if self.unmix is None:
                raise Exception("We should never reach this point without unmixing coefficients")
                
            recon = transform.transform_kspace_to_image(self.buffer,dim=(1,2))*np.sqrt(scale)
            recon = np.squeeze(np.sum(recon * self.unmix,0))
            self.buffer[:] = 0
            self.samp_mask[:] = 0
            self.put_next(img_head,recon,*args)
        return 0
# -*- coding: utf-8 -*-

#%%
#Basic setup
import time
import numpy as np
from ismrmrdtools import simulation, coils, show

matrix_size = 256
csm = simulation.generate_birdcage_sensitivities(matrix_size)
phan = simulation.phantom(matrix_size)
coil_images = phan[np.newaxis, :, :] * csm
show.imshow(abs(coil_images), tile_shape=(4, 2))

tstart = time.time()
(csm_est, rho) = coils.calculate_csm_walsh(coil_images)
print("Walsh coil estimation duration: {}s".format(time.time() - tstart))
combined_image = np.sum(csm_est * coil_images, axis=0)

show.imshow(abs(csm_est), tile_shape=(4, 2), scale=(0, 1))
show.imshow(abs(combined_image), scale=(0, 1))

tstart = time.time()
(csm_est2, rho2) = coils.calculate_csm_inati_iter(coil_images)
print("Inati coil estimation duration: {}s".format(time.time() - tstart))
combined_image2 = np.sum(csm_est2 * coil_images, axis=0)

show.imshow(abs(csm_est2), tile_shape=(4, 2), scale=(0, 1))
show.imshow(abs(combined_image2), scale=(0, 1))