def process(self, acq, data): orig_size = list(data.shape); data2 = data.reshape([(data.size/data.shape[data.ndim-1]), data.shape[data.ndim-1]]) new_length = data2.shape[1]>>1 data2 = transform.transform_image_to_kspace(transform.transform_kspace_to_image(data2,dim=(1,))[:,(0+(new_length>>1)):(new_length+(new_length>>1))],dim=(1,)) orig_size[data.ndim-1] = new_length data2.reshape(tuple(orig_size)) acq.samples = new_length self.put_next(acq,data2) return 0
def process(self, acq, data): orig_size = list(data.shape) data2 = data.reshape([data.shape[0], int(data.size / data.shape[0])]) new_length = data2.shape[0] >> 1 data2 = transform.transform_image_to_kspace( transform.transform_kspace_to_image( data2, dim=(0, ))[(0 + (new_length >> 1)):(new_length + (new_length >> 1)), :], dim=(0, )) orig_size[0] = new_length data2.reshape(tuple(orig_size)) acq.samples = new_length self.put_next(acq, data2) return 0
def sample_data(img_obj, csm, acc=1, ref=0, sshift=0): #% Samples the k-space of object provided in 'img_obj' after first applying #% coil sensitivity maps in 'csm' and Fourier transforming to k-space. #% #% INPUT: #% - img_obj [x,y] : Object in image space #% - csm [x,y,c] : Coil sensitivity maps #% - acc scalar : Acceleration factor #% - ref scalar : Reference lines (in center of k-space) #% - sshift scalar : Sampling shift, i.e for undersampling, do we #% start with line 1 or line 1+sshift? #% #% OUPUT: #% - data [kx,ky,c]: Sampled data in k-space (zeros where not sampled) #% - pat [kx,ky,c]: Sampling pattern (0 = not sampled, #% 1 = imaging data, #% 2 = reference data, #% 3 = reference and imaging data) #% #% #% Code made available for the ISMRM 2013 Sunrise Educational Course #% #% Michael S. Hansen ([email protected]) #% sshift = sshift % acc assert img_obj.ndim == 2, "Only two dimensional objects supported at the moment" assert csm.ndim == 3, "csm must be a 3 dimensional array" assert img_obj.shape[0] == csm.shape[ 1], "Object and csm dimension mismatch" assert img_obj.shape[1] == csm.shape[ 2], "Object and csm dimension mismatch" pat_img = np.zeros(img_obj.shape, dtype=np.int8) pat_img[sshift:-1:acc, :] = 1 pat_ref = np.zeros(img_obj.shape, dtype=np.int8) if ref > 0: pat_ref[(0 + img_obj.shape[0] / 2):(ref + img_obj.shape[0] / 2), :] = 2 pat = pat_img + pat_ref coil_images = np.tile(img_obj, (csm.shape[0], 1, 1)) * csm data = transform.transform_image_to_kspace(coil_images, dim=(1, 2)) data = data * (np.tile(pat, (csm.shape[0], 1, 1)) > 0).astype('float32') return (data, pat)
def process(self, acq, data,*args): if not acq.isFlagSet(ismrmrd.ACQ_IS_NOISE_MEASUREMENT): ro_length = acq.number_of_samples padded_ro_length = (acq.number_of_samples-acq.center_sample)*2 if padded_ro_length != ro_length: #partial fourier data2 = np.zeros((data.shape[0], padded_ro_length),dtype=np.complex64) offset = (padded_ro_length>>1) - acq.center_sample data2[:,0+offset:offset+ro_length] = data else: data2 = data data2=transform.transform_kspace_to_image(data2,dim=(1,)) data2=data2[:,(padded_ro_length>>2):(padded_ro_length>>2)+(padded_ro_length>>1)] data2=transform.transform_image_to_kspace(data2,dim=(1,)) * np.sqrt(float(padded_ro_length)/ro_length) acq.center_sample = padded_ro_length>>2 acq.number_of_samples = data2.shape[1] self.put_next(acq,data2,*args) return 0
def sample_data(img_obj, csm, acc=1, ref=0, sshift=0): #% Samples the k-space of object provided in 'img_obj' after first applying #% coil sensitivity maps in 'csm' and Fourier transforming to k-space. #% #% INPUT: #% - img_obj [x,y] : Object in image space #% - csm [x,y,c] : Coil sensitivity maps #% - acc scalar : Acceleration factor #% - ref scalar : Reference lines (in center of k-space) #% - sshift scalar : Sampling shift, i.e for undersampling, do we #% start with line 1 or line 1+sshift? #% #% OUPUT: #% - data [kx,ky,c]: Sampled data in k-space (zeros where not sampled) #% - pat [kx,ky,c]: Sampling pattern (0 = not sampled, #% 1 = imaging data, #% 2 = reference data, #% 3 = reference and imaging data) #% #% #% Code made available for the ISMRM 2013 Sunrise Educational Course #% #% Michael S. Hansen ([email protected]) #% sshift = sshift%acc; assert img_obj.ndim == 2, "Only two dimensional objects supported at the moment" assert csm.ndim == 3, "csm must be a 3 dimensional array" assert img_obj.shape[0] == csm.shape[1], "Object and csm dimension mismatch" assert img_obj.shape[1] == csm.shape[2], "Object and csm dimension mismatch" pat_img = np.zeros(img_obj.shape,dtype=np.int8) pat_img[sshift:-1:acc,:] = 1 pat_ref = np.zeros(img_obj.shape,dtype=np.int8) if ref>0: pat_ref[(0+img_obj.shape[0]/2):(ref+img_obj.shape[0]/2),:] = 2 pat = pat_img + pat_ref coil_images = np.tile(img_obj,(csm.shape[0], 1, 1)) * csm data = transform.transform_image_to_kspace(coil_images,dim=(1,2)) data = data * (np.tile(pat,(csm.shape[0], 1, 1))>0).astype('float32') return (data,pat)
a = diff_angle.sum() plt.title(str("{0:.9f}".format(a))) plt.show() folder = "/home/benoit/Documents/IHUBordeaux/test_sms_4/out/" name = "donnee_mb_apres_extract_memcpy" name2 = "donnee_sb_apres_extract_memcpy" print(folder + name) ref_coil_map = read_real_imaginary_part(folder, name) ref_coil_map2 = read_real_imaginary_part(folder, name2) dims = (ref_coil_map.shape) dims2 = (ref_coil_map2.shape) print(dims) print(dims2) cha = 0 slc = 0 kspace_data = ref_coil_map[:, :, 0, cha, 0, 0, slc] kspace_data2 = ref_coil_map2[:, :, 0, cha, 0, 0, slc] image = transform.transform_image_to_kspace(kspace_data, dim=(0, 1)) image2 = transform.transform_image_to_kspace(kspace_data2, dim=(0, 1)) display(kspace_data2, image2) display(kspace_data, image) #comparaison(kspace_data, kspace_data2)
def create(filename='testdata.h5', matrix_size=256, coils=8, oversampling=2, repetitions=1, acceleration=1, noise_level=0.05): # Generate the phantom and coil sensitivity maps phan = simulation.phantom(matrix_size) csm = simulation.generate_birdcage_sensitivities(matrix_size, coils) coil_images = np.tile(phan, (coils, 1, 1)) * csm # Oversample if needed if oversampling > 1: padding = round((oversampling * phan.shape[1] - phan.shape[1]) / 2) phan = np.pad(phan, ((0, 0), (padding, padding)), mode='constant') csm = np.pad(csm, ((0, 0), (0, 0), (padding, padding)), mode='constant') coil_images = np.pad(coil_images, ((0, 0), (0, 0), (padding, padding)), mode='constant') # The number of points in x,y,kx,ky nx = matrix_size ny = matrix_size nkx = oversampling * nx nky = ny # Open the dataset dset = ismrmrd.Dataset(filename, "dataset", create_if_needed=True) # Create the XML header and write it to the file header = ismrmrd.xsd.ismrmrdHeader() # Experimental Conditions exp = ismrmrd.xsd.experimentalConditionsType() exp.H1resonanceFrequency_Hz = 128000000 header.experimentalConditions = exp # Acquisition System Information sys = ismrmrd.xsd.acquisitionSystemInformationType() sys.receiverChannels = coils header.acquisitionSystemInformation = sys # Encoding encoding = ismrmrd.xsd.encoding() encoding.trajectory = ismrmrd.xsd.trajectoryType.cartesian # encoded and recon spaces efov = ismrmrd.xsd.fieldOfView_mm() efov.x = oversampling * 256 efov.y = 256 efov.z = 5 rfov = ismrmrd.xsd.fieldOfView_mm() rfov.x = 256 rfov.y = 256 rfov.z = 5 ematrix = ismrmrd.xsd.matrixSize() ematrix.x = nkx ematrix.y = nky ematrix.z = 1 rmatrix = ismrmrd.xsd.matrixSize() rmatrix.x = nx rmatrix.y = ny rmatrix.z = 1 espace = ismrmrd.xsd.encodingSpaceType() espace.matrixSize = ematrix espace.fieldOfView_mm = efov rspace = ismrmrd.xsd.encodingSpaceType() rspace.matrixSize = rmatrix rspace.fieldOfView_mm = rfov # Set encoded and recon spaces encoding.encodedSpace = espace encoding.reconSpace = rspace # Encoding limits limits = ismrmrd.xsd.encodingLimitsType() limits1 = ismrmrd.xsd.limitType() limits1.minimum = 0 limits1.center = round(ny / 2) limits1.maximum = ny - 1 limits.kspace_encoding_step_1 = limits1 limits_rep = ismrmrd.xsd.limitType() limits_rep.minimum = 0 limits_rep.center = round(repetitions / 2) limits_rep.maximum = repetitions - 1 limits.repetition = limits_rep limits_rest = ismrmrd.xsd.limitType() limits_rest.minimum = 0 limits_rest.center = 0 limits_rest.maximum = 0 limits.kspace_encoding_step_0 = limits_rest limits.slice = limits_rest limits.average = limits_rest limits.contrast = limits_rest limits.kspaceEncodingStep2 = limits_rest limits.phase = limits_rest limits.segment = limits_rest limits.set = limits_rest encoding.encodingLimits = limits header.encoding.append(encoding) dset.write_xml_header(header.toxml('utf-8')) # Synthesize the k-space data Ktrue = transform.transform_image_to_kspace(coil_images, (1, 2)) # Create an acquistion and reuse it acq = ismrmrd.Acquisition() acq.resize(nkx, coils) acq.version = 1 acq.available_channels = coils acq.center_sample = round(nkx / 2) acq.read_dir[0] = 1.0 acq.phase_dir[1] = 1.0 acq.slice_dir[2] = 1.0 # Initialize an acquisition counter counter = 0 # Write out a few noise scans for n in range(32): noise = noise_level * (np.random.randn(coils, nkx) + 1j * np.random.randn(coils, nkx)) # here's where we would make the noise correlated acq.scan_counter = counter acq.clearAllFlags() acq.setFlag(ismrmrd.ACQ_IS_NOISE_MEASUREMENT) acq.data[:] = noise dset.append_acquisition(acq) counter += 1 # increment the scan counter # Loop over the repetitions, add noise and write to disk # simulating a T-SENSE type scan for rep in range(repetitions): noise = noise_level * (np.random.randn(coils, nky, nkx) + 1j * np.random.randn(coils, nky, nkx)) # here's where we would make the noise correlated K = Ktrue + noise acq.idx.repetition = rep for acc in range(acceleration): for line in np.arange(acc, nky, acceleration): # set some fields in the header acq.scan_counter = counter acq.idx.kspace_encode_step_1 = line acq.clearAllFlags() if line == 0: acq.setFlag(ismrmrd.ACQ_FIRST_IN_ENCODE_STEP1) acq.setFlag(ismrmrd.ACQ_FIRST_IN_SLICE) acq.setFlag(ismrmrd.ACQ_FIRST_IN_REPETITION) elif line == nky - 1: acq.setFlag(ismrmrd.ACQ_LAST_IN_ENCODE_STEP1) acq.setFlag(ismrmrd.ACQ_LAST_IN_SLICE) acq.setFlag(ismrmrd.ACQ_LAST_IN_REPETITION) # set the data and append acq.data[:] = K[:, line, :] dset.append_acquisition(acq) counter += 1 # Clean up dset.close()
def load_ismrmrd_ifft3d_reconstruction(filename): """ Load .h5 file, read header (head) and reconstruct images Parameters ---------- filename : path to the .h5 file Returns ------- head : read imsrmrd dataset head (dataset.head) hdr : deserialized ismrmrd xml dataset file img_scaled : reconstructed image """ if not os.path.isfile(filename): print("%s is not a valid file" % filename) raise SystemExit dset = ismrmrd.Dataset(filename, 'dataset', create_if_needed=False) #Read some fields from the XML header hdr = ismrmrd.xsd.CreateFromDocument(dset.read_xml_header()) #get encoding and reconstruction information enc = hdr.encoding[0] # Matrix size eNx = enc.encodedSpace.matrixSize.x eNy = enc.encodedSpace.matrixSize.y eNz = enc.encodedSpace.matrixSize.z rNx = enc.reconSpace.matrixSize.x # Number of Slices, Reps, Contrasts, etc. #We have to wrap the following in a if/else because a valid xml header may #not have an entry for some of the parameters ncoils = hdr.acquisitionSystemInformation.receiverChannels if enc.encodingLimits.slice != None: nslices = enc.encodingLimits.slice.maximum + 1 else: nslices = 1 if enc.encodingLimits.repetition != None: nreps = enc.encodingLimits.repetition.maximum + 1 else: nreps = 1 if enc.encodingLimits.contrast != None: ncontrasts = enc.encodingLimits.contrast.maximum + 1 else: ncontrasts = 1 # Loop through the acquisitions looking for noise scans firstacq = 0 for acqnum in range(dset.number_of_acquisitions()): acq = dset.read_acquisition(acqnum) # TODO: Currently ignoring noise scans if acq.isFlagSet(ismrmrd.ACQ_IS_NOISE_MEASUREMENT): print("Found noise scan at acq ", acqnum) continue else: firstacq = acqnum print("Imaging acquisition starts acq ", acqnum) break # Initialiaze a storage array all_data = np.zeros((nreps, ncontrasts, nslices, ncoils, eNz, eNy, rNx), dtype=np.complex64) # Loop through the rest of the acquisitions and stuff for acqnum in range(firstacq, dset.number_of_acquisitions()): acq = dset.read_acquisition(acqnum) head = acq.getHead() # TODO: this is where we would apply noise pre-whitening #padd if acquisition data is not complete (padding) if acq.data.shape[1] < eNx: x0 = int((eNx - acq.data.shape[1]) / 2) zeros = np.zeros((acq.data.shape[0], x0)) padded_acq_data = np.append(np.append(zeros, acq.data, axis=1), zeros, axis=1) acq.resize(eNx, acq.active_channels, acq.trajectory_dimensions) acq.data[:] = padded_acq_data # Remove oversampling if needed if eNx != rNx: #xline = transform.transform_kspace_to_image(acq.data, [1]) xline = transform.transform_kspace_to_image(acq.data, dim=(1, ), img_shape=(eNx, )) x0 = int((eNx - rNx) / 2) x1 = int((eNx - rNx) / 2 + rNx) xline = xline[:, x0:x1] acq.resize(rNx, acq.active_channels, acq.trajectory_dimensions) acq.center_sample = int(rNx / 2) # need to use the [:] notation here to fill the data acq.data[:] = transform.transform_image_to_kspace(xline, dim=(1, ), k_shape=(rNx, )) # Stuff into the buffer rep = acq.idx.repetition contrast = acq.idx.contrast slice = acq.idx.slice y = acq.idx.kspace_encode_step_1 z = acq.idx.kspace_encode_step_2 all_data[rep, contrast, slice, :, z, y, :] = acq.data # Reconstruct images images = np.zeros((nreps, ncontrasts, nslices, eNz, eNy, rNx), dtype=np.float32) img_scaled = [] for rep in range(nreps): for contrast in range(ncontrasts): for slice in range(nslices): # FFT if eNz > 1: # 3D im = transform.transform_kspace_to_image( all_data[rep, contrast, slice, :, :, :, :], [1, 2, 3]) else: # 2D im = transform.transform_kspace_to_image( all_data[rep, contrast, slice, :, 0, :, :], [2, 3]) # Sum of squares im = np.sqrt(np.sum(np.abs(im)**2, 0)) # Stuff into the output if eNz > 1: # 3D images[rep, contrast, slice, :, :, :] = im else: # 2D images[rep, contrast, slice, 0, :, :] = im img_scaled.append(im) dset.close() return [head, hdr, img_scaled]
# Loop through the rest of the acquisitions and stuff for acqnum in range(firstacq, dset.number_of_acquisitions()): acq = dset.read_acquisition(acqnum) # TODO: this is where we would apply noise pre-whitening # Remove oversampling if needed if eNx != rNx: xline = transform.transform_kspace_to_image(acq.data, [1]) x0 = (eNx - rNx) / 2 x1 = (eNx - rNx) / 2 + rNx xline = xline[:, x0:x1] acq.resize(rNx, acq.active_channels, acq.trajectory_dimensions) acq.center_sample = rNx / 2 # need to use the [:] notation here to fill the data acq.data[:] = transform.transform_image_to_kspace(xline, [1]) # Stuff into the buffer rep = acq.idx.repetition contrast = acq.idx.contrast slice = acq.idx.slice y = acq.idx.kspace_encode_step_1 z = acq.idx.kspace_encode_step_2 all_data[rep, contrast, slice, :, z, y, :] = acq.data # Reconstruct images images = np.zeros((nreps, ncontrasts, nslices, eNz, eNy, rNx), dtype=np.float32) for rep in range(nreps): for contrast in range(ncontrasts): for slice in range(nslices):
databuff[:, 0:acq.data.shape[1]] = acq.data else: #databuff[:,xcenter-acq.data.shape[1]/2:xcenter+acq.data.shape[1]/2] = acq.data databuff = acq.data #databuff = acq.data if args.removeOS: print "removeOS" xline = transform.transform_kspace_to_image(databuff, [1]) x0 = (eNx - rNx) / 2 x1 = (eNx - rNx) / 2 + rNx / 2 xline = xline[:, x0:x1] databuff.resize(rNx, acq.active_channels, acq.trajectory_dimensions) acq.center_sample = rNx / 2 # need to use the [:] notation here to fill the data databuff = transform.transform_image_to_kspace(xline, [1]) #print "databuff.shape=", databuff.shape print "seg", seg, " / avg", avg, " / set_", set_, " / rep", rep, " / contrast", contrast, " / slice_", slice, " / xcenter", xcenter, " / y", y, " / z", z if acq.isFlagSet(ismrmrd.ACQ_IS_PARALLEL_CALIBRATION): print "calibration data: acq:", acqnum all_data_calib[seg, set_, avg, phase, rep, contrast, slice, :, z, y, :] = databuff elif acq.isFlagSet(ismrmrd.ACQ_IS_PARALLEL_CALIBRATION_AND_IMAGING): print "calibration data and imaging: acq:", acqnum all_data_calib[seg, set_, avg, phase, rep, contrast, slice, :, z, y, :] = databuff elif acq.isFlagSet(ismrmrd.ACQ_IS_DUMMYSCAN_DATA): print "dummy scan data: acq:", acqnum #all_data[seg,set_,avg, phase, rep, contrast, slice, :, z, y, : ] = databuff;
# Loop through the rest of the acquisitions and stuff for acqnum in range(firstacq,dset.number_of_acquisitions()): acq = dset.read_acquisition(acqnum) # TODO: this is where we would apply noise pre-whitening # Remove oversampling if needed if eNx != rNx: xline = transform.transform_kspace_to_image(acq.data, [1]) x0 = (eNx - rNx) / 2 x1 = (eNx - rNx) / 2 + rNx xline = xline[:,x0:x1] acq.resize(rNx,acq.active_channels,acq.trajectory_dimensions) acq.center_sample = rNx/2 # need to use the [:] notation here to fill the data acq.data[:] = transform.transform_image_to_kspace(xline, [1]) # Stuff into the buffer rep = acq.idx.repetition contrast = acq.idx.contrast slice = acq.idx.slice y = acq.idx.kspace_encode_step_1 z = acq.idx.kspace_encode_step_2 all_data[rep, contrast, slice, :, z, y, :] = acq.data # Reconstruct images images = np.zeros((nreps, ncontrasts, nslices, eNz, eNy, rNx), dtype=np.float32) for rep in range(nreps): for contrast in range(ncontrasts): for slice in range(nslices): # FFT
def test_bssfp_data(self): '''Sample bSSFP data set.''' dset = pyport(file=self.sample, debug=False) import numpy as np import ismrmrd import ismrmrd.xsd from ismrmrdtools import show, transform header = ismrmrd.xsd.CreateFromDocument(dset.read_xml_header()) enc = header.encoding[0] # Matrix size eNx = enc.encodedSpace.matrixSize.x eNy = enc.encodedSpace.matrixSize.y eNz = enc.encodedSpace.matrixSize.z rNx = enc.reconSpace.matrixSize.x _rNy = enc.reconSpace.matrixSize.y _rNz = enc.reconSpace.matrixSize.z # Field of View _eFOVx = enc.encodedSpace.fieldOfView_mm.x _eFOVy = enc.encodedSpace.fieldOfView_mm.y _eFOVz = enc.encodedSpace.fieldOfView_mm.z _rFOVx = enc.reconSpace.fieldOfView_mm.x _rFOVy = enc.reconSpace.fieldOfView_mm.y _rFOVz = enc.reconSpace.fieldOfView_mm.z # Number of Slices, Reps, Contrasts, etc. ncoils = header.acquisitionSystemInformation.receiverChannels if enc.encodingLimits.slice is not None: nslices = enc.encodingLimits.slice.maximum + 1 else: nslices = 1 if enc.encodingLimits.average is not None: nreps = enc.encodingLimits.average.maximum + 1 else: nreps = 1 if enc.encodingLimits.contrast is not None: ncontrasts = enc.encodingLimits.contrast.maximum + 1 else: ncontrasts = 1 # TODO loop through the acquisitions looking for noise scans firstacq = 0 for acqnum in range(dset.number_of_acquisitions()): acq = dset.read_acquisition(acqnum) # TODO: Currently ignoring noise scans if acq.isFlagSet(ismrmrd.ACQ_IS_NOISE_MEASUREMENT): print("Found noise scan at acq ", acqnum) continue else: firstacq = acqnum print("Imaging acquisition starts acq ", acqnum) break # Initialiaze a storage array all_data = np.zeros( (nreps, ncontrasts, nslices, ncoils, eNz, eNy, rNx), dtype=np.complex64) #pylint: disable=E1101 # Loop through the rest of the acquisitions and stuff for acqnum in range(firstacq, dset.number_of_acquisitions()): acq = dset.read_acquisition(acqnum) # TODO: this is where we would apply noise pre-whitening # Remove oversampling if needed if eNx != rNx: xline = transform.transform_kspace_to_image(acq.data, [1]) x0 = int((eNx - rNx) / 2) x1 = int((eNx - rNx) / 2 + rNx) xline = xline[:, x0:x1] acq.resize(rNx, acq.active_channels, acq.trajectory_dimensions) #pylint: disable=E1101 acq.center_sample = int(rNx / 2) # need to use the [:] notation here to fill the data acq.data[:] = transform.transform_image_to_kspace(xline, [1]) # Stuff into the buffer rep = acq.idx.average #pylint: disable=E1101 contrast = acq.idx.contrast #pylint: disable=E1101 slise = acq.idx.slice #pylint: disable=E1101 y = acq.idx.kspace_encode_step_1 #pylint: disable=E1101 z = acq.idx.kspace_encode_step_2 #pylint: disable=E1101 all_data[rep, contrast, slise, :, z, y, :] = acq.data # Reconstruct images images = np.zeros((nreps, ncontrasts, nslices, eNz, eNy, rNx), dtype=np.float32) #pylint: disable=E1101 for rep in range(nreps): for contrast in range(ncontrasts): for slise in range(nslices): # FFT if eNz > 1: #3D im = transform.transform_kspace_to_image( all_data[rep, contrast, slise, ...], [1, 2, 3]) else: #2D im = transform.transform_kspace_to_image( all_data[rep, contrast, slise, :, 0, ...], [1, 2]) # Sum of squares im = np.sqrt(np.sum(np.abs(im)**2, 0)) # Stuff into the output if eNz > 1: #3D images[rep, contrast, slise, ...] = im else: #2D images[rep, contrast, slise, 0, ...] = im # Show an image show.imshow(np.squeeze(images[0, 0, 0, ...]))
def create(filename='testdata.h5', matrix_size=256, coils=8, oversampling=2, repetitions=1, acceleration=1, noise_level=0.05): # Generate the phantom and coil sensitivity maps phan = simulation.phantom(matrix_size) csm = simulation.generate_birdcage_sensitivities(matrix_size, coils) coil_images = np.tile(phan,(coils, 1, 1)) * csm # Oversample if needed if oversampling>1: padding = (oversampling*phan.shape[1] - phan.shape[1])/2 phan = np.pad(phan,((0,0),(padding,padding)),mode='constant') csm = np.pad(csm,((0,0),(0,0),(padding,padding)),mode='constant') coil_images = np.pad(coil_images,((0,0),(0,0),(padding,padding)),mode='constant') # The number of points in x,y,kx,ky nx = matrix_size ny = matrix_size nkx = oversampling*nx nky = ny # Open the dataset dset = ismrmrd.Dataset(filename, "dataset", create_if_needed=True) # Create the XML header and write it to the file header = ismrmrd.xsd.ismrmrdHeader() # Experimental Conditions exp = ismrmrd.xsd.experimentalConditionsType() exp.H1resonanceFrequency_Hz = 128000000 header.experimentalConditions = exp # Acquisition System Information sys = ismrmrd.xsd.acquisitionSystemInformationType() sys.receiverChannels = coils header.acquisitionSystemInformation = sys # Encoding encoding = ismrmrd.xsd.encoding() encoding.trajectory = ismrmrd.xsd.trajectoryType.cartesian # encoded and recon spaces efov = ismrmrd.xsd.fieldOfView_mm() efov.x = oversampling*256 efov.y = 256 efov.z = 5 rfov = ismrmrd.xsd.fieldOfView_mm() rfov.x = 256 rfov.y = 256 rfov.z = 5 ematrix = ismrmrd.xsd.matrixSize() ematrix.x = nkx ematrix.y = nky ematrix.z = 1 rmatrix = ismrmrd.xsd.matrixSize() rmatrix.x = nx rmatrix.y = ny rmatrix.z = 1 espace = ismrmrd.xsd.encodingSpaceType() espace.matrixSize = ematrix espace.fieldOfView_mm = efov rspace = ismrmrd.xsd.encodingSpaceType() rspace.matrixSize = rmatrix rspace.fieldOfView_mm = rfov # Set encoded and recon spaces encoding.encodedSpace = espace encoding.reconSpace = rspace # Encoding limits limits = ismrmrd.xsd.encodingLimitsType() limits1 = ismrmrd.xsd.limitType() limits1.minimum = 0 limits1.center = ny/2 limits1.maximum = ny - 1 limits.kspace_encoding_step_1 = limits1 limits_rep = ismrmrd.xsd.limitType() limits_rep.minimum = 0 limits_rep.center = repetitions / 2 limits_rep.maximum = repetitions - 1 limits.repetition = limits_rep limits_rest = ismrmrd.xsd.limitType() limits_rest.minimum = 0 limits_rest.center = 0 limits_rest.maximum = 0 limits.kspace_encoding_step_0 = limits_rest limits.slice = limits_rest limits.average = limits_rest limits.contrast = limits_rest limits.kspaceEncodingStep2 = limits_rest limits.phase = limits_rest limits.segment = limits_rest limits.set = limits_rest encoding.encodingLimits = limits header.encoding.append(encoding) dset.write_xml_header(header.toxml('utf-8')) # Synthesize the k-space data Ktrue = transform.transform_image_to_kspace(coil_images,(1,2)) # Create an acquistion and reuse it acq = ismrmrd.Acquisition() acq.resize(nkx, coils) acq.version = 1 acq.available_channels = coils acq.center_sample = nkx/2 acq.read_dir[0] = 1.0 acq.phase_dir[1] = 1.0 acq.slice_dir[2] = 1.0 # Initialize an acquisition counter counter = 0 # Write out a few noise scans for n in range(32): noise = noise_level * (np.random.randn(coils, nkx) + 1j * np.random.randn(coils, nkx)) # here's where we would make the noise correlated acq.scan_counter = counter acq.clearAllFlags() acq.setFlag(ismrmrd.ACQ_IS_NOISE_MEASUREMENT) acq.data[:] = noise dset.append_acquisition(acq) counter += 1 # increment the scan counter # Loop over the repetitions, add noise and write to disk # simulating a T-SENSE type scan for rep in range(repetitions): noise = noise_level * (np.random.randn(coils, nky, nkx) + 1j * np.random.randn(coils, nky, nkx)) # here's where we would make the noise correlated K = Ktrue + noise acq.idx.repetition = rep for acc in range(acceleration): for line in np.arange(acc,nky,acceleration): # set some fields in the header acq.scan_counter = counter acq.idx.kspace_encode_step_1 = line acq.clearAllFlags() if line == 0: acq.setFlag(ismrmrd.ACQ_FIRST_IN_ENCODE_STEP1) acq.setFlag(ismrmrd.ACQ_FIRST_IN_SLICE) acq.setFlag(ismrmrd.ACQ_FIRST_IN_REPETITION) elif line == nky - 1: acq.setFlag(ismrmrd.ACQ_LAST_IN_ENCODE_STEP1) acq.setFlag(ismrmrd.ACQ_LAST_IN_SLICE) acq.setFlag(ismrmrd.ACQ_LAST_IN_REPETITION) # set the data and append acq.data[:] = K[:,line,:] dset.append_acquisition(acq) counter += 1 # Clean up dset.close()
def compute(self): do_squeeze = self.getVal('Squeeze') do_remos = self.getVal('Remove Oversampling') do_zeropad = self.getVal('Zeropad') do_noiseadj = self.getVal('Noise Adjust') receiver_noise_bw = self.getVal('Receiver Noise BW Ratio') #Get the file name use the file browser widget fname = gpi.TranslateFileURI(self.getVal('File Browser')) #Check if the file exists if not os.path.exists(fname): self.log.node("Path does not exist: "+str(fname)) return 0 dset = ismrmrd.Dataset(fname, 'dataset', create_if_needed=False) xml_header = dset.read_xml_header() header = ismrmrd.xsd.CreateFromDocument(xml_header) self.setData('ISMRMRDHeader', str(xml_header)) enc = header.encoding[0] # Matrix size eNx = enc.encodedSpace.matrixSize.x eNy = enc.encodedSpace.matrixSize.y eNz = enc.encodedSpace.matrixSize.z rNx = enc.reconSpace.matrixSize.x rNy = enc.reconSpace.matrixSize.y rNz = enc.reconSpace.matrixSize.z # Field of View eFOVx = enc.encodedSpace.fieldOfView_mm.x eFOVy = enc.encodedSpace.fieldOfView_mm.y eFOVz = enc.encodedSpace.fieldOfView_mm.z rFOVx = enc.reconSpace.fieldOfView_mm.x rFOVy = enc.reconSpace.fieldOfView_mm.y rFOVz = enc.reconSpace.fieldOfView_mm.z # Number of Slices, Reps, Contrasts, etc. ncoils = header.acquisitionSystemInformation.receiverChannels if enc.encodingLimits.slice != None: nslices = enc.encodingLimits.slice.maximum + 1 else: nslices = 1 if enc.encodingLimits.repetition != None: nreps = enc.encodingLimits.repetition.maximum + 1 else: nreps = 1 if enc.encodingLimits.contrast != None: ncontrasts = enc.encodingLimits.contrast.maximum + 1 else: ncontrasts = 1 # In case there are noise scans in the actual dataset, we will skip them. noise_data = list() noise_dmtx = None firstacq=0 for acqnum in range(dset.number_of_acquisitions()): acq = dset.read_acquisition(acqnum) if acq.isFlagSet(ismrmrd.ACQ_IS_NOISE_MEASUREMENT): noise_data.append((acq.getHead(),acq.data)) continue else: firstacq = acqnum break if len(noise_data): profiles = len(noise_data) channels = noise_data[0][1].shape[0] samples_per_profile = noise_data[0][1].shape[1] noise = np.zeros((channels,profiles*samples_per_profile),dtype=np.complex64) counter = 0 for p in noise_data: noise[:,counter*samples_per_profile:(counter*samples_per_profile+samples_per_profile)] = p[1] counter = counter + 1 self.setData('noise',noise) scale = (acq.sample_time_us/noise_data[0][0].sample_time_us)*receiver_noise_bw noise_dmtx = coils.calculate_prewhitening(noise,scale_factor=scale) noise_data = list() # Empty array for the output data acq = dset.read_acquisition(firstacq) ro_length = acq.number_of_samples padded_ro_length = (acq.number_of_samples-acq.center_sample)*2 size_nx = 0 if do_remos: size_nx = rNx do_zeropad = True elif do_zeropad: size_nx = padded_ro_length else: size_nx = ro_length all_data = np.zeros((nreps, ncontrasts, nslices, ncoils, eNz, eNy, size_nx), dtype=np.complex64) # Loop through the rest of the acquisitions and stuff for acqnum in range(firstacq,dset.number_of_acquisitions()): acq = dset.read_acquisition(acqnum) acq_data_prw = np.zeros(acq.data.shape,dtype=np.complex64) acq_data_prw[:] = acq.data[:] if do_noiseadj and (noise_dmtx is not None): acq_data_prw = coils.apply_prewhitening(acq_data_prw, noise_dmtx) data2 = None if (padded_ro_length != ro_length) and do_zeropad: #partial fourier data2 = np.zeros((acq_data_prw.shape[0], padded_ro_length),dtype=np.complex64) offset = (padded_ro_length>>1) - acq.center_sample data2[:,0+offset:offset+ro_length] = acq_data_prw else: data2 = acq_data_prw if do_remos: data2=transform.transform_kspace_to_image(data2,dim=(1,)) data2=data2[:,(padded_ro_length>>2):(padded_ro_length>>2)+(padded_ro_length>>1)] data2=transform.transform_image_to_kspace(data2,dim=(1,)) * np.sqrt(float(padded_ro_length)/ro_length) # Stuff into the buffer rep = acq.idx.repetition contrast = acq.idx.contrast slice = acq.idx.slice y = acq.idx.kspace_encode_step_1 z = acq.idx.kspace_encode_step_2 all_data[rep, contrast, slice, :, z, y, :] = data2 all_data = all_data.astype('complex64') if do_squeeze: all_data = np.squeeze(all_data) self.setData('data',all_data) return 0