static void homodyne(struct wdata wdata, unsigned int flags, unsigned int N, const long dims[N], const long strs[N], complex float* data, const complex float* idata, const long pstrs[N], const complex float* phase) { md_zmul2(N, dims, strs, data, strs, idata, wdata.wstrs, wdata.weights); ifftuc(N, dims, flags, data, data); md_zmulc2(N, dims, strs, data, strs, data, pstrs, phase); md_zreal(N, dims, data, data); }
static void sense_adjoint(const void* _data, complex float* imgs, const complex float* out) { const struct sense_data* data = _data; md_zmulc2(DIMS, data->data_dims, data->data_strs, data->tmp, data->data_strs, out, data->mask_strs, data->pattern); ifftc(DIMS, data->data_dims, FFT_FLAGS, data->tmp, data->tmp); fftscale(DIMS, data->data_dims, FFT_FLAGS, data->tmp, data->tmp); md_clear(DIMS, data->imgs_dims, imgs, CFL_SIZE); md_zfmacc2(DIMS, data->sens_dims, data->imgs_strs, imgs, data->data_strs, data->tmp, data->sens_strs, data->sens); }
void noir_adj(struct noir_data* data, complex float* dst, const complex float* src) { long split = md_calc_size(DIMS, data->imgs_dims); md_zmulc2(DIMS, data->sign_dims, data->sign_strs, data->tmp, data->data_strs, src, data->ptrn_strs, data->pattern); ifft(DIMS, data->sign_dims, FFT_FLAGS, data->tmp, data->tmp); // we should move it to the end, but fft scaling is applied so this would be need to moved into data->xn or weights maybe? md_zmulc2(DIMS, data->sign_dims, data->sign_strs, data->tmp, data->sign_strs, data->tmp, data->mask_strs, data->mask); md_clear(DIMS, data->coil_dims, dst + split, CFL_SIZE); md_zfmacc2(DIMS, data->sign_dims, data->coil_strs, dst + split, data->sign_strs, data->tmp, data->imgs_strs, data->xn); noir_back_coils(data, dst + split, dst + split); md_clear(DIMS, data->imgs_dims, dst, CFL_SIZE); md_zfmacc2(DIMS, data->sign_dims, data->imgs_strs, dst, data->sign_strs, data->tmp, data->coil_strs, data->sens); if (data->rvc) md_zreal(DIMS, data->imgs_dims, dst, dst); }
// Adjoint: from kspace to image static void nufft_apply_adjoint(const void* _data, complex float* dst, const complex float* src) { const struct nufft_data* data = _data; unsigned int ND = data->N + 3; complex float* gridX = md_alloc(data->N, data->cm2_dims, CFL_SIZE); md_clear(data->N, data->cm2_dims, gridX, CFL_SIZE); complex float* wdat = NULL; if (NULL != data->weights) { wdat = md_alloc(data->N, data->ksp_dims, CFL_SIZE); md_zmulc2(data->N, data->ksp_dims, data->ksp_strs, wdat, data->ksp_strs, src, data->wgh_strs, data->weights); src = wdat; } grid2(2., data->width, data->beta, ND, data->trj_dims, data->traj, data->cm2_dims, gridX, data->ksp_dims, src); md_free(wdat); long factors[data->N]; for (unsigned int i = 0; i < data->N; i++) factors[i] = ((data->img_dims[i] > 1) && (i < 3)) ? 2 : 1; md_decompose(data->N, factors, data->cml_dims, data->grid, data->cm2_dims, gridX, CFL_SIZE); md_free(gridX); md_zmulc2(ND, data->cml_dims, data->cml_strs, data->grid, data->cml_strs, data->grid, data->img_strs, data->fftmod); linop_adjoint(data->fft_op, ND, data->cml_dims, data->grid, ND, data->cml_dims, data->grid); md_clear(ND, data->cim_dims, dst, CFL_SIZE); md_zfmacc2(ND, data->cml_dims, data->cim_strs, dst, data->cml_strs, data->grid, data->lph_strs, data->linphase); if (data->conf.toeplitz) md_zmul2(ND, data->cim_dims, data->cim_strs, dst, data->cim_strs, dst, data->img_strs, data->roll); }
void noir_back_coils(struct noir_data* data, complex float* dst, const complex float* src) { // fftmod(DIMS, data->coil_dims, 7, dst); fft(DIMS, data->coil_dims, FFT_FLAGS, dst, src); md_zmulc2(DIMS, data->coil_dims, data->coil_strs, dst, data->coil_strs, dst, data->wght_strs, data->weights); }