int main(int argc, const char *argv[]) { const char *me; char *err, *outS; hestOpt *hopt=NULL; airArray *mop; int xi, yi, zi, samp; float *tdata; double clp[2], xyz[3], q[4], len; double mD[9], mRF[9], mRI[9], mT[9]; Nrrd *nten; mop = airMopNew(); me = argv[0]; hestOptAdd(&hopt, "n", "# samples", airTypeInt, 1, 1, &samp, "4", "number of samples along each edge of cube"); hestOptAdd(&hopt, "c", "cl cp", airTypeDouble, 2, 2, clp, NULL, "shape of tensor to use; \"cl\" and \"cp\" are cl1 " "and cp1 values, both in [0.0,1.0]"); hestOptAdd(&hopt, "o", "nout", airTypeString, 1, 1, &outS, "-", "output file to save tensors into"); hestParseOrDie(hopt, argc-1, argv+1, NULL, me, info, AIR_TRUE, AIR_TRUE, AIR_TRUE); airMopAdd(mop, hopt, (airMopper)hestOptFree, airMopAlways); airMopAdd(mop, hopt, (airMopper)hestParseFree, airMopAlways); nten = nrrdNew(); airMopAdd(mop, nten, (airMopper)nrrdNuke, airMopAlways); _clp2xyz(xyz, clp); fprintf(stderr, "%s: want evals = %g %g %g\n", me, xyz[0], xyz[1], xyz[2]); if (nrrdMaybeAlloc_va(nten, nrrdTypeFloat, 4, AIR_CAST(size_t, 7), AIR_CAST(size_t, samp), AIR_CAST(size_t, samp), AIR_CAST(size_t, samp))) { airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: couldn't allocate output:\n%s\n", me, err); airMopError(mop); return 1; } ELL_3M_IDENTITY_SET(mD); ELL_3M_DIAG_SET(mD, xyz[0], xyz[1], xyz[2]); tdata = (float*)nten->data; for (zi=0; zi<samp; zi++) { for (yi=0; yi<samp; yi++) { for (xi=0; xi<samp; xi++) { q[0] = 1.0; q[1] = AIR_AFFINE(-0.5, (float)xi, samp-0.5, -1, 1); q[2] = AIR_AFFINE(-0.5, (float)yi, samp-0.5, -1, 1); q[3] = AIR_AFFINE(-0.5, (float)zi, samp-0.5, -1, 1); len = ELL_4V_LEN(q); ELL_4V_SCALE(q, 1.0/len, q); washQtoM3(mRF, q); ELL_3M_TRANSPOSE(mRI, mRF); ELL_3M_IDENTITY_SET(mT); ell_3m_post_mul_d(mT, mRI); ell_3m_post_mul_d(mT, mD); ell_3m_post_mul_d(mT, mRF); tdata[0] = 1.0; TEN_M2T(tdata, mT); tdata += 7; } } } if (nrrdSave(outS, nten, NULL)) { airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: couldn't save output:\n%s\n", me, err); airMopError(mop); return 1; } airMopOkay(mop); return 0; }
int main(int argc, char *argv[]) { char *me, *err, *outS; hestOpt *hopt=NULL; airArray *mop; int sx, sy, xi, yi, samp, version, whole, right; float *tdata; double p[3], xyz[3], q[4], len, hackcp=0, maxca; double ca, cp, mD[9], mRF[9], mRI[9], mT[9], hack; Nrrd *nten; mop = airMopNew(); me = argv[0]; hestOptAdd(&hopt, "n", "# samples", airTypeInt, 1, 1, &samp, "4", "number of glyphs along each edge of triangle"); hestOptAdd(&hopt, "p", "x y z", airTypeDouble, 3, 3, p, NULL, "location in quaternion quotient space"); hestOptAdd(&hopt, "ca", "max ca", airTypeDouble, 1, 1, &maxca, "0.8", "maximum ca to use at bottom edge of triangle"); hestOptAdd(&hopt, "r", NULL, airTypeInt, 0, 0, &right, NULL, "sample a right-triangle-shaped region, instead of " "a roughly equilateral triangle. "); hestOptAdd(&hopt, "w", NULL, airTypeInt, 0, 0, &whole, NULL, "sample the whole triangle of constant trace, " "instead of just the " "sixth of it in which the eigenvalues have the " "traditional sorted order. "); hestOptAdd(&hopt, "hack", "hack", airTypeDouble, 1, 1, &hack, "0.04", "this is a hack"); hestOptAdd(&hopt, "v", "version", airTypeInt, 1, 1, &version, "1", "which version of the Westin metrics to use to parameterize " "triangle; \"1\" for ISMRM 97, \"2\" for MICCAI 99"); hestOptAdd(&hopt, "o", "nout", airTypeString, 1, 1, &outS, "-", "output file to save tensors into"); hestParseOrDie(hopt, argc-1, argv+1, NULL, me, info, AIR_TRUE, AIR_TRUE, AIR_TRUE); airMopAdd(mop, hopt, (airMopper)hestOptFree, airMopAlways); airMopAdd(mop, hopt, (airMopper)hestParseFree, airMopAlways); nten = nrrdNew(); airMopAdd(mop, nten, (airMopper)nrrdNuke, airMopAlways); if (!( 1 == version || 2 == version )) { fprintf(stderr, "%s: version must be 1 or 2 (not %d)\n", me, version); airMopError(mop); return 1; } if (right) { sx = samp; sy = (int)(1.0*samp/sqrt(3.0)); } else { sx = 2*samp-1; sy = samp; } if (nrrdMaybeAlloc_va(nten, nrrdTypeFloat, 4, AIR_CAST(size_t, 7), AIR_CAST(size_t, sx), AIR_CAST(size_t, sy), AIR_CAST(size_t, 3))) { airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: couldn't allocate output:\n%s\n", me, err); airMopError(mop); return 1; } q[0] = 1.0; q[1] = p[0]; q[2] = p[1]; q[3] = p[2]; len = ELL_4V_LEN(q); ELL_4V_SCALE(q, 1.0/len, q); washQtoM3(mRF, q); ELL_3M_TRANSPOSE(mRI, mRF); if (right) { _ra2t(nten, 0.00, 0.0, mRI, mRF, hack); _ra2t(nten, 0.10, 0.0, mRI, mRF, hack); _ra2t(nten, 0.10, 60.0, mRI, mRF, hack); _ra2t(nten, 0.20, 0.0, mRI, mRF, hack); _ra2t(nten, 0.20, 30.0, mRI, mRF, hack); _ra2t(nten, 0.20, 60.0, mRI, mRF, hack); _ra2t(nten, 0.30, 0.0, mRI, mRF, hack); _ra2t(nten, 0.30, 20.0, mRI, mRF, hack); _ra2t(nten, 0.30, 40.0, mRI, mRF, hack); _ra2t(nten, 0.30, 60.0, mRI, mRF, hack); _ra2t(nten, 0.40, 0.0, mRI, mRF, hack); _ra2t(nten, 0.40, 15.0, mRI, mRF, hack); _ra2t(nten, 0.40, 30.0, mRI, mRF, hack); _ra2t(nten, 0.40, 45.0, mRI, mRF, hack); _ra2t(nten, 0.40, 60.0, mRI, mRF, hack); _ra2t(nten, 0.50, 0.0, mRI, mRF, hack); _ra2t(nten, 0.50, 12.0, mRI, mRF, hack); _ra2t(nten, 0.50, 24.0, mRI, mRF, hack); _ra2t(nten, 0.50, 36.0, mRI, mRF, hack); _ra2t(nten, 0.50, 48.0, mRI, mRF, hack); _ra2t(nten, 0.50, 60.0, mRI, mRF, hack); /* _ra2t(nten, 0.60, 30.0, mRI, mRF, hack); */ _ra2t(nten, 0.60, 40.0, mRI, mRF, hack); _ra2t(nten, 0.60, 50.0, mRI, mRF, hack); _ra2t(nten, 0.60, 60.0, mRI, mRF, hack); /* _ra2t(nten, 0.70, 34.3, mRI, mRF, hack); */ /* _ra2t(nten, 0.70, 42.8, mRI, mRF, hack); */ _ra2t(nten, 0.70, 51.4, mRI, mRF, hack); _ra2t(nten, 0.70, 60.0, mRI, mRF, hack); /* _ra2t(nten, 0.80, 45.0, mRI, mRF, hack); */ _ra2t(nten, 0.80, 52.5, mRI, mRF, hack); _ra2t(nten, 0.80, 60.0, mRI, mRF, hack); _ra2t(nten, 0.90, 60.0, mRI, mRF, hack); _ra2t(nten, 1.00, 60.0, mRI, mRF, hack); /* _ra2t(nten, 0.000, 0.0, mRI, mRF, hack); _ra2t(nten, 0.125, 0.0, mRI, mRF, hack); _ra2t(nten, 0.125, 60.0, mRI, mRF, hack); _ra2t(nten, 0.250, 0.0, mRI, mRF, hack); _ra2t(nten, 0.250, 30.0, mRI, mRF, hack); _ra2t(nten, 0.250, 60.0, mRI, mRF, hack); _ra2t(nten, 0.375, 0.0, mRI, mRF, hack); _ra2t(nten, 0.375, 20.0, mRI, mRF, hack); _ra2t(nten, 0.375, 40.0, mRI, mRF, hack); _ra2t(nten, 0.375, 60.0, mRI, mRF, hack); _ra2t(nten, 0.500, 0.0, mRI, mRF, hack); _ra2t(nten, 0.500, 15.0, mRI, mRF, hack); _ra2t(nten, 0.500, 30.0, mRI, mRF, hack); _ra2t(nten, 0.500, 45.0, mRI, mRF, hack); _ra2t(nten, 0.500, 60.0, mRI, mRF, hack); _ra2t(nten, 0.625, 37.0, mRI, mRF, hack); _ra2t(nten, 0.625, 47.5, mRI, mRF, hack); _ra2t(nten, 0.625, 60.0, mRI, mRF, hack); _ra2t(nten, 0.750, 49.2, mRI, mRF, hack); _ra2t(nten, 0.750, 60.0, mRI, mRF, hack); _ra2t(nten, 0.875, 60.0, mRI, mRF, hack); _ra2t(nten, 1.000, 60.0, mRI, mRF, hack); */ nten->axis[1].spacing = 1; nten->axis[2].spacing = (sx-1)/(sqrt(3.0)*(sy-1)); nten->axis[3].spacing = 1; } else { for (yi=0; yi<samp; yi++) { if (whole) { ca = AIR_AFFINE(0, yi, samp-1, 0.0, 1.0); } else { ca = AIR_AFFINE(0, yi, samp-1, hack, maxca); hackcp = AIR_AFFINE(0, yi, samp-1, hack, 0); } for (xi=0; xi<=yi; xi++) { if (whole) { cp = AIR_AFFINE(0, xi, samp-1, 0.0, 1.0); } else { cp = AIR_AFFINE(0, xi, samp-1, hackcp, maxca-hack/2.0); } _cap2xyz(xyz, ca, cp, version, whole); /* fprintf(stderr, "%s: (%d,%d) -> (%g,%g) -> %g %g %g\n", me, yi, xi, ca, cp, xyz[0], xyz[1], xyz[2]); */ ELL_3M_IDENTITY_SET(mD); ELL_3M_DIAG_SET(mD, xyz[0], xyz[1], xyz[2]); ELL_3M_IDENTITY_SET(mT); ell_3m_post_mul_d(mT, mRI); ell_3m_post_mul_d(mT, mD); ell_3m_post_mul_d(mT, mRF); tdata = (float*)nten->data + 7*(2*(samp-1-xi) - (samp-1-yi) + (2*samp-1)*((samp-1-yi) + samp)); tdata[0] = 1.0; TEN_M2T(tdata, mT); } } nten->axis[1].spacing = 1; nten->axis[2].spacing = 1.5; nten->axis[3].spacing = 1; } if (nrrdSave(outS, nten, NULL)) { airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: couldn't save output:\n%s\n", me, err); airMopError(mop); return 1; } airMopOkay(mop); return 0; }