int unrrdu_lut2Main(int argc, char **argv, char *me, hestParm *hparm) { hestOpt *opt = NULL; char *out, *err; Nrrd *nin, *nlut, *nout, *ntmp[2]; airArray *mop; int typeOut, rescale[2], pret, blind8BitRange; double min[2], max[2]; NrrdRange *range[2]={NULL,NULL}; unsigned int mapAxis, rai; hestOptAdd(&opt, "m,map", "lut", airTypeOther, 1, 1, &nlut, NULL, "lookup table to map input nrrd through", NULL, NULL, nrrdHestNrrd); hestOptAdd(&opt, "r,rescale", "bool bool", airTypeBool, 2, 2, rescale, "false false", "rescale one or both of 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", "min0 min1", airTypeDouble, 2, 2, min, "nan nan", "Low ends of input range. Defaults to lowest values " "found in input nrrd. Explicitly setting this is useful " "only with rescaling (\"-r\")"); hestOptAdd(&opt, "max,maximum", "max0 max1", airTypeDouble, 2, 2, max, "nan nan", "High end of input range. Defaults to highest values " "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_lut2InfoL); PARSE(); airMopAdd(mop, opt, (airMopper)hestParseFree, airMopAlways); nout = nrrdNew(); airMopAdd(mop, nout, (airMopper)nrrdNuke, airMopAlways); if (!( nin->dim > 1 && 2 == nin->axis[0].size )) { fprintf(stderr, "%s: input nrrd dim must be > 1, and axis[0].size " "must be 2 (not " _AIR_SIZE_T_CNV ")", me, nin->axis[0].size); airMopError(mop); return 1; } mapAxis = nlut->dim - 2; if (!(0 == mapAxis || 1 == mapAxis)) { fprintf(stderr, "%s: dimension of lut should be 2 or 3, not %d", me, nlut->dim); airMopError(mop); return 1; } /* see comment in rmap.c */ for (rai=0; rai<=1; rai++) { if (!( AIR_EXISTS(nlut->axis[mapAxis + rai].min) && AIR_EXISTS(nlut->axis[mapAxis + rai].max) )) { rescale[rai] = AIR_TRUE; } if (rescale[rai]) { ntmp[rai] = nrrdNew(); airMopAdd(mop, ntmp[rai], AIR_CAST(airMopper, nrrdNuke), airMopAlways); if (nrrdSlice(ntmp[rai], nin, 0, rai)) { airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: trouble slicing input value %u:\n%s", me, rai, err); airMopError(mop); return 1; } range[rai] = nrrdRangeNew(min[rai], max[rai]); airMopAdd(mop, range[rai], (airMopper)nrrdRangeNix, airMopAlways); nrrdRangeSafeSet(range[rai], ntmp[rai], blind8BitRange); } } if (nrrdTypeDefault == typeOut) { typeOut = nlut->type; } if (nrrdApply2DLut(nout, nin, 0, range[0], range[1], nlut, typeOut, rescale[0], rescale[1])) { airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: trouble applying 2-D 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 *outTenS, *outCovarS, *outRmvS; int seed, E; unsigned int NN; Nrrd *_ninTen, *ninTen, *ngrad, *_ninB0, *ninB0, *nmask, *noutCovar, *noutTen, *noutRmv, *ntbuff; float sigma, bval; size_t sizeX, sizeY, sizeZ; tenEstimateContext *tec; int axmap[NRRD_DIM_MAX], randrot; mop = airMopNew(); me = argv[0]; hestOptAdd(&hopt, "i", "ten", airTypeOther, 1, 1, &_ninTen, NULL, "input tensor volume", NULL, NULL, nrrdHestNrrd); hestOptAdd(&hopt, "n", "#sim", airTypeUInt, 1, 1, &NN, "100", "number of simulations to run"); hestOptAdd(&hopt, "seed", "seed", airTypeInt, 1, 1, &seed, "42", "seed value for RNG which creates noise"); hestOptAdd(&hopt, "r", "reference field", airTypeOther, 1, 1, &_ninB0, NULL, "reference anatomical scan, with no diffusion weighting", NULL, NULL, nrrdHestNrrd); hestOptAdd(&hopt, "rr", NULL, airTypeOther, 0, 0, &randrot, NULL, "randomize gradient set orientation"); hestOptAdd(&hopt, "g", "grad list", airTypeOther, 1, 1, &ngrad, "", "gradient list, one row per diffusion-weighted image", NULL, NULL, nrrdHestNrrd); hestOptAdd(&hopt, "b", "b", airTypeFloat, 1, 1, &bval, "1000", "b value for simulated scan"); hestOptAdd(&hopt, "sigma", "sigma", airTypeFloat, 1, 1, &sigma, "0.0", "Rician noise parameter"); hestOptAdd(&hopt, "ot", "filename", airTypeString, 1, 1, &outTenS, "tout.nrrd", "file to write output tensor nrrd to"); hestOptAdd(&hopt, "oc", "filename", airTypeString, 1, 1, &outCovarS, "cout.nrrd", "file to write output covariance nrrd to"); hestOptAdd(&hopt, "or", "filename", airTypeString, 1, 1, &outRmvS, "rout.nrrd", "file to write output R_i means, variances to"); 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 (tenGradientCheck(ngrad, nrrdTypeDefault, 7)) { airMopAdd(mop, err = biffGetDone(TEN), airFree, airMopAlways); fprintf(stderr, "%s: problem with gradient list:\n%s\n", me, err); airMopError(mop); return 1; } if (tenTensorCheck(_ninTen, nrrdTypeDefault, AIR_TRUE, AIR_TRUE)) { airMopAdd(mop, err = biffGetDone(TEN), airFree, airMopAlways); fprintf(stderr, "%s: didn't like input:\n%s\n", me, err); airMopError(mop); return 1; } sizeX = _ninTen->axis[1].size; sizeY = _ninTen->axis[2].size; sizeZ = _ninTen->axis[3].size; if (!(3 == _ninB0->dim && sizeX == _ninB0->axis[0].size && sizeY == _ninB0->axis[1].size && sizeZ == _ninB0->axis[2].size)) { fprintf(stderr, "%s: given B0 (%u-D) volume not 3-D " _AIR_SIZE_T_CNV "x" _AIR_SIZE_T_CNV "x" _AIR_SIZE_T_CNV, me, _ninB0->dim, sizeX, sizeY, sizeZ); airMopError(mop); return 1; } ninTen = nrrdNew(); airMopAdd(mop, ninTen, (airMopper)nrrdNuke, airMopOnError); nmask = nrrdNew(); airMopAdd(mop, nmask, (airMopper)nrrdNuke, airMopOnError); ninB0 = nrrdNew(); airMopAdd(mop, ninB0, (airMopper)nrrdNuke, airMopOnError); noutCovar = nrrdNew(); airMopAdd(mop, noutCovar, (airMopper)nrrdNuke, airMopOnError); noutTen = nrrdNew(); airMopAdd(mop, noutTen, (airMopper)nrrdNuke, airMopOnError); noutRmv = nrrdNew(); airMopAdd(mop, noutRmv, (airMopper)nrrdNuke, airMopOnError); ntbuff = nrrdNew(); airMopAdd(mop, ntbuff, (airMopper)nrrdNuke, airMopOnError); if (nrrdConvert(ninTen, _ninTen, nrrdTypeDouble) || nrrdSlice(nmask, ninTen, 0, 0) || nrrdConvert(ninB0, _ninB0, nrrdTypeDouble) || nrrdMaybeAlloc_va(noutTen, nrrdTypeDouble, 4, AIR_CAST(size_t, 7), sizeX, sizeY, sizeZ) || nrrdMaybeAlloc_va(noutCovar, nrrdTypeDouble, 4, AIR_CAST(size_t, 21), sizeX, sizeY, sizeZ) || nrrdMaybeAlloc_va(noutRmv, nrrdTypeDouble, 4, AIR_CAST(size_t, 6), sizeX, sizeY, sizeZ) || nrrdMaybeAlloc_va(ntbuff, nrrdTypeDouble, 2, AIR_CAST(size_t, 7), NN)) { airMopAdd(mop, err=biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: trouble setting up tec:\n%s\n", me, err); airMopError(mop); return 1; } tec = tenEstimateContextNew(); airMopAdd(mop, tec, (airMopper)tenEstimateContextNix, airMopAlways); E = 0; if (!E) E |= tenEstimateMethodSet(tec, tenEstimate1MethodLLS); if (!E) E |= tenEstimateValueMinSet(tec, 0.000000001); if (!E) E |= tenEstimateGradientsSet(tec, ngrad, bval, AIR_TRUE); if (!E) E |= tenEstimateThresholdSet(tec, 0, 0); if (!E) E |= tenEstimateUpdate(tec); if (E) { airMopAdd(mop, err=biffGetDone(TEN), airFree, airMopAlways); fprintf(stderr, "%s: trouble setting up tec:\n%s\n", me, err); airMopError(mop); return 1; } airSrandMT(seed); fprintf(stderr, "!%s: randrot = %d\n", me, randrot); if (1) { unsigned int II; unsigned int nsamp; double *inTen, *outTen, *outCovar, *outRmv, *dwibuff, (*lup)(const void *, size_t); char doneStr[AIR_STRLEN_SMALL]; dwibuff = AIR_CAST(double *, calloc(ngrad->axis[1].size, sizeof(double))); airMopAdd(mop, dwibuff, airFree, airMopAlways); nsamp = sizeX*sizeY*sizeZ; inTen = AIR_CAST(double *, ninTen->data); lup = nrrdDLookup[nrrdTypeDouble]; outTen = AIR_CAST(double *, noutTen->data); outCovar = AIR_CAST(double *, noutCovar->data); outRmv = AIR_CAST(double *, noutRmv->data); fprintf(stderr, "!%s: simulating ... ", me); fflush(stderr); for (II=0; II<nsamp; II++) { if (!(II % sizeX)) { fprintf(stderr, "%s", airDoneStr(0, II, nsamp, doneStr)); fflush(stderr); } if (csimDo(outTen, outCovar, outRmv + 0, outRmv + 3, ntbuff, tec, dwibuff, sigma, bval, lup(ninB0->data, II), NN, randrot, inTen)) { airMopAdd(mop, err=biffGetDone(TEN), airFree, airMopAlways); fprintf(stderr, "%s: trouble:\n%s\n", me, err); airMopError(mop); return 1; } inTen += 7; outTen += 7; outCovar += 21; outRmv += 6; } fprintf(stderr, "%s\n", airDoneStr(0, II, nsamp, doneStr)); }
int main(int argc, const char *argv[]) { const char *me; hestOpt *hopt; hestParm *hparm; airArray *mop; char **ninStr, *err, *outS, doneStr[13]; Nrrd *nin0, *nin, *nrgb, *nout, *nhist[2], *npreout, *nhproj[3]; float *rgb; float *out, *preout, *hist[2], maxSum, upSample, overSampleScale; unsigned int size0, sX, sY, sH, ninLen, ti, overSampleNum; NrrdResampleContext *rsmc; NrrdKernelSpec *ksp; me = argv[0]; mop = airMopNew(); hopt = NULL; hparm = hestParmNew(); airMopAdd(mop, hparm, (airMopper)hestParmFree, airMopAlways); hparm->respFileEnable = AIR_TRUE; hestOptAdd(&hopt, "i", "images", airTypeString, 1, -1, &ninStr, NULL, "input image sequence", &ninLen, NULL, NULL); hestOptAdd(&hopt, "sh", "histo size", airTypeUInt, 1, 1, &sH, "500", "histogram size"); hestOptAdd(&hopt, "k", "kern", airTypeOther, 1, 1, &ksp, "tent", "kernel for upsampling images", NULL, NULL, nrrdHestKernelSpec); hestOptAdd(&hopt, "us", "upsampling", airTypeFloat, 1, 1, &upSample, "1", "amount of upsampling of image"); hestOptAdd(&hopt, "osn", "# oversmp", airTypeUInt, 1, 1, &overSampleNum, "1", "number of sample per (upsampled) pixel"); hestOptAdd(&hopt, "osc", "scaling", airTypeFloat, 1, 1, &overSampleScale, "1", "scaling with oversampling"); hestOptAdd(&hopt, "ms", "max sum", airTypeFloat, 1, 1, &maxSum, "10", "per-hue histogram summation is non-linearly and " "asymptotically clamped to this maximum"); hestOptAdd(&hopt, "o", "nout", airTypeString, 1, 1, &outS, "-", "output filename", NULL); hestParseOrDie(hopt, argc-1, argv+1, hparm, me, mchistInfo, AIR_TRUE, AIR_TRUE, AIR_TRUE); airMopAdd(mop, hopt, (airMopper)hestOptFree, airMopAlways); airMopAdd(mop, hopt, (airMopper)hestParseFree, airMopAlways); if (0 == overSampleNum) { fprintf(stderr, "%s: overSampleNum must be > 0\n", me); airMopError(mop); return 1; } nin0 = nrrdNew(); airMopAdd(mop, nin0, (airMopper)nrrdNuke, airMopAlways); if (nrrdLoad(nin0, ninStr[0], NULL)) { airMopAdd(mop, err=biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: couldn't load first image:\n%s", me, err); airMopError(mop); return 1; } if (!( (3 == nin0->axis[0].size || 4 == nin0->axis[0].size) && 3 == nin0->dim && nrrdTypeUChar == nin0->type )) { fprintf(stderr, "%s: 1st image not 3D (3-or-4)-by-X-by-Y %s array " "(got %u-D %s array)\n", me, airEnumStr(nrrdType, nrrdTypeUChar), nin0->dim, airEnumStr(nrrdType, nin0->type)); airMopError(mop); return 1; } rsmc = nrrdResampleContextNew(); airMopAdd(mop, rsmc, (airMopper)nrrdResampleContextNix, airMopAlways); size0 = AIR_CAST(unsigned int, nin0->axis[0].size); sX = AIR_CAST(unsigned int, upSample*nin0->axis[1].size); sY = AIR_CAST(unsigned int, upSample*nin0->axis[2].size); nrgb = nrrdNew(); airMopAdd(mop, nrgb, (airMopper)nrrdNuke, airMopAlways); if (nrrdResampleDefaultCenterSet(rsmc, nrrdCenterCell) || nrrdResampleInputSet(rsmc, nin0) || nrrdResampleKernelSet(rsmc, 1, ksp->kernel, ksp->parm) || nrrdResampleKernelSet(rsmc, 2, ksp->kernel, ksp->parm) || nrrdResampleSamplesSet(rsmc, 1, sX) || nrrdResampleSamplesSet(rsmc, 2, sY) || nrrdResampleRangeFullSet(rsmc, 1) || nrrdResampleRangeFullSet(rsmc, 2) || nrrdResampleTypeOutSet(rsmc, nrrdTypeFloat) || nrrdResampleRenormalizeSet(rsmc, AIR_TRUE) || nrrdResampleExecute(rsmc, nrgb)) { airMopAdd(mop, err=biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: error resampling slice:\n%s", me, err); airMopError(mop); return 1; } nhist[0] = nrrdNew(); airMopAdd(mop, nhist[0], (airMopper)nrrdNuke, airMopAlways); nhist[1] = nrrdNew(); airMopAdd(mop, nhist[1], (airMopper)nrrdNuke, airMopAlways); if (nrrdMaybeAlloc_va(nhist[0], nrrdTypeFloat, 2, AIR_CAST(size_t, sH), AIR_CAST(size_t, sH)) || nrrdMaybeAlloc_va(nhist[1], nrrdTypeFloat, 2, AIR_CAST(size_t, sH), AIR_CAST(size_t, sH))) { airMopAdd(mop, err=biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: error allocating histos:\n%s", me, err); airMopError(mop); return 1; } nhist[0]->axis[0].min = nhist[0]->axis[1].min = 0.0; nhist[0]->axis[0].max = nhist[0]->axis[1].max = 1.0; nhist[1]->axis[0].min = nhist[1]->axis[1].min = 0.0; nhist[1]->axis[0].max = nhist[1]->axis[1].max = 1.0; nhproj[0] = nrrdNew(); airMopAdd(mop, nhproj[0], (airMopper)nrrdNix, airMopAlways); nhproj[1] = nrrdNew(); airMopAdd(mop, nhproj[1], (airMopper)nrrdNix, airMopAlways); nhproj[2] = nrrdNew(); airMopAdd(mop, nhproj[2], (airMopper)nrrdNix, airMopAlways); printf("working ... "); hist[0] = AIR_CAST(float *, nhist[0]->data); hist[1] = AIR_CAST(float *, nhist[1]->data); nin = nrrdNew(); airMopAdd(mop, nin, (airMopper)nrrdNuke, airMopAlways); npreout = nrrdNew(); airMopAdd(mop, npreout, (airMopper)nrrdNuke, airMopAlways); if (nrrdMaybeAlloc_va(npreout, nrrdTypeFloat, 3, AIR_CAST(size_t, 3), AIR_CAST(size_t, sH), AIR_CAST(size_t, ninLen))) { airMopAdd(mop, err=biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: error allocating pre-output:\n%s", me, err); airMopError(mop); return 1; } preout = AIR_CAST(float *, npreout->data); for (ti=0; ti<ninLen; ti++) { printf("%s", airDoneStr(0, ti, ninLen, doneStr)); fflush(stdout); if (nrrdLoad(nin, ninStr[ti], NULL)) { airMopAdd(mop, err=biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: couldn't load image[%u]:\n%s", me, ti, err); airMopError(mop); return 1; } if (!nrrdSameSize(nin0, nin, AIR_TRUE)) { airMopAdd(mop, err=biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: nin[%u] not like nin[0]:\n%s", me, ti, err); airMopError(mop); return 1; } if (nrrdResampleInputSet(rsmc, nin) || nrrdResampleExecute(rsmc, nrgb)) { airMopAdd(mop, err=biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: trouble resampling nin[%u]:\n%s", me, ti, err); airMopError(mop); return 1; } if (nrrdWrap_va(nhproj[0], preout + 0*sH, nrrdTypeFloat, 1, AIR_CAST(size_t, sH)) || nrrdWrap_va(nhproj[1], preout + 1*sH, nrrdTypeFloat, 1, AIR_CAST(size_t, sH)) || nrrdWrap_va(nhproj[2], preout + 2*sH, nrrdTypeFloat, 1, AIR_CAST(size_t, sH))) { airMopAdd(mop, err=biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: trouble wrapping output[%u]:\n%s", me, ti, err); airMopError(mop); return 1; } rgb = AIR_CAST(float *, nrgb->data); imageProc(nhproj, nhist, sH, rgb, size0, sX*sY, overSampleNum, overSampleScale); preout += 3*sH; } printf("%s\n", airDoneStr(0, ti, ninLen, doneStr)); fflush(stdout); nout = nrrdNew(); airMopAdd(mop, nout, (airMopper)nrrdNuke, airMopAlways); if (nrrdMaybeAlloc_va(nout, nrrdTypeFloat, 3, AIR_CAST(size_t, 3), AIR_CAST(size_t, sH), AIR_CAST(size_t, ninLen))) { airMopAdd(mop, err=biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: error allocating output:\n%s", me, err); airMopError(mop); return 1; } out = AIR_CAST(float *, nout->data); preout = AIR_CAST(float *, npreout->data); for (ti=0; ti<ninLen; ti++) { unsigned int hi; float hh, vv, ss, scl; for (hi=0; hi<sH; hi++) { hh = AIR_AFFINE(0, hi, sH, 0, 1); if (!preout[hi + 2*sH]) { ELL_3V_SET(out + 3*hi, 0, 0, 0); } else { ss = preout[hi + 2*sH]; scl = ss/(maxSum + ss); vv = scl*preout[hi + 1*sH]; dyeHSVtoRGB(out + 0 + 3*hi, out + 1 + 3*hi, out + 2 + 3*hi, hh, preout[hi + 0*sH], vv); } } out += 3*sH; preout += 3*sH; } if (nrrdSave(outS, nout, NULL)) { airMopAdd(mop, err=biffGetDone(NRRD), airFree, airMopAlways); fprintf(stderr, "%s: error saving output:\n%s", me, err); airMopError(mop); return 1; } airMopOkay(mop); return 0; }
int gageDeconvolve(Nrrd *_nout, double *lastDiffP, const Nrrd *nin, const gageKind *kind, const NrrdKernelSpec *ksp, int typeOut, unsigned int maxIter, int saveAnyway, double step, double epsilon, int verbose) { char me[]="gageDeconvolve", err[BIFF_STRLEN]; gageContext *ctx[2]; gagePerVolume *pvl[2]; double *out[2], *val[2], alpha, (*lup)(const void *, size_t), meandiff=0; const double *ans[2]; Nrrd *nout[2]; airArray *mop; unsigned int sx, sy, sz, xi, yi, zi, anslen, this, last, inIdx, iter; int E, valItem; if (!(_nout && lastDiffP && nin && kind && ksp)) { sprintf(err, "%s: got NULL pointer", me); biffAdd(GAGE, err); return 1; } if (!(nrrdTypeDefault == typeOut || !airEnumValCheck(nrrdType, typeOut))) { sprintf(err, "%s: typeOut %d not valid", me, typeOut); biffAdd(GAGE, err); return 1; } if (!( maxIter >= 1 )) { sprintf(err, "%s: need maxIter >= 1 (not %u)", me, maxIter); biffAdd(GAGE, err); return 1; } if (!( epsilon >= 0 )) { sprintf(err, "%s: need epsilon >= 0.0 (not %g)", me, epsilon); biffAdd(GAGE, err); return 1; } /* this once changed from 0 to 1, but is unlikely to change again */ valItem = 1; mop = airMopNew(); for (iter=0; iter<2; iter++) { nout[iter] = nrrdNew(); airMopAdd(mop, nout[iter], (airMopper)nrrdNuke, airMopAlways); if (nrrdConvert(nout[iter], nin, nrrdTypeDouble)) { sprintf(err, "%s: couldn't allocate working buffer %u", me, iter); biffMove(GAGE, err, NRRD); airMopError(mop); return 1; } ctx[iter] = gageContextNew(); airMopAdd(mop, ctx[iter], (airMopper)gageContextNix, airMopAlways); E = 0; if (!E) E |= !(pvl[iter] = gagePerVolumeNew(ctx[iter], nout[iter], kind)); if (!E) E |= gagePerVolumeAttach(ctx[iter], pvl[iter]); if (!E) E |= gageKernelSet(ctx[iter], gageKernel00, ksp->kernel, ksp->parm); if (!E) E |= gageQueryItemOn(ctx[iter], pvl[iter], valItem); if (!E) E |= gageUpdate(ctx[iter]); if (E) { sprintf(err, "%s: trouble setting up context %u", me, iter); biffAdd(GAGE, err); airMopError(mop); return 1; } out[iter] = AIR_CAST(double*, nout[iter]->data); ans[iter] = gageAnswerPointer(ctx[iter], pvl[iter], valItem); } anslen = kind->table[valItem].answerLength; lup = nrrdDLookup[nin->type]; alpha = ksp->kernel->eval1_d(0.0, ksp->parm); sx = ctx[0]->shape->size[0]; sy = ctx[0]->shape->size[1]; sz = ctx[0]->shape->size[2]; for (iter=0; iter<maxIter; iter++) { this = (iter+1) % 2; last = (iter+0) % 2; val[this] = out[this]; val[last] = out[last]; inIdx = 0; meandiff = 0; for (zi=0; zi<sz; zi++) { for (yi=0; yi<sy; yi++) { for (xi=0; xi<sx; xi++) { unsigned int ai; double in, aa; gageProbe(ctx[last], xi, yi, zi); for (ai=0; ai<anslen; ai++) { in = lup(nin->data, ai + anslen*inIdx); aa = ans[last][ai]; val[this][ai] = val[last][ai] + step*(in - aa)/alpha; meandiff += 2*(in - aa)*(in - aa)/(DBL_EPSILON + in*in + aa*aa); } val[this] += anslen; val[last] += anslen; ++inIdx; } } } meandiff /= sx*sy*sz; if (verbose) { fprintf(stderr, "%s: iter %u meandiff = %g\n", me, iter, meandiff); } if (meandiff < epsilon) { /* we have indeed converged while iter < maxIter */ break; } } if (iter == maxIter) { if (!saveAnyway) { sprintf(err, "%s: failed to converge in %u iterations, meandiff = %g", me, maxIter, meandiff); biffAdd(GAGE, err); airMopError(mop); return 1; } else { if (verbose) { fprintf(stderr, "%s: at maxIter %u; err %g still > thresh %g\n", me, iter, meandiff, epsilon); } } } if (nrrdClampConvert(_nout, nout[this], (nrrdTypeDefault == typeOut ? nin->type : typeOut))) { sprintf(err, "%s: couldn't create output", me); biffAdd(GAGE, err); airMopError(mop); return 1; } *lastDiffP = meandiff; airMopOkay(mop); return 0; }