int tend_unmfMain(int argc, const char **argv, const char *me, hestParm *hparm) { int pret; hestOpt *hopt = NULL; char *perr, *err; airArray *mop; Nrrd *nin, *nout; char *outS; hestOptAdd(&hopt, "i", "nin", airTypeOther, 1, 1, &nin, NULL, "input diffusion tensor volume " "(sorry, can't use usual default of \"-\" for stdin " "because of hest quirk)", NULL, NULL, nrrdHestNrrd); hestOptAdd(&hopt, "o", "nout", airTypeString, 1, 1, &outS, "-", "output tensor volume"); mop = airMopNew(); airMopAdd(mop, hopt, (airMopper)hestOptFree, airMopAlways); USAGE(_tend_unmfInfoL); PARSE(); airMopAdd(mop, hopt, (airMopper)hestParseFree, airMopAlways); nout = nrrdNew(); airMopAdd(mop, nout, (airMopper)nrrdNuke, airMopAlways); if (tenMeasurementFrameReduce(nout, nin)) { airMopAdd(mop, err=biffGetDone(TEN), airFree, airMopAlways); fprintf(stderr, "%s: trouble:\n%s\n", me, err); airMopError(mop); return 1; } if (nrrdSave(outS, nout, NULL)) { airMopAdd(mop, err=biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: trouble writing:\n%s\n", me, err); airMopError(mop); return 1; } airMopOkay(mop); return 0; }
int main(int argc, char *argv[]) { char *me, *err; hestOpt *hopt=NULL; airArray *mop; char *outS[3]; char *gravStr, *gravGradStr, *seedStr; pushContext *pctx; Nrrd *_nin, *nin, *nPosIn, *nPosOut, *nTenOut, *nEnrOut; NrrdKernelSpec *ksp00, *ksp11, *ksp22; pushEnergySpec *ensp; int E; me = argv[0]; mop = airMopNew(); pctx = pushContextNew(); airMopAdd(mop, pctx, (airMopper)pushContextNix, airMopAlways); hestOptAdd(&hopt, "i", "nin", airTypeOther, 1, 1, &_nin, NULL, "input volume to filter", NULL, NULL, nrrdHestNrrd); hestOptAdd(&hopt, "np", "# points", airTypeUInt, 1, 1, &(pctx->pointNum), "1000", "number of points to use in simulation"); hestOptAdd(&hopt, "pi", "npos", airTypeOther, 1, 1, &nPosIn, "", "positions to start at (overrides \"-np\")", NULL, NULL, nrrdHestNrrd); hestOptAdd(&hopt, "step", "step", airTypeDouble, 1, 1, &(pctx->stepInitial), "1", "step size for gradient descent"); hestOptAdd(&hopt, "scl", "scale", airTypeDouble, 1, 1, &(pctx->scale), "1500", "scaling from tensor size to glyph size"); hestOptAdd(&hopt, "wall", "wall", airTypeDouble, 1, 1, &(pctx->wall), "0.0", "spring constant of containing walls"); hestOptAdd(&hopt, "cnts", "scale", airTypeDouble, 1, 1, &(pctx->cntScl), "0.0", "scaling of containment force"); hestOptAdd(&hopt, "limit", "frac", airTypeDouble, 1, 1, &(pctx->deltaLimit), "0.3", "speed limit on particles' motion"); hestOptAdd(&hopt, "dfmin", "frac", airTypeDouble, 1, 1, &(pctx->deltaFracMin), "0.2", "decrease step size if deltaFrac goes below this"); hestOptAdd(&hopt, "esf", "frac", airTypeDouble, 1, 1, &(pctx->energyStepFrac), "0.9", "when energy goes up instead of down, fraction by " "which to scale step size"); hestOptAdd(&hopt, "dfsf", "frac", airTypeDouble, 1, 1, &(pctx->deltaFracStepFrac), "0.5", "when deltaFrac goes below deltaFracMin, fraction by " "which to scale step size"); hestOptAdd(&hopt, "eimin", "frac", airTypeDouble, 1, 1, &(pctx->energyImprovMin), "0.01", "convergence threshold: stop when fracional improvement " "(decrease) in energy dips below this"); hestOptAdd(&hopt, "detr", NULL, airTypeBool, 0, 0, &(pctx->detReject), NULL, "do determinant-based rejection of initial sample locations"); hestOptAdd(&hopt, "rng", "seed", airTypeUInt, 1, 1, &(pctx->seedRNG), "42", "seed value for RNG which determines initial point locations"); hestOptAdd(&hopt, "nt", "# threads", airTypeUInt, 1, 1, &(pctx->threadNum), "1", "number of threads to run"); hestOptAdd(&hopt, "nprob", "# iters", airTypeDouble, 1, 1, &(pctx->neighborTrueProb), "1.0", "do full neighbor traversal with this probability"); hestOptAdd(&hopt, "pprob", "# iters", airTypeDouble, 1, 1, &(pctx->probeProb), "1.0", "do field probing with this probability"); hestOptAdd(&hopt, "maxi", "# iters", airTypeUInt, 1, 1, &(pctx->maxIter), "0", "if non-zero, max # iterations to run"); hestOptAdd(&hopt, "snap", "iters", airTypeUInt, 1, 1, &(pctx->snap), "0", "if non-zero, # iterations between which a snapshot " "is saved"); hestOptAdd(&hopt, "grv", "item", airTypeString, 1, 1, &gravStr, "none", "item to act as gravity"); hestOptAdd(&hopt, "grvgv", "item", airTypeString, 1, 1, &gravGradStr, "none", "item to act as gravity gradient"); hestOptAdd(&hopt, "grvs", "scale", airTypeDouble, 1, 1, &(pctx->gravScl), "nan", "magnitude and scaling of gravity vector"); hestOptAdd(&hopt, "grvz", "scale", airTypeDouble, 1, 1, &(pctx->gravZero), "nan", "height (WRT gravity) of zero potential energy"); hestOptAdd(&hopt, "seed", "item", airTypeString, 1, 1, &seedStr, "none", "item to act as seed threshold"); hestOptAdd(&hopt, "seedth", "thresh", airTypeDouble, 1, 1, &(pctx->seedThresh), "nan", "seed threshold threshold"); hestOptAdd(&hopt, "energy", "spec", airTypeOther, 1, 1, &ensp, "cotan", "specification of energy function to use", NULL, NULL, pushHestEnergySpec); hestOptAdd(&hopt, "nobin", NULL, airTypeBool, 0, 0, &(pctx->binSingle), NULL, "turn off spatial binning (which prevents multi-threading " "from being useful), for debugging or speed-up measurement"); hestOptAdd(&hopt, "k00", "kernel", airTypeOther, 1, 1, &ksp00, "tent", "kernel for tensor field sampling", NULL, NULL, nrrdHestKernelSpec); hestOptAdd(&hopt, "k11", "kernel", airTypeOther, 1, 1, &ksp11, "fordif", "kernel for finding containment gradient from mask", NULL, NULL, nrrdHestKernelSpec); hestOptAdd(&hopt, "k22", "kernel", airTypeOther, 1, 1, &ksp22, "cubicdd:1,0", "kernel for 2nd derivatives", NULL, NULL, nrrdHestKernelSpec); hestOptAdd(&hopt, "o", "nout", airTypeString, 3, 3, outS, "p.nrrd t.nrrd e.nrrd", "output files to save position and tensor info 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); nPosOut = nrrdNew(); airMopAdd(mop, nPosOut, (airMopper)nrrdNuke, airMopAlways); nTenOut = nrrdNew(); airMopAdd(mop, nTenOut, (airMopper)nrrdNuke, airMopAlways); nEnrOut = nrrdNew(); airMopAdd(mop, nEnrOut, (airMopper)nrrdNuke, airMopAlways); if (3 == _nin->spaceDim && AIR_EXISTS(_nin->measurementFrame[0][0])) { nin = nrrdNew(); airMopAdd(mop, nin, (airMopper)nrrdNuke, airMopAlways); if (tenMeasurementFrameReduce(nin, _nin)) { airMopAdd(mop, err = biffGetDone(TEN), airFree, airMopAlways); fprintf(stderr, "%s: trouble undoing measurement frame:\n%s", me, err); airMopError(mop); exit(1); } } else { nin = _nin; } pctx->nin = nin; pctx->npos = nPosIn; pctx->verbose = 0; pctx->binIncr = 84; /* random small-ish value */ pushEnergySpecSet(pctx->ensp, ensp->energy, ensp->parm); nrrdKernelSpecSet(pctx->ksp00, ksp00->kernel, ksp00->parm); nrrdKernelSpecSet(pctx->ksp11, ksp11->kernel, ksp11->parm); nrrdKernelSpecSet(pctx->ksp22, ksp22->kernel, ksp22->parm); if (strcmp("none", gravStr)) { pctx->gravItem = airEnumVal(tenGage, gravStr); if (tenGageUnknown == pctx->gravItem) { fprintf(stderr, "%s: couldn't parse \"%s\" as a %s (gravity)\n", me, gravStr, tenGage->name); airMopError(mop); return 1; } pctx->gravGradItem = airEnumVal(tenGage, gravGradStr); if (tenGageUnknown == pctx->gravGradItem) { fprintf(stderr, "%s: couldn't parse \"%s\" as a %s (gravity grad)\n", me, gravGradStr, tenGage->name); airMopError(mop); return 1; } } else { pctx->gravItem = tenGageUnknown; pctx->gravGradItem = tenGageUnknown; pctx->gravZero = AIR_NAN; pctx->gravScl = AIR_NAN; } if (strcmp("none", seedStr)) { pctx->seedThreshItem = airEnumVal(tenGage, seedStr); if (tenGageUnknown == pctx->seedThreshItem) { fprintf(stderr, "%s: couldn't parse \"%s\" as a %s (seedthresh)\n", me, seedStr, tenGage->name); airMopError(mop); return 1; } } else { pctx->seedThreshItem = 0; pctx->seedThresh = AIR_NAN; } E = 0; if (!E) E |= pushStart(pctx); if (!E) E |= pushRun(pctx); if (!E) E |= pushOutputGet(nPosOut, nTenOut, nEnrOut, pctx); if (!E) E |= pushFinish(pctx); if (E) { airMopAdd(mop, err = biffGetDone(PUSH), airFree, airMopAlways); fprintf(stderr, "%s: trouble:\n%s\n", me, err); airMopError(mop); return 1; } fprintf(stderr, "%s: time for %d iterations= %g secs\n", me, pctx->iter, pctx->timeRun); if (nrrdSave(outS[0], nPosOut, NULL) || nrrdSave(outS[1], nTenOut, NULL) || nrrdSave(outS[2], nEnrOut, 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 tend_expandMain(int argc, char **argv, char *me, hestParm *hparm) { int pret; hestOpt *hopt = NULL; char *perr, *err; airArray *mop; Nrrd *nin, *nout; char *outS; int orientRed, orientRedWithOrigin, mfRed; float scale, thresh; hestOptAdd(&hopt, "t", "thresh", airTypeFloat, 1, 1, &thresh, "0.5", "confidence level to threshold output tensors at. Should " "be between 0.0 and 1.0."); hestOptAdd(&hopt, "s", "scale", airTypeFloat, 1, 1, &scale, "1.0", "how to scale values before saving as 9-value tensor. Useful " "for visualization tools which assume certain characteristic " "ranges of eigenvalues"); hestOptAdd(&hopt, "unmf", NULL, airTypeInt, 0, 0, &mfRed, NULL, "apply and remove the measurement frame, if it exists"); hestOptAdd(&hopt, "ro", NULL, airTypeInt, 0, 0, &orientRed, NULL, "reduce general image orientation to axis-aligned spacings"); hestOptAdd(&hopt, "roo", NULL, airTypeInt, 0, 0, &orientRedWithOrigin, NULL, "reduce general image orientation to axis-aligned spacings, " "while also making some effort to set axis mins from " "space origin"); hestOptAdd(&hopt, "i", "nin", airTypeOther, 1, 1, &nin, "-", "input diffusion tensor volume, with 7 values per sample", NULL, NULL, nrrdHestNrrd); hestOptAdd(&hopt, "o", "nout", airTypeString, 1, 1, &outS, NULL, "output tensor volume, with the 9 matrix components per sample"); mop = airMopNew(); airMopAdd(mop, hopt, (airMopper)hestOptFree, airMopAlways); USAGE(_tend_expandInfoL); PARSE(); airMopAdd(mop, hopt, (airMopper)hestParseFree, airMopAlways); nout = nrrdNew(); airMopAdd(mop, nout, (airMopper)nrrdNuke, airMopAlways); if (mfRed && 3 == nin->spaceDim && AIR_EXISTS(nin->measurementFrame[0][0])) { if (tenMeasurementFrameReduce(nin, nin)) { airMopAdd(mop, err=biffGetDone(TEN), airFree, airMopAlways); fprintf(stderr, "%s: trouble with measurement frame:\n%s\n", me, err); airMopError(mop); return 1; } } if (tenExpand(nout, nin, scale, thresh)) { airMopAdd(mop, err=biffGetDone(TEN), airFree, airMopAlways); fprintf(stderr, "%s: trouble expanding tensors:\n%s\n", me, err); airMopError(mop); return 1; } if (orientRedWithOrigin || orientRed) { if (nrrdOrientationReduce(nout, nout, orientRedWithOrigin ? AIR_TRUE : AIR_FALSE)) { airMopAdd(mop, err=biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: trouble unorienting:\n%s\n", me, err); airMopError(mop); return 1; } } if (nrrdSave(outS, nout, NULL)) { airMopAdd(mop, err=biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: trouble writing:\n%s\n", me, err); airMopError(mop); return 1; } airMopOkay(mop); return 0; }