int main_ecalib(int argc, char* argv[]) { long calsize[3] = { 24, 24, 24 }; int maps = 2; bool one = false; bool calcen = false; bool print_svals = false; struct ecalib_conf conf = ecalib_defaults; const struct opt_s opts[] = { OPT_FLOAT('t', &conf.threshold, "threshold", "This determined the size of the null-space."), OPT_FLOAT('c', &conf.crop, "crop_value", "Crop the sensitivities if the eigenvalue is smaller than {crop_value}."), OPT_VEC3('k', &conf.kdims, "ksize", "kernel size"), OPT_VEC3('K', &conf.kdims, "", "()"), OPT_VEC3('r', &calsize, "cal_size", "Limits the size of the calibration region."), OPT_VEC3('R', &calsize, "", "()"), OPT_INT('m', &maps, "maps", "Number of maps to compute."), OPT_SET('S', &conf.softcrop, "create maps with smooth transitions (Soft-SENSE)."), OPT_SET('W', &conf.weighting, "soft-weighting of the singular vectors."), OPT_SET('I', &conf.intensity, "intensity correction"), OPT_SET('1', &one, "perform only first part of the calibration"), OPT_CLEAR('P', &conf.rotphase, "Do not rotate the phase with respect to the first principal component"), OPT_CLEAR('O', &conf.orthiter, "()"), OPT_FLOAT('b', &conf.perturb, "", "()"), OPT_SET('V', &print_svals, "()"), OPT_SET('C', &calcen, "()"), OPT_SET('g', &conf.usegpu, "()"), OPT_FLOAT('p', &conf.percentsv, "", "()"), OPT_INT('n', &conf.numsv, "", "()"), OPT_FLOAT('v', &conf.var, "variance", "Variance of noise in data."), OPT_SET('a', &conf.automate, "Automatically pick thresholds."), OPT_INT('d', &debug_level, "level", "Debug level"), }; cmdline(&argc, argv, 2, 3, usage_str, help_str, ARRAY_SIZE(opts), opts); if (-1. != conf.percentsv) conf.threshold = -1.; if (-1 != conf.numsv) conf.threshold = -1.; if (conf.automate) { conf.crop = -1.; conf.weighting = true; } if (conf.weighting) { conf.numsv = -1.; conf.threshold = 0; conf.percentsv = -1.; conf.orthiter = false; } int N = DIMS; long ksp_dims[N]; complex float* in_data = load_cfl(argv[1], N, ksp_dims); // assert((kdims[0] < calsize_ro) && (kdims[1] < calsize_ro) && (kdims[2] < calsize_ro)); // assert((ksp_dims[0] == 1) || (calsize_ro < ksp_dims[0])); if (1 != ksp_dims[MAPS_DIM]) error("MAPS dimension is not of size one.\n"); long cal_dims[N]; complex float* cal_data = NULL; if (!calcen) { #ifdef USE_CC_EXTRACT_CALIB cal_data = cc_extract_calib(cal_dims, calsize, ksp_dims, in_data); #else cal_data = extract_calib(cal_dims, calsize, ksp_dims, in_data, false); #endif } else { for (int i = 0; i < 3; i++) cal_dims[i] = (calsize[i] < ksp_dims[i]) ? calsize[i] : ksp_dims[i]; for (int i = 3; i < N; i++) cal_dims[i] = ksp_dims[i]; cal_data = md_alloc(5, cal_dims, CFL_SIZE); md_resize_center(5, cal_dims, cal_data, ksp_dims, in_data, CFL_SIZE); } for (int i = 0; i < 3; i++) if (1 == ksp_dims[i]) conf.kdims[i] = 1; long channels = cal_dims[3]; unsigned int K = conf.kdims[0] * conf.kdims[1] * conf.kdims[2] * channels; float svals[K]; for (unsigned int i = 0; i < 3; i++) if ((1 == cal_dims[i]) && (1 != ksp_dims[i])) error("Calibration region not found!\n"); // To reproduce old results turn off rotation of phase. // conf.rotphase = false; // FIXME: we should scale the data (conf.usegpu ? num_init_gpu : num_init)(); if ((conf.var < 0) && (conf.weighting || (conf.crop < 0))) conf.var = estvar_calreg(conf.kdims, cal_dims, cal_data); if (one) { #if 0 long maps = out_dims[4]; assert(caldims[3] == out_dims[3]); assert(maps <= channels); #endif long cov_dims[4]; calone_dims(&conf, cov_dims, channels); complex float* imgcov = md_alloc(4, cov_dims, CFL_SIZE); calone(&conf, cov_dims, imgcov, K, svals, cal_dims, cal_data); complex float* out = create_cfl(argv[2], 4, cov_dims); md_copy(4, cov_dims, out, imgcov, CFL_SIZE); unmap_cfl(4, cov_dims, out); // caltwo(crthr, out_dims, out_data, emaps, cov_dims, imgcov, NULL, NULL); md_free(imgcov); } else { long out_dims[N]; long map_dims[N]; for (int i = 0; i < N; i++) { out_dims[i] = 1; map_dims[i] = 1; if ((i < 3) && (1 < conf.kdims[i])) { out_dims[i] = ksp_dims[i]; map_dims[i] = ksp_dims[i]; } } assert(maps <= ksp_dims[COIL_DIM]); out_dims[COIL_DIM] = ksp_dims[COIL_DIM]; out_dims[MAPS_DIM] = maps; map_dims[COIL_DIM] = 1; map_dims[MAPS_DIM] = maps; const char* emaps_file = NULL; if (4 == argc) emaps_file = argv[3]; complex float* out_data = create_cfl(argv[2], N, out_dims); complex float* emaps = (emaps_file ? create_cfl : anon_cfl)(emaps_file, N, map_dims); calib(&conf, out_dims, out_data, emaps, K, svals, cal_dims, cal_data); unmap_cfl(N, out_dims, out_data); unmap_cfl(N, map_dims, emaps); } if (print_svals) { for (unsigned int i = 0; i < K; i++) printf("SVALS %d %f\n", i, svals[i]); } printf("Done.\n"); unmap_cfl(N, ksp_dims, in_data); md_free(cal_data); return 0; }
void calib2(const struct ecalib_conf* conf, const long out_dims[DIMS], complex float* out_data, complex float* eptr, unsigned int SN, float svals[SN], const long calreg_dims[DIMS], const complex float* data, const long msk_dims[3], const bool* msk) { long channels = calreg_dims[3]; long maps = out_dims[4]; assert(calreg_dims[3] == out_dims[3]); assert(maps <= channels); assert(1 == md_calc_size(DIMS - 5, out_dims + 5)); assert(1 == md_calc_size(DIMS - 5, calreg_dims + 5)); complex float rot[channels][channels]; if (conf->rotphase) { long scc_dims[DIMS] = MD_INIT_ARRAY(DIMS, 1); scc_dims[COIL_DIM] = channels; scc_dims[MAPS_DIM] = channels; scc(scc_dims, &rot[0][0], calreg_dims, data); } else { for (unsigned int i = 0; i < channels; i++) for (unsigned int j = 0; j < channels; j++) rot[i][j] = (i == j) ? 1. : 0.; } long cov_dims[4]; calone_dims(conf, cov_dims, channels); complex float* imgcov = md_alloc(4, cov_dims, CFL_SIZE); calone(conf, cov_dims, imgcov, SN, svals, calreg_dims, data); caltwo(conf, out_dims, out_data, eptr, cov_dims, imgcov, msk_dims, msk); /* Intensity and phase normalization similar as proposed * for adaptive combine (Walsh's method) in * Griswold et al., ISMRM 10:2410 (2002) */ if (conf->intensity) { debug_printf(DP_DEBUG1, "Normalize...\n"); /* I think the reason this works is because inhomogeneity usually * comes from only a few coil elements which are close. The l1-norm * is more resilient against such outliers. -- Martin */ normalizel1(DIMS, COIL_FLAG, out_dims, out_data); md_zsmul(DIMS, out_dims, out_data, out_data, sqrtf((float)channels)); } debug_printf(DP_DEBUG1, "Crop maps... (%.2f)\n", conf->crop); crop_sens(out_dims, out_data, conf->softcrop, conf->crop, eptr); debug_printf(DP_DEBUG1, "Fix phase...\n"); // rotate the the phase with respect to the first principle component fixphase2(DIMS, out_dims, COIL_DIM, rot[0], out_data, out_data); md_free(imgcov); }