Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
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));
  }
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 4
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;
}