int main(int argc, const char **argv) { char *single, *triple[3], *maybe, **many; int howMany, i, N; hestOpt *opt = NULL; char *err = NULL; hestOptAdd(&opt, "A", "token", airTypeOther, 1, 1, &single, "alpha", "testing A", NULL, NULL, &cbinfo); hestOptAdd(&opt, "B", "tok1 tok2 tok3", airTypeOther, 3, 3, triple, "beta psi rho", "testing B", NULL, NULL, &cbinfo); hestOptAdd(&opt, "C", "mtok", airTypeOther, 0, 1, &maybe, "gamma", "testing C", NULL, NULL, &cbinfo); hestOptAdd(&opt, "D", "tok", airTypeOther, 1, -1, &many, "kappa omega", "testing D", &howMany, NULL, &cbinfo); hestOptAdd(&opt, "int", "N", airTypeInt, 1, 1, &N, NULL, "an integer"); if (hestParse(opt, argc-1, argv+1, &err, NULL)) { fprintf(stderr, "ERROR: %s\n", err); free(err); hestUsage(stderr, opt, argv[0], NULL); hestGlossary(stderr, opt, NULL); exit(1); } printf("single: %s\n", single); printf("triple: %s %s %s\n", triple[0], triple[1], triple[2]); printf("maybe: %s\n", maybe); printf("many(%d):", howMany); for (i=0; i<=howMany-1; i++) { printf(" %s", many[i]); } printf("\n"); hestParseFree(opt); exit(0); }
int main(int argc, char *argv[]) { gageKind *kind; char *me, *whatS, *err, *outS, *stackSavePath; hestParm *hparm; hestOpt *hopt = NULL; NrrdKernelSpec *k00, *k11, *k22, *kSS, *kSSblur; float pos[3], lineInfo[4]; double gmc, rangeSS[2], posSS, *scalePos; unsigned int ansLen, numSS, ninSSIdx, lineStepNum; int what, E=0, renorm, SSrenorm, SSuniform, verbose; const double *answer; Nrrd *nin, **ninSS=NULL, *nout=NULL; gageContext *ctx; gagePerVolume *pvl; limnPolyData *lpld=NULL; airArray *mop; int worldSpace; Nrrd *ngrad=NULL, *nbmat=NULL; double bval, eps; unsigned int *skip, skipNum; mop = airMopNew(); me = argv[0]; hparm = hestParmNew(); airMopAdd(mop, hparm, (airMopper)hestParmFree, airMopAlways); hparm->elideSingleOtherType = AIR_TRUE; hestOptAdd(&hopt, "i", "nin", airTypeOther, 1, 1, &nin, NULL, "input volume", NULL, NULL, nrrdHestNrrd); hestOptAdd(&hopt, "k", "kind", airTypeOther, 1, 1, &kind, NULL, "\"kind\" of volume (\"scalar\", \"vector\", or \"tensor\")", NULL, NULL, &probeKindHestCB); hestOptAdd(&hopt, "p", "x y z", airTypeFloat, 3, 3, pos, NULL, "the position in space at which to probe"); hestOptAdd(&hopt, "wsp", NULL, airTypeInt, 0, 0, &worldSpace, NULL, "if using this option, position (\"-p\") will be in world " "space, instead of index space (the default)"); hestOptAdd(&hopt, "pi", "lpld in", airTypeOther, 1, 1, &lpld, "", "input polydata (overrides \"-p\")", NULL, NULL, limnHestPolyDataLMPD); hestOptAdd(&hopt, "pl", "x y z s", airTypeFloat, 4, 4, lineInfo, "0 0 0 0", "probe along line, instead of at point. " "The \"-p\" three coords are the line start point. " "If \"s\" is zero, (x,y,z) is the line end point. " "If \"s\" is non-zero, (x,y,z) is the line direction, " "which is scaled to have length \"s\", " "and then used as the step between line samples. "); hestOptAdd(&hopt, "pln", "num", airTypeUInt, 1, 1, &lineStepNum, "0", "if non-zero, number of steps of probing to do along line, " "which overrides \"-p\" and \"-pi\""); hestOptAdd(&hopt, "v", "verbosity", airTypeInt, 1, 1, &verbose, "1", "verbosity level"); hestOptAdd(&hopt, "q", "query", airTypeString, 1, 1, &whatS, NULL, "the quantity (scalar, vector, or matrix) to learn by probing"); hestOptAdd(&hopt, "eps", "epsilon", airTypeDouble, 1, 1, &eps, "0", "if non-zero, and if query is a scalar, epsilon around probe " "location where we will do discrete differences to find the " "gradient and hessian (for debugging)"); hestOptAdd(&hopt, "k00", "kern00", airTypeOther, 1, 1, &k00, "tent", "kernel for gageKernel00", NULL, NULL, nrrdHestKernelSpec); hestOptAdd(&hopt, "k11", "kern11", airTypeOther, 1, 1, &k11, "cubicd:1,0", "kernel for gageKernel11", NULL, NULL, nrrdHestKernelSpec); hestOptAdd(&hopt, "k22", "kern22", airTypeOther, 1, 1, &k22, "cubicdd:1,0", "kernel for gageKernel22", NULL, NULL, nrrdHestKernelSpec); hestOptAdd(&hopt, "ssn", "SS #", airTypeUInt, 1, 1, &numSS, "0", "how many scale-space samples to evaluate, or, " "0 to turn-off all scale-space behavior"); hestOptAdd(&hopt, "ssr", "scale range", airTypeDouble, 2, 2, rangeSS, "nan nan", "range of scales in scale-space"); hestOptAdd(&hopt, "sss", "scale save path", airTypeString, 1, 1, &stackSavePath, "", "give a non-empty path string (like \"./\") to save out " "the pre-blurred volumes computed for the stack"); hestOptAdd(&hopt, "ssp", "SS pos", airTypeDouble, 1, 1, &posSS, "0", "position at which to sample in scale-space"); hestOptAdd(&hopt, "kssblur", "kernel", airTypeOther, 1, 1, &kSSblur, "dgauss:1,5", "blurring kernel, to sample scale space", NULL, NULL, nrrdHestKernelSpec); hestOptAdd(&hopt, "kss", "kernel", airTypeOther, 1, 1, &kSS, "tent", "kernel for reconstructing from scale space samples", NULL, NULL, nrrdHestKernelSpec); hestOptAdd(&hopt, "ssrn", "ssrn", airTypeInt, 1, 1, &SSrenorm, "0", "enable derivative normalization based on scale space"); hestOptAdd(&hopt, "ssu", NULL, airTypeInt, 0, 0, &SSuniform, NULL, "do uniform samples along sigma, and not (by default) " "samples according to the logarithm of diffusion time"); hestOptAdd(&hopt, "rn", NULL, airTypeInt, 0, 0, &renorm, NULL, "renormalize kernel weights at each new sample location. " "\"Accurate\" kernels don't need this; doing it always " "makes things go slower"); hestOptAdd(&hopt, "gmc", "min gradmag", airTypeDouble, 1, 1, &gmc, "0.0", "For curvature-based queries, use zero when gradient " "magnitude is below this"); hestOptAdd(&hopt, "o", "nout", airTypeString, 1, 1, &outS, "-", "output array, when probing on polydata vertices"); hestParseOrDie(hopt, argc-1, argv+1, hparm, me, probeInfo, AIR_TRUE, AIR_TRUE, AIR_TRUE); airMopAdd(mop, hopt, (airMopper)hestOptFree, airMopAlways); airMopAdd(mop, hopt, (airMopper)hestParseFree, airMopAlways); what = airEnumVal(kind->enm, whatS); if (!what) { /* 0 indeed always means "unknown" for any gageKind */ fprintf(stderr, "%s: couldn't parse \"%s\" as measure of \"%s\" volume\n", me, whatS, kind->name); hestUsage(stderr, hopt, me, hparm); hestGlossary(stderr, hopt, hparm); airMopError(mop); return 1; } if (ELL_4V_LEN(lineInfo) && !lineStepNum) { fprintf(stderr, "%s: gave line info (\"-pl\") but not " "# samples (\"-pln\")", me); hestUsage(stderr, hopt, me, hparm); hestGlossary(stderr, hopt, hparm); airMopError(mop); return 1; } /* special set-up required for DWI kind */ if (!strcmp(TEN_DWI_GAGE_KIND_NAME, kind->name)) { if (tenDWMRIKeyValueParse(&ngrad, &nbmat, &bval, &skip, &skipNum, nin)) { airMopAdd(mop, err = biffGetDone(TEN), airFree, airMopAlways); fprintf(stderr, "%s: trouble parsing DWI info:\n%s\n", me, err); airMopError(mop); return 1; } if (skipNum) { fprintf(stderr, "%s: sorry, can't do DWI skipping in tenDwiGage", me); airMopError(mop); return 1; } /* this could stand to use some more command-line arguments */ if (tenDwiGageKindSet(kind, 50, 1, bval, 0.001, ngrad, nbmat, tenEstimate1MethodLLS, tenEstimate2MethodQSegLLS, /* randSeed */ 7919)) { airMopAdd(mop, err = biffGetDone(TEN), airFree, airMopAlways); fprintf(stderr, "%s: trouble parsing DWI info:\n%s\n", me, err); airMopError(mop); return 1; } } ansLen = kind->table[what].answerLength; /* for setting up pre-blurred scale-space samples */ if (numSS) { unsigned int vi; ninSS = AIR_CAST(Nrrd **, calloc(numSS, sizeof(Nrrd *))); scalePos = AIR_CAST(double *, calloc(numSS, sizeof(double))); if (!(ninSS && scalePos)) { fprintf(stderr, "%s: couldn't allocate ninSS", me); airMopError(mop); return 1; } for (ninSSIdx=0; ninSSIdx<numSS; ninSSIdx++) { ninSS[ninSSIdx] = nrrdNew(); airMopAdd(mop, ninSS[ninSSIdx], (airMopper)nrrdNuke, airMopAlways); } if (SSuniform) { for (vi=0; vi<numSS; vi++) { scalePos[vi] = AIR_AFFINE(0, vi, numSS-1, rangeSS[0], rangeSS[1]); } } else { double rangeTau[2], tau; rangeTau[0] = gageTauOfSig(rangeSS[0]); rangeTau[1] = gageTauOfSig(rangeSS[1]); for (vi=0; vi<numSS; vi++) { tau = AIR_AFFINE(0, vi, numSS-1, rangeTau[0], rangeTau[1]); scalePos[vi] = gageSigOfTau(tau); } } if (verbose > 2) { fprintf(stderr, "%s: sampling scale range %g--%g %suniformly:\n", me, rangeSS[0], rangeSS[1], SSuniform ? "" : "non-"); for (vi=0; vi<numSS; vi++) { fprintf(stderr, " scalePos[%u] = %g\n", vi, scalePos[vi]); } } if (gageStackBlur(ninSS, scalePos, numSS, nin, kind->baseDim, kSSblur, nrrdBoundaryBleed, AIR_TRUE, verbose)) { airMopAdd(mop, err = biffGetDone(GAGE), airFree, airMopAlways); fprintf(stderr, "%s: trouble pre-computing blurrings:\n%s\n", me, err); airMopError(mop); return 1; } if (airStrlen(stackSavePath)) { char fnform[AIR_STRLEN_LARGE]; sprintf(fnform, "%s/blur-%%02u.nrrd", stackSavePath); fprintf(stderr, "%s: |%s|\n", me, fnform); if (nrrdSaveMulti(fnform, AIR_CAST(const Nrrd *const *, ninSS), numSS, 0, NULL)) { airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: trouble saving blurrings:\n%s\n", me, err); airMopError(mop); return 1; } } } else {
int main(int argc, char **argv) { static int res[2], v, numIn; static char **in, *out; static int *mm, mmm; int n; hestOpt opt[] = { {"res", "sx sy", airTypeInt, 2, 2, res, NULL, "image resolution"}, {"v", "level", airTypeInt, 0, 1, &v, NULL /* "0" */, "verbosity level"}, {"VV", "level", airTypeInt, 0, 5, &mm, "33 22 11", "gonzo level", &mmm}, {"out", "file", airTypeString, 1, 1, &out, "output.ppm", "PPM image output"}, {NULL, "input", airTypeString, 1, -1, &in, NULL, "input image file(s)", &numIn}, {NULL, NULL, 0} }; hestParm *parm; char *err = NULL, info[] = "This program does nothing in particular, though it does attempt " "to pose as some sort of command-line image processing program. " "Any implied functionality is purely coincidental, especially since " "this software was written by a sleep-deprived grad student."; parm = hestParmNew(); parm->respFileEnable = AIR_TRUE; if (1 == argc) { /* didn't get anything at all on command line */ hestInfo(stderr, argv[0], info, parm); hestUsage(stderr, opt, argv[0], parm); hestGlossary(stderr, opt, parm); parm = hestParmFree(parm); exit(1); } /* else we got something, see if we can parse it */ if (hestParse(opt, argc-1, argv+1, &err, parm)) { fprintf(stderr, "ERROR: %s\n", err); free(err); hestUsage(stderr, opt, argv[0], parm); hestGlossary(stderr, opt, parm); parm = hestParmFree(parm); exit(1); } printf("(err = %s)\n", err); printf("res = %d %d\n", res[0], res[1]); printf(" v = %d\n", v); printf("out = \"%s\"\n", out); printf(" mm = %d ints:", mmm); for (n=0; n<=mmm-1; n++) { printf(" %d", mm[n]); } printf("\n"); printf(" in = %d files:", numIn); for (n=0; n<=numIn-1; n++) { printf(" \"%s\"", in[n]); } printf("\n"); hestParseFree(opt); parm = hestParmFree(parm); exit(0); }
int main(int argc, char **argv) { int res[2], v, numIn; char **in, *out, *blah[3], *option = NULL; int n, *ints, numN; hestOpt *opt = NULL; hestParm *parm; char *err = NULL, info[] = "This program does nothing in particular, though it does attempt " "to pose as some sort of command-line image processing program. " "As usual, any implied functionality is purely coincidental, " "especially since this is the output of a unicyclist."; parm = hestParmNew(); parm->respFileEnable = AIR_TRUE; parm->verbosity = 3; opt = NULL; hestOptAdd(&opt, "v,verbose", "level", airTypeInt, 0, 1, &v, "0", "verbosity level"); hestOptAdd(&opt, "out", "file", airTypeString, 1, 1, &out, "output.ppm", "PPM image output"); hestOptAdd(&opt, "blah", "input", airTypeString, 3, 3, blah, "a b c", "input image file(s)"); hestOptAdd(&opt, "option","opt", airTypeString, 0, 1, &option, "default", "this is just a test"); hestOptAdd(&opt, NULL, "input", airTypeString, 1, -1, &in, NULL, "input image file(s)", &numIn); hestOptAdd(&opt, "ints", "N", airTypeInt, 1, -1, &ints, "10 20 30", "a list of integers", &numN); hestOptAdd(&opt, "res", "sx sy", airTypeInt, 2, 2, res, NULL, "image resolution"); printf("what 0\n"); if (1 == argc) { /* didn't get anything at all on command line */ /* print program information ... */ hestInfo(stderr, argv[0], info, parm); /* ... and usage information ... */ hestUsage(stderr, opt, argv[0], parm); hestGlossary(stderr, opt, parm); /* ... and avoid memory leaks */ opt = hestOptFree(opt); parm = hestParmFree(parm); exit(1); } printf("what 1\n"); /* else we got something, see if we can parse it */ if (hestParse(opt, argc-1, argv+1, &err, parm)) { fprintf(stderr, "ERROR: %s\n", err); free(err); /* print usage information ... */ hestUsage(stderr, opt, argv[0], parm); hestGlossary(stderr, opt, parm); /* ... and then avoid memory leaks */ opt = hestOptFree(opt); parm = hestParmFree(parm); printf(" ---- in = %lx\n", (unsigned long)in); printf(" ---- blah[0] = %lx\n", (unsigned long)(blah[0])); printf(" ---- option = %lx\n", (unsigned long)option); exit(1); } printf("what 2\n"); printf("(err = %s)\n", err ? err : "(null)"); printf(" v = %d\n", v); printf("out = \"%s\"\n", out ? out : "(null)"); printf("blah = \"%s\" \"%s\" \"%s\"\n", blah[0], blah[1], blah[2]); printf("option = \"%s\"\n", option ? option : "(null)"); printf("res = %d %d\n", res[0], res[1]); /* printf(" ---- in = %lx\n", (unsigned long)in); printf(" in = %d files:", numIn); for (n=0; n<=numIn-1; n++) { printf(" \"%s\"", in[n] ? in[n] : "(null)"); } printf("\n"); */ printf(" ints = %d ints:", numN); for (n=0; n<=numN-1; n++) { printf(" %d", ints[n]); } printf("\n"); printf("what 3\n"); /* free the memory allocated by parsing ... */ hestParseFree(opt); /* ... and the other stuff */ opt = hestOptFree(opt); parm = hestParmFree(parm); exit(0); }
int main(int argc, const char *argv[]) { gageKind *kind; const char *me; char *whatS, *err, *outS, *stackReadFormat, *stackSaveFormat; hestParm *hparm; hestOpt *hopt = NULL; NrrdKernelSpec *k00, *k11, *k22, *kSS, *kSSblur; int what, E=0, renorm, SSuniform, SSoptim, verbose, zeroZ, orientationFromSpacing, SSnormd; unsigned int iBaseDim, oBaseDim, axi, numSS, ninSSIdx, seed; const double *answer; Nrrd *nin, *nout, **ninSS=NULL; Nrrd *ngrad=NULL, *nbmat=NULL; size_t ai, ansLen, idx, xi, yi, zi, six, siy, siz, sox, soy, soz; double bval=0, gmc, rangeSS[2], wrlSS, idxSS=AIR_NAN, dsix, dsiy, dsiz, dsox, dsoy, dsoz; gageContext *ctx; gagePerVolume *pvl=NULL; double t0, t1, x, y, z, scale[3], rscl[3], min[3], maxOut[3], maxIn[3]; airArray *mop; unsigned int hackZi, *skip, skipNum; double (*ins)(void *v, size_t I, double d); gageStackBlurParm *sbp; char hackKeyStr[]="TEEM_VPROBE_HACK_ZI", *hackValStr; int otype, hackSet; char stmp[4][AIR_STRLEN_SMALL]; me = argv[0]; /* parse environment variables first, in case they break nrrdDefault* or nrrdState* variables in a way that nrrdSanity() should see */ nrrdDefaultGetenv(); nrrdStateGetenv(); /* no harm done in making sure we're sane */ if (!nrrdSanity()) { fprintf(stderr, "******************************************\n"); fprintf(stderr, "******************************************\n"); fprintf(stderr, "\n"); fprintf(stderr, " %s: nrrd sanity check FAILED.\n", me); fprintf(stderr, "\n"); fprintf(stderr, " This means that either nrrd can't work on this " "platform, or (more likely)\n"); fprintf(stderr, " there was an error in the compilation options " "and variable definitions\n"); fprintf(stderr, " for how Teem was built here.\n"); fprintf(stderr, "\n"); fprintf(stderr, " %s\n", err = biffGetDone(NRRD)); fprintf(stderr, "\n"); fprintf(stderr, "******************************************\n"); fprintf(stderr, "******************************************\n"); free(err); return 1; } mop = airMopNew(); hparm = hestParmNew(); airMopAdd(mop, hparm, AIR_CAST(airMopper, hestParmFree), airMopAlways); hparm->elideSingleOtherType = AIR_TRUE; hestOptAdd(&hopt, "i", "nin", airTypeOther, 1, 1, &nin, NULL, "input volume", NULL, NULL, nrrdHestNrrd); hestOptAdd(&hopt, "k", "kind", airTypeOther, 1, 1, &kind, NULL, "\"kind\" of volume (\"scalar\", \"vector\", " "\"tensor\", or \"dwi\")", NULL, NULL, meetHestGageKind); hestOptAdd(&hopt, "v", "verbosity", airTypeInt, 1, 1, &verbose, "1", "verbosity level"); hestOptAdd(&hopt, "q", "query", airTypeString, 1, 1, &whatS, NULL, "the quantity (scalar, vector, or matrix) to learn by probing"); hestOptAdd(&hopt, "s", "sclX sclY sxlZ", airTypeDouble, 3, 3, scale, "1.0 1.0 1.0", "scaling factor for resampling on each axis " "(>1.0 : supersampling)"); hestOptAdd(&hopt, "k00", "kern00", airTypeOther, 1, 1, &k00, "tent", "kernel for gageKernel00", NULL, NULL, nrrdHestKernelSpec); hestOptAdd(&hopt, "k11", "kern11", airTypeOther, 1, 1, &k11, "cubicd:1,0", "kernel for gageKernel11", NULL, NULL, nrrdHestKernelSpec); hestOptAdd(&hopt, "k22", "kern22", airTypeOther, 1, 1, &k22, "cubicdd:1,0", "kernel for gageKernel22", NULL, NULL, nrrdHestKernelSpec); hestOptAdd(&hopt, "seed", "N", airTypeUInt, 1, 1, &seed, "42", "RNG seed; mostly for debugging"); hestOptAdd(&hopt, "zz", "bool", airTypeBool, 1, 1, &zeroZ, "false", "enable \"zeroZ\" behavior in gage that partially " "implements working with 3D images as if they are 2D"); hestOptAdd(&hopt, "ssn", "SS #", airTypeUInt, 1, 1, &numSS, "0", "how many scale-space samples to evaluate, or, " "0 to turn-off all scale-space behavior"); hestOptAdd(&hopt, "ssr", "scale range", airTypeDouble, 2, 2, rangeSS, "nan nan", "range of scales in scale-space"); hestOptAdd(&hopt, "ssrf", "SS read format", airTypeString, 1, 1, &stackReadFormat, "", "printf-style format (including a \"%u\") for the " "filenames from which to *read* " "pre-blurred volumes computed for the stack"); hestOptAdd(&hopt, "sssf", "SS save format", airTypeString, 1, 1, &stackSaveFormat, "", "printf-style format (including a \"%u\") for the " "filenames in which to *save* " "pre-blurred volumes computed for the stack"); hestOptAdd(&hopt, "ssw", "SS pos", airTypeDouble, 1, 1, &wrlSS, "0", "\"world\"-space position (true sigma) " "at which to sample in scale-space"); hestOptAdd(&hopt, "kssb", "kernel", airTypeOther, 1, 1, &kSSblur, "dgauss:1,5", "blurring kernel, to sample scale space", NULL, NULL, nrrdHestKernelSpec); hestOptAdd(&hopt, "kssr", "kernel", airTypeOther, 1, 1, &kSS, "hermite", "kernel for reconstructing from scale space samples", NULL, NULL, nrrdHestKernelSpec); hestOptAdd(&hopt, "ssu", NULL, airTypeInt, 0, 0, &SSuniform, NULL, "do uniform samples along sigma, and not (by default) " "samples according to the effective diffusion scale"); hestOptAdd(&hopt, "sso", NULL, airTypeInt, 0, 0, &SSoptim, NULL, "if not using \"-ssu\", use pre-computed optimal " "sigmas when possible"); hestOptAdd(&hopt, "ssnd", NULL, airTypeInt, 0, 0, &SSnormd, NULL, "normalize derivatives by scale"); hestOptAdd(&hopt, "rn", NULL, airTypeInt, 0, 0, &renorm, NULL, "renormalize kernel weights at each new sample location. " "\"Accurate\" kernels don't need this; doing it always " "makes things go slower"); hestOptAdd(&hopt, "gmc", "min gradmag", airTypeDouble, 1, 1, &gmc, "0.0", "For curvature-based queries, use zero when gradient " "magnitude is below this"); hestOptAdd(&hopt, "ofs", "ofs", airTypeInt, 0, 0, &orientationFromSpacing, NULL, "If only per-axis spacing is available, use that to " "contrive full orientation info"); hestOptAdd(&hopt, "t", "type", airTypeEnum, 1, 1, &otype, "float", "type of output volume", NULL, nrrdType); hestOptAdd(&hopt, "o", "nout", airTypeString, 1, 1, &outS, "-", "output volume"); hestParseOrDie(hopt, argc-1, argv+1, hparm, me, probeInfo, AIR_TRUE, AIR_TRUE, AIR_TRUE); airMopAdd(mop, hopt, AIR_CAST(airMopper, hestOptFree), airMopAlways); airMopAdd(mop, hopt, AIR_CAST(airMopper, hestParseFree), airMopAlways); what = airEnumVal(kind->enm, whatS); if (!what) { /* 0 indeed always means "unknown" for any gageKind */ fprintf(stderr, "%s: couldn't parse \"%s\" as measure of \"%s\" volume\n", me, whatS, kind->name); hestUsage(stderr, hopt, me, hparm); hestGlossary(stderr, hopt, hparm); airMopError(mop); return 1; } /* special set-up required for DWI kind */ if (!strcmp(TEN_DWI_GAGE_KIND_NAME, kind->name)) { if (tenDWMRIKeyValueParse(&ngrad, &nbmat, &bval, &skip, &skipNum, nin)) { airMopAdd(mop, err = biffGetDone(TEN), airFree, airMopAlways); fprintf(stderr, "%s: trouble parsing DWI info:\n%s\n", me, err); airMopError(mop); return 1; } if (skipNum) { fprintf(stderr, "%s: sorry, can't do DWI skipping in tenDwiGage", me); airMopError(mop); return 1; } /* this could stand to use some more command-line arguments */ if (tenDwiGageKindSet(kind, 50, 1, bval, 0.001, ngrad, nbmat, tenEstimate1MethodLLS, tenEstimate2MethodQSegLLS, seed)) { airMopAdd(mop, err = biffGetDone(TEN), airFree, airMopAlways); fprintf(stderr, "%s: trouble parsing DWI info:\n%s\n", me, err); airMopError(mop); return 1; } } /* for setting up pre-blurred scale-space samples */ if (numSS) { unsigned int vi; sbp = gageStackBlurParmNew(); airMopAdd(mop, sbp, (airMopper)gageStackBlurParmNix, airMopAlways); ninSS = AIR_CAST(Nrrd **, calloc(numSS, sizeof(Nrrd *))); if (!ninSS) { fprintf(stderr, "%s: couldn't allocate ninSS", me); airMopError(mop); return 1; } for (ninSSIdx=0; ninSSIdx<numSS; ninSSIdx++) { ninSS[ninSSIdx] = nrrdNew(); airMopAdd(mop, ninSS[ninSSIdx], (airMopper)nrrdNuke, airMopAlways); } if (gageStackBlurParmScaleSet(sbp, numSS, rangeSS[0], rangeSS[1], SSuniform, SSoptim) || gageStackBlurParmKernelSet(sbp, kSSblur) || gageStackBlurParmRenormalizeSet(sbp, AIR_TRUE) || gageStackBlurParmBoundarySet(sbp, nrrdBoundaryBleed, AIR_NAN) || gageStackBlurParmVerboseSet(sbp, verbose)) { airMopAdd(mop, err = biffGetDone(GAGE), airFree, airMopAlways); fprintf(stderr, "%s: trouble with stack blur info:\n%s\n", me, err); airMopError(mop); return 1; } if (airStrlen(stackReadFormat)) { if (nrrdLoadMulti(ninSS, numSS, stackReadFormat, 0, NULL)) { airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: trouble loading blurrings:\n%s\n", me, err); airMopError(mop); return 1; } if (gageStackBlurCheck(AIR_CAST(const Nrrd *const*, ninSS), sbp, nin, kind)) { airMopAdd(mop, err = biffGetDone(GAGE), airFree, airMopAlways); fprintf(stderr, "%s: trouble:\n%s\n", me, err); airMopError(mop); return 1; } } else { if (gageStackBlur(ninSS, sbp, nin, kind)) {
int main(int argc, char *argv[]) { gageKind *kind; char *me, *outS, *whatS, *err, hackKeyStr[]="TEEM_VPROBE_HACK_ZI", *hackValStr, *stackSavePath; hestParm *hparm; hestOpt *hopt = NULL; NrrdKernelSpec *k00, *k11, *k22, *kSS, *kSSblur; int what, E=0, otype, renorm, hackSet, SSrenorm, SSuniform, verbose; unsigned int iBaseDim, oBaseDim, axi, numSS, ninSSIdx, seed; const double *answer; Nrrd *nin, *nout, **ninSS=NULL; Nrrd *ngrad=NULL, *nbmat=NULL; size_t ai, ansLen, idx, xi, yi, zi, six, siy, siz, sox, soy, soz; double bval=0, gmc, rangeSS[2], wrlSS, idxSS=AIR_NAN, *scalePos; gageContext *ctx; gagePerVolume *pvl=NULL; double t0, t1, x, y, z, scale[3], rscl[3], min[3], maxOut[3], maxIn[3]; airArray *mop; unsigned int hackZi, *skip, skipNum; double (*ins)(void *v, size_t I, double d); mop = airMopNew(); me = argv[0]; hparm = hestParmNew(); airMopAdd(mop, hparm, AIR_CAST(airMopper, hestParmFree), airMopAlways); hparm->elideSingleOtherType = AIR_TRUE; hestOptAdd(&hopt, "i", "nin", airTypeOther, 1, 1, &nin, NULL, "input volume", NULL, NULL, nrrdHestNrrd); hestOptAdd(&hopt, "k", "kind", airTypeOther, 1, 1, &kind, NULL, "\"kind\" of volume (\"scalar\", \"vector\", " "\"tensor\", or \"dwi\")", NULL, NULL, &probeKindHestCB); hestOptAdd(&hopt, "v", "verbosity", airTypeInt, 1, 1, &verbose, "1", "verbosity level"); hestOptAdd(&hopt, "q", "query", airTypeString, 1, 1, &whatS, NULL, "the quantity (scalar, vector, or matrix) to learn by probing"); hestOptAdd(&hopt, "s", "sclX sclY sxlZ", airTypeDouble, 3, 3, scale, "1.0 1.0 1.0", "scaling factor for resampling on each axis " "(>1.0 : supersampling)"); hestOptAdd(&hopt, "k00", "kern00", airTypeOther, 1, 1, &k00, "tent", "kernel for gageKernel00", NULL, NULL, nrrdHestKernelSpec); hestOptAdd(&hopt, "k11", "kern11", airTypeOther, 1, 1, &k11, "cubicd:1,0", "kernel for gageKernel11", NULL, NULL, nrrdHestKernelSpec); hestOptAdd(&hopt, "k22", "kern22", airTypeOther, 1, 1, &k22, "cubicdd:1,0", "kernel for gageKernel22", NULL, NULL, nrrdHestKernelSpec); hestOptAdd(&hopt, "seed", "N", airTypeUInt, 1, 1, &seed, "42", "RNG seed; mostly for debugging"); hestOptAdd(&hopt, "ssn", "SS #", airTypeUInt, 1, 1, &numSS, "0", "how many scale-space samples to evaluate, or, " "0 to turn-off all scale-space behavior"); hestOptAdd(&hopt, "ssr", "scale range", airTypeDouble, 2, 2, rangeSS, "nan nan", "range of scales in scale-space"); hestOptAdd(&hopt, "sss", "scale save path", airTypeString, 1, 1, &stackSavePath, "", "give a non-empty path string (like \"./\") to save out " "the pre-blurred volumes computed for the stack"); hestOptAdd(&hopt, "ssw", "SS pos", airTypeDouble, 1, 1, &wrlSS, "0", "\"world\"-space position (true sigma) " "at which to sample in scale-space"); hestOptAdd(&hopt, "kssblur", "kernel", airTypeOther, 1, 1, &kSSblur, "dgauss:1,5", "blurring kernel, to sample scale space", NULL, NULL, nrrdHestKernelSpec); hestOptAdd(&hopt, "kss", "kernel", airTypeOther, 1, 1, &kSS, "tent", "kernel for reconstructing from scale space samples", NULL, NULL, nrrdHestKernelSpec); hestOptAdd(&hopt, "ssrn", "ssrn", airTypeInt, 1, 1, &SSrenorm, "0", "enable derivative normalization based on scale space"); hestOptAdd(&hopt, "ssu", NULL, airTypeInt, 0, 0, &SSuniform, NULL, "do uniform samples along sigma, and not (by default) " "samples according to the logarithm of diffusion time"); hestOptAdd(&hopt, "rn", NULL, airTypeInt, 0, 0, &renorm, NULL, "renormalize kernel weights at each new sample location. " "\"Accurate\" kernels don't need this; doing it always " "makes things go slower"); hestOptAdd(&hopt, "gmc", "min gradmag", airTypeDouble, 1, 1, &gmc, "0.0", "For curvature-based queries, use zero when gradient " "magnitude is below this"); hestOptAdd(&hopt, "t", "type", airTypeEnum, 1, 1, &otype, "float", "type of output volume", NULL, nrrdType); hestOptAdd(&hopt, "o", "nout", airTypeString, 1, 1, &outS, "-", "output volume"); hestParseOrDie(hopt, argc-1, argv+1, hparm, me, probeInfo, AIR_TRUE, AIR_TRUE, AIR_TRUE); airMopAdd(mop, hopt, AIR_CAST(airMopper, hestOptFree), airMopAlways); airMopAdd(mop, hopt, AIR_CAST(airMopper, hestParseFree), airMopAlways); what = airEnumVal(kind->enm, whatS); if (!what) { /* 0 indeed always means "unknown" for any gageKind */ fprintf(stderr, "%s: couldn't parse \"%s\" as measure of \"%s\" volume\n", me, whatS, kind->name); hestUsage(stderr, hopt, me, hparm); hestGlossary(stderr, hopt, hparm); airMopError(mop); return 1; } /* special set-up required for DWI kind */ if (!strcmp(TEN_DWI_GAGE_KIND_NAME, kind->name)) { if (tenDWMRIKeyValueParse(&ngrad, &nbmat, &bval, &skip, &skipNum, nin)) { airMopAdd(mop, err = biffGetDone(TEN), airFree, airMopAlways); fprintf(stderr, "%s: trouble parsing DWI info:\n%s\n", me, err); airMopError(mop); return 1; } if (skipNum) { fprintf(stderr, "%s: sorry, can't do DWI skipping in tenDwiGage", me); airMopError(mop); return 1; } /* this could stand to use some more command-line arguments */ if (tenDwiGageKindSet(kind, 50, 1, bval, 0.001, ngrad, nbmat, tenEstimate1MethodLLS, tenEstimate2MethodQSegLLS, seed)) { airMopAdd(mop, err = biffGetDone(TEN), airFree, airMopAlways); fprintf(stderr, "%s: trouble parsing DWI info:\n%s\n", me, err); airMopError(mop); return 1; } } /* for setting up pre-blurred scale-space samples */ if (numSS) { unsigned int vi; ninSS = AIR_CAST(Nrrd **, calloc(numSS, sizeof(Nrrd *))); scalePos = AIR_CAST(double *, calloc(numSS, sizeof(double))); if (!(ninSS && scalePos)) { fprintf(stderr, "%s: couldn't allocate ninSS", me); airMopError(mop); return 1; } for (ninSSIdx=0; ninSSIdx<numSS; ninSSIdx++) { ninSS[ninSSIdx] = nrrdNew(); airMopAdd(mop, ninSS[ninSSIdx], (airMopper)nrrdNuke, airMopAlways); } if (SSuniform) { for (vi=0; vi<numSS; vi++) { scalePos[vi] = AIR_AFFINE(0, vi, numSS-1, rangeSS[0], rangeSS[1]); } } else { double rangeTau[2], tau; rangeTau[0] = gageTauOfSig(rangeSS[0]); rangeTau[1] = gageTauOfSig(rangeSS[1]); for (vi=0; vi<numSS; vi++) { tau = AIR_AFFINE(0, vi, numSS-1, rangeTau[0], rangeTau[1]); scalePos[vi] = gageSigOfTau(tau); } } if (verbose > 2) { fprintf(stderr, "%s: sampling scale range %g--%g %suniformly:\n", me, rangeSS[0], rangeSS[1], SSuniform ? "" : "non-"); for (vi=0; vi<numSS; vi++) { fprintf(stderr, " scalePos[%u] = %g\n", vi, scalePos[vi]); } } if (gageStackBlur(ninSS, scalePos, numSS, nin, kind->baseDim, kSSblur, nrrdBoundaryBleed, AIR_TRUE, verbose)) { airMopAdd(mop, err = biffGetDone(GAGE), airFree, airMopAlways); fprintf(stderr, "%s: trouble pre-computing blurrings:\n%s\n", me, err); airMopError(mop); return 1; } if (airStrlen(stackSavePath)) { char fnform[AIR_STRLEN_LARGE]; sprintf(fnform, "%s/blur-%%02u.nrrd", stackSavePath); fprintf(stderr, "%s: |%s|\n", me, fnform); if (nrrdSaveMulti(fnform, AIR_CAST(const Nrrd *const *, ninSS), numSS, 0, NULL)) { airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: trouble saving blurrings:\n%s\n", me, err); airMopError(mop); return 1; } } /* there's actually work to do here, weirdly: gageProbe can either work in index space, or in world space, but vprobe has basically always been index-space-centric. For doing any kind scale/stack space hacking for which vprobe is suited, its nicer to have the stack position be in the stack's "world" space, not the (potentially non-uniform) index space. So here, we have to actually replicate work that is done by _gageProbeSpace() in converting from world to index space */ for (vi=0; vi<numSS-1; vi++) { if (AIR_IN_CL(scalePos[vi], wrlSS, scalePos[vi+1])) { idxSS = vi + AIR_AFFINE(scalePos[vi], wrlSS, scalePos[vi+1], 0, 1); if (verbose > 1) { fprintf(stderr, "%s: scale pos %g -> idx %g = %u + %g\n", me, wrlSS, idxSS, vi, AIR_AFFINE(scalePos[vi], wrlSS, scalePos[vi+1], 0, 1)); } break; } } if (vi == numSS-1) { fprintf(stderr, "%s: scale pos %g outside range %g=%g, %g=%g\n", me, wrlSS, rangeSS[0], scalePos[0], rangeSS[1], scalePos[numSS-1]); airMopError(mop); return 1; } } else {