int main(int argc, char **argv) { char *err, *me, *filename; Nrrd *nin; unsigned int axi; me = argv[0]; if (2 != argc) { fprintf(stderr, "usage: %s <filename>\n", me); return 1; } filename = argv[1]; /* create a nrrd; at this point this is just an empty container */ nin = nrrdNew(); /* read in the nrrd from file */ if (nrrdLoad(nin, filename, NULL)) { err = biffGetDone(NRRD); fprintf(stderr, "%s: trouble reading \"%s\":\n%s", me, filename, err); free(err); return 1; } /* say something about the array */ printf("%s: \"%s\" is a %d-dimensional nrrd of type %s (%d)\n", me, filename, nin->dim, airEnumStr(nrrdType, nin->type), nin->type); for (axi=0; axi<nin->dim; axi++) { printf(" axis[%d] size = %u\n", axi, (unsigned int)nin->axis[axi].size); } printf("%s: the array contains %d elements, each %d bytes in size\n", me, (int)nrrdElementNumber(nin), (int)nrrdElementSize(nin)); /* blow away both the Nrrd struct *and* the memory at nin->data (nrrdNix() frees the struct but not the data, nrrdEmpty() frees the data but not the struct) */ nrrdNuke(nin); { Nrrd *nout; unsigned int sx=640, sy=480, xi, yi, idx; unsigned char *odata, rr, gg, bb; odata = (unsigned char *)(malloc(sx*sy*3)); for (yi=0; yi<sy; yi++) { rr = (unsigned char)(AIR_AFFINE(0, yi, sy, 0, 255)); for (xi=0; xi<sx; xi++) { gg = (unsigned char)(AIR_AFFINE(0, xi, sx, 0, 255)); bb = (unsigned char)(AIR_AFFINE(0, xi+yi, sx+sy, 0, 255)); idx = xi + sx*yi; odata[0 + 3*idx] = rr; odata[1 + 3*idx] = gg; odata[2 + 3*idx] = bb; } } //Saves the contents of the buffer as a png image //Currently upsidedown nout = nrrdNew(); if (nrrdWrap_va(nout, odata, nrrdTypeUChar, 3, (size_t)3, (size_t)sx, (size_t)sy) || nrrdSave("out.png", nout, NULL)) { err = biffGetDone(NRRD); fprintf(stderr, "%s: trouble wrapping image:\n%s", me, err); free(err); return 1; } nrrdNix(nout); free(odata); } return 0; }
int unrrdu_mlutMain(int argc, char **argv, char *me, hestParm *hparm) { hestOpt *opt = NULL; char *out, *err; Nrrd *nin, **_nmlut, *nmlut, *nout; airArray *mop; int typeOut, rescale, pret, blind8BitRange; unsigned int _nmlutLen, mapAxis; double min, max; NrrdRange *range=NULL; hestOptAdd(&opt, "m,map", "mlut", airTypeOther, 1, -1, &_nmlut, NULL, "one nrrd of lookup tables to map input nrrd through, or, " "list of nrrds which contain the individual entries of " "the lookup table at each voxel, which will be joined together.", &_nmlutLen, NULL, nrrdHestNrrd); hestOptAdd(&opt, "r,rescale", NULL, airTypeInt, 0, 0, &rescale, NULL, "rescale the input values from the input range to the " "lut domain. The lut domain is either explicitly " "defined by the axis min,max along axis 0 or 1, or, it " "is implicitly defined as zero to the length of that axis " "minus one."); hestOptAdd(&opt, "min,minimum", "value", airTypeDouble, 1, 1, &min, "nan", "Low end of input range. Defaults to lowest value " "found in input nrrd. Explicitly setting this is useful " "only with rescaling (\"-r\")"); hestOptAdd(&opt, "max,maximum", "value", airTypeDouble, 1, 1, &max, "nan", "High end of input range. Defaults to highest value " "found in input nrrd. Explicitly setting this is useful " "only with rescaling (\"-r\")"); hestOptAdd(&opt, "blind8", "bool", airTypeBool, 1, 1, &blind8BitRange, nrrdStateBlind8BitRange ? "true" : "false", "Whether to know the range of 8-bit data blindly " "(uchar is always [0,255], signed char is [-128,127]). " "Explicitly setting this is useful only with rescaling (\"-r\")"); hestOptAdd(&opt, "t,type", "type", airTypeOther, 1, 1, &typeOut, "default", "specify the type (\"int\", \"float\", etc.) of the " "output nrrd. " "By default (not using this option), the output type " "is the lut's type.", NULL, NULL, &unrrduHestMaybeTypeCB); OPT_ADD_NIN(nin, "input nrrd"); OPT_ADD_NOUT(out, "output nrrd"); mop = airMopNew(); airMopAdd(mop, opt, (airMopper)hestOptFree, airMopAlways); USAGE(_unrrdu_mlutInfoL); PARSE(); airMopAdd(mop, opt, (airMopper)hestParseFree, airMopAlways); nout = nrrdNew(); airMopAdd(mop, nout, (airMopper)nrrdNuke, airMopAlways); /* by the end of this block we need to have nmlut and mapAxis */ if (1 == _nmlutLen) { /* we got the mlut as a single nrrd */ nmlut = _nmlut[0]; mapAxis = nmlut->dim - nin->dim - 1; /* its not our job to do real error checking ... */ mapAxis = AIR_MIN(mapAxis, nmlut->dim - 1); } else { /* we have to join together multiple nrrds to get the mlut */ nmlut = nrrdNew(); airMopAdd(mop, nmlut, (airMopper)nrrdNuke, airMopAlways); /* assume that mlut component nrrds are all compatible sizes, nrrdJoin will fail if they aren't */ mapAxis = _nmlut[0]->dim - nin->dim; if (nrrdJoin(nmlut, (const Nrrd**)_nmlut, _nmlutLen, mapAxis, AIR_TRUE)) { airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: trouble joining mlut:\n%s", me, err); airMopError(mop); return 1; } /* set these if they were given, they'll be NaN otherwise */ nmlut->axis[mapAxis].min = min; nmlut->axis[mapAxis].max = max; } if (!( AIR_EXISTS(nmlut->axis[mapAxis].min) && AIR_EXISTS(nmlut->axis[mapAxis].max) )) { rescale = AIR_TRUE; } if (rescale) { range = nrrdRangeNew(min, max); airMopAdd(mop, range, (airMopper)nrrdRangeNix, airMopAlways); nrrdRangeSafeSet(range, nin, blind8BitRange); } if (nrrdTypeDefault == typeOut) { typeOut = nmlut->type; } if (nrrdApplyMulti1DLut(nout, nin, range, nmlut, typeOut, rescale)) { airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: trouble applying multi-LUT:\n%s", me, err); airMopError(mop); return 1; } SAVE(out, nout, NULL); 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 main(int argc, const char *argv[]) { gageKind *kind; const char *me; char *outS, *err; hestParm *hparm; hestOpt *hopt = NULL; NrrdKernelSpec *ksp; int otype, separ, ret; unsigned int maxIter; double epsilon, lastDiff, step; Nrrd *nin, *nout; airArray *mop; 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, meetHestGageKind); hestOptAdd(&hopt, "k00", "kernel", airTypeOther, 1, 1, &ksp, NULL, "convolution kernel", NULL, NULL, nrrdHestKernelSpec); hestOptAdd(&hopt, "mi", "max # iters", airTypeUInt, 1, 1, &maxIter, "100", "maximum number of iterations with which to compute the " "deconvolution"); hestOptAdd(&hopt, "e", "epsilon", airTypeDouble, 1, 1, &epsilon, "0.00000001", "convergence threshold"); hestOptAdd(&hopt, "s", "step", airTypeDouble, 1, 1, &step, "1.0", "scaling of value update"); hestOptAdd(&hopt, "t", "type", airTypeOther, 1, 1, &otype, "default", "type to save output as. By default (not using this option), " "the output type is the same as the input type", NULL, NULL, &unrrduHestMaybeTypeCB); hestOptAdd(&hopt, "sep", "bool", airTypeBool, 1, 1, &separ, "false", "use fast separable deconvolution instead of brain-dead " "brute-force iterative method"); hestOptAdd(&hopt, "o", "nout", airTypeString, 1, 1, &outS, "-", "output volume"); hestParseOrDie(hopt, argc-1, argv+1, hparm, me, deconvInfo, AIR_TRUE, AIR_TRUE, AIR_TRUE); airMopAdd(mop, hopt, AIR_CAST(airMopper, hestOptFree), airMopAlways); airMopAdd(mop, hopt, AIR_CAST(airMopper, hestParseFree), airMopAlways); nout = nrrdNew(); airMopAdd(mop, nout, AIR_CAST(airMopper, nrrdNuke), airMopAlways); if (separ) { ret = gageDeconvolveSeparable(nout, nin, kind, ksp, otype); } else { ret = gageDeconvolve(nout, &lastDiff, nin, kind, ksp, otype, maxIter, AIR_TRUE, step, epsilon, 1); } if (ret) { airMopAdd(mop, err = biffGetDone(GAGE), 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 saving output:\n%s\n", me, err); airMopError(mop); return 1; } airMopOkay(mop); return 0; }
int main(int argc, const char *argv[]) { const char *me; char *err; hestOpt *hopt = NULL; airArray *mop; char *outS; alanContext *actx; int *size, sizeLen, fi, si, wrap, nt, cfn, ha, maxi; unsigned int srnd; double deltaT, mch, xch, alphabeta[2], time0, time1, deltaX, react, rrange; Nrrd *ninit=NULL, *nten=NULL, *nparm=NULL; me = argv[0]; hestOptAdd(&hopt, "s", "sx sy", airTypeInt, 2, 3, &size, "128 128", "size of texture, and also determines its dimension", &sizeLen); hestOptAdd(&hopt, "srand", "N", airTypeUInt, 1, 1, &srnd, "42", "number to seed random number generator with. This uses " "airDrandMT(), so it should be portable."); hestOptAdd(&hopt, "i", "tensors", airTypeOther, 1, 1, &nten, "", "diffusion tensors to use for guiding the texture generation. " "If used, over-rides the \"-s\" option, both for setting " "texture dimension and size. If you want upsampling, you " "do it yourself before sending it here.", NULL, NULL, nrrdHestNrrd); hestOptAdd(&hopt, "ha", NULL, airTypeInt, 0, 0, &ha, NULL, "use the homogenous anisotropy assumption- that the spatial " "derivative of the diffusion tensor is negligible when " "computing the diffusive term "); hestOptAdd(&hopt, "wrap", NULL, airTypeInt, 0, 0, &wrap, NULL, "wrap edges of texture around a topological torus (which " "makes a texture suitable for tiling)"); hestOptAdd(&hopt, "ab", "alpha beta", airTypeDouble, 2, 2, alphabeta, "16.0 12.0", "the growth and decay parameters appearing in the reaction " "terms of the reaction-diffusion equations. The default " "values were the ones published by Turing."); hestOptAdd(&hopt, "sr", "react", airTypeDouble, 1, 1, &react, "1.0", "scaling of reaction term"); hestOptAdd(&hopt, "rr", "range range", airTypeDouble, 1, 1, &rrange, "4.0", "amount of random noise to add to inital textures"); hestOptAdd(&hopt, "dt", "time", airTypeDouble, 1, 1, &deltaT, "1.0", "time-step size in Euler integration. Can be larger, at " "risk of hitting divergent instability."); hestOptAdd(&hopt, "dx", "size", airTypeDouble, 1, 1, &deltaX, "1.3", "nominal size of simulation grid element."); hestOptAdd(&hopt, "mch", "change", airTypeDouble, 1, 1, &mch, "0.00001", "the minimum significant change (averaged over the whole " "texture) in the first morphogen: to signify convergence"); hestOptAdd(&hopt, "xch", "change", airTypeDouble, 1, 1, &xch, "6", "the maximum allowable change (averaged over the whole " "texture) in the first morphogen: to signify divergence"); hestOptAdd(&hopt, "maxi", "# iter", airTypeInt, 1, 1, &maxi, "0", "maximum number of iterations to run for, or \"0\" to have " "no limit based on iteration count"); hestOptAdd(&hopt, "fi", "frame inter", airTypeInt, 1, 1, &fi, "0", "the number of iterations between which to save out an 8-bit " "image of the texture, or \"0\" to disable such action"); hestOptAdd(&hopt, "si", "snap inter", airTypeInt, 1, 1, &si, "0", "the number of iterations between which to save out a complete " "floating-point snapshot of the morphogen state, suitable for " "later re-initialization, or \"0\" to disable such action"); hestOptAdd(&hopt, "cfn", NULL, airTypeInt, 0, 0, &cfn, NULL, "when saving out frames or snapshots, use a constant filename, " "instead of incrementing it each save"); hestOptAdd(&hopt, "nt", "# threads", airTypeInt, 1, 1, &nt, "1", (airThreadCapable ? "number of threads to use in computation" : "number of \"threads\" to use in computation, which is " "moot here because this Teem build doesn't support " "multi-threading. ")); hestOptAdd(&hopt, "o", "nout", airTypeString, 1, 1, &outS, NULL, "filename for output of final converged (two-channel) texture"); hestParseOrDie(hopt, argc-1, argv+1, NULL, me, spotsInfo, AIR_TRUE, AIR_TRUE, AIR_TRUE); mop = airMopNew(); airMopAdd(mop, hopt, (airMopper)hestOptFree, airMopAlways); airMopAdd(mop, hopt, (airMopper)hestParseFree, airMopAlways); actx = alanContextNew(); airMopAdd(mop, actx, (airMopper)alanContextNix, airMopAlways); if (nten) { if (alanDimensionSet(actx, nten->dim - 1) || alanTensorSet(actx, nten, 1)) { airMopAdd(mop, err = biffGetDone(ALAN), airFree, airMopAlways); fprintf(stderr, "%s: trouble setting parameters:\n%s\n", me, err); airMopError(mop); return 1; } } else { alanDimensionSet(actx, sizeLen); if (2 == sizeLen) { alan2DSizeSet(actx, size[0], size[1]); } else { alan3DSizeSet(actx, size[0], size[1], size[2]); } } airSrandMT(srnd); if (alanParmSet(actx, alanParmVerbose, 1) || alanParmSet(actx, alanParmTextureType, alanTextureTypeTuring) || alanParmSet(actx, alanParmK, 0.0125) || alanParmSet(actx, alanParmAlpha, alphabeta[0]) || alanParmSet(actx, alanParmBeta, alphabeta[1]) || alanParmSet(actx, alanParmDeltaX, deltaX) || alanParmSet(actx, alanParmDeltaT, deltaT) || alanParmSet(actx, alanParmReact, react) || alanParmSet(actx, alanParmMinAverageChange, mch) || alanParmSet(actx, alanParmMaxPixelChange, xch) || alanParmSet(actx, alanParmMaxIteration, maxi) || alanParmSet(actx, alanParmRandRange, rrange) || alanParmSet(actx, alanParmSaveInterval, si) || alanParmSet(actx, alanParmFrameInterval, fi) || alanParmSet(actx, alanParmConstantFilename, cfn) || alanParmSet(actx, alanParmWrapAround, wrap) || alanParmSet(actx, alanParmHomogAniso, ha) || alanParmSet(actx, alanParmNumThreads, nt)) { airMopAdd(mop, err = biffGetDone(ALAN), airFree, airMopAlways); fprintf(stderr, "%s: trouble setting parameters:\n%s\n", me, err); airMopError(mop); return 1; } if (alanUpdate(actx) || alanInit(actx, ninit, nparm)) { airMopAdd(mop, err = biffGetDone(ALAN), airFree, airMopAlways); fprintf(stderr, "%s: trouble initializing texture: %s\n", me, err); airMopError(mop); return 1; } fprintf(stderr, "%s: going to run (%d threads) ...\n", me, actx->numThreads); time0 = airTime(); if (alanRun(actx)) { airMopAdd(mop, err = biffGetDone(ALAN), airFree, airMopAlways); fprintf(stderr, "%s: trouble generating texture: %s\n", me, err); airMopError(mop); return 1; } time1 = airTime(); fprintf(stderr, "%s: stopped after %d iterations (%g seconds): %s\n", me, actx->iter, time1 - time0, airEnumDesc(alanStop, actx->stop)); if (nrrdSave(outS, actx->nlev, NULL)) { airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: trouble saving output:\n%s\n", me, err); airMopError(mop); return 1; } airMopOkay(mop); return 0; }
int tend_simMain(int argc, char **argv, char *me, hestParm *hparm) { int pret; hestOpt *hopt = NULL; char *perr, *err; tenEstimateContext *tec; airArray *mop; int E, oldstuff, seed; Nrrd *nin, *nT2, *nbmat, *nout; char *outS; float b, sigma; hestOptAdd(&hopt, "old", NULL, airTypeInt, 0, 0, &oldstuff, NULL, "don't use the new tenEstimateContext functionality"); hestOptAdd(&hopt, "sigma", "sigma", airTypeFloat, 1, 1, &sigma, "0.0", "Rician noise parameter"); hestOptAdd(&hopt, "seed", "seed", airTypeInt, 1, 1, &seed, "42", "seed value for RNG which creates noise"); hestOptAdd(&hopt, "B", "B matrix", airTypeOther, 1, 1, &nbmat, NULL, "B matrix, one row per diffusion-weighted image", NULL, NULL, nrrdHestNrrd); hestOptAdd(&hopt, "r", "reference field", airTypeOther, 1, 1, &nT2, "-", "reference anatomical scan, with no diffusion weighting", NULL, NULL, nrrdHestNrrd); hestOptAdd(&hopt, "i", "tensor field", airTypeOther, 1, 1, &nin, "-", "input diffusion tensor field", NULL, NULL, nrrdHestNrrd); hestOptAdd(&hopt, "b", "b", airTypeFloat, 1, 1, &b, "1", "b value for simulated scan"); hestOptAdd(&hopt, "o", "nout", airTypeString, 1, 1, &outS, "-", "output image (floating point)"); mop = airMopNew(); airMopAdd(mop, hopt, (airMopper)hestOptFree, airMopAlways); USAGE(_tend_simInfoL); PARSE(); airMopAdd(mop, hopt, (airMopper)hestParseFree, airMopAlways); nout = nrrdNew(); airMopAdd(mop, nout, (airMopper)nrrdNuke, airMopAlways); if (!oldstuff) { airSrandMT(seed); tec = tenEstimateContextNew(); airMopAdd(mop, tec, (airMopper)tenEstimateContextNix, airMopAlways); E = 0; if (!E) E |= tenEstimateMethodSet(tec, tenEstimateMethodLLS); if (!E) E |= tenEstimateValueMinSet(tec, 0.0001); if (!E) E |= tenEstimateBMatricesSet(tec, nbmat, b, AIR_TRUE); if (!E) E |= tenEstimateThresholdSet(tec, 0, 0); if (!E) E |= tenEstimateUpdate(tec); if (!E) E |= tenEstimate1TensorSimulateVolume(tec, nout, sigma, b, nT2, nin, nrrdTypeFloat); if (E) { airMopAdd(mop, err=biffGetDone(TEN), airFree, airMopAlways); fprintf(stderr, "%s: trouble making DWI volume (new):\n%s\n", me, err); airMopError(mop); return 1; } } else { if (tenSimulate(nout, nT2, nin, nbmat, b)) { airMopAdd(mop, err=biffGetDone(TEN), airFree, airMopAlways); fprintf(stderr, "%s: trouble making DWI volume:\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, *outS, *err; hestOpt *hopt; hestParm *hparm; airArray *mop; Nrrd *nin, *nmat, *ninv, *nidn; int (*func)(Nrrd *, Nrrd *); double m3[9], m4[16]; me = argv[0]; mop = airMopNew(); hparm = hestParmNew(); hopt = NULL; airMopAdd(mop, hparm, (airMopper)hestParmFree, airMopAlways); hestOptAdd(&hopt, NULL, "matrix", airTypeOther, 1, 1, &nin, NULL, "transform(s) to apply to image", NULL, NULL, nrrdHestNrrd); hestOptAdd(&hopt, "o", "filename", airTypeString, 1, 1, &outS, "-", "file to write output nrrd to"); hestParseOrDie(hopt, argc-1, argv+1, hparm, me, invInfo, AIR_TRUE, AIR_TRUE, AIR_TRUE); airMopAdd(mop, hopt, (airMopper)hestOptFree, airMopAlways); airMopAdd(mop, hopt, (airMopper)hestParseFree, airMopAlways); ninv = nrrdNew(); airMopAdd(mop, ninv, (airMopper)nrrdNuke, airMopAlways); nidn = nrrdNew(); airMopAdd(mop, nidn, (airMopper)nrrdNuke, airMopAlways); nmat = nrrdNew(); airMopAdd(mop, nmat, (airMopper)nrrdNuke, airMopAlways); nrrdConvert(nmat, nin, nrrdTypeDouble); if (3 == nmat->axis[0].size && 3 == nmat->axis[1].size) { ell_3m_inv_d(m3, (double *)nmat->data); fprintf(stderr, "%s: input:\n", me); ell_3m_print_d(stderr, (double *)nmat->data); fprintf(stderr, "%s: inverse:\n", me); ell_3m_print_d(stderr, m3); } if (4 == nmat->axis[0].size && 4 == nmat->axis[1].size) { ell_4m_inv_d(m4, (double *)nmat->data); fprintf(stderr, "%s: input:\n", me); ell_4m_print_d(stderr, (double *)nmat->data); fprintf(stderr, "%s: inverse:\n", me); ell_4m_print_d(stderr, m4); } func = (nmat->axis[0].size == nmat->axis[1].size ? ell_Nm_inv : ell_Nm_pseudo_inv); if (func(ninv, nmat)) { airMopAdd(mop, err = biffGetDone(ELL), airFree, airMopAlways); fprintf(stderr, "%s: problem inverting:\n%s\n", me, err); airMopError(mop); return 1; } if (nrrdSave(outS, ninv, NULL)) { airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: problem saving output:\n%s\n", me, err); airMopError(mop); return 1; } airMopOkay(mop); exit(0); }
int main(int argc, char **argv) { int i, ret; char *me, *argv0 = NULL, *err; hestParm *hparm; airArray *mop; me = argv[0]; /* 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 Teem.\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, (airMopper)hestParmFree, airMopAlways); hparm->elideSingleEnumType = AIR_TRUE; hparm->elideSingleOtherType = AIR_TRUE; hparm->elideSingleOtherDefault = AIR_FALSE; hparm->elideSingleNonExistFloatDefault = AIR_TRUE; hparm->elideMultipleNonExistFloatDefault = AIR_TRUE; hparm->elideSingleEmptyStringDefault = AIR_TRUE; hparm->elideMultipleEmptyStringDefault = AIR_TRUE; hparm->cleverPluralizeOtherY = AIR_TRUE; hparm->columns = 78; /* if there are no arguments, then we give general usage information */ if (1 >= argc) { baneGkmsUsage(GKMS, hparm); airMopError(mop); exit(1); } /* else, we should see if they're asking for a command we know about */ /* baneGkmsCmdList[] is NULL-terminated */ for (i=0; baneGkmsCmdList[i]; i++) { if (!strcmp(argv[1], baneGkmsCmdList[i]->name)) break; } if (baneGkmsCmdList[i]) { /* yes, we have that command */ /* initialize variables used by the various commands */ argv0 = AIR_CAST(char*, malloc(strlen(GKMS) + strlen(argv[1]) + 2)); airMopMem(mop, &argv0, airMopAlways); sprintf(argv0, "%s %s", GKMS, argv[1]); /* run the individual unu program, saving its exit status */ ret = baneGkmsCmdList[i]->main(argc-2, argv+2, argv0, hparm); if (1 == ret) { airMopAdd(mop, err=biffGetDone(BANE), airFree, airMopAlways); fprintf(stderr, "%s: error:\n%s", argv0, err); } else if (2 == ret) { /* gkms command has already handled printing error messages */ ret = 1; } } else {
int unrrdu_acropMain(int argc, const char **argv, const char *me, hestParm *hparm) { hestOpt *opt = NULL; char *out, *err; Nrrd *nin, *nout; int pret; airArray *mop; size_t min[NRRD_DIM_MAX], max[NRRD_DIM_MAX]; unsigned int *axes, axesLen; double frac; int measr, offset; Nrrd *nbounds; char *boundsSave; hestOptAdd(&opt, "a,axes", "ax0", airTypeUInt, 0, -1, &axes, "", "the axes (if any) that should NOT be cropped", &axesLen); hestOptAdd(&opt, "m,measure", "measr", airTypeEnum, 1, 1, &measr, NULL, "How to measure slices (along axes to crop) as scalars, " "to form 1-D array analyzed to determine cropping extent. " "All the measures from \"unu project\" can be used, but " "those that make more sense here include:\n " "\b\bo \"max\", \"mean\", \"median\", " "\"variance\": (self-explanatory)\n " "\b\bo \"stdv\": standard deviation\n " "\b\bo \"cov\": coefficient of variation\n " "\b\bo \"product\", \"sum\": product or sum of all values\n " "\b\bo \"L1\", \"L2\", \"NL2\", \"RMS\", \"Linf\": " "different norms.", NULL, nrrdMeasure); hestOptAdd(&opt, "f,frac", "frac", airTypeDouble, 1, 1, &frac, "0.1", "threshold of cumulative sum of 1-D array at which to crop. " "Needs to be in interval [0.0,0.5)."); hestOptAdd(&opt, "off,offset", "offset", airTypeInt, 1, 1, &offset, "1", "how much to offset the numerically determined cropping; " "positive offsets means expanding the interval of kept " "indices (less cropping)"); hestOptAdd(&opt, "b,bounds", "filename", airTypeString, 1, 1, &boundsSave, "", "if a filename is given here, the automatically determined " "min and max bounds for cropping are saved to this file " "as a 2-D array; first scanline is for -min, second is for -max. " "Unfortunately nothing using the \"m\" and \"M\" semantics " "(above) can currently be saved in the bounds file."); OPT_ADD_NIN(nin, "input nrrd"); OPT_ADD_NOUT(out, "output nrrd"); mop = airMopNew(); airMopAdd(mop, opt, (airMopper)hestOptFree, airMopAlways); USAGE(_unrrdu_acropInfoL); PARSE(); airMopAdd(mop, opt, (airMopper)hestParseFree, airMopAlways); nout = nrrdNew(); airMopAdd(mop, nout, (airMopper)nrrdNuke, airMopAlways); if (nrrdCropAuto(nout, nin, min, max, axes, axesLen, measr, frac, offset)) { airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: error cropping nrrd:\n%s", me, err); airMopError(mop); return 1; } if (airStrlen(boundsSave)) { unsigned int axi; airULLong *bounds; nbounds = nrrdNew(); airMopAdd(mop, nbounds, (airMopper)nrrdNuke, airMopAlways); if (nrrdMaybeAlloc_va(nbounds, nrrdTypeULLong, 2, AIR_CAST(airULLong, nin->dim), AIR_CAST(airULLong, 2))) { airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: error allocating cropping bounds array:\n%s", me, err); airMopError(mop); return 1; } bounds = AIR_CAST(airULLong*, nbounds->data); for (axi=0; axi<nin->dim; axi++) { bounds[axi + 0*(nin->dim)] = AIR_CAST(airULLong, min[axi]); bounds[axi + 1*(nin->dim)] = AIR_CAST(airULLong, max[axi]); } if (nrrdSave(boundsSave, nbounds, NULL)) { airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: error saving cropping bounds array:\n%s", me, err); airMopError(mop); return 1; } } SAVE(out, nout, NULL); airMopOkay(mop); return 0; }
int tend_estimMain(int argc, char **argv, char *me, hestParm *hparm) { int pret; hestOpt *hopt = NULL; char *perr, *err; airArray *mop; Nrrd **nin, *nin4d, *nbmat, *nterr, *nB0, *nout; char *outS, *terrS, *bmatS, *eb0S; float soft, scale, sigma; int dwiax, EE, knownB0, oldstuff, estmeth, verbose, fixneg; unsigned int ninLen, axmap[4], wlsi, *skip, skipNum, skipIdx; double valueMin, thresh; Nrrd *ngradKVP=NULL, *nbmatKVP=NULL; double bKVP, bval; tenEstimateContext *tec; hestOptAdd(&hopt, "old", NULL, airTypeInt, 0, 0, &oldstuff, NULL, "instead of the new tenEstimateContext code, use " "the old tenEstimateLinear code"); hestOptAdd(&hopt, "sigma", "sigma", airTypeFloat, 1, 1, &sigma, "nan", "Rician noise parameter"); hestOptAdd(&hopt, "v", "verbose", airTypeInt, 1, 1, &verbose, "0", "verbosity level"); hestOptAdd(&hopt, "est", "estimate method", airTypeEnum, 1, 1, &estmeth, "lls", "estimation method to use. \"lls\": linear-least squares", NULL, tenEstimate1Method); hestOptAdd(&hopt, "wlsi", "WLS iters", airTypeUInt, 1, 1, &wlsi, "1", "when using weighted-least-squares (\"-est wls\"), how " "many iterations to do after the initial weighted fit."); hestOptAdd(&hopt, "fixneg", NULL, airTypeInt, 0, 0, &fixneg, NULL, "after estimating the tensor, ensure that there are no negative " "eigenvalues by adding (to all eigenvalues) the amount by which " "the smallest is negative (corresponding to increasing the " "non-DWI image value)."); hestOptAdd(&hopt, "ee", "filename", airTypeString, 1, 1, &terrS, "", "Giving a filename here allows you to save out the tensor " "estimation error: a value which measures how much error there " "is between the tensor model and the given diffusion weighted " "measurements for each sample. By default, no such error " "calculation is saved."); hestOptAdd(&hopt, "eb", "filename", airTypeString, 1, 1, &eb0S, "", "In those cases where there is no B=0 reference image given " "(\"-knownB0 false\"), " "giving a filename here allows you to save out the B=0 image " "which is estimated from the data. By default, this image value " "is estimated but not saved."); hestOptAdd(&hopt, "t", "thresh", airTypeDouble, 1, 1, &thresh, "nan", "value at which to threshold the mean DWI value per pixel " "in order to generate the \"confidence\" mask. By default, " "the threshold value is calculated automatically, based on " "histogram analysis."); hestOptAdd(&hopt, "soft", "soft", airTypeFloat, 1, 1, &soft, "0", "how fuzzy the confidence boundary should be. By default, " "confidence boundary is perfectly sharp"); hestOptAdd(&hopt, "scale", "scale", airTypeFloat, 1, 1, &scale, "1", "After estimating the tensor, scale all of its elements " "(but not the confidence value) by this amount. Can help with " "downstream numerical precision if values are very large " "or small."); hestOptAdd(&hopt, "mv", "min val", airTypeDouble, 1, 1, &valueMin, "1.0", "minimum plausible value (especially important for linear " "least squares estimation)"); hestOptAdd(&hopt, "B", "B-list", airTypeString, 1, 1, &bmatS, NULL, "6-by-N list of B-matrices characterizing " "the diffusion weighting for each " "image. \"tend bmat\" is one source for such a matrix; see " "its usage info for specifics on how the coefficients of " "the B-matrix are ordered. " "An unadorned plain text file is a great way to " "specify the B-matrix.\n **OR**\n " "Can say just \"-B kvp\" to try to learn B matrices from " "key/value pair information in input images."); hestOptAdd(&hopt, "b", "b", airTypeDouble, 1, 1, &bval, "nan", "\"b\" diffusion-weighting factor (units of sec/mm^2)"); hestOptAdd(&hopt, "knownB0", "bool", airTypeBool, 1, 1, &knownB0, NULL, "Indicates if the B=0 non-diffusion-weighted reference image " "is known, or if it has to be estimated along with the tensor " "elements.\n " "\b\bo if \"true\": in the given list of diffusion gradients or " "B-matrices, there are one or more with zero norm, which are " "simply averaged to find the B=0 reference image value\n " "\b\bo if \"false\": there may or may not be diffusion-weighted " "images among the input; the B=0 image value is going to be " "estimated along with the diffusion model"); hestOptAdd(&hopt, "i", "dwi0 dwi1", airTypeOther, 1, -1, &nin, "-", "all the diffusion-weighted images (DWIs), as separate 3D nrrds, " "**OR**: One 4D nrrd of all DWIs stacked along axis 0", &ninLen, NULL, nrrdHestNrrd); hestOptAdd(&hopt, "o", "nout", airTypeString, 1, 1, &outS, "-", "output tensor volume"); mop = airMopNew(); airMopAdd(mop, hopt, (airMopper)hestOptFree, airMopAlways); USAGE(_tend_estimInfoL); JUSTPARSE(); airMopAdd(mop, hopt, (airMopper)hestParseFree, airMopAlways); nout = nrrdNew(); airMopAdd(mop, nout, (airMopper)nrrdNuke, airMopAlways); nbmat = nrrdNew(); airMopAdd(mop, nbmat, (airMopper)nrrdNuke, airMopAlways); /* figure out B-matrix */ if (strcmp("kvp", airToLower(bmatS))) { /* its NOT coming from key/value pairs */ if (!AIR_EXISTS(bval)) { fprintf(stderr, "%s: need to specify scalar b-value\n", me); airMopError(mop); return 1; } if (nrrdLoad(nbmat, bmatS, NULL)) { airMopAdd(mop, err=biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: trouble loading B-matrix:\n%s\n", me, err); airMopError(mop); return 1; } nin4d = nin[0]; skip = NULL; skipNum = 0; } else { /* it IS coming from key/value pairs */ if (1 != ninLen) { fprintf(stderr, "%s: require a single 4-D DWI volume for " "key/value pair based calculation of B-matrix\n", me); airMopError(mop); return 1; } if (oldstuff) { if (knownB0) { fprintf(stderr, "%s: sorry, key/value-based DWI info not compatible " "with older implementation of knownB0\n", me); airMopError(mop); return 1; } } if (tenDWMRIKeyValueParse(&ngradKVP, &nbmatKVP, &bKVP, &skip, &skipNum, nin[0])) { airMopAdd(mop, err=biffGetDone(TEN), airFree, airMopAlways); fprintf(stderr, "%s: trouble parsing DWI info:\n%s\n", me, err); airMopError(mop); return 1; } if (AIR_EXISTS(bval)) { fprintf(stderr, "%s: WARNING: key/value pair derived b-value %g " "over-riding %g from command-line", me, bKVP, bval); } bval = bKVP; if (ngradKVP) { airMopAdd(mop, ngradKVP, (airMopper)nrrdNuke, airMopAlways); if (tenBMatrixCalc(nbmat, ngradKVP)) { airMopAdd(mop, err=biffGetDone(TEN), airFree, airMopAlways); fprintf(stderr, "%s: trouble finding B-matrix:\n%s\n", me, err); airMopError(mop); return 1; } } else { airMopAdd(mop, nbmatKVP, (airMopper)nrrdNuke, airMopAlways); if (nrrdConvert(nbmat, nbmatKVP, nrrdTypeDouble)) { airMopAdd(mop, err=biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: trouble converting B-matrix:\n%s\n", me, err); airMopError(mop); return 1; } } /* this will work because of the impositions of tenDWMRIKeyValueParse */ dwiax = ((nrrdKindList == nin[0]->axis[0].kind || nrrdKindVector == nin[0]->axis[0].kind) ? 0 : ((nrrdKindList == nin[0]->axis[1].kind || nrrdKindVector == nin[0]->axis[1].kind) ? 1 : ((nrrdKindList == nin[0]->axis[2].kind || nrrdKindVector == nin[0]->axis[2].kind) ? 2 : 3))); if (0 == dwiax) { nin4d = nin[0]; } else { axmap[0] = dwiax; axmap[1] = 1 > dwiax ? 1 : 0; axmap[2] = 2 > dwiax ? 2 : 1; axmap[3] = 3 > dwiax ? 3 : 2; nin4d = nrrdNew(); airMopAdd(mop, nin4d, (airMopper)nrrdNuke, airMopAlways); if (nrrdAxesPermute(nin4d, nin[0], axmap)) { airMopAdd(mop, err=biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: trouble creating DWI volume:\n%s\n", me, err); airMopError(mop); return 1; } } } nterr = NULL; nB0 = NULL; if (!oldstuff) { if (1 != ninLen) { fprintf(stderr, "%s: sorry, currently need single 4D volume " "for new implementation\n", me); airMopError(mop); return 1; } if (!AIR_EXISTS(thresh)) { if (tend_estimThresholdFind(&thresh, nbmat, nin4d)) { airMopAdd(mop, err=biffGetDone(TEN), airFree, airMopAlways); fprintf(stderr, "%s: trouble finding threshold:\n%s\n", me, err); airMopError(mop); return 1; } /* HACK to lower threshold a titch */ thresh *= 0.93; fprintf(stderr, "%s: using mean DWI threshold %g\n", me, thresh); } tec = tenEstimateContextNew(); tec->progress = AIR_TRUE; airMopAdd(mop, tec, (airMopper)tenEstimateContextNix, airMopAlways); EE = 0; if (!EE) tenEstimateVerboseSet(tec, verbose); if (!EE) tenEstimateNegEvalShiftSet(tec, fixneg); if (!EE) EE |= tenEstimateMethodSet(tec, estmeth); if (!EE) EE |= tenEstimateBMatricesSet(tec, nbmat, bval, !knownB0); if (!EE) EE |= tenEstimateValueMinSet(tec, valueMin); for (skipIdx=0; skipIdx<skipNum; skipIdx++) { /* fprintf(stderr, "%s: skipping %u\n", me, skip[skipIdx]); */ if (!EE) EE |= tenEstimateSkipSet(tec, skip[skipIdx], AIR_TRUE); } switch(estmeth) { case tenEstimate1MethodLLS: if (airStrlen(terrS)) { tec->recordErrorLogDwi = AIR_TRUE; /* tec->recordErrorDwi = AIR_TRUE; */ } break; case tenEstimate1MethodNLS: if (airStrlen(terrS)) { tec->recordErrorDwi = AIR_TRUE; } break; case tenEstimate1MethodWLS: if (!EE) tec->WLSIterNum = wlsi; if (airStrlen(terrS)) { tec->recordErrorDwi = AIR_TRUE; } break; case tenEstimate1MethodMLE: if (!(AIR_EXISTS(sigma) && sigma > 0.0)) { fprintf(stderr, "%s: can't do %s w/out sigma > 0 (not %g)\n", me, airEnumStr(tenEstimate1Method, tenEstimate1MethodMLE), sigma); airMopError(mop); return 1; } if (!EE) EE |= tenEstimateSigmaSet(tec, sigma); if (airStrlen(terrS)) { tec->recordLikelihoodDwi = AIR_TRUE; } break; } if (!EE) EE |= tenEstimateThresholdSet(tec, thresh, soft); if (!EE) EE |= tenEstimateUpdate(tec); if (EE) { airMopAdd(mop, err=biffGetDone(TEN), airFree, airMopAlways); fprintf(stderr, "%s: trouble setting up estimation:\n%s\n", me, err); airMopError(mop); return 1; } if (tenEstimate1TensorVolume4D(tec, nout, &nB0, airStrlen(terrS) ? &nterr : NULL, nin4d, nrrdTypeFloat)) { airMopAdd(mop, err=biffGetDone(TEN), airFree, airMopAlways); fprintf(stderr, "%s: trouble doing estimation:\n%s\n", me, err); airMopError(mop); return 1; } if (airStrlen(terrS)) { airMopAdd(mop, nterr, (airMopper)nrrdNuke, airMopAlways); } } else { EE = 0; if (1 == ninLen) { EE = tenEstimateLinear4D(nout, airStrlen(terrS) ? &nterr : NULL, &nB0, nin4d, nbmat, knownB0, thresh, soft, bval); } else { EE = tenEstimateLinear3D(nout, airStrlen(terrS) ? &nterr : NULL, &nB0, (const Nrrd**)nin, ninLen, nbmat, knownB0, thresh, soft, bval); } if (EE) { airMopAdd(mop, err=biffGetDone(TEN), airFree, airMopAlways); fprintf(stderr, "%s: trouble making tensor volume:\n%s\n", me, err); airMopError(mop); return 1; } } if (nterr) { /* it was allocated by tenEstimate*, we have to clean it up */ airMopAdd(mop, nterr, (airMopper)nrrdNuke, airMopAlways); } if (nB0) { /* it was allocated by tenEstimate*, we have to clean it up */ airMopAdd(mop, nB0, (airMopper)nrrdNuke, airMopAlways); } if (1 != scale) { if (tenSizeScale(nout, nout, scale)) { airMopAdd(mop, err=biffGetDone(TEN), airFree, airMopAlways); fprintf(stderr, "%s: trouble doing scaling:\n%s\n", me, err); airMopError(mop); return 1; } } if (nterr) { if (nrrdSave(terrS, nterr, NULL)) { airMopAdd(mop, err=biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: trouble writing error image:\n%s\n", me, err); airMopError(mop); return 1; } } if (!knownB0 && airStrlen(eb0S)) { if (nrrdSave(eb0S, nB0, NULL)) { airMopAdd(mop, err=biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: trouble writing estimated B=0 image:\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 unrrdu_shuffleMain(int argc, char **argv, char *me, hestParm *hparm) { hestOpt *opt = NULL; char *out, *err; Nrrd *nin, *nout; unsigned int di, axis, permLen, *perm, *iperm, *whichperm; size_t *realperm; int inverse, pret; airArray *mop; /* so that long permutations can be read from file */ hparm->respFileEnable = AIR_TRUE; hestOptAdd(&opt, "p,permute", "slc0 slc1", airTypeUInt, 1, -1, &perm, NULL, "new slice ordering", &permLen); hestOptAdd(&opt, "inv,inverse", NULL, airTypeInt, 0, 0, &inverse, NULL, "use inverse of given permutation"); OPT_ADD_AXIS(axis, "axis to shuffle along"); OPT_ADD_NIN(nin, "input nrrd"); OPT_ADD_NOUT(out, "output nrrd"); mop = airMopNew(); airMopAdd(mop, opt, (airMopper)hestOptFree, airMopAlways); USAGE(_unrrdu_shuffleInfoL); PARSE(); airMopAdd(mop, opt, (airMopper)hestParseFree, airMopAlways); nout = nrrdNew(); airMopAdd(mop, nout, (airMopper)nrrdNuke, airMopAlways); /* we have to do error checking on axis in order to do error checking on length of permutation */ if (!( axis < nin->dim )) { fprintf(stderr, "%s: axis %d not in valid range [0,%d]\n", me, axis, nin->dim-1); airMopError(mop); return 1; } if (!( permLen == nin->axis[axis].size )) { fprintf(stderr, "%s: permutation length (%u) != axis %d's size (" _AIR_SIZE_T_CNV ")\n", me, permLen, axis, nin->axis[axis].size); airMopError(mop); return 1; } if (inverse) { iperm = (unsigned int*)calloc(permLen, sizeof(unsigned int)); airMopAdd(mop, iperm, airFree, airMopAlways); if (nrrdInvertPerm(iperm, perm, permLen)) { fprintf(stderr, "%s: couldn't compute inverse of given permutation\n", me); airMopError(mop); return 1; } whichperm = iperm; } else { whichperm = perm; } realperm = (size_t*)calloc(permLen, sizeof(size_t)); airMopAdd(mop, realperm, airFree, airMopAlways); for (di=0; di<permLen; di++) { realperm[di] = whichperm[di]; } if (nrrdShuffle(nout, nin, axis, realperm)) { airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: error shuffling nrrd:\n%s", me, err); airMopError(mop); return 1; } SAVE(out, nout, NULL); airMopOkay(mop); return 0; }
int tend_evecMain(int argc, char **argv, char *me, hestParm *hparm) { int pret; hestOpt *hopt = NULL; char *perr, *err; airArray *mop; int ret, *comp, compLen, cc; Nrrd *nin, *nout; char *outS; float thresh, *edata, *tdata, eval[3], evec[9], scl; size_t N, I, sx, sy, sz; hestOptAdd(&hopt, "c", "c0 ", airTypeInt, 1, 3, &comp, NULL, "which eigenvalues should be saved out. \"0\" for the " "largest, \"1\" for the middle, \"2\" for the smallest, " "\"0 1\", \"1 2\", \"0 1 2\" or similar for more than one", &compLen); hestOptAdd(&hopt, "t", "thresh", airTypeFloat, 1, 1, &thresh, "0.5", "confidence threshold"); hestOptAdd(&hopt, "i", "nin", airTypeOther, 1, 1, &nin, "-", "input diffusion tensor volume", NULL, NULL, nrrdHestNrrd); hestOptAdd(&hopt, "o", "nout", airTypeString, 1, 1, &outS, "-", "output image (floating point)"); mop = airMopNew(); airMopAdd(mop, hopt, (airMopper)hestOptFree, airMopAlways); USAGE(_tend_evecInfoL); PARSE(); airMopAdd(mop, hopt, (airMopper)hestParseFree, airMopAlways); for (cc=0; cc<compLen; cc++) { if (!AIR_IN_CL(0, comp[cc], 2)) { fprintf(stderr, "%s: requested component %d (%d of 3) not in [0..2]\n", me, comp[cc], cc+1); airMopError(mop); return 1; } } if (tenTensorCheck(nin, nrrdTypeFloat, AIR_TRUE, AIR_TRUE)) { airMopAdd(mop, err=biffGetDone(TEN), airFree, airMopAlways); fprintf(stderr, "%s: didn't get a valid DT volume:\n%s\n", me, err); airMopError(mop); return 1; } sx = nin->axis[1].size; sy = nin->axis[2].size; sz = nin->axis[3].size; nout = nrrdNew(); airMopAdd(mop, nout, (airMopper)nrrdNuke, airMopAlways); ret = nrrdMaybeAlloc_va(nout, nrrdTypeFloat, 4, AIR_CAST(size_t, 3*compLen), sx, sy, sz); if (ret) { airMopAdd(mop, err=biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: trouble allocating output:\n%s\n", me, err); airMopError(mop); return 1; } N = sx*sy*sz; edata = (float *)nout->data; tdata = (float *)nin->data; if (1 == compLen) { for (I=0; I<N; I++) { tenEigensolve_f(eval, evec, tdata); scl = AIR_CAST(float, tdata[0] >= thresh); ELL_3V_SCALE(edata, scl, evec+3*comp[0]); edata += 3; tdata += 7; } } else { for (I=0; I<N; I++) {
int unrrdu_rmapMain(int argc, const char **argv, const char *me, hestParm *hparm) { hestOpt *opt = NULL; char *out, *err; Nrrd *nin, *nmap, *nout; airArray *mop; NrrdRange *range=NULL; int typeOut, rescale, pret, blind8BitRange; double min, max; hestOptAdd(&opt, "m,map", "map", airTypeOther, 1, 1, &nmap, NULL, "regular map to map input nrrd through", NULL, NULL, nrrdHestNrrd); hestOptAdd(&opt, "r,rescale", NULL, airTypeInt, 0, 0, &rescale, NULL, "rescale the input values from the input range to the " "map domain. The map domain is either explicitly " "defined by the axis min,max along axis 0 or 1, or, it " "is implicitly defined as zero to the length of " "that axis minus one."); hestOptAdd(&opt, "min,minimum", "value", airTypeDouble, 1, 1, &min, "nan", "Low end of input range. Defaults to lowest value " "found in input nrrd. Explicitly setting this is useful " "only with rescaling (\"-r\") or if the map domain is only " "implicitly defined"); hestOptAdd(&opt, "max,maximum", "value", airTypeDouble, 1, 1, &max, "nan", "High end of input range. Defaults to highest value " "found in input nrrd. Explicitly setting this is useful " "only with rescaling (\"-r\") or if the map domain is only " "implicitly defined"); hestOptAdd(&opt, "blind8", "bool", airTypeBool, 1, 1, &blind8BitRange, nrrdStateBlind8BitRange ? "true" : "false", "Whether to know the range of 8-bit data blindly " "(uchar is always [0,255], signed char is [-128,127]). " "Explicitly setting this is useful " "only with rescaling (\"-r\") or if the map domain is only " "implicitly defined"); hestOptAdd(&opt, "t,type", "type", airTypeOther, 1, 1, &typeOut, "default", "specify the type (\"int\", \"float\", etc.) of the " "output nrrd. " "By default (not using this option), the output type " "is the map's type.", NULL, NULL, &unrrduHestMaybeTypeCB); OPT_ADD_NIN(nin, "input nrrd"); OPT_ADD_NOUT(out, "output nrrd"); mop = airMopNew(); airMopAdd(mop, opt, (airMopper)hestOptFree, airMopAlways); USAGE(_unrrdu_rmapInfoL); PARSE(); airMopAdd(mop, opt, (airMopper)hestParseFree, airMopAlways); nout = nrrdNew(); airMopAdd(mop, nout, (airMopper)nrrdNuke, airMopAlways); /* here is a big difference between unu and nrrd: we enforce rescaling any time that the map domain is implicit. This is how the pre-1.6 functionality is recreated. Also, whenever there is rescaling we pass a NrrdRange to reflect the (optional) user range specification, instead of letting nrrdApply1DRegMap find the input range itself (by passing a NULL NrrdRange). */ if (!( AIR_EXISTS(nmap->axis[nmap->dim - 1].min) && AIR_EXISTS(nmap->axis[nmap->dim - 1].max) )) { rescale = AIR_TRUE; } if (rescale) { range = nrrdRangeNew(min, max); airMopAdd(mop, range, (airMopper)nrrdRangeNix, airMopAlways); nrrdRangeSafeSet(range, nin, blind8BitRange); } if (nrrdTypeDefault == typeOut) { typeOut = nmap->type; } if (nrrdApply1DRegMap(nout, nin, range, nmap, typeOut, rescale)) { airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: trouble applying map:\n%s", me, err); airMopError(mop); return 1; } SAVE(out, nout, NULL); airMopOkay(mop); return 0; }
int main(int argc, const char *argv[]) { const char *me; hestOpt *hopt; hestParm *hparm; airArray *mop; char *err, *outS; double sigmaMax, convEps, cutoff; int measr[2], tentRecon; unsigned int sampleNumMax, dim, measrSampleNum, maxIter, num, ii; gageOptimSigParm *osparm; double *scalePos, *out, info[512]; Nrrd *nout; double *plotPos; unsigned int plotPosNum; me = argv[0]; mop = airMopNew(); hparm = hestParmNew(); hopt = NULL; airMopAdd(mop, hparm, (airMopper)hestParmFree, airMopAlways); hestOptAdd(&hopt, "num", "# samp", airTypeUInt, 1, 1, &sampleNumMax, NULL, "maximum number of samples to optimize"); hestOptAdd(&hopt, "dim", "dimension", airTypeUInt, 1, 1, &dim, "3", "dimension of image to work with"); hestOptAdd(&hopt, "max", "sigma", airTypeDouble, 1, 1, &sigmaMax, NULL, "sigma to use for top sample (using 0 for bottom sample)"); hestOptAdd(&hopt, "cut", "cut", airTypeDouble, 1, 1, &cutoff, "4", "at how many sigmas to cut-off discrete gaussian"); hestOptAdd(&hopt, "mi", "max", airTypeUInt, 1, 1, &maxIter, "1000", "maximum # iterations"); hestOptAdd(&hopt, "N", "# samp", airTypeUInt, 1, 1, &measrSampleNum, "300", "number of samples in the measurement of error across scales"); hestOptAdd(&hopt, "eps", "eps", airTypeDouble, 1, 1, &convEps, "0.0001", "convergence threshold for optimization"); hestOptAdd(&hopt, "m", "m1 m2", airTypeEnum, 2, 2, measr, "l2 l2", "how to measure error across image, and across scales", NULL, nrrdMeasure); hestOptAdd(&hopt, "p", "s0 s1", airTypeDouble, 2, -1, &plotPos, "nan nan", "hack: dont do optimization; just plot the recon error given " "these samples along scale", &plotPosNum); hestOptAdd(&hopt, "tent", NULL, airTypeInt, 0, 0, &tentRecon, NULL, "same hack: plot error with tent recon, not hermite"); hestOptAdd(&hopt, "o", "nout", airTypeString, 1, 1, &outS, NULL, "output array"); hestParseOrDie(hopt, argc-1, argv+1, hparm, me, optsigInfo, AIR_TRUE, AIR_TRUE, AIR_TRUE); airMopAdd(mop, hopt, (airMopper)hestOptFree, airMopAlways); airMopAdd(mop, hopt, (airMopper)hestParseFree, airMopAlways); nout = nrrdNew(); airMopAdd(mop, nout, AIR_CAST(airMopper, nrrdNuke), airMopAlways); osparm = gageOptimSigParmNew(sampleNumMax); airMopAdd(mop, osparm, AIR_CAST(airMopper, gageOptimSigParmNix), airMopAlways); scalePos = AIR_CAST(double *, calloc(sampleNumMax, sizeof(double))); airMopAdd(mop, scalePos, airFree, airMopAlways); osparm->plotting = (AIR_EXISTS(plotPos[0]) && AIR_EXISTS(plotPos[1])); if (gageOptimSigTruthSet(osparm, dim, sigmaMax, cutoff, measrSampleNum)) { airMopAdd(mop, err = biffGetDone(GAGE), airFree, airMopAlways); fprintf(stderr, "%s: trouble:\n%s", me, err); airMopError(mop); return 1; } if (osparm->plotting) { if (gageOptimSigPlot(osparm, nout, plotPos, plotPosNum, measr[0], tentRecon)) { airMopAdd(mop, err = biffGetDone(GAGE), airFree, airMopAlways); fprintf(stderr, "%s: trouble:\n%s", me, err); airMopError(mop); return 1; } } else { /* do sample position optimization */ if (nrrdMaybeAlloc_va(nout, nrrdTypeDouble, 2, AIR_CAST(size_t, sampleNumMax+1), AIR_CAST(size_t, sampleNumMax+1))) { airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: trouble allocating output:\n%s", me, err); airMopError(mop); return 1; } out = AIR_CAST(double *, nout->data); /* hacky way of saving some of the computation information */ info[0] = cutoff; info[1] = measrSampleNum; info[2] = measr[0]; info[3] = measr[1]; info[4] = convEps; info[5] = maxIter; for (ii=0; ii<sampleNumMax+1; ii++) { out[ii] = info[ii]; } for (num=2; num<=sampleNumMax; num++) { printf("\n%s: ======= optimizing %u/%u samples (sigmaMax %g) \n\n", me, num, sampleNumMax, sigmaMax); if (gageOptimSigCalculate(osparm, scalePos, num, measr[0], measr[1], convEps, maxIter)) { airMopAdd(mop, err = biffGetDone(GAGE), airFree, airMopAlways); fprintf(stderr, "%s: trouble:\n%s", me, err); airMopError(mop); return 1; } out[sampleNumMax + (sampleNumMax+1)*num] = osparm->finalErr; for (ii=0; ii<num; ii++) { out[ii + (sampleNumMax+1)*num] = scalePos[ii]; } } } if (nrrdSave(outS, nout, NULL)) { airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: trouble saving output:\n%s\n", me, err); airMopError(mop); return 1; } airMopOkay(mop); exit(0); }
int main(int argc, const char *argv[]) { const char *me; char *err, *outS; hestOpt *hopt=NULL; airArray *mop; limnPolyData *pld, *pldSub; gageContext *gctx=NULL; gagePerVolume *pvl; Nrrd *nin, *nmeas; double kparm[3], strength, scaling[3]; seekContext *sctx; FILE *file; unsigned int ncc; size_t samples[3]; gageKind *kind; char *itemGradS; /* , *itemEvalS[2], *itemEvecS[2]; */ int itemGrad; /* , itemEval[2], itemEvec[2]; */ int E; me = argv[0]; hestOptAdd(&hopt, "i", "nin", airTypeOther, 1, 1, &nin, NULL, "input volume to analyze", NULL, NULL, nrrdHestNrrd); hestOptAdd(&hopt, "k", "kind", airTypeOther, 1, 1, &kind, NULL, "\"kind\" of volume (\"scalar\", \"vector\", \"tensor\")", NULL, NULL, &probeKindHestCB); hestOptAdd(&hopt, "s", "strength", airTypeDouble, 1, 1, &strength, "0.01", "strength"); hestOptAdd(&hopt, "gi", "grad item", airTypeString, 1, 1, &itemGradS, NULL, "item for gradient vector"); hestOptAdd(&hopt, "c", "scaling", airTypeDouble, 3, 3, scaling, "1 1 1", "amount by which to up/down-sample on each spatial axis"); hestOptAdd(&hopt, "n", "# CC", airTypeUInt, 1, 1, &ncc, "0", "if non-zero, number of CC to save"); hestOptAdd(&hopt, "o", "output LMPD", airTypeString, 1, 1, &outS, "out.lmpd", "output file to save LMPD into"); hestParseOrDie(hopt, argc-1, argv+1, NULL, me, info, AIR_TRUE, AIR_TRUE, AIR_TRUE); mop = airMopNew(); airMopAdd(mop, hopt, (airMopper)hestOptFree, airMopAlways); airMopAdd(mop, hopt, (airMopper)hestParseFree, airMopAlways); itemGrad = airEnumVal(kind->enm, itemGradS); pld = limnPolyDataNew(); airMopAdd(mop, pld, (airMopper)limnPolyDataNix, airMopAlways); pldSub = limnPolyDataNew(); airMopAdd(mop, pldSub, (airMopper)limnPolyDataNix, airMopAlways); file = airFopen(outS, stdout, "w"); airMopAdd(mop, file, (airMopper)airFclose, airMopAlways); sctx = seekContextNew(); airMopAdd(mop, sctx, (airMopper)seekContextNix, airMopAlways); gctx = gageContextNew(); airMopAdd(mop, gctx, (airMopper)gageContextNix, airMopAlways); ELL_3V_SET(kparm, 1, 1.0, 0.0); if (!(pvl = gagePerVolumeNew(gctx, nin, kind)) || gagePerVolumeAttach(gctx, pvl) || gageKernelSet(gctx, gageKernel00, nrrdKernelBCCubic, kparm) || gageKernelSet(gctx, gageKernel11, nrrdKernelBCCubicD, kparm) || gageKernelSet(gctx, gageKernel22, nrrdKernelBCCubicDD, kparm) || gageQueryItemOn(gctx, pvl, itemGrad) || gageQueryItemOn(gctx, pvl, gageSclHessEval) || gageQueryItemOn(gctx, pvl, gageSclHessEval2) || gageQueryItemOn(gctx, pvl, gageSclHessEvec) || gageQueryItemOn(gctx, pvl, gageSclHessEvec2) || gageUpdate(gctx)) { airMopAdd(mop, err = biffGetDone(GAGE), airFree, airMopAlways); fprintf(stderr, "%s: trouble:\n%s\n", me, err); airMopError(mop); return 1; } seekVerboseSet(sctx, 10); E = 0; if (!E) E |= seekDataSet(sctx, NULL, gctx, 0); ELL_3V_SET(samples, scaling[0]*nin->axis[kind->baseDim + 0].size, scaling[1]*nin->axis[kind->baseDim + 1].size, scaling[2]*nin->axis[kind->baseDim + 2].size); if (!E) E |= seekSamplesSet(sctx, samples); if (!E) E |= seekItemGradientSet(sctx, itemGrad); if (!E) E |= seekItemEigensystemSet(sctx, gageSclHessEval, gageSclHessEvec); if (!E) E |= seekItemNormalSet(sctx, gageSclHessEvec2); if (!E) E |= seekStrengthUseSet(sctx, AIR_TRUE); if (!E) E |= seekStrengthSet(sctx, -1, strength); if (!E) E |= seekItemStrengthSet(sctx, gageSclHessEval2); if (!E) E |= seekNormalsFindSet(sctx, AIR_TRUE); if (!E) E |= seekTypeSet(sctx, seekTypeRidgeSurface); if (!E) E |= seekUpdate(sctx); if (!E) E |= seekExtract(sctx, pld); if (E) { airMopAdd(mop, err = biffGetDone(SEEK), airFree, airMopAlways); fprintf(stderr, "%s: trouble:\n%s\n", me, err); airMopError(mop); return 1; } fprintf(stderr, "%s: extraction time = %g\n", me, sctx->time); nmeas = nrrdNew(); airMopAdd(mop, nmeas, (airMopper)nrrdNuke, airMopAlways); if (limnPolyDataVertexWindingFix(pld, AIR_TRUE) || limnPolyDataVertexWindingFlip(pld) || limnPolyDataVertexNormals(pld) || limnPolyDataCCFind(pld) || limnPolyDataPrimitiveArea(nmeas, pld) || limnPolyDataPrimitiveSort(pld, nmeas)) { err = biffGetDone(LIMN); fprintf(stderr, "%s: trouble sorting:\n%s", me, err); free(err); } if (ncc > 1) { double *meas; unsigned int ccIdx; nrrdSave("meas.nrrd", nmeas, NULL); ncc = AIR_MIN(ncc, nmeas->axis[0].size); meas = AIR_CAST(double *, nmeas->data); for (ccIdx=ncc; ccIdx<nmeas->axis[0].size; ccIdx++) { meas[ccIdx] = 0.0; } if (!E) E |= limnPolyDataPrimitiveSelect(pldSub, pld, nmeas); if (!E) E |= limnPolyDataWriteLMPD(file, pldSub); } else {
int main(int argc, char *argv[]) { char *me, *err; hestOpt *hopt=NULL; airArray *mop; unsigned int sx, sy, sz, ss, ii, anisoTypeNum, anisoTypeIdx, roiVoxNum, roiVoxIdx, statNum, statIdx; float *ten, *roi, *aniso, eval[3], *stat; Nrrd *nten, *_nroi, *nroi, *naniso, *nstat; int *anisoType, *measr; size_t anisoSize[2]; mop = airMopNew(); me = argv[0]; hestOptAdd(&hopt, "r,roi", "roi", airTypeOther, 1, 1, &_nroi, NULL, "ROI volume", NULL, NULL, nrrdHestNrrd); hestOptAdd(&hopt, "i,input", "volume", airTypeOther, 1, 1, &nten, "-", "tensor volume", NULL, NULL, nrrdHestNrrd); hestOptAdd(&hopt, "a,aniso", "aniso", airTypeEnum, 1, -1, &anisoType, NULL, "which anisotropy measures to measure", &anisoTypeNum, tenAniso); hestOptAdd(&hopt, "m,measr", "measr", airTypeEnum, 1, -1, &measr, NULL, "which measures/statistics to calculate", &statNum, nrrdMeasure); 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); if (tenTensorCheck(nten, nrrdTypeFloat, AIR_TRUE, AIR_TRUE)) { airMopAdd(mop, err = biffGetDone(TEN), airFree, airMopAlways); fprintf(stderr, "%s: didn't get tensor input:\n%s\n", me, err); airMopError(mop); return 1; } nroi = nrrdNew(); airMopAdd(mop, nroi, AIR_CAST(airMopper, nrrdNuke), airMopAlways); if (nrrdConvert(nroi, _nroi, nrrdTypeFloat)) { airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: couldn't convert ROI to float:\n%s\n", me, err); airMopError(mop); return 1; } sx = nten->axis[1].size; sy = nten->axis[2].size; sz = nten->axis[3].size; if (!(3 == nroi->dim && sx == nroi->axis[0].size && sy == nroi->axis[1].size && sz == nroi->axis[2].size)) { fprintf(stderr, "%s: ROI dimension or axis sizes don't match volume", me); airMopError(mop); return 1; } ss = sx*sy*sz; ten = AIR_CAST(float*, nten->data); roi = AIR_CAST(float*, nroi->data); /* NOTE: for time being the statistics are not weighted, because nrrdMeasureLine[]() can't take a weight vector... */ /* find number of voxels in ROI */ roiVoxNum = 0; for (ii=0; ii<ss; ii++) { roiVoxNum += (roi[ii] > 0); } /* fprintf(stderr, "%s: # voxels in ROI == %u\n", me, roiVoxNum); */ /* allocate anisotropy buffers */ naniso = nrrdNew(); airMopAdd(mop, naniso, AIR_CAST(airMopper, nrrdNuke), airMopAlways); anisoSize[0] = roiVoxNum; anisoSize[1] = anisoTypeNum; if (nrrdMaybeAlloc_nva(naniso, nrrdTypeFloat, 2, anisoSize)) { airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: couldn't allocate aniso:\n%s\n", me, err); airMopError(mop); return 1; } aniso = AIR_CAST(float *, naniso->data); /* store all anisotropies in all ROI voxels */ roiVoxIdx = 0; for (ii=0; ii<ss; ii++) { if (roi[ii] > 0) { tenEigensolve_f(eval, NULL, ten + 7*ii); for (anisoTypeIdx=0; anisoTypeIdx<anisoTypeNum; anisoTypeIdx++) { aniso[roiVoxIdx + roiVoxNum*anisoTypeIdx] = tenAnisoEval_f(eval, anisoType[anisoTypeIdx]); } roiVoxIdx++; } } printf("statistic:"); for (anisoTypeIdx=0; anisoTypeIdx<anisoTypeNum; anisoTypeIdx++) { printf(" %s", airEnumStr(tenAniso, anisoType[anisoTypeIdx])); } printf("\n"); /* do per-anisotropy statistics */ nstat = nrrdNew(); airMopAdd(mop, nstat, AIR_CAST(airMopper, nrrdNuke), airMopAlways); for (statIdx=0; statIdx<statNum; statIdx++) { printf("%s:", airEnumStr(nrrdMeasure, measr[statIdx])); if (nrrdProject(nstat, naniso, 0, measr[statIdx], nrrdTypeFloat)) { airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: couldn't measure:\n%s\n", me, err); airMopError(mop); return 1; } stat = AIR_CAST(float *, nstat->data); for (anisoTypeIdx=0; anisoTypeIdx<anisoTypeNum; anisoTypeIdx++) { printf(" %g", stat[anisoTypeIdx]); } printf("\n"); } airMopOkay(mop); return 0; }
int limnpu_pselMain(int argc, char **argv, char *me, hestParm *hparm) { hestOpt *hopt = NULL; char *err, *perr; airArray *mop; int pret; limnPolyData *pldIn, *pldOut; unsigned int prange[2], pi; Nrrd *nsel; double *sel; char *out; size_t size[NRRD_DIM_MAX]; hestOptAdd(&hopt, "r", "range", airTypeUInt, 2, 2, prange, NULL, "range of indices of primitives to select"); hestOptAdd(&hopt, NULL, "input", airTypeOther, 1, 1, &pldIn, NULL, "input polydata filename", NULL, NULL, limnHestPolyDataLMPD); hestOptAdd(&hopt, NULL, "output", airTypeString, 1, 1, &out, NULL, "output polydata filename"); mop = airMopNew(); airMopAdd(mop, hopt, (airMopper)hestOptFree, airMopAlways); USAGE(myinfo); PARSE(); airMopAdd(mop, hopt, (airMopper)hestParseFree, airMopAlways); if (!( prange[0] <= pldIn->primNum-1 && prange[1] <= pldIn->primNum-1 )) { fprintf(stderr, "%s: prange[0] %u or [1] %u outside range [0,%u]", me, prange[0], prange[1], pldIn->primNum-1); airMopError(mop); return 1; } if (!( prange[0] <= prange[1] )) { fprintf(stderr, "%s: need prange[0] %u <= [1] %u", me, prange[0], prange[1]); airMopError(mop); return 1; } nsel = nrrdNew(); airMopAdd(mop, nsel, (airMopper)nrrdNuke, airMopAlways); size[0] = pldIn->primNum; if (nrrdMaybeAlloc_nva(nsel, nrrdTypeDouble, 1, size)) { airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: trouble allocating buffer:%s", me, err); airMopError(mop); return 1; } sel = AIR_CAST(double *, nsel->data); for (pi=prange[0]; pi<=prange[1]; pi++) { sel[pi] = 1; } pldOut = limnPolyDataNew(); airMopAdd(mop, pldOut, (airMopper)limnPolyDataNix, airMopAlways); if (limnPolyDataPrimitiveSelect(pldOut, pldIn, nsel) || limnPolyDataSave(out, pldOut)) { airMopAdd(mop, err = biffGetDone(LIMN), airFree, airMopAlways); fprintf(stderr, "%s: trouble:%s", me, err); airMopError(mop); return 1; } airMopOkay(mop); return 0; }
int unrrdu_cropMain(int argc, char **argv, char *me, hestParm *hparm) { hestOpt *opt = NULL; char *out, *err; Nrrd *nin, *nout; unsigned int ai; int minLen, maxLen, pret; long int *minOff, *maxOff; size_t min[NRRD_DIM_MAX], max[NRRD_DIM_MAX]; airArray *mop; OPT_ADD_BOUND("min,minimum", minOff, "low corner of bounding box.\n " "\b\bo <int> gives 0-based index\n " "\b\bo M, M+<int>, M-<int> give index relative " "to the last sample on the axis (M == #samples-1).", minLen); OPT_ADD_BOUND("max,maximum", maxOff, "high corner of bounding box. Besides " "the specification styles described above, there's also:\n " "\b\bo m+<int> give index relative to minimum.", maxLen); OPT_ADD_NIN(nin, "input nrrd"); OPT_ADD_NOUT(out, "output nrrd"); mop = airMopNew(); airMopAdd(mop, opt, (airMopper)hestOptFree, airMopAlways); USAGE(_unrrdu_cropInfoL); PARSE(); airMopAdd(mop, opt, (airMopper)hestParseFree, airMopAlways); if (!( minLen == (int)nin->dim && maxLen == (int)nin->dim )) { fprintf(stderr, "%s: # min coords (%d) or max coords (%d) != nrrd dim (%d)\n", me, minLen, maxLen, nin->dim); airMopError(mop); return 1; } for (ai=0; ai<nin->dim; ai++) { if (-1 == minOff[0 + 2*ai]) { fprintf(stderr, "%s: can't use m+<int> specification for axis %d min\n", me, ai); airMopError(mop); return 1; } } for (ai=0; ai<nin->dim; ai++) { min[ai] = minOff[0 + 2*ai]*(nin->axis[ai].size-1) + minOff[1 + 2*ai]; if (-1 == maxOff[0 + 2*ai]) { max[ai] = min[ai] + maxOff[1 + 2*ai]; } else { max[ai] = maxOff[0 + 2*ai]*(nin->axis[ai].size-1) + maxOff[1 + 2*ai]; } /* fprintf(stderr, "%s: ai %2d: min = %4d, max = %4d\n", me, ai, min[ai], max[ai]); */ } nout = nrrdNew(); airMopAdd(mop, nout, (airMopper)nrrdNuke, airMopAlways); if (nrrdCrop(nout, nin, min, max)) { airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: error cropping nrrd:\n%s", me, err); airMopError(mop); return 1; } SAVE(out, nout, NULL); airMopOkay(mop); return 0; }
/* ******** pushIterate ** ** (documentation) ** ** NB: this implements the body of thread 0 */ int pushIterate(pushContext *pctx) { char me[]="pushIterate", *_err, err[BIFF_STRLEN]; unsigned int ti, numThing; if (!pctx) { sprintf(err, "%s: got NULL pointer", me); biffAdd(PUSH, err); return 1; } if (pctx->verbose) { fprintf(stderr, "%s: starting iteration\n", me); } /* the _pushWorker checks finished after the barriers */ pctx->finished = AIR_FALSE; pctx->binIdx=0; pctx->stageIdx=0; for (ti=0; ti<pctx->numThread; ti++) { pctx->task[ti]->sumVel = 0; pctx->task[ti]->numThing = 0; } do { if (pctx->numThread > 1) { airThreadBarrierWait(pctx->stageBarrierA); } if (pctx->verbose) { fprintf(stderr, "%s: starting iter %d stage %d\n", me, pctx->iter, pctx->stageIdx); } if (_pushStageRun(pctx->task[0], pctx->stageIdx)) { _err = biffGetDone(PUSH); fprintf(stderr, "%s: task %d trouble w/ iter %d stage %d:\n%s", me, pctx->task[0]->threadIdx, pctx->iter, pctx->task[0]->pctx->stageIdx, _err); return 1; } if (pctx->numThread > 1) { airThreadBarrierWait(pctx->stageBarrierB); } /* This is the only code to happen between barriers */ pctx->stageIdx++; pctx->binIdx=0; } while (pctx->stageIdx < pctx->numStage); pctx->meanVel = 0; numThing = 0; for (ti=0; ti<pctx->numThread; ti++) { pctx->meanVel += pctx->task[ti]->sumVel; /* fprintf(stderr, "!%s: task %d sumVel = %g\n", me, ti, pctx->task[ti]->sumVel); */ numThing += pctx->task[ti]->numThing; } pctx->meanVel /= numThing; if (pushRebin(pctx)) { sprintf(err, "%s: problem with new point locations", me); biffAdd(PUSH, err); return 1; } if (0 && 100 == pctx->iter) { _pushForceSample(pctx, 300, 300); } return 0; }
int unrrdu_quantizeMain(int argc, const char **argv, const char *me, hestParm *hparm) { hestOpt *opt = NULL; char *out, *err; Nrrd *nin, *nout; char *minStr, *maxStr; int pret, blind8BitRange; unsigned int bits, hbins; NrrdRange *range; airArray *mop; hestOptAdd(&opt, "b,bits", "bits", airTypeOther, 1, 1, &bits, NULL, "Number of bits to quantize down to; determines the type " "of the output nrrd:\n " "\b\bo \"8\": unsigned char\n " "\b\bo \"16\": unsigned short\n " "\b\bo \"32\": unsigned int", NULL, NULL, &unrrduHestBitsCB); hestOptAdd(&opt, "min,minimum", "value", airTypeString, 1, 1, &minStr, "nan", "The value to map to zero, given explicitly as a regular number, " "*or*, if the number is given with a \"" NRRD_MINMAX_PERC_SUFF "\" suffix, this " "minimum is specified in terms of the percentage of samples in " "input that are lower. " "\"0" NRRD_MINMAX_PERC_SUFF "\" means the " "lowest input value is used, " "\"1" NRRD_MINMAX_PERC_SUFF "\" means that the " "1% of the lowest values are all mapped to zero. " "By default (not using this option), the lowest input value is " "used."); hestOptAdd(&opt, "max,maximum", "value", airTypeString, 1, 1, &maxStr, "nan", "The value to map to the highest unsigned integral value, given " "explicitly as a regular number, " "*or*, if the number is given with " "a \"" NRRD_MINMAX_PERC_SUFF "\" suffix, " "this maximum is specified " "in terms of the percentage of samples in input that are higher. " "\"0" NRRD_MINMAX_PERC_SUFF "\" means the highest input value is " "used, which is also the default " "behavior (same as not using this option)."); hestOptAdd(&opt, "hb,bins", "bins", airTypeUInt, 1, 1, &hbins, "5000", "number of bins in histogram of values, for determining min " "or max by percentiles. This has to be large enough so that " "any errant very high or very low values do not compress the " "interesting part of the histogram to an inscrutably small " "number of bins."); hestOptAdd(&opt, "blind8", "bool", airTypeBool, 1, 1, &blind8BitRange, nrrdStateBlind8BitRange ? "true" : "false", "if not using \"-min\" or \"-max\", whether to know " "the range of 8-bit data blindly (uchar is always [0,255], " "signed char is [-128,127])"); OPT_ADD_NIN(nin, "input nrrd"); OPT_ADD_NOUT(out, "output nrrd"); mop = airMopNew(); airMopAdd(mop, opt, (airMopper)hestOptFree, airMopAlways); USAGE(_unrrdu_quantizeInfoL); PARSE(); airMopAdd(mop, opt, (airMopper)hestParseFree, airMopAlways); range = nrrdRangeNew(AIR_NAN, AIR_NAN); airMopAdd(mop, range, (airMopper)nrrdRangeNix, airMopAlways); nout = nrrdNew(); airMopAdd(mop, nout, (airMopper)nrrdNuke, airMopAlways); if (nrrdRangePercentileFromStringSet(range, nin, minStr, maxStr, hbins, blind8BitRange) || nrrdQuantize(nout, nin, range, bits)) { airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: error with range or quantizing:\n%s", me, err); airMopError(mop); return 1; } SAVE(out, nout, NULL); airMopOkay(mop); return 0; }
int unrrdu_jhistoMain(int argc, char **argv, char *me, hestParm *hparm) { hestOpt *opt = NULL; char *out, *err; Nrrd **nin; Nrrd *nout, *nwght; size_t *bin; int type, clamp[NRRD_DIM_MAX], pret; unsigned int binLen, minLen, maxLen, ninLen, ai; airArray *mop; double *min, *max; NrrdRange **range; hestOptAdd(&opt, "b,bin", "bins0 bins1", airTypeSize_t, 2, -1, &bin, NULL, "bins<i> is the number of bins to use along axis i (of joint " "histogram), which represents the values of nin<i> ", &binLen); hestOptAdd(&opt, "w,weight", "nweight", airTypeOther, 1, 1, &nwght, "", "how to weigh contributions to joint histogram. By default " "(not using this option), the increment is one bin count per " "sample, but by giving a nrrd, the value in the nrrd at the " "corresponding location will be the bin count increment ", NULL, NULL, nrrdHestNrrd); hestOptAdd(&opt, "min,minimum", "min0 min1", airTypeDouble, 2, -1, &min, "nan nan", "min<i> is the low range of values to be quantized along " "axis i; use \"nan\" to represent lowest value present ", &minLen); hestOptAdd(&opt, "max,maximum", "max0 max1", airTypeDouble, 2, -1, &max, "nan nan", "max<i> is the high range of values to be quantized along " "axis i; use \"nan\" to represent highest value present ", &maxLen); OPT_ADD_TYPE(type, "type to use for output (the type used to store hit " "counts in the joint histogram). Clamping is done on hit " "counts so that they never overflow a fixed-point type", "uint"); hestOptAdd(&opt, "i,input", "nin0 nin1", airTypeOther, 2, -1, &nin, NULL, "All input nrrds", &ninLen, NULL, nrrdHestNrrd); OPT_ADD_NOUT(out, "output nrrd"); mop = airMopNew(); airMopAdd(mop, opt, (airMopper)hestOptFree, airMopAlways); USAGE(_unrrdu_jhistoInfoL); PARSE(); airMopAdd(mop, opt, (airMopper)hestParseFree, airMopAlways); if (ninLen != binLen) { fprintf(stderr, "%s: # input nrrds (%d) != # bin specifications (%d)\n", me, ninLen, binLen); airMopError(mop); return 1; } range = (NrrdRange **)calloc(ninLen, sizeof(NrrdRange*)); airMopAdd(mop, range, airFree, airMopAlways); for (ai=0; ai<ninLen; ai++) { range[ai] = nrrdRangeNew(AIR_NAN, AIR_NAN); airMopAdd(mop, range[ai], (airMopper)nrrdRangeNix, airMopAlways); } if (2 != minLen || (AIR_EXISTS(min[0]) || AIR_EXISTS(min[1]))) { if (minLen != ninLen) { fprintf(stderr, "%s: # mins (%d) != # input nrrds (%d)\n", me, minLen, ninLen); airMopError(mop); return 1; } for (ai=0; ai<ninLen; ai++) { range[ai]->min = min[ai]; } } if (2 != maxLen || (AIR_EXISTS(max[0]) || AIR_EXISTS(max[1]))) { if (maxLen != ninLen) { fprintf(stderr, "%s: # maxs (%d) != # input nrrds (%d)\n", me, maxLen, ninLen); airMopError(mop); return 1; } for (ai=0; ai<ninLen; ai++) { range[ai]->max = max[ai]; } } for (ai=0; ai<ninLen; ai++) { clamp[ai] = 0; } nout = nrrdNew(); airMopAdd(mop, nout, (airMopper)nrrdNuke, airMopAlways); if (nrrdHistoJoint(nout, (const Nrrd**)nin, (const NrrdRange**)range, ninLen, nwght, bin, type, clamp)) { airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: error doing joint histogram:\n%s", me, err); airMopError(mop); return 1; } SAVE(out, nout, NULL); airMopOkay(mop); return 0; }
int main(int argc, char *argv[]) { char *me, *err, *outS; limnCamera *cam; float matA[16], matB[16], winscale, edgeWidth[5]; hestOpt *hopt=NULL; airArray *mop; limnObject *obj; limnLook *look; int lookIdx; limnWindow *win; int partIdx, wire, concave; Nrrd *nmap; mop = airMopNew(); cam = limnCameraNew(); airMopAdd(mop, cam, (airMopper)limnCameraNix, airMopAlways); me = argv[0]; hestOptAdd(&hopt, "fr", "from point", airTypeDouble, 3, 3, cam->from,"4 4 4", "position of camera, used to determine view vector"); hestOptAdd(&hopt, "at", "at point", airTypeDouble, 3, 3, cam->at, "0 0 0", "camera look-at point, used to determine view vector"); hestOptAdd(&hopt, "up", "up vector", airTypeDouble, 3, 3, cam->up, "0 0 1", "camera pseudo-up vector, used to determine view coordinates"); hestOptAdd(&hopt, "rh", NULL, airTypeInt, 0, 0, &(cam->rightHanded), NULL, "use a right-handed UVN frame (V points down)"); hestOptAdd(&hopt, "or", NULL, airTypeInt, 0, 0, &(cam->orthographic), NULL, "use orthogonal projection"); hestOptAdd(&hopt, "ur", "uMin uMax", airTypeDouble, 2, 2, cam->uRange, "-1 1", "range in U direction of image plane"); hestOptAdd(&hopt, "vr", "vMin vMax", airTypeDouble, 2, 2, cam->vRange, "-1 1", "range in V direction of image plane"); hestOptAdd(&hopt, "e", "envmap", airTypeOther, 1, 1, &nmap, NULL, "16checker-based environment map", NULL, NULL, nrrdHestNrrd); hestOptAdd(&hopt, "ws", "winscale", airTypeFloat, 1, 1, &winscale, "200", "world to points (PostScript) scaling"); hestOptAdd(&hopt, "wire", NULL, airTypeInt, 0, 0, &wire, NULL, "just do wire-frame rendering"); hestOptAdd(&hopt, "concave", NULL, airTypeInt, 0, 0, &concave, NULL, "use slightly buggy rendering method suitable for " "concave or self-occluding objects"); hestOptAdd(&hopt, "wd", "5 widths", airTypeFloat, 5, 5, edgeWidth, "0.0 0.0 3.0 2.0 0.0", "width of edges drawn for five kinds of " "edges: back non-crease, back crease, " "silohuette, front crease, front non-crease"); hestOptAdd(&hopt, "o", "output PS", airTypeString, 1, 1, &outS, "out.ps", "output file to render postscript 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); cam->neer = -0.000000001; cam->dist = 0; cam->faar = 0.0000000001; cam->atRelative = AIR_TRUE; if (limnCameraUpdate(cam)) { fprintf(stderr, "%s: trouble:\n%s\n", me, err = biffGet(LIMN)); free(err); return 1; } obj = limnObjectNew(10, AIR_TRUE); airMopAdd(mop, obj, (airMopper)limnObjectNix, airMopAlways); /* create limnLooks for diffuse (#0) and flat (#1) shading */ lookIdx = airArrayLenIncr(obj->lookArr, 2); look = obj->look + lookIdx + 0; ELL_4V_SET(look->rgba, 1, 1, 1, 1); ELL_3V_SET(look->kads, 0, 1, 0); look->spow = 0; look = obj->look + lookIdx + 1; ELL_4V_SET(look->rgba, 1, 1, 1, 1); ELL_3V_SET(look->kads, 1, 0, 0); look->spow = 0; /* X axis: rod */ partIdx = limnObjectCylinderAdd(obj, 0, 0, 16); ELL_4M_IDENTITY_SET(matA); ELL_4M_SCALE_SET(matB, 1, 0.2, 0.2); ell_4m_post_mul_f(matA, matB); ELL_4M_TRANSLATE_SET(matB, 1.3, 0.0, 0.0); ell_4m_post_mul_f(matA, matB); limnObjectPartTransform(obj, partIdx, matA); /* Y axis: rod + ball */ partIdx = limnObjectCylinderAdd(obj, 0, 1, 16); ELL_4M_IDENTITY_SET(matA); ELL_4M_SCALE_SET(matB, 0.2, 1, 0.2); ell_4m_post_mul_f(matA, matB); ELL_4M_TRANSLATE_SET(matB, 0.0, 1.3, 0.0); ell_4m_post_mul_f(matA, matB); limnObjectPartTransform(obj, partIdx, matA); partIdx = limnObjectPolarSphereAdd(obj, 0, 0, 32, 16); ELL_4M_IDENTITY_SET(matA); ELL_4M_SCALE_SET(matB, 0.28, 0.28, 0.28); ell_4m_post_mul_f(matA, matB); ELL_4M_TRANSLATE_SET(matB, 0.0, 2.6, 0.0); ell_4m_post_mul_f(matA, matB); limnObjectPartTransform(obj, partIdx, matA); /* Z axis: rod + ball + ball */ partIdx = limnObjectCylinderAdd(obj, 0, 2, 16); ELL_4M_IDENTITY_SET(matA); ELL_4M_SCALE_SET(matB, 0.2, 0.2, 1); ell_4m_post_mul_f(matA, matB); ELL_4M_TRANSLATE_SET(matB, 0.0, 0.0, 1.3); ell_4m_post_mul_f(matA, matB); limnObjectPartTransform(obj, partIdx, matA); partIdx = limnObjectPolarSphereAdd(obj, 0, 1, 32, 16); ELL_4M_IDENTITY_SET(matA); ELL_4M_SCALE_SET(matB, 0.28, 0.28, 0.28); ell_4m_post_mul_f(matA, matB); ELL_4M_TRANSLATE_SET(matB, 0.0, 0.0, 2.6); ell_4m_post_mul_f(matA, matB); limnObjectPartTransform(obj, partIdx, matA); partIdx = limnObjectPolarSphereAdd(obj, 0, 2, 32, 16); ELL_4M_IDENTITY_SET(matA); ELL_4M_SCALE_SET(matB, 0.28, 0.28, 0.28); ell_4m_post_mul_f(matA, matB); ELL_4M_TRANSLATE_SET(matB, 0.0, 0.0, 3.2); ell_4m_post_mul_f(matA, matB); limnObjectPartTransform(obj, partIdx, matA); win = limnWindowNew(limnDevicePS); win->scale = winscale; win->ps.wireFrame = wire; win->ps.lineWidth[limnEdgeTypeBackFacet] = edgeWidth[0]; win->ps.lineWidth[limnEdgeTypeBackCrease] = edgeWidth[1]; win->ps.lineWidth[limnEdgeTypeContour] = edgeWidth[2]; win->ps.lineWidth[limnEdgeTypeFrontCrease] = edgeWidth[3]; win->ps.lineWidth[limnEdgeTypeFrontFacet] = edgeWidth[4]; win->file = fopen(outS, "w"); airMopAdd(mop, win, (airMopper)limnWindowNix, airMopAlways); if (limnObjectRender(obj, cam, win) || (concave ? limnObjectPSDrawConcave(obj, cam, nmap, win) : limnObjectPSDraw(obj, cam, nmap, win))) { airMopAdd(mop, err = biffGetDone(LIMN), airFree, airMopAlways); fprintf(stderr, "%s: trouble:\n%s\n", me, err); airMopError(mop); return 1; } fclose(win->file); airMopOkay(mop); return 0; }
int NrrdWriter(HxUniformScalarField3* field, const char* filename, int encoding) { // Identify data type int nrrdType = nrrdTypeUnknown; switch ( field->primType() ) { case McPrimType::mc_uint8: nrrdType = nrrdTypeUChar; break; case McPrimType::mc_int8: nrrdType = nrrdTypeChar; break; case McPrimType::mc_uint16: nrrdType = nrrdTypeUShort; break; case McPrimType::mc_int16: nrrdType = nrrdTypeShort; break; case McPrimType::mc_int32: nrrdType = nrrdTypeInt; break; case McPrimType::mc_float: nrrdType = nrrdTypeFloat; break; case McPrimType::mc_double: nrrdType = nrrdTypeDouble; break; default: break; } if(nrrdType == nrrdTypeUnknown) { theMsg->printf("ERROR: unsupported output type: %s for nrrd",field->primType().getName()); return 0; } void* data = field->lattice.dataPtr(); Nrrd *nrrd = nrrdNew(); NrrdIoState *nios = nrrdIoStateNew(); if ( encoding == nrrdEncodingTypeGzip) { if (nrrdEncodingGzip->available() ) { nrrdIoStateEncodingSet( nios, nrrdEncodingGzip ); nrrdIoStateSet( nios, nrrdIoStateZlibLevel, 9 ); } else theMsg->printf("WARNING: Nrrd library does not support Gzip compression encoding.\n Make sure Teem_ZLIB is on in CMAKE when building Nrrd library.\n"); } else if ( encoding == nrrdEncodingTypeBzip2) { if (nrrdEncodingBzip2->available() ) { nrrdIoStateEncodingSet( nios, nrrdEncodingBzip2 ); // nrrdIoStateSet( nios, nrrdIoStateBzip2BlockSize, 9 ); } else theMsg->printf("WARNING: Nrrd library does not support Bzip2 compression encoding.\n Make sure Teem_BZIP2 is on in CMAKE when building Nrrd library.\n"); } else if ( encoding == nrrdEncodingTypeAscii) { nrrdIoStateEncodingSet( nios, nrrdEncodingAscii ); } else { theMsg->printf("ERROR: Unimplemented nrrd encoding type: %d\n",encoding); return 0; } try { if ( nrrdWrap_va( nrrd, data, nrrdType, (size_t)3, (size_t)field->lattice.dimsInt()[0], (size_t)field->lattice.dimsInt()[1], (size_t)field->lattice.dimsInt()[2] ) ) { throw( biffGetDone(NRRD) ); } nrrdSpaceDimensionSet( nrrd, 3 ); // TODO: Would be nice to set space units. How does Amira store this? // if ( writeVolume->MetaKeyExists(CMTK_META_SPACE_UNITS_STRING) ) // { // nrrd->spaceUnits[0] = strdup( writeVolume->m_MetaInformation[CMTK_META_SPACE_UNITS_STRING].c_str() ); // nrrd->spaceUnits[1] = strdup( writeVolume->m_MetaInformation[CMTK_META_SPACE_UNITS_STRING].c_str() ); // nrrd->spaceUnits[2] = strdup( writeVolume->m_MetaInformation[CMTK_META_SPACE_UNITS_STRING].c_str() ); // } int kind[NRRD_DIM_MAX] = { nrrdKindDomain, nrrdKindDomain, nrrdKindDomain }; nrrdAxisInfoSet_nva( nrrd, nrrdAxisInfoKind, kind ); // TODO: Would be nice to write some kind of space if this exists // Fetch bounding box information and voxel size float* bbox = field->bbox(); McVec3f voxelSize = field->getVoxelSize(); // Just deal with space directions orthogonal to data axes // TODO: Fetch transformation and use that double spaceDir[NRRD_DIM_MAX][NRRD_SPACE_DIM_MAX]; for ( int i = 0; i < 3; ++i ) { for ( int j = 0; j < 3; ++j ) { if (i == j) spaceDir[i][j] = (double) voxelSize[i]; else spaceDir[i][j] = 0.0; // Can't assume that memory is zeroed } } nrrdAxisInfoSet_nva( nrrd, nrrdAxisInfoSpaceDirection, spaceDir ); double origin[NRRD_DIM_MAX] = { bbox[0], bbox[2], bbox[4] }; if ( nrrdSpaceOriginSet( nrrd, origin ) ) { throw( biffGetDone(NRRD) ); } nrrdAxisInfoSet_va( nrrd, nrrdAxisInfoLabel, "x", "y", "z" ); if ( nrrdSave( filename, nrrd, nios ) ) { throw( biffGetDone(NRRD) ); } } catch ( char* err ) { theMsg->printf("ERROR: hxNrrdIO library returned error '%s'\n", err); free( err ); return 0; } nrrdIoStateNix( nios ); nrrdNix(nrrd); return 1; }
int main(int argc, char *argv[]) { char *me, *outS; hestOpt *hopt; hestParm *hparm; airArray *mop; char *err; Nrrd *nin, *nhist; double vmin, vmax, rmax, val, cent[2], rad; int bins[2], sx, sy, xi, yi, ridx, hidx, rbins, hbins; NrrdRange *range; double (*lup)(const void *v, size_t I), *hist; me = argv[0]; mop = airMopNew(); hparm = hestParmNew(); hopt = NULL; airMopAdd(mop, hparm, (airMopper)hestParmFree, airMopAlways); hestOptAdd(&hopt, "i", "nin", airTypeOther, 1, 1, &nin, NULL, "input image", NULL, NULL, nrrdHestNrrd); hestOptAdd(&hopt, "b", "rbins hbins", airTypeInt, 2, 2, bins, NULL, "# of histogram bins: radial and value"); hestOptAdd(&hopt, "min", "value", airTypeDouble, 1, 1, &vmin, "nan", "Value at low end of histogram. Defaults to lowest value " "found in input nrrd."); hestOptAdd(&hopt, "max", "value", airTypeDouble, 1, 1, &vmax, "nan", "Value at high end of histogram. Defaults to highest value " "found in input nrrd."); hestOptAdd(&hopt, "rmax", "max radius", airTypeDouble, 1, 1, &rmax, "nan", "largest radius to include in histogram"); hestOptAdd(&hopt, "c", "center x, y", airTypeDouble, 2, 2, cent, NULL, "The center point around which to build radial histogram"); hestOptAdd(&hopt, "o", "filename", airTypeString, 1, 1, &outS, "-", "file to write histogram to"); hestParseOrDie(hopt, argc-1, argv+1, hparm, me, histradInfo, AIR_TRUE, AIR_TRUE, AIR_TRUE); airMopAdd(mop, hopt, (airMopper)hestOptFree, airMopAlways); airMopAdd(mop, hopt, (airMopper)hestParseFree, airMopAlways); if (2 != nin->dim) { fprintf(stderr, "%s: need 2-D input (not %d-D)\n", me, nin->dim); airMopError(mop); return 1; } rbins = bins[0]; hbins = bins[1]; nhist = nrrdNew(); airMopAdd(mop, nhist, (airMopper)nrrdNuke, airMopAlways); if (nrrdMaybeAlloc_va(nhist, nrrdTypeDouble, 2, AIR_CAST(size_t, rbins), AIR_CAST(size_t, hbins))) { airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: couldn't allocate histogram:\n%s", me, err); airMopError(mop); return 1; } if (!( AIR_EXISTS(vmin) && AIR_EXISTS(vmax) )) { range = nrrdRangeNewSet(nin, nrrdStateBlind8BitRange); airMopAdd(mop, range, (airMopper)nrrdRangeNix, airMopAlways); vmin = AIR_EXISTS(vmin) ? vmin : range->min; vmax = AIR_EXISTS(vmax) ? vmax : range->max; } #define DIST(x0, y0, x1, y1) (sqrt((x0-x1)*(x0-x1) + (y0-y1)*(y0-y1))) sx = nin->axis[0].size; sy = nin->axis[1].size; if (!AIR_EXISTS(rmax)) { rmax = 0; rmax = AIR_MAX(rmax, DIST(cent[0], cent[1], 0, 0)); rmax = AIR_MAX(rmax, DIST(cent[0], cent[1], sx-1, 0)); rmax = AIR_MAX(rmax, DIST(cent[0], cent[1], 0, sy-1)); rmax = AIR_MAX(rmax, DIST(cent[0], cent[1], sx-1, sy-1)); } lup = nrrdDLookup[nin->type]; hist = (double*)(nhist->data); for (xi=0; xi<sx; xi++) { for (yi=0; yi<sy; yi++) { rad = DIST(cent[0], cent[1], xi, yi); if (!AIR_IN_OP(0, rad, rmax)) { continue; } val = lup(nin->data, xi + sx*yi); if (!AIR_IN_OP(vmin, val, vmax)) { continue; } ridx = airIndex(0, rad, rmax, rbins); hidx = airIndex(vmin, val, vmax, hbins); hist[ridx + rbins*hidx] += 1; } } nhist->axis[0].min = 0; nhist->axis[0].max = rmax; nhist->axis[1].min = vmin; nhist->axis[1].max = vmax; if (nrrdSave(outS, nhist, NULL)) { airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: couldn't save output:\n%s", me, err); airMopError(mop); return 1; } airMopOkay(mop); exit(0); }
int unrrdu_diceMain(int argc, char **argv, char *me, hestParm *hparm) { hestOpt *opt = NULL; char *base, *err, fnout[AIR_STRLEN_MED], /* file name out */ fffname[AIR_STRLEN_MED], /* format for filename */ *ftmpl; /* format template */ Nrrd *nin, *nout; int top, pret, start, fit; unsigned int axis; size_t pos; airArray *mop; OPT_ADD_AXIS(axis, "axis to slice along"); OPT_ADD_NIN(nin, "input nrrd"); hestOptAdd(&opt, "s,start", "start", airTypeInt, 1, 1, &start, "0", "integer value to start numbering with"); hestOptAdd(&opt, "ff,format", "form", airTypeString, 1, 1, &ftmpl, "", "a printf-style format to use for generating all " "filenames. Use this to override the number of characters " "used to represent the slice position, or the file format " "of the output, e.g. \"-ff %03d.ppm\" for 000.ppm, " "001.ppm, etc. By default (not using this option), slices " "are saved in NRRD format (or PNM or PNG where possible) " "with shortest possible filenames."); hestOptAdd(&opt, "o,output", "prefix", airTypeString, 1, 1, &base, NULL, "output filename prefix (excluding info set via \"-ff\"), " "basically to set path of output files (so be sure to end " "with \"/\"."); mop = airMopNew(); airMopAdd(mop, opt, (airMopper)hestOptFree, airMopAlways); USAGE(_unrrdu_diceInfoL); PARSE(); airMopAdd(mop, opt, (airMopper)hestParseFree, airMopAlways); if (start < 0) { fprintf(stderr, "%s: given start index (%d) less than zero\n", me, start); airMopError(mop); return 1; } if (!( axis < nin->dim )) { fprintf(stderr, "%s: given axis (%u) outside range [0,%u]\n", me, axis, nin->dim-1); airMopError(mop); return 1; } /* HEY: this should use nrrdSaveMulti(), and if there's additional smarts here, they should be moved into nrrdSaveMulti() */ if (airStrlen(ftmpl)) { if (!( _nrrdContainsPercentThisAndMore(ftmpl, 'd') || _nrrdContainsPercentThisAndMore(ftmpl, 'u') )) { fprintf(stderr, "%s: given filename format \"%s\" doesn't seem to " "have the converstion specification to print an integer\n", me, ftmpl); airMopError(mop); return 1; } sprintf(fffname, "%%s%s", ftmpl); } else { top = start + nin->axis[axis].size-1; if (top > 9999999) { sprintf(fffname, "%%s%%08d.nrrd"); } else if (top > 999999) { sprintf(fffname, "%%s%%07d.nrrd"); } else if (top > 99999) { sprintf(fffname, "%%s%%06d.nrrd"); } else if (top > 9999) { sprintf(fffname, "%%s%%05d.nrrd"); } else if (top > 999) { sprintf(fffname, "%%s%%04d.nrrd"); } else if (top > 99) { sprintf(fffname, "%%s%%03d.nrrd"); } else if (top > 9) { sprintf(fffname, "%%s%%02d.nrrd"); } else { sprintf(fffname, "%%s%%01d.nrrd"); } } nout = nrrdNew(); airMopAdd(mop, nout, (airMopper)nrrdNuke, airMopAlways); for (pos=0; pos<nin->axis[axis].size; pos++) { if (nrrdSlice(nout, nin, axis, pos)) { airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: error slicing nrrd:%s\n", me, err); airMopError(mop); return 1; } if (0 == pos && !airStrlen(ftmpl)) { /* See if these slices would be better saved as PNG or PNM images. Altering the file name will tell nrrdSave() to use a different file format. */ if (nrrdFormatPNG->fitsInto(nout, nrrdEncodingRaw, AIR_FALSE)) { strcpy(fffname + strlen(fffname) - 4, "png"); } else { fit = nrrdFormatPNM->fitsInto(nout, nrrdEncodingRaw, AIR_FALSE); if (2 == fit) { strcpy(fffname + strlen(fffname) - 4, "pgm"); } else if (3 == fit) { strcpy(fffname + strlen(fffname) - 4, "ppm"); } } } sprintf(fnout, fffname, base, pos+start); fprintf(stderr, "%s: %s ...\n", me, fnout); if (nrrdSave(fnout, nout, NULL)) { airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: error writing nrrd to \"%s\":%s\n", me, fnout, err); airMopError(mop); return 1; } } airMopOkay(mop); return 0; }
int main(int argc, const char *argv[]) { const char *me; char *err, *inS, *outS; limnCamera *cam; float bg[3], winscale, edgeWidth[5], creaseAngle; hestOpt *hopt=NULL; airArray *mop; limnObject *obj; limnLook *look; unsigned int lookIdx; limnWindow *win; Nrrd *nmap; FILE *file; int wire, concave, describe, reverse, nobg; mop = airMopNew(); cam = limnCameraNew(); airMopAdd(mop, cam, (airMopper)limnCameraNix, airMopAlways); me = argv[0]; hestOptAdd(&hopt, "i", "input OFF", airTypeString, 1, 1, &inS, NULL, "input OFF file"); hestOptAdd(&hopt, "fr", "from point", airTypeDouble, 3, 3, cam->from,"4 4 4", "position of camera, used to determine view vector"); hestOptAdd(&hopt, "at", "at point", airTypeDouble, 3, 3, cam->at, "0 0 0", "camera look-at point, used to determine view vector"); hestOptAdd(&hopt, "up", "up vector", airTypeDouble, 3, 3, cam->up, "0 0 1", "camera pseudo-up vector, used to determine view coordinates"); hestOptAdd(&hopt, "rh", NULL, airTypeInt, 0, 0, &(cam->rightHanded), NULL, "use a right-handed UVN frame (V points down)"); hestOptAdd(&hopt, "or", NULL, airTypeInt, 0, 0, &(cam->orthographic), NULL, "use orthogonal projection"); hestOptAdd(&hopt, "ur", "uMin uMax", airTypeDouble, 2, 2, cam->uRange, "-1 1", "range in U direction of image plane"); hestOptAdd(&hopt, "vr", "vMin vMax", airTypeDouble, 2, 2, cam->vRange, "-1 1", "range in V direction of image plane"); hestOptAdd(&hopt, "e", "envmap", airTypeOther, 1, 1, &nmap, "", "16octa-based environment map", NULL, NULL, nrrdHestNrrd); hestOptAdd(&hopt, "ws", "winscale", airTypeFloat, 1, 1, &winscale, "200", "world to points (PostScript) scaling"); hestOptAdd(&hopt, "wire", NULL, airTypeInt, 0, 0, &wire, NULL, "just do wire-frame rendering"); hestOptAdd(&hopt, "concave", NULL, airTypeInt, 0, 0, &concave, NULL, "use slightly buggy rendering method suitable for " "concave or self-occluding objects"); hestOptAdd(&hopt, "reverse", NULL, airTypeInt, 0, 0, &reverse, NULL, "reverse ordering of vertices per face (needed if they " "specified in clockwise order)"); hestOptAdd(&hopt, "describe", NULL, airTypeInt, 0, 0, &describe, NULL, "for debugging: list object definition of OFF read"); hestOptAdd(&hopt, "bg", "background", airTypeFloat, 3, 3, bg, "1 1 1", "background RGB color; each component in range [0.0,1.0]"); hestOptAdd(&hopt, "nobg", NULL, airTypeInt, 0, 0, &nobg, NULL, "don't initially fill with background color"); hestOptAdd(&hopt, "wd", "5 widths", airTypeFloat, 5, 5, edgeWidth, "0.0 0.0 3.0 2.0 0.0", "width of edges drawn for five kinds of " "edges: back non-crease, back crease, " "silohuette, front crease, front non-crease"); hestOptAdd(&hopt, "ca", "angle", airTypeFloat, 1, 1, &creaseAngle, "30", "dihedral angles greater than this are creases"); hestOptAdd(&hopt, "o", "output PS", airTypeString, 1, 1, &outS, "out.ps", "output file to render postscript 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); cam->neer = -0.000000001; cam->dist = 0; cam->faar = 0.0000000001; cam->atRelative = AIR_TRUE; if (limnCameraUpdate(cam)) { fprintf(stderr, "%s: trouble:\n%s\n", me, err = biffGet(LIMN)); free(err); return 1; } obj = limnObjectNew(10, AIR_TRUE); airMopAdd(mop, obj, (airMopper)limnObjectNix, airMopAlways); if (!(file = airFopen(inS, stdin, "r"))) { fprintf(stderr, "%s: couldn't open \"%s\" for reading\n", me, inS); airMopError(mop); return 1; } airMopAdd(mop, file, (airMopper)airFclose, airMopAlways); if (limnObjectReadOFF(obj, file)) { airMopAdd(mop, err = biffGetDone(LIMN), airFree, airMopAlways); fprintf(stderr, "%s: trouble:\n%s\n", me, err); airMopError(mop); return 1; } if (describe) { fprintf(stdout, "----------------- POST-READ -----------------\n"); limnObjectDescribe(stdout, obj); fprintf(stdout, "----------------- POST-READ -----------------\n"); } if (reverse) { if (limnObjectFaceReverse(obj)) { airMopAdd(mop, err = biffGetDone(LIMN), airFree, airMopAlways); fprintf(stderr, "%s: trouble:\n%s\n", me, err); airMopError(mop); return 1; } } if (describe) { fprintf(stdout, "----------------- POST-REVERSE -----------------\n"); limnObjectDescribe(stdout, obj); fprintf(stdout, "----------------- POST-REVERSE -----------------\n"); } win = limnWindowNew(limnDevicePS); win->ps.lineWidth[limnEdgeTypeBackFacet] = edgeWidth[0]; win->ps.lineWidth[limnEdgeTypeBackCrease] = edgeWidth[1]; win->ps.lineWidth[limnEdgeTypeContour] = edgeWidth[2]; win->ps.lineWidth[limnEdgeTypeFrontCrease] = edgeWidth[3]; win->ps.lineWidth[limnEdgeTypeFrontFacet] = edgeWidth[4]; win->ps.wireFrame = wire; win->ps.creaseAngle = creaseAngle; win->ps.noBackground = nobg; ELL_3V_COPY(win->ps.bg, bg); win->file = airFopen(outS, stdout, "w"); airMopAdd(mop, win, (airMopper)limnWindowNix, airMopAlways); win->scale = winscale; for (lookIdx=0; lookIdx<obj->lookNum; lookIdx++) { look = obj->look + lookIdx; /* earlier version of limn/test/soid used (0.2,0.8,0.0), I think. Now we assume that any useful shading is happening in the emap */ ELL_3V_SET(look->kads, 0.2, 0.8, 0); } if (limnObjectRender(obj, cam, win) || (concave ? limnObjectPSDrawConcave(obj, cam, nmap, win) : limnObjectPSDraw(obj, cam, nmap, win))) { airMopAdd(mop, err = biffGetDone(LIMN), airFree, airMopAlways); fprintf(stderr, "%s: trouble:\n%s\n", me, err); airMopError(mop); return 1; } fclose(win->file); if (describe) { fprintf(stdout, "----------------- POST-RENDER -----------------\n"); limnObjectDescribe(stdout, obj); fprintf(stdout, "----------------- POST-RENDER -----------------\n"); } airMopOkay(mop); return 0; }
int main(int argc, const char **argv) { /* stock variables */ char me[] = BKEY; hestOpt *hopt=NULL; hestParm *hparm; airArray *mop; /* variables specific to this program */ int negskip, progress; Nrrd *nref, *nin; size_t *size, ii, nn, tick, pad[2]; unsigned int axi, refCRC, gotCRC, sizeNum; char *berr, *outS[2], stmp[AIR_STRLEN_SMALL], doneStr[AIR_STRLEN_SMALL]; airRandMTState *rng; unsigned int seed, *rdata, printbytes; unsigned char *dataUC; double time0, time1; FILE *fout; /* start-up */ mop = airMopNew(); hparm = hestParmNew(); airMopAdd(mop, hparm, (airMopper)hestParmFree, airMopAlways); /* learn things from hest */ hestOptAdd(&hopt, "seed", "N", airTypeUInt, 1, 1, &seed, "42", "seed for RNG"); hestOptAdd(&hopt, "s", "sz0", airTypeSize_t, 1, -1, &size, NULL, "sizes of desired output", &sizeNum); hestOptAdd(&hopt, "p", "pb pa", airTypeSize_t, 2, 2, pad, "0 0", "bytes of padding before, and after, the data segment " "in the written data"); hestOptAdd(&hopt, "ns", "bool", airTypeInt, 0, 0, &negskip, NULL, "skipping should be relative to end of file"); hestOptAdd(&hopt, "pb", "print", airTypeUInt, 1, 1, &printbytes, "0", "bytes to print at beginning and end of data, to help " "debug problems"); hestOptAdd(&hopt, "o", "out.data out.nhdr", airTypeString, 2, 2, outS, NULL, "output filenames of data and header"); hestParseOrDie(hopt, argc-1, argv+1, hparm, me, tskipInfo, AIR_TRUE, AIR_TRUE, AIR_TRUE); airMopAdd(mop, hopt, (airMopper)hestOptFree, airMopAlways); airMopAdd(mop, hopt, (airMopper)hestParseFree, airMopAlways); /* generate reference nrrd data */ nref = nrrdNew(); airMopAdd(mop, nref, (airMopper)nrrdNuke, airMopAlways); if (nrrdMaybeAlloc_nva(nref, nrrdTypeUInt, sizeNum, size)) { airMopAdd(mop, berr=biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: error allocating data: %s\n", me, berr); airMopError(mop); return 1; } rng = airRandMTStateNew(seed); airMopAdd(mop, rng, (airMopper)airRandMTStateNix, airMopAlways); nn = nrrdElementNumber(nref); rdata = AIR_CAST(unsigned int *, nref->data); fprintf(stderr, "generating data: . . . "); fflush(stderr); time0 = airTime(); progress = AIR_FALSE; tick = nn/100; for (ii=0; ii<nn; ii++) { rdata[ii] = airUIrandMT_r(rng); if (ii && tick && !(ii % tick)) { time1 = airTime(); if (time1 - time0 > 1.0) { /* if it took more than a second to do 1% of the thing, would be good to generate some progress indication */ progress = AIR_TRUE; } if (progress) { fprintf(stderr, "%s", airDoneStr(0, ii, nn, doneStr)); fflush(stderr); } } } if (progress) { fprintf(stderr, "%s\n", airDoneStr(0, ii, nn, doneStr)); fflush(stderr); } else { fprintf(stderr, "\n"); } fprintf(stderr, "finding reference (big-endian) CRC: "); fflush(stderr); refCRC = nrrdCRC32(nref, airEndianBig); fprintf(stderr, "%u\n", refCRC); /* write data, with padding */ fprintf(stderr, "saving data . . . "); fflush(stderr); if (!(fout = fopen(outS[0], "wb" COMMIT))) { fprintf(stderr, "\n%s: couldn't open %s for writing: %s\n", me, outS[0], strerror(errno)); airMopError(mop); return 1; } airMopAdd(mop, fout, (airMopper)airFclose, airMopAlways); for (ii=0; ii<pad[0]; ii++) { if (EOF == fputc(1, fout)) { fprintf(stderr, "\n%s: error doing pre-padding\n", me); airMopError(mop); return 1; } } if (nn != fwrite(nref->data, nrrdElementSize(nref), nn, fout)) { fprintf(stderr, "\n%s: error writing data\n", me); airMopError(mop); return 1; } for (ii=0; ii<pad[1]; ii++) { if (EOF == fputc(2, fout)) { fprintf(stderr, "\n%s: error doing post-padding\n", me); airMopError(mop); return 1; } } if (EOF == fflush(fout)) { fprintf(stderr, "\n%s: error fflushing data: %s\n", me, strerror(errno)); } fprintf(stderr, "\n"); if (printbytes) { size_t bi, rpb, nn; char stmp[AIR_STRLEN_SMALL]; nn = nrrdElementSize(nref)*nrrdElementNumber(nref); rpb = AIR_MIN(printbytes, nn); dataUC = AIR_CAST(unsigned char *, nref->data); fprintf(stderr, "CORRECT %s bytes at beginning:\n", airSprintSize_t(stmp, rpb)); for (bi=0; bi<rpb; bi++) { fprintf(stderr, "%x ", dataUC[bi]); } fprintf(stderr, "...\n"); fprintf(stderr, "CORRECT %s bytes at end:\n", airSprintSize_t(stmp, rpb)); fprintf(stderr, "..."); for (bi=nn - rpb; bi<nn; bi++) { fprintf(stderr, " %x", dataUC[bi]); } fprintf(stderr, "\n"); } airMopSingleOkay(mop, fout); airMopSingleOkay(mop, nref); nref = NULL; /* write header; for now just writing the header directly */ fprintf(stderr, "writing header . . . \n"); if (!(fout = fopen(outS[1], "w"))) { fprintf(stderr, "%s: couldn't open %s for writing: %s\n", me, outS[1], strerror(errno)); airMopError(mop); return 1; } airMopAdd(mop, fout, (airMopper)airFclose, airMopAlways); fprintf(fout, "NRRD0005\n"); fprintf(fout, "type: unsigned int\n"); fprintf(fout, "dimension: %u\n", sizeNum); fprintf(fout, "sizes:"); for (axi=0; axi<sizeNum; axi++) { fprintf(fout, " %s", airSprintSize_t(stmp, size[axi])); } fprintf(fout, "\n"); fprintf(fout, "endian: %s\n", airEnumStr(airEndian, airMyEndian())); fprintf(fout, "encoding: %s\n", airEnumStr(nrrdEncodingType, nrrdEncodingTypeRaw)); if (!negskip) { if (pad[0]) { fprintf(fout, "byte skip: %s\n", airSprintSize_t(stmp, pad[0])); } } else { fprintf(fout, "byte skip: -%s\n", airSprintSize_t(stmp, pad[1]+1)); } fprintf(fout, "data file: %s\n", outS[0]); airMopSingleOkay(mop, fout); /* read it in, make sure it checks out */ fprintf(stderr, "reading data . . . \n"); nin = nrrdNew(); airMopAdd(mop, nin, (airMopper)nrrdNuke, airMopAlways); if (nrrdLoad(nin, outS[1], NULL)) { airMopAdd(mop, berr=biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: error reading back in: %s\n", me, berr); airMopError(mop); return 1; } if (printbytes) { size_t bi, rpb, nn; char stmp[AIR_STRLEN_SMALL]; nn = nrrdElementSize(nin)*nrrdElementNumber(nin); rpb = AIR_MIN(printbytes, nn); dataUC = AIR_CAST(unsigned char *, nin->data); fprintf(stderr, "FOUND %s bytes at beginning:\n", airSprintSize_t(stmp, rpb)); for (bi=0; bi<rpb; bi++) { fprintf(stderr, "%x ", dataUC[bi]); } fprintf(stderr, "...\n"); fprintf(stderr, "FOUND %s bytes at end:\n", airSprintSize_t(stmp, rpb)); fprintf(stderr, "..."); for (bi=nn - rpb; bi<nn; bi++) { fprintf(stderr, " %x", dataUC[bi]); } fprintf(stderr, "\n"); } fprintf(stderr, "finding new CRC . . . \n"); gotCRC = nrrdCRC32(nin, airEndianBig); if (refCRC != gotCRC) { fprintf(stderr, "%s: got CRC %u but wanted %u\n", me, gotCRC, refCRC); airMopError(mop); return 1; } fprintf(stderr, "(all ok)\n"); /* HEY: to test gzip reading, we really want to do a system call to gzip compress the data, and write a new header to point to the compressed data, and make sure we can read in that just the same */ airMopOkay(mop); return 0; }
int main(int argc, const char **argv) { const char *me; Nrrd *nscl; double *dscl; airArray *mop; char *fullname; gageContext *igctx[INTERP_KERN_NUM], *bgctx[BLUR_KERN_NUM]; const NrrdKernel *ikern[INTERP_KERN_NUM] = { nrrdKernelBox, nrrdKernelTent, nrrdKernelBCCubic, nrrdKernelCatmullRom, }; double ikparm[INTERP_KERN_NUM][NRRD_KERNEL_PARMS_NUM] = { {1.0}, {1.0}, {1.0, 0.0, 0.5}, {AIR_NAN}, }; const NrrdKernel *bkern[BLUR_KERN_NUM] = { nrrdKernelTent, nrrdKernelBSpline3, nrrdKernelBSpline5, nrrdKernelBCCubic, nrrdKernelGaussian, }; const NrrdKernel *bkernD[BLUR_KERN_NUM] = { nrrdKernelForwDiff, nrrdKernelBSpline3D, nrrdKernelBSpline5D, nrrdKernelBCCubicD, nrrdKernelGaussianD, }; const NrrdKernel *bkernDD[BLUR_KERN_NUM] = { nrrdKernelZero, nrrdKernelBSpline3DD, nrrdKernelBSpline5DD, nrrdKernelBCCubicDD, nrrdKernelGaussianDD, }; double bkparm[BLUR_KERN_NUM][NRRD_KERNEL_PARMS_NUM] = { {1.0}, {AIR_NAN}, {AIR_NAN}, {2.0, 1.0, 0.0}, {1.2, 5.0}, }; const double *ivalAns[INTERP_KERN_NUM], *bvalAns[BLUR_KERN_NUM], *bgrdAns[BLUR_KERN_NUM], *bhesAns[BLUR_KERN_NUM]; int E; unsigned int sx, sy, sz, ki; AIR_UNUSED(argc); me = argv[0]; mop = airMopNew(); nscl = nrrdNew(); airMopAdd(mop, nscl, (airMopper)nrrdNuke, airMopAlways); fullname = testDataPathPrefix("fmob-c4h.nrrd"); airMopAdd(mop, fullname, airFree, airMopAlways); if (nrrdLoad(nscl, fullname, NULL)) { char *err; airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: trouble reading data \"%s\":\n%s", me, fullname, err); airMopError(mop); return 1; } /* make sure its a double-type volume (assumed below) */ if (nrrdTypeDouble != nscl->type) { fprintf(stderr, "%s: volume type %s != expected type %s\n", me, airEnumStr(nrrdType, nscl->type), airEnumStr(nrrdType, nrrdTypeDouble)); airMopError(mop); return 1; } dscl = AIR_CAST(double *, nscl->data); sx = AIR_CAST(unsigned int, nscl->axis[0].size); sy = AIR_CAST(unsigned int, nscl->axis[1].size); sz = AIR_CAST(unsigned int, nscl->axis[2].size); for (ki=0; ki<INTERP_KERN_NUM; ki++) { gagePerVolume *gpvl; igctx[ki] = gageContextNew(); airMopAdd(mop, igctx[ki], (airMopper)gageContextNix, airMopAlways); gageParmSet(igctx[ki], gageParmRenormalize, AIR_FALSE); gageParmSet(igctx[ki], gageParmCheckIntegrals, AIR_TRUE); gageParmSet(igctx[ki], gageParmOrientationFromSpacing, AIR_FALSE); E = 0; if (!E) E |= !(gpvl = gagePerVolumeNew(igctx[ki], nscl, gageKindScl)); if (!E) E |= gageKernelSet(igctx[ki], gageKernel00, ikern[ki], ikparm[ki]); if (!E) E |= gagePerVolumeAttach(igctx[ki], gpvl); if (!E) E |= gageQueryItemOn(igctx[ki], gpvl, gageSclValue); if (!E) E |= gageUpdate(igctx[ki]); if (E) { char *err; airMopAdd(mop, err = biffGetDone(GAGE), airFree, airMopAlways); fprintf(stderr, "%s: trouble %s set-up:\n%s\n", me, ikern[ki]->name, err); airMopError(mop); return 1; } ivalAns[ki] = gageAnswerPointer(igctx[ki], gpvl, gageSclValue); } /* traverse all samples of volume, probing with the interpolating kernels, make sure we recover the original values */ { unsigned int xi, yi, zi; double pval[INTERP_KERN_NUM], err, rval; int pret; for (zi=0; zi<sz; zi++) { for (yi=0; yi<sy; yi++) { for (xi=0; xi<sx; xi++) { rval = dscl[xi + sx*(yi + sy*zi)]; for (ki=0; ki<INTERP_KERN_NUM; ki++) { pret = gageProbeSpace(igctx[ki], xi, yi, zi, AIR_TRUE /* indexSpace */, AIR_FALSE /* clamp */); if (pret) { fprintf(stderr, "%s: %s probe error(%d): %s\n", me, ikern[ki]->name, igctx[ki]->errNum, igctx[ki]->errStr); airMopError(mop); return 1; } pval[ki] = *ivalAns[ki]; err = AIR_ABS(rval - pval[ki]); if (err) { fprintf(stderr, "%s: interp's [%u,%u,%u] %s probe %f " "!= true %f (err %f)\n", me, xi, yi, zi, ikern[ki]->name, pval[ki], rval, err); airMopError(mop); return 1; } } } } } } /* set up contexts for non-interpolating (blurring) kernels, and their first and second derivatives */ for (ki=0; ki<BLUR_KERN_NUM; ki++) { gagePerVolume *gpvl; bgctx[ki] = gageContextNew(); airMopAdd(mop, bgctx[ki], (airMopper)gageContextNix, airMopAlways); gageParmSet(bgctx[ki], gageParmRenormalize, AIR_TRUE); gageParmSet(bgctx[ki], gageParmCheckIntegrals, AIR_TRUE); gageParmSet(bgctx[ki], gageParmOrientationFromSpacing, AIR_FALSE); E = 0; if (!E) E |= !(gpvl = gagePerVolumeNew(bgctx[ki], nscl, gageKindScl)); if (!E) E |= gageKernelSet(bgctx[ki], gageKernel00, bkern[ki], bkparm[ki]); if (!E) E |= gageKernelSet(bgctx[ki], gageKernel11, bkernD[ki], bkparm[ki]); if (!E) E |= gageKernelSet(bgctx[ki], gageKernel22, bkernDD[ki], bkparm[ki]); if (!E) E |= gagePerVolumeAttach(bgctx[ki], gpvl); if (!E) E |= gageQueryItemOn(bgctx[ki], gpvl, gageSclValue); if (!E) E |= gageQueryItemOn(bgctx[ki], gpvl, gageSclGradVec); if (!E) E |= gageQueryItemOn(bgctx[ki], gpvl, gageSclHessian); if (!E) E |= gageUpdate(bgctx[ki]); if (E) { char *err; airMopAdd(mop, err = biffGetDone(GAGE), airFree, airMopAlways); fprintf(stderr, "%s: trouble %s set-up:\n%s\n", me, bkern[ki]->name, err); airMopError(mop); return 1; } fprintf(stderr, "%s radius = %u\n", bkern[ki]->name, bgctx[ki]->radius); bvalAns[ki] = gageAnswerPointer(bgctx[ki], gpvl, gageSclValue); bgrdAns[ki] = gageAnswerPointer(bgctx[ki], gpvl, gageSclGradVec); bhesAns[ki] = gageAnswerPointer(bgctx[ki], gpvl, gageSclHessian); } { #define POS_NUM 12 double xp[POS_NUM], yp[POS_NUM], zp[POS_NUM], pos[POS_NUM*POS_NUM*POS_NUM][3], *prbd, offs[POS_NUM/2] = {0, 1.22222, 2.444444, 3.777777, 5.88888, 7.55555}; Nrrd *nprbd, *ncorr; unsigned int ii, jj, kk, qlen = 1 + 3 + 9; char *corrfn, explain[AIR_STRLEN_LARGE]; int pret, differ; corrfn = testDataPathPrefix("test/probeSclAns.nrrd"); airMopAdd(mop, corrfn, airFree, airMopAlways); ncorr = nrrdNew(); airMopAdd(mop, ncorr, (airMopper)nrrdNuke, airMopAlways); if (nrrdLoad(ncorr, corrfn, NULL)) { char *err; airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: trouble reading data \"%s\":\n%s", me, corrfn, err); airMopError(mop); return 1; } for (ii=0; ii<POS_NUM/2; ii++) { xp[ii] = yp[ii] = zp[ii] = offs[ii]; xp[POS_NUM-1-ii] = AIR_CAST(double, sx)-1.0-offs[ii]; yp[POS_NUM-1-ii] = AIR_CAST(double, sy)-1.0-offs[ii]; zp[POS_NUM-1-ii] = AIR_CAST(double, sz)-1.0-offs[ii]; } for (kk=0; kk<POS_NUM; kk++) { for (jj=0; jj<POS_NUM; jj++) { for (ii=0; ii<POS_NUM; ii++) { ELL_3V_SET(pos[ii + POS_NUM*(jj + POS_NUM*kk)], xp[ii], yp[jj], zp[kk]); } } } nprbd = nrrdNew(); airMopAdd(mop, nprbd, (airMopper)nrrdNuke, airMopAlways); if (nrrdMaybeAlloc_va(nprbd, nrrdTypeDouble, 3, AIR_CAST(size_t, qlen), AIR_CAST(size_t, BLUR_KERN_NUM), AIR_CAST(size_t, POS_NUM*POS_NUM*POS_NUM))) { char *err; airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: trouble setting up prbd:\n%s", me, err); airMopError(mop); return 1; } prbd = AIR_CAST(double *, nprbd->data); for (ii=0; ii<POS_NUM*POS_NUM*POS_NUM; ii++) { for (ki=0; ki<BLUR_KERN_NUM; ki++) { pret = gageProbeSpace(bgctx[ki], pos[ii][0], pos[ii][1], pos[ii][2], AIR_TRUE /* indexSpace */, AIR_FALSE /* clamp */); if (pret) { fprintf(stderr, "%s: %s probe error(%d): %s\n", me, bkern[ki]->name, bgctx[ki]->errNum, bgctx[ki]->errStr); airMopError(mop); return 1; } prbd[0 + qlen*(ki + BLUR_KERN_NUM*(ii))] = bvalAns[ki][0]; ELL_3V_COPY(prbd + 1 + qlen*(ki + BLUR_KERN_NUM*(ii)), bgrdAns[ki]); ELL_9V_COPY(prbd + 4 + qlen*(ki + BLUR_KERN_NUM*(ii)), bhesAns[ki]); } } /* HEY: weirdly, so far its only on Windows (and more than 10 times worse on Cygwin) this epsilon needs to be larger than zero, and only for the radius 6 Gaussian? */ if (nrrdCompare(ncorr, nprbd, AIR_FALSE /* onlyData */, 8.0e-14 /* epsilon */, &differ, explain)) { char *err; airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: trouble comparing:\n%s", me, err); airMopError(mop); return 1; } if (differ) { fprintf(stderr, "%s: probed values not correct: %s\n", me, explain); airMopError(mop); return 1; } else { fprintf(stderr, "all good\n"); } } airMopOkay(mop); return 0; }
int main() { char *tmp, *s1, *s2; biffMsg *msg1, *msg2; /* biffAdd("axis", "the first error axis"); biffAdd("axis", "the second error axis"); biffAdd("axis", "the third error axis"); biffAdd("chard", "the first error chard"); biffAdd("chard", "the second error chard"); biffAdd("chard", "the third error chard"); biffAdd("bingo", "zero-eth bingo message"); biffMove("bingo", NULL, "chard"); biffAdd("bingo", "the first error bingo"); biffAdd("bingo", "the second bll boo boo boo error bingo"); biffAdd("bingo", "the third error bingo"); printf("%s\n", (tmp = biffGet("bingo"))); free(tmp); biffDone("bingo"); printf("%s\n", (tmp = biffGet("chard"))); free(tmp); biffDone("chard"); printf("%s\n", (tmp = biffGet("axis"))); free(tmp); biffDone("axis"); biffAdd("harold", "the first error harold"); biffAdd("harold", "the second error harold"); biffAdd("harold", "the third error harold"); printf("%s\n", (tmp = biffGet("harold"))); free(tmp); */ biffAdd("axis", "the first error axis"); biffAdd("axis", "the second error axis"); biffAdd("axis", "the third error axis"); biffAdd("axis", "the fourth error axis"); biffAdd("axis", "the fifth error axis"); printf("%s", (tmp = biffGet("axis"))); free(tmp); biffDone("axis"); biffAdd("axo", "the first error axis"); biffAdd("axo", "the second error axis"); biffAdd("axo", "the third error axis"); biffAdd("axo", "the fourth error axis"); biffAdd("axo", "the fifth error axis"); printf("%s", (tmp = biffGetDone("axo"))); free(tmp); printf("=================================\n"); msg1 = biffMsgNew("roberts"); biffMsgAdd(msg1, "biffMsgAdd hello, said roberts"); biffMsgAddf(msg1, "biffMsgAddf: there's an int %d and a float %g", 42, AIR_PI); s1 = biffMsgStrGet(msg1); printf("from msg1:\n%s", s1); s1 = airFree(s1); msg2 = biffMsgNew("sue"); biffMsgAdd(msg2, "biffMsgAdd hi from sue"); biffMsgAddf(msg2, "biffMsgAddf: another float %g", AIR_PI*AIR_PI); s2 = biffMsgStrGet(msg2); printf("from msg2:\n%s", s2); s2 = airFree(s2); biffMsgMovef(msg1, msg2, "biffMsgMovef: good int %d", 10); s1 = biffMsgStrGet(msg1); printf("from msg1:\n%s", s1); s1 = airFree(s1); printf("=================================\n"); msg1 = biffMsgNix(msg1); msg2 = biffMsgNix(msg2); /* biffAddf("test", "%s: this is a test %d %f", "me", 1, 2.0); printf("%s\n", (tmp = biffGet("test"))); free(tmp); biffDone("test"); */ exit(0); }
int main(int argc, char **argv) { int i, ret; char *me, *argv0 = NULL, *err; hestParm *hparm; airArray *mop; me = argv[0]; /* parse environment variables first, in case they break nrrdDefault* or nrrdState* variables in a way that nrrdSanity() should see */ nrrdDefaultGetenv(); nrrdStateGetenv(); /* if user hasn't tried to set nrrdStateKindNoop by an environment variable, we set it to false, since its probably what people expect */ if (!getenv("NRRD_STATE_KIND_NOOP")) { nrrdStateKindNoop = AIR_FALSE; } /* 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, (airMopper)hestParmFree, airMopAlways); hparm->elideSingleEnumType = AIR_TRUE; hparm->elideSingleOtherType = AIR_TRUE; hparm->elideSingleOtherDefault = AIR_TRUE; hparm->elideSingleNonExistFloatDefault = AIR_TRUE; hparm->elideMultipleNonExistFloatDefault = AIR_TRUE; hparm->elideSingleEmptyStringDefault = AIR_TRUE; hparm->elideMultipleEmptyStringDefault = AIR_TRUE; hparm->columns = unrrduDefNumColumns; /* if there are no arguments, then we give general usage information */ if (1 >= argc) { unrrduUsage("unu", hparm); airMopError(mop); exit(1); } /* else, we should see if they're asking for a command we know about */ for (i=0; unrrduCmdList[i]; i++) { if (!strcmp(argv[1], unrrduCmdList[i]->name)) break; } /* unrrduCmdList[] is NULL-terminated */ if (unrrduCmdList[i]) { /* yes, we have that command */ /* initialize variables used by the various commands */ argv0 = (char *)calloc(strlen(UNU) + strlen(argv[1]) + 2, sizeof(char)); airMopMem(mop, &argv0, airMopAlways); sprintf(argv0, "%s %s", UNU, argv[1]); /* run the individual unu program, saving its exit status */ ret = unrrduCmdList[i]->main(argc-2, argv+2, argv0, hparm); } else { fprintf(stderr, "%s: unrecognized command: \"%s\"; type \"%s\" for " "complete list\n", me, argv[1], me); ret = 1; } airMopDone(mop, ret); return ret; }