int baneGkms_miteMain(int argc, char **argv, char *me, hestParm *hparm) { hestOpt *opt = NULL; char *out, *perr, err[BIFF_STRLEN]; Nrrd *nin, *nout; airArray *mop; int pret, E; hestOptAdd(&opt, "i", "opacIn", airTypeOther, 1, 1, &nin, NULL, "input opacity function (1 or 2 dimensional), from " "\"gkms opac\"", NULL, NULL, nrrdHestNrrd); hestOptAdd(&opt, "o", "opacOut", airTypeString, 1, 1, &out, NULL, "output opacity function filename"); mop = airMopNew(); airMopAdd(mop, opt, (airMopper)hestOptFree, airMopAlways); USAGE(_baneGkms_miteInfoL); PARSE(); airMopAdd(mop, opt, (airMopper)hestParseFree, airMopAlways); if (1 == nin->axis[0].size && nin->axis[0].label && !strcmp("A", nin->axis[0].label)) { fprintf(stderr, "%s: already\n", me); nout = nin; } else { nout = nrrdNew(); airMopAdd(mop, nout, (airMopper)nrrdNuke, airMopAlways); E = 0; if (!E) E |= nrrdAxesInsert(nout, nin, 0); if (!E) E |= !(nout->axis[0].label = airStrdup("A")); if (!E) E |= !(nout->axis[1].label = airStrdup("gage(v)")); if (3 == nout->dim) { if (!E) E |= !(nout->axis[2].label = airStrdup("gage(gm)")); } if (E) { sprintf(err, "%s: trouble modifying opacity function nrrd", me); biffMove(BANE, err, NRRD); airMopError(mop); return 1; } } if (nrrdSave(out, nout, NULL)) { sprintf(err, "%s: trouble saving opacity function", me); biffMove(BANE, err, NRRD); airMopError(mop); return 1; } airMopOkay(mop); return 0; }
int unrrdu_minmaxDoit(char *me, char *inS, int blind8BitRange, FILE *fout) { char err[BIFF_STRLEN]; Nrrd *nrrd; NrrdRange *range; airArray *mop; mop = airMopNew(); airMopAdd(mop, nrrd=nrrdNew(), (airMopper)nrrdNuke, airMopAlways); if (nrrdLoad(nrrd, inS, NULL)) { sprintf(err, "%s: trouble loading \"%s\"", me, inS); biffMove(me, err, NRRD); airMopError(mop); return 1; } range = nrrdRangeNewSet(nrrd, blind8BitRange); airMopAdd(mop, range, (airMopper)nrrdRangeNix, airMopAlways); airSinglePrintf(fout, NULL, "min: %g\n", range->min); airSinglePrintf(fout, NULL, "max: %g\n", range->max); if (0 == range->min && 0 == range->max) { fprintf(fout, "# min == max == 0.0 exactly\n"); } if (range->hasNonExist) { fprintf(fout, "# has non-existent values\n"); } airMopOkay(mop); return 0; }
int limnEnvMapCheck(Nrrd *envMap) { char me[]="limnEnvMapCheck", err[BIFF_STRLEN]; if (nrrdCheck(envMap)) { sprintf(err, "%s: basic nrrd validity check failed", me); biffMove(LIMN, err, NRRD); return 1; } if (!(nrrdTypeFloat == envMap->type)) { sprintf(err, "%s: type should be %s, not %s", me, airEnumStr(nrrdType, nrrdTypeFloat), airEnumStr(nrrdType, envMap->type)); biffAdd(LIMN, err); return 1; } if (!(3 == envMap->dim)) { sprintf(err, "%s: dimension should be 3, not %d", me, envMap->dim); biffAdd(LIMN, err); return 1; } if (!(3 == envMap->axis[0].size && 256 == envMap->axis[1].size && 256 == envMap->axis[2].size)) { sprintf(err, "%s: dimension should be 3x256x256, not " _AIR_SIZE_T_CNV "x" _AIR_SIZE_T_CNV "x" _AIR_SIZE_T_CNV, me, envMap->axis[0].size, envMap->axis[1].size, envMap->axis[2].size); biffAdd(LIMN, err); return 1; } return 0; }
int _pullContextCheck(pullContext *pctx) { char me[]="_pullContextCheck", err[BIFF_STRLEN]; unsigned int ii, sclvi; int gotIspec, gotConstr; if (!pctx) { sprintf(err, "%s: got NULL pointer", me); biffAdd(PULL, err); return 1; } if (pctx->npos) { if (nrrdCheck(pctx->npos)) { sprintf(err, "%s: got a broken npos", me); biffMove(PULL, err, NRRD); return 1; } if (!( 2 == pctx->npos->dim && 4 == pctx->npos->axis[0].size && (nrrdTypeDouble == pctx->npos->type || nrrdTypeFloat == pctx->npos->type) )) { sprintf(err, "%s: npos not a 2-D 4-by-N array of %s or %s" "(got %u-D %u-by-X of %s)", me, airEnumStr(nrrdType, nrrdTypeFloat), airEnumStr(nrrdType, nrrdTypeDouble), pctx->npos->dim, AIR_CAST(unsigned int, pctx->npos->axis[0].size), airEnumStr(nrrdType, pctx->npos->type)); biffAdd(PULL, err); return 1; } } else {
int limnSplineSample(Nrrd *nout, limnSpline *spline, double minT, size_t M, double maxT) { char me[]="limnSplineSample", err[BIFF_STRLEN]; airArray *mop; Nrrd *ntt; double *tt; size_t I; if (!(nout && spline)) { sprintf(err, "%s: got NULL pointer", me); biffAdd(LIMN, err); return 1; } mop = airMopNew(); airMopAdd(mop, ntt=nrrdNew(), (airMopper)nrrdNuke, airMopAlways); if (nrrdMaybeAlloc_va(ntt, nrrdTypeDouble, 1, M)) { sprintf(err, "%s: trouble allocating tmp nrrd", me); biffMove(LIMN, err, NRRD); airMopError(mop); return 1; } tt = (double*)(ntt->data); for (I=0; I<M; I++) { tt[I] = AIR_AFFINE(0, I, M-1, minT, maxT); } if (limnSplineNrrdEvaluate(nout, spline, ntt)) { sprintf(err, "%s: trouble", me); biffAdd(LIMN, err); airMopError(mop); return 1; } airMopOkay(mop); return 0; }
int mossImageAlloc (Nrrd *image, int type, int sx, int sy, int ncol) { char me[]="mossImageAlloc", err[BIFF_STRLEN]; int ret; if (!(image && AIR_IN_OP(nrrdTypeUnknown, type, nrrdTypeBlock) && sx > 0 && sy > 0 && ncol > 0)) { sprintf(err, "%s: got NULL pointer or bad args", me); biffAdd(MOSS, err); return 1; } if (1 == ncol) { ret = nrrdMaybeAlloc_va(image, type, 2, AIR_CAST(size_t, sx), AIR_CAST(size_t, sy)); } else { ret = nrrdMaybeAlloc_va(image, type, 3, AIR_CAST(size_t, ncol), AIR_CAST(size_t, sx), AIR_CAST(size_t, sy)); } if (ret) { sprintf(err, "%s: couldn't allocate image", me); biffMove(MOSS, err, NRRD); return 1; } return 0; }
int ninspect_proj(Nrrd *nout, Nrrd *nin, int axis, int smart, float amount) { char me[]="ninspect_proj", err[BIFF_STRLEN]; airArray *mop; Nrrd *ntmpA, *ntmpB, *nrgb[3]; int bins; if (!(nout && nin)) { sprintf(err, "%s: got NULL pointer", me); biffAdd(NINSPECT, err); return 1; } if (!( AIR_IN_CL(0, axis, 2) )) { sprintf(err, "%s: given axis %d outside valid range [0,1,2]", me, axis); biffAdd(NINSPECT, err); return 1; } /* allocate a bunch of nrrds to use as basically temp variables */ mop = airMopNew(); airMopAdd(mop, ntmpA = nrrdNew(), (airMopper)nrrdNuke, airMopAlways); airMopAdd(mop, ntmpB = nrrdNew(), (airMopper)nrrdNuke, airMopAlways); airMopAdd(mop, nrgb[0] = nrrdNew(), (airMopper)nrrdNuke, airMopAlways); airMopAdd(mop, nrgb[1] = nrrdNew(), (airMopper)nrrdNuke, airMopAlways); airMopAdd(mop, nrgb[2] = nrrdNew(), (airMopper)nrrdNuke, airMopAlways); /* these arguments to nrrdHistoEq will control its behavior */ bins = 3000; /* equalization will use a histogram with this many bins */ /* the following idiom is one way of handling the fact that any non-trivial nrrd call can fail, and if it does, then any subsequent nrrd calls should be avoided (to be perfectly safe), so that you can get the error message from biff. Because of the left-to-right ordering ensured for logical expressions, this will all be called in sequence until one of them has a non-zero return. If he had exception handling, we'd put all the nrrd calls in one "try" block. */ if (nrrdProject(ntmpA, nin, axis, nrrdMeasureSum, nrrdTypeDefault) || nrrdHistoEq(ntmpB, ntmpA, NULL, bins, smart, amount) || nrrdQuantize(nrgb[0], ntmpB, NULL, 8) || nrrdProject(ntmpA, nin, axis, nrrdMeasureVariance, nrrdTypeDefault) || nrrdHistoEq(ntmpB, ntmpA, NULL, bins, smart, amount) || nrrdQuantize(nrgb[1], ntmpB, NULL, 8) || nrrdProject(ntmpA, nin, axis, nrrdMeasureMax, nrrdTypeDefault) || nrrdQuantize(nrgb[2], ntmpA, NULL, 8) || nrrdJoin(nout, (const Nrrd**)nrgb, 3, 0, AIR_TRUE)) { sprintf(err, "%s: trouble with nrrd operations", me); biffMove(NINSPECT, err, NRRD); airMopError(mop); return 1; } airMopOkay(mop); return 0; }
int tkwbExpandImageInfo(tkwbSlide **slide) { char me[]="tkwbExpandImageInfo", err[BIFF_STRLEN], *image; Nrrd *nimg; int si, sx, sy, len; airArray *mop; mop = airMopNew(); nimg = nrrdNew(); airMopAdd(mop, nimg, (airMopper)nrrdNuke, airMopAlways); for (si=0; slide[si]; si++) { if (nrrdLoad(nimg, slide[si]->image, NULL)) { sprintf(err, "%s: trouble reading slide image \"%s\"", me, slide[si]->image); biffMove(TKWB, err, NRRD); airMopError(mop); return 1; } if (!nrrdFormatPNG->fitsInto(nimg, nrrdEncodingGzip, AIR_TRUE)) { sprintf(err, "%s: slide image \"%s\" doesn't seem to be an image", me, slide[si]->image); biffMove(TKWB, err, NRRD); airMopError(mop); return 1; } sx = nimg->axis[nimg->dim-2].size; sy = nimg->axis[nimg->dim-1].size; len = (strlen("<img width=xxxx height=xxxx src=\"\">") + strlen(slide[si]->image) + 1); image = (char *)calloc(len, sizeof(char)); sprintf(image, "<img width=%d height=%d src=\"%s\">", sx, sy, slide[si]->image); free(slide[si]->image); slide[si]->image = image; } airMopOkay(mop); return 0; }
int baneGkms_infoMain(int argc, char **argv, char *me, hestParm *hparm) { hestOpt *opt = NULL; char *outS, *perr, err[BIFF_STRLEN]; Nrrd *hvol, *nout; airArray *mop; int pret, one, measr; hestOptAdd(&opt, "m", "measr", airTypeEnum, 1, 1, &measr, "mean", "How to project along the 2nd derivative axis. Possibilities " "include:\n " "\b\bo \"mean\": average value\n " "\b\bo \"median\": value at 50th percentile\n " "\b\bo \"mode\": most common value\n " "\b\bo \"min\", \"max\": probably not useful", NULL, baneGkmsMeasr); hestOptAdd(&opt, "one", NULL, airTypeInt, 0, 0, &one, NULL, "Create 1-dimensional info file; default is 2-dimensional"); hestOptAdd(&opt, "i", "hvolIn", airTypeOther, 1, 1, &hvol, NULL, "input histogram volume (from \"gkms hvol\")", NULL, NULL, nrrdHestNrrd); hestOptAdd(&opt, "o", "infoOut", airTypeString, 1, 1, &outS, NULL, "output info file, used by \"gkms pvg\" and \"gkms opac\""); mop = airMopNew(); airMopAdd(mop, opt, (airMopper)hestOptFree, airMopAlways); USAGE(_baneGkms_infoInfoL); PARSE(); airMopAdd(mop, opt, (airMopper)hestParseFree, airMopAlways); nout = nrrdNew(); airMopAdd(mop, nout, (airMopper)nrrdNuke, airMopAlways); if (baneOpacInfo(nout, hvol, one ? 1 : 2, measr)) { sprintf(err, "%s: trouble distilling histogram info", me); biffAdd(BANE, err); airMopError(mop); return 1; } if (nrrdSave(outS, nout, NULL)) { sprintf(err, "%s: trouble saving info file", me); biffMove(BANE, err, NRRD); airMopError(mop); return 1; } airMopOkay(mop); return 0; }
/* ** _gageStandardPadder() ** ********************************************************* ** as of about Wed Apr 20 19:32:54 EDT 2005, this is moot ********************************************************* ** ** the usual/default padder used in gage, basically just a simple ** wrapper around nrrdPad_va(), but similar in spirit to nrrdSimplePad(). ** ** The "kind" is needed to learn the baseDim for this kind of volume. ** The "_info" pointer is ignored. ** ** Any padder used in gage must, if it generates biff errors, ** accumulate them under the GAGE key. This padder is a shining ** example of this. */ Nrrd * _gageStandardPadder(Nrrd *nin, gageKind *kind, int padding, gagePerVolume *pvl) { Nrrd *npad; char me[]="_gageStandardPadder", err[BIFF_STRLEN]; int i, baseDim; ptrdiff_t amin[NRRD_DIM_MAX], amax[NRRD_DIM_MAX]; AIR_UNUSED(pvl); if (!(nin && kind)) { sprintf(err, "%s: got NULL pointer", me); biffAdd(GAGE, err); return NULL; } baseDim = kind->baseDim; if (!( padding >= 0 )) { sprintf(err, "%s: given padding %d invalid", me, padding); biffAdd(GAGE, err); return NULL; } if (0 == padding) { /* we can use the original volume if we promise not to blow it away, see _gageStandardNixer() */ return nin; } else { npad = nrrdNew(); for (i=0; i<baseDim; i++) { amin[i] = 0; amax[i] = nin->axis[i].size - 1; } amin[0 + baseDim] = -padding; amin[1 + baseDim] = -padding; amin[2 + baseDim] = -padding; amax[0 + baseDim] = nin->axis[0 + baseDim].size - 1 + padding; amax[1 + baseDim] = nin->axis[1 + baseDim].size - 1 + padding; amax[2 + baseDim] = nin->axis[2 + baseDim].size - 1 + padding; if (nrrdPad_va(npad, nin, amin, amax, nrrdBoundaryBleed)) { sprintf(err, "%s: trouble padding input volume", me); biffMove(GAGE, err, NRRD); nrrdNuke(npad); return NULL; } } return npad; }
int alanUpdate(alanContext *actx) { char me[]="alanUpdate", err[BIFF_STRLEN]; int ret; if (_alanCheck(actx)) { sprintf(err, "%s: ", me); biffAdd(ALAN, err); return 1; } if (actx->_nlev[0] || actx->_nlev[0]) { sprintf(err, "%s: confusion: _nlev[0,1] already allocated?", me); biffAdd(ALAN, err); return 1; } actx->_nlev[0] = nrrdNew(); actx->_nlev[1] = nrrdNew(); actx->nparm = nrrdNew(); if (2 == actx->dim) { ret = (nrrdMaybeAlloc_va(actx->_nlev[0], alan_nt, 3, AIR_CAST(size_t, 2), AIR_CAST(size_t, actx->size[0]), AIR_CAST(size_t, actx->size[1])) || nrrdCopy(actx->_nlev[1], actx->_nlev[0]) || nrrdMaybeAlloc_va(actx->nparm, alan_nt, 3, AIR_CAST(size_t, 3), AIR_CAST(size_t, actx->size[0]), AIR_CAST(size_t, actx->size[1]))); } else { ret = (nrrdMaybeAlloc_va(actx->_nlev[0], alan_nt, 4, AIR_CAST(size_t, 2), AIR_CAST(size_t, actx->size[0]), AIR_CAST(size_t, actx->size[1]), AIR_CAST(size_t, actx->size[2])) || nrrdCopy(actx->_nlev[1], actx->_nlev[0]) || nrrdMaybeAlloc_va(actx->nparm, alan_nt, 4, AIR_CAST(size_t, 3), AIR_CAST(size_t, actx->size[0]), AIR_CAST(size_t, actx->size[1]), AIR_CAST(size_t, actx->size[2]))); } if (ret) { sprintf(err, "%s: trouble allocating buffers", me); biffMove(ALAN, err, NRRD); return 1; } return 0; }
int limnPolyDataSpiralTubeWrap(limnPolyData *pldOut, const limnPolyData *pldIn, unsigned int infoBitFlag, Nrrd *nvertmap, unsigned int tubeFacet, unsigned int endFacet, double radius) { char me[]="limnPolyDataSpiralTubeWrap", err[BIFF_STRLEN]; double *cost, *sint; unsigned int tubeVertNum = 0, tubeIndxNum = 0, primIdx, pi, *vertmap; unsigned int inVertTotalIdx = 0, outVertTotalIdx = 0, outIndxIdx = 0; int color; airArray *mop; if (!( pldOut && pldIn )) { sprintf(err, "%s: got NULL pointer", me); return 1; } if ((1 << limnPrimitiveLineStrip) != limnPolyDataPrimitiveTypes(pldIn)) { sprintf(err, "%s: sorry, can only handle %s primitives", me, airEnumStr(limnPrimitive, limnPrimitiveLineStrip)); biffAdd(LIMN, err); return 1; } for (primIdx=0; primIdx<pldIn->primNum; primIdx++) { tubeVertNum += tubeFacet*(2*endFacet + pldIn->icnt[primIdx]) + 1; tubeIndxNum += 2*tubeFacet*(2*endFacet + pldIn->icnt[primIdx] + 1)-2; } if (limnPolyDataAlloc(pldOut, /* sorry have to have normals, even if they weren't asked for, because currently they're used as part of vertex position calc */ (infoBitFlag | (1 << limnPolyDataInfoNorm)), tubeVertNum, tubeIndxNum, pldIn->primNum)) { sprintf(err, "%s: trouble allocating output", me); biffAdd(LIMN, err); return 1; } if (nvertmap) { if (nrrdMaybeAlloc_va(nvertmap, nrrdTypeUInt, 1, AIR_CAST(size_t, tubeVertNum))) { sprintf(err, "%s: trouble allocating vert map", me); biffMove(LIMN, err, NRRD); return 1; } vertmap = AIR_CAST(unsigned int *, nvertmap->data); } else {
int tenFiberKernelSet(tenFiberContext *tfx, const NrrdKernel *kern, const double parm[NRRD_KERNEL_PARMS_NUM]) { char me[]="tenFiberKernelSet", err[BIFF_STRLEN]; if (!(tfx && kern)) { sprintf(err, "%s: got NULL pointer", me); biffAdd(TEN, err); return 1; } nrrdKernelSpecSet(tfx->ksp, kern, parm); if (gageKernelSet(tfx->gtx, gageKernel00, tfx->ksp->kernel, tfx->ksp->parm)) { sprintf(err, "%s: problem setting kernel", me); biffMove(TEN, err, GAGE); return 1; } return 0; }
int tenFiberUpdate(tenFiberContext *tfx) { char me[]="tenFiberUpdate", err[BIFF_STRLEN]; if (!tfx) { sprintf(err, "%s: got NULL pointer", me); biffAdd(TEN, err); return 1; } if (tenFiberTypeUnknown == tfx->fiberType) { sprintf(err, "%s: fiber type not set", me); biffAdd(TEN, err); return 1; } if (!( AIR_IN_OP(tenFiberTypeUnknown, tfx->fiberType, tenFiberTypeLast) )) { sprintf(err, "%s: tfx->fiberType set to bogus value (%d)", me, tfx->fiberType); biffAdd(TEN, err); return 1; } if (tenFiberIntgUnknown == tfx->intg) { sprintf(err, "%s: integration type not set", me); biffAdd(TEN, err); return 1; } if (!( AIR_IN_OP(tenFiberIntgUnknown, tfx->intg, tenFiberIntgLast) )) { sprintf(err, "%s: tfx->intg set to bogus value (%d)", me, tfx->intg); biffAdd(TEN, err); return 1; } if (0 == tfx->stop) { sprintf(err, "%s: no fiber stopping criteria set", me); biffAdd(TEN, err); return 1; } if (gageQuerySet(tfx->gtx, tfx->pvl, tfx->query) || gageUpdate(tfx->gtx)) { sprintf(err, "%s: trouble with gage", me); biffMove(TEN, err, GAGE); return 1; } if (tfx->useDwi) { if (!(0 == tfx->ten2Which || 1 == tfx->ten2Which)) { sprintf(err, "%s: ten2Which must be 0 or 1 (not %u)", me, tfx->ten2Which); biffAdd(TEN, err); return 1; } } return 0; }
int mossImageCheck (Nrrd *image) { char me[]="mossImageCheck", err[BIFF_STRLEN]; if (nrrdCheck(image)) { sprintf(err, "%s: given nrrd invalid", me); biffMove(MOSS, err, NRRD); return 1; } if (!( (2 == image->dim || 3 == image->dim) && nrrdTypeBlock != image->type )) { sprintf(err, "%s: image has invalid dimension (%d) or type (%s)", me, image->dim, airEnumStr(nrrdType, image->type)); biffAdd(MOSS, err); return 1; } return 0; }
int limnSplineNrrdEvaluate(Nrrd *nout, limnSpline *spline, Nrrd *nin) { char me[]="limnSplineNrrdEvaluate", err[BIFF_STRLEN]; double tt, *out, (*lup)(const void *, size_t); int odim, infoSize; size_t I, M, size[NRRD_DIM_MAX+1]; if (!(nout && spline && nin)) { sprintf(err, "%s: got NULL pointer", me); biffAdd(LIMN, err); return 1; } if (limnSplineInfoScalar == spline->info) { nrrdAxisInfoGet_va(nin, nrrdAxisInfoSize, size); infoSize = 1; odim = nin->dim; } else { nrrdAxisInfoGet_va(nin, nrrdAxisInfoSize, size+1); infoSize = size[0] = limnSplineInfoSize[spline->info]; odim = 1 + nin->dim; } if (nrrdMaybeAlloc_nva(nout, nrrdTypeDouble, odim, size)) { sprintf(err, "%s: output allocation failed", me); biffMove(LIMN, err, NRRD); return 1; } lup = nrrdDLookup[nin->type]; out = (double*)(nout->data); M = nrrdElementNumber(nin); for (I=0; I<M; I++) { tt = lup(nin->data, I); limnSplineEvaluate(out, spline, tt); out += infoSize; } /* HEY: peripheral info copying? */ return 0; }
int baneInputCheck (Nrrd *nin, baneHVolParm *hvp) { char me[]="baneInputCheck", err[BIFF_STRLEN]; int i; if (nrrdCheck(nin)) { sprintf(err, "%s: basic nrrd validity check failed", me); biffMove(BANE, err, NRRD); return 1; } if (3 != nin->dim) { sprintf(err, "%s: need a 3-dimensional nrrd (not %d)", me, nin->dim); biffAdd(BANE, err); return 1; } if (nrrdTypeBlock == nin->type) { sprintf(err, "%s: can't operate on block type", me); biffAdd(BANE, err); return 1; } if (!( AIR_EXISTS(nin->axis[0].spacing) && nin->axis[0].spacing != 0 && AIR_EXISTS(nin->axis[1].spacing) && nin->axis[1].spacing != 0 && AIR_EXISTS(nin->axis[2].spacing) && nin->axis[2].spacing != 0 )) { sprintf(err, "%s: must have non-zero existant spacing for all 3 axes", me); biffAdd(BANE, err); return 1; } for (i=0; i<=2; i++) { if (_baneAxisCheck(hvp->axis + i)) { sprintf(err, "%s: trouble with axis %d", me, i); biffAdd(BANE, err); return 1; } } if (!hvp->clip) { sprintf(err, "%s: got NULL baneClip", me); biffAdd(BANE, err); return 1; } /* all okay */ return 0; }
/* ** so that you can see if a given volume will work as the given kind */ int gageKindVolumeCheck(const gageKind *kind, const Nrrd *nrrd) { char me[]="gageKindVolumeCheck", err[BIFF_STRLEN]; if (!(kind && nrrd)) { sprintf(err, "%s: got NULL pointer", me); biffAdd(GAGE, err); return 1; } if (nrrdCheck(nrrd)) { sprintf(err, "%s: problem with nrrd", me); biffMove(GAGE, err, NRRD); return 1; } if (!(nrrd->dim == 3 + kind->baseDim)) { sprintf(err, "%s: nrrd should be %u-D, not %u-D", me, 3 + kind->baseDim, nrrd->dim); biffAdd(GAGE, err); return 1; } if (nrrdTypeBlock == nrrd->type) { sprintf(err, "%s: can't handle %s-type volumes", me, airEnumStr(nrrdType, nrrdTypeBlock)); biffAdd(GAGE, err); return 1; } if (1 == kind->baseDim && (kind->valLen != nrrd->axis[0].size)) { sprintf(err, "%s: kind requires %u axis 0 values, not " _AIR_SIZE_T_CNV, me, kind->valLen, nrrd->axis[0].size); biffAdd(GAGE, err); return 1; } /* this eventually calls _gageShapeSet(), which, for purely historical reasons, does the brunt of the error checking, some of which is almost certainly redundant with checks above ... */ if (gageVolumeCheck(NULL, nrrd, kind)) { sprintf(err, "%s: trouble", me); biffAdd(GAGE, err); return 1; } return 0; }
int doit(Nrrd *nout, Nrrd *nin, int smart, float amount) { char me[]="doit", err[BIFF_STRLEN]; Nrrd *nproj[3]; airArray *mop; int axis, srl, sap, ssi, E, margin, which; size_t min[3]; if (!(nout && nin)) { sprintf(err, "%s: got NULL pointer", me); biffAdd(NINSPECT, err); return 1; } if (!(3 == nin->dim)) { sprintf(err, "%s: given nrrd has dimension %d, not 3\n", me, nin->dim); biffAdd(NINSPECT, err); return 1; } mop = airMopNew(); airMopAdd(mop, nproj[0]=nrrdNew(), (airMopper)nrrdNuke, airMopAlways); airMopAdd(mop, nproj[1]=nrrdNew(), (airMopper)nrrdNuke, airMopAlways); airMopAdd(mop, nproj[2]=nrrdNew(), (airMopper)nrrdNuke, airMopAlways); /* how much space to put between and around the projections */ margin = 6; /* do projections for each axis, with some progress indication to sterr */ for (axis=0; axis<=2; axis++) { fprintf(stderr, "%s: doing axis %d projections ... ", me, axis); fflush(stderr); if (ninspect_proj(nproj[axis], nin, axis, smart, amount)) { fprintf(stderr, "ERROR\n"); sprintf(err, "%s: trouble doing projections for axis %d", me, axis); biffAdd(NINSPECT, err); airMopError(mop); return 1; } fprintf(stderr, "done\n"); } if (nrrdSpaceRightAnteriorSuperior == nin->space) { if (fixproj(nproj, nin)) { fprintf(stderr, "ERROR\n"); sprintf(err, "%s: trouble orienting projections", me); biffAdd(NINSPECT, err); airMopError(mop); return 1; } } srl = nproj[1]->axis[0+1].size; sap = nproj[0]->axis[0+1].size; ssi = nproj[1]->axis[1+1].size; /* allocate output as 8-bit color image. We know output type is nrrdTypeUChar because ninspect_proj finishes each projection with nrrdQuantize to 8-bits */ if (nrrdMaybeAlloc_va(nout, nrrdTypeUChar, 3, AIR_CAST(size_t, 3), AIR_CAST(size_t, srl + 3*margin + sap), AIR_CAST(size_t, ssi + 3*margin + sap))) { sprintf(err, "%s: couldn't allocate output", me); biffMove(NINSPECT, err, NRRD); airMopError(mop); return 1; } min[0] = 0; E = 0; which = 0; if (!E) { min[1] = margin; min[2] = margin; which = 1; } if (!E) E |= nrrdInset(nout, nout, nproj[1], min); if (!E) { min[1] = margin; min[2] = 2*margin + ssi; which = 2; } if (!E) E |= nrrdInset(nout, nout, nproj[2], min); if (!E) { min[1] = 2*margin + srl; min[2] = margin; which = 3; } if (!E) E |= nrrdInset(nout, nout, nproj[0], min); if (E) { sprintf(err, "%s: couldn't composite output (which = %d)", me, which); biffMove(NINSPECT, err, NRRD); airMopError(mop); return 1; } airMopOkay(mop); return 0; }
/* ** used to set all the fields of pullVolume at once, including the ** gageContext inside the pullVolume ** ** used both for top-level volumes in the pullContext (pctx->vol[i]) ** in which case pctx is non-NULL, ** and for the per-task volumes (task->vol[i]), ** in which case pctx is NULL */ int _pullVolumeSet(pullContext *pctx, pullVolume *vol, char *name, const Nrrd *ninSingle, const Nrrd *const *ninScale, double *scalePos, unsigned int ninNum, const gageKind *kind, const NrrdKernelSpec *ksp00, const NrrdKernelSpec *ksp11, const NrrdKernelSpec *ksp22, const NrrdKernelSpec *kspSS) { char me[]="_pullVolumeSet", err[BIFF_STRLEN]; int E; unsigned int vi; if (!( vol && (ninSingle || ninScale) && kind && airStrlen(name) && ksp00 && ksp11 && ksp22 )) { sprintf(err, "%s: got NULL pointer", me); biffAdd(PULL, err); return 1; } if (pctx) { for (vi=0; vi<pctx->volNum; vi++) { if (pctx->vol[vi] == vol) { sprintf(err, "%s: already got vol %p as vol[%u]", me, vol, vi); biffAdd(PULL, err); return 1; } } } if (ninScale && !scalePos) { sprintf(err, "%s: need scalePos array if using scale-space", me); biffAdd(PULL, err); return 1; } if (ninScale && !(ninNum >= 2)) { sprintf(err, "%s: need at least 2 volumes (not %u)", me, ninNum); biffAdd(PULL, err); return 1; } if (!(vol->gctx)) { sprintf(err, "%s: got NULL vol->gageContext", me); biffAdd(PULL, err); return 1; } gageParmSet(vol->gctx, gageParmRequireAllSpacings, AIR_TRUE); gageParmSet(vol->gctx, gageParmRenormalize, AIR_FALSE); gageParmSet(vol->gctx, gageParmCheckIntegrals, AIR_TRUE); E = 0; if (!E) E |= !(vol->gpvl = gagePerVolumeNew(vol->gctx, (ninSingle ? ninSingle : ninScale[0]), kind)); if (!E) E |= gageKernelSet(vol->gctx, gageKernel00, ksp00->kernel, ksp00->parm); if (!E) E |= gageKernelSet(vol->gctx, gageKernel11, ksp11->kernel, ksp11->parm); if (!E) E |= gageKernelSet(vol->gctx, gageKernel22, ksp22->kernel, ksp22->parm); if (ninScale) { gagePerVolume **pvlSS; if (!kspSS) { sprintf(err, "%s: got NULL kspSS", me); biffAdd(PULL, err); return 1; } gageParmSet(vol->gctx, gageParmStackUse, AIR_TRUE); gageParmSet(vol->gctx, gageParmStackRenormalize, AIR_TRUE); if (!E) E |= gageStackPerVolumeNew(vol->gctx, &pvlSS, ninScale, ninNum, kind); if (!E) E |= gageStackPerVolumeAttach(vol->gctx, vol->gpvl, pvlSS, scalePos, ninNum); if (!E) E |= gageKernelSet(vol->gctx, gageKernelStack, kspSS->kernel, kspSS->parm); } else { if (!E) E |= gagePerVolumeAttach(vol->gctx, vol->gpvl); } if (E) { sprintf(err, "%s: trouble", me); biffMove(PULL, err, GAGE); return 1; } vol->name = airStrdup(name); if (!vol->name) { sprintf(err, "%s: couldn't strdup name (len %u)", me, AIR_CAST(unsigned int, airStrlen(name))); biffAdd(PULL, err); return 1; }
int baneGkms_scatMain(int argc, char **argv, char *me, hestParm *hparm) { hestOpt *opt = NULL; char *out[2], *perr, err[BIFF_STRLEN]; Nrrd *hvol, *nvgRaw, *nvhRaw, *nvgQuant, *nvhQuant; NrrdRange *vgRange, *vhRange; airArray *mop; int pret, E; double gamma; hestOptAdd(&opt, "g", "gamma", airTypeDouble, 1, 1, &gamma, "1.0", "gamma used to brighten/darken scatterplots. " "gamma > 1.0 brightens; gamma < 1.0 darkens. " "Negative gammas invert values (like in xv). "); hestOptAdd(&opt, "i", "hvolIn", airTypeOther, 1, 1, &hvol, NULL, "input histogram volume (from \"gkms hvol\")", NULL, NULL, nrrdHestNrrd); hestOptAdd(&opt, "o", "vgOut vhOut", airTypeString, 2, 2, out, NULL, "Filenames to use for two output scatterplots, (gradient " "magnitude versus value, and 2nd derivative versus value); " "can use PGM or PNG format"); mop = airMopNew(); airMopAdd(mop, opt, (airMopper)hestOptFree, airMopAlways); USAGE(_baneGkms_scatInfoL); PARSE(); airMopAdd(mop, opt, (airMopper)hestParseFree, airMopAlways); nvgRaw = nrrdNew(); nvhRaw = nrrdNew(); nvgQuant = nrrdNew(); nvhQuant = nrrdNew(); airMopAdd(mop, nvgRaw, (airMopper)nrrdNuke, airMopAlways); airMopAdd(mop, nvhRaw, (airMopper)nrrdNuke, airMopAlways); airMopAdd(mop, nvgQuant, (airMopper)nrrdNuke, airMopAlways); airMopAdd(mop, nvhQuant, (airMopper)nrrdNuke, airMopAlways); if (baneRawScatterplots(nvgRaw, nvhRaw, hvol, AIR_TRUE)) { sprintf(err, "%s: trouble creating raw scatterplots", me); biffAdd(BANE, err); airMopError(mop); return 1; } vgRange = nrrdRangeNewSet(nvgRaw, nrrdBlind8BitRangeFalse); vhRange = nrrdRangeNewSet(nvhRaw, nrrdBlind8BitRangeFalse); airMopAdd(mop, vgRange, (airMopper)nrrdRangeNix, airMopAlways); airMopAdd(mop, vhRange, (airMopper)nrrdRangeNix, airMopAlways); E = 0; if (!E) E |= nrrdArithGamma(nvgRaw, nvgRaw, vgRange, gamma); if (!E) E |= nrrdArithGamma(nvhRaw, nvhRaw, vhRange, gamma); if (!E) E |= nrrdQuantize(nvgQuant, nvgRaw, vgRange, 8); if (!E) E |= nrrdQuantize(nvhQuant, nvhRaw, vhRange, 8); if (E) { sprintf(err, "%s: trouble doing gamma or quantization", me); biffMove(BANE, err, NRRD); airMopError(mop); return 1; } if (!E) E |= nrrdSave(out[0], nvgQuant, NULL); if (!E) E |= nrrdSave(out[1], nvhQuant, NULL); if (E) { sprintf(err, "%s: trouble saving scatterplot images", me); biffMove(BANE, err, NRRD); airMopError(mop); return 1; } airMopOkay(mop); return 0; }
int baneRawScatterplots(Nrrd *nvg, Nrrd *nvh, Nrrd *hvol, int histEq) { Nrrd *gA, *hA, *gB, *hB; char me[]="baneRawScatterplots", err[BIFF_STRLEN]; int E; if (!( nvg && nvh && hvol )) { sprintf(err, "%s: got NULL pointer", me); biffAdd(BANE, err); return 1; } if (baneHVolCheck(hvol)) { sprintf(err, "%s: didn't get a valid histogram volume", me); biffAdd(BANE, err); return 1; } gA = nrrdNew(); gB = nrrdNew(); hA = nrrdNew(); hB = nrrdNew(); /* create initial projections */ E = 0; if (!E) E |= nrrdProject(gA, hvol, 1, nrrdMeasureSum, nrrdTypeDefault); if (!E) E |= nrrdProject(hA, hvol, 0, nrrdMeasureSum, nrrdTypeDefault); if (E) { sprintf(err, "%s: trouble creating raw scatterplots", me); biffMove(BANE, err, NRRD); return 1; } /* do histogram equalization on them */ if (histEq) { if (!E) E |= nrrdHistoEq(gB, gA, NULL, baneStateHistEqBins, baneStateHistEqSmart, 1.0); if (!E) E |= nrrdHistoEq(hB, hA, NULL, baneStateHistEqBins, baneStateHistEqSmart, 1.0); } else { if (!E) E |= nrrdCopy(gB, gA); if (!E) E |= nrrdCopy(hB, hA); } if (E) { sprintf(err, "%s: couldn't histogram equalize or copy", me); biffMove(BANE, err, NRRD); return 1; } /* re-orient them so they look correct on the screen */ if (!E) E |= nrrdAxesSwap(gA, gB, 0, 1); if (!E) E |= nrrdAxesSwap(hA, hB, 0, 1); if (!E) E |= nrrdFlip(gB, gA, 1); if (!E) E |= nrrdFlip(hB, hA, 1); if (E) { sprintf(err, "%s: couldn't re-orient scatterplots", me); biffMove(BANE, err, NRRD); return 1; } if (!E) E |= nrrdCopy(nvg, gB); if (!E) E |= nrrdCopy(nvh, hB); if (E) { sprintf(err, "%s: trouble saving results to given nrrds", me); biffMove(BANE, err, NRRD); return 1; } nrrdNuke(gA); nrrdNuke(gB); nrrdNuke(hA); nrrdNuke(hB); return 0; }
int main(int argc, const char *argv[]) { const char *me; char *tmp; airArray *mop; AIR_UNUSED(argc); me = argv[0]; mop = airMopNew(); /* HEY: the creation and comparison of these strings is not very flexible, especially the hard-coded "good[]" strings */ biffAdd("axis", "the first error axis"); biffAdd("chard", "the first error chard"); biffAdd("chard", "the second error chard"); biffAdd("axis", "the second error axis"); 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"); biffAdd("axis", "the third error axis"); { char good[] = ("[bingo] the third error bingo\n" "[bingo] the second bll boo boo boo error bingo\n" "[bingo] the first error bingo\n" "[bingo] [chard] the third error chard\n" "[bingo] [chard] the second error chard\n" "[bingo] [chard] the first error chard\n" "[bingo] zero-eth bingo message\n"); tmp = biffGet("bingo"); airMopAdd(mop, tmp, airFree, airMopAlways); /* an ugly macro */ #define COMPARE(N) \ airMopAdd(mop, tmp, airFree, airMopAlways); \ if (strcmp(tmp, good)) { \ fprintf(stderr, "%s: %d: #%s# != #%s#\n", me, N, tmp, good); \ airMopError(mop); \ exit(1); \ } COMPARE(1); } { char good[] = ""; tmp = biffGet("chard"); COMPARE(2); } { char good[] = ("[axis] the third error axis\n" "[axis] the second error axis\n" "[axis] the first error axis\n"); tmp = biffGet("axis"); COMPARE(3); } biffAdd("harold", "the first error harold"); biffAdd("harold", "the second error harold"); biffAdd("harold", "the third error harold"); { char good[] = ("[harold] the third error harold\n" "[harold] the second error harold\n" "[harold] the first error harold\n"); tmp = biffGetDone("harold"); COMPARE(4); } biffDone("bingo"); biffDone("axis"); biffDone("chard"); 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"); { char good[] = ("[axis] the fifth error axis\n" "[axis] the fourth error axis\n" "[axis] the third error axis\n" "[axis] the second error axis\n" "[axis] the first error axis\n"); tmp = biffGetDone("axis"); COMPARE(5); } biffAddf("test", "%s: this is a test of biffAddf %d %g", "me", 1, 4.2); { char good[] = "[test] me: this is a test of biffAddf 1 4.2\n"; tmp = biffGetDone("test"); COMPARE(6); } biffAddf("test2", "%s: this is a test of biffAddf %d %g", "me", 1, 4.2); biffMovef("test3", "test2", "%s: testing biffMove %d.", "me", 1729); { char good[] = ("[test3] me: testing biffMove 1729.\n" "[test3] [test2] me: this is a test of biffAddf 1 4.2\n"); tmp = biffGet("test3"); COMPARE(7); } airMopOkay(mop); exit(0); }
/* ******** tenBVecNonLinearFit ** ** Assuming that axis 0 represents a sequence of DWI measurements at a ** range of b values (as described by bb[i]), do non-linear least-squares ** fitting of those measurements, governed by weights ww[i] (with at ** most iterMax interations, or terminated when L2 norm change < eps). ** ** Based on model fit amp*exp(-b*dec), output nrrd's axis 0 has three values: ** 0: amp ** 1: dec ** 2: error of fit ** and all other axes are unchanged from input. Output type is always double. */ int tenBVecNonLinearFit(Nrrd *nout, const Nrrd *nin, double *bb, double *ww, int iterMax, double eps) { char me[]="tenBVecNonLinearFit", err[BIFF_STRLEN]; int map[NRRD_DIM_MAX], vecSize, iter; size_t ii, size[NRRD_DIM_MAX], vecI, vecNum; char *vec; double *out, ss[AIR_STRLEN_SMALL], amp, dec, d_amp, d_dec, error, diff, (*vecLup)(const void *v, size_t I); if (!( nout && nin && bb && ww )) { sprintf(err, "%s: got NULL pointer", me); biffAdd(TEN, err); return 1; } if (!( nin->dim >= 2 )) { sprintf(err, "%s: nin->dim (%d) not >= 2", me, nin->dim); biffAdd(TEN, err); return 1; } if (!( nin->axis[0].size < AIR_STRLEN_SMALL )) { sprintf(err, "%s: sorry need nin->axis[0].size (" _AIR_SIZE_T_CNV ") < %d", me, nin->axis[0].size, AIR_STRLEN_SMALL); biffAdd(TEN, err); return 1; } /* allocate/set-up output */ nrrdAxisInfoGet_nva(nin, nrrdAxisInfoSize, size); size[0] = 3; if (nrrdMaybeAlloc_nva(nout, nrrdTypeDouble, nin->dim, size)) { sprintf(err, "%s: couldn't allocate output", me); biffMove(TEN, err, NRRD); return 1; } for (ii=1; ii<nin->dim; ii++) { map[ii] = ii; } map[0] = -1; if (nrrdAxisInfoCopy(nout, nin, map, NRRD_AXIS_INFO_NONE)) { sprintf(err, "%s: couldn't copy axis info", me); biffMove(TEN, err, NRRD); return 1; } /* process all b vectors */ vecSize = nin->axis[0].size*nrrdTypeSize[nin->type]; vecNum = nrrdElementNumber(nin)/nin->axis[0].size; vecLup = nrrdDLookup[nin->type]; vec = (char*)nin->data; out = (double*)nout->data; for (vecI=0; vecI<vecNum; vecI++) { /* copy DWI signal values */ for (ii=0; ii<nin->axis[0].size; ii++) { ss[ii] = vecLup(vec, ii); } /* start with linear fit */ tenBVecNonLinearFit_linear(&, &dec, bb, ss, ww, nin->axis[0].size); error = tenBVecNonLinearFit_error(bb, ss, ww, nin->axis[0].size, amp, dec); /* possibly refine with gauss-newton */ if (iterMax > 0) { iter = 0; do { iter++; tenBVecNonLinearFit_GNstep(&d_amp, &d_dec, bb, ss, ww, nin->axis[0].size, amp, dec); amp += 0.3*d_amp; dec += 0.3*d_dec; diff = d_amp*d_amp + d_dec*d_dec; } while (iter < iterMax && diff > eps); } error = tenBVecNonLinearFit_error(bb, ss, ww, nin->axis[0].size, amp, dec); out[0] = amp; out[1] = dec; out[2] = error; vec += vecSize; out += 3; } return 0; }
int tenGlyphGen(limnObject *glyphsLimn, echoScene *glyphsEcho, tenGlyphParm *parm, const Nrrd *nten, const Nrrd *npos, const Nrrd *nslc) { char me[]="tenGlyphGen", err[BIFF_STRLEN]; gageShape *shape; airArray *mop; float *tdata, eval[3], evec[9], *cvec, rotEvec[9], mA_f[16]; double pI[3], pW[3], cl, cp, sRot[16], mA[16], mB[16], msFr[9], tmpvec[3], R, G, B, qA, qB, glyphAniso, sliceGray; unsigned int duh; int slcCoord[3], idx, _idx=0, glyphIdx, axis, numGlyphs, svRGBAfl=AIR_FALSE; limnLook *look; int lookIdx; echoObject *eglyph, *inst, *list=NULL, *split, *esquare; echoPos_t eM[16], originOffset[3], edge0[3], edge1[3]; /* int eret; double tmp1[3], tmp2[3]; */ if (!( (glyphsLimn || glyphsEcho) && nten && parm)) { sprintf(err, "%s: got NULL pointer", me); biffAdd(TEN, err); return 1; } mop = airMopNew(); shape = gageShapeNew(); shape->defaultCenter = nrrdCenterCell; airMopAdd(mop, shape, (airMopper)gageShapeNix, airMopAlways); if (npos) { if (!( 2 == nten->dim && 7 == nten->axis[0].size )) { sprintf(err, "%s: nten isn't 2-D 7-by-N array", me); biffAdd(TEN, err); airMopError(mop); return 1; } if (!( 2 == npos->dim && 3 == npos->axis[0].size && nten->axis[1].size == npos->axis[1].size )) { sprintf(err, "%s: npos isn't 2-D 3-by-" _AIR_SIZE_T_CNV " array", me, nten->axis[1].size); biffAdd(TEN, err); airMopError(mop); return 1; } if (!( nrrdTypeFloat == nten->type && nrrdTypeFloat == npos->type )) { sprintf(err, "%s: nten and npos must be %s, not %s and %s", me, airEnumStr(nrrdType, nrrdTypeFloat), airEnumStr(nrrdType, nten->type), airEnumStr(nrrdType, npos->type)); biffAdd(TEN, err); airMopError(mop); return 1; } } else { if (tenTensorCheck(nten, nrrdTypeFloat, AIR_TRUE, AIR_TRUE)) { sprintf(err, "%s: didn't get a valid DT volume", me); biffAdd(TEN, err); airMopError(mop); return 1; } } if (tenGlyphParmCheck(parm, nten, npos, nslc)) { sprintf(err, "%s: trouble", me); biffAdd(TEN, err); airMopError(mop); return 1; } if (!npos) { if (gageShapeSet(shape, nten, tenGageKind->baseDim)) { sprintf(err, "%s: trouble", me); biffMove(TEN, err, GAGE); airMopError(mop); return 1; } } if (parm->doSlice) { ELL_3V_COPY(edge0, shape->voxLen); ELL_3V_COPY(edge1, shape->voxLen); edge0[parm->sliceAxis] = edge1[parm->sliceAxis] = 0.0; switch(parm->sliceAxis) { case 0: edge0[1] = edge1[2] = 0; ELL_4M_ROTATE_Y_SET(sRot, AIR_PI/2); break; case 1: edge0[0] = edge1[2] = 0; ELL_4M_ROTATE_X_SET(sRot, AIR_PI/2); break; case 2: default: edge0[0] = edge1[1] = 0; ELL_4M_IDENTITY_SET(sRot); break; } ELL_3V_COPY(originOffset, shape->voxLen); ELL_3V_SCALE(originOffset, -0.5, originOffset); originOffset[parm->sliceAxis] *= -2*parm->sliceOffset; } if (glyphsLimn) { /* create limnLooks for diffuse and ambient-only shading */ /* ??? */ /* hack: save old value of setVertexRGBAFromLook, and set to true */ svRGBAfl = glyphsLimn->setVertexRGBAFromLook; glyphsLimn->setVertexRGBAFromLook = AIR_TRUE; } if (glyphsEcho) { list = echoObjectNew(glyphsEcho, echoTypeList); } if (npos) { numGlyphs = nten->axis[1].size; } else { numGlyphs = shape->size[0] * shape->size[1] * shape->size[2]; } /* find measurement frame transform */ if (3 == nten->spaceDim && AIR_EXISTS(nten->measurementFrame[0][0])) { /* msFr nten->measurementFrame ** 0 1 2 [0][0] [1][0] [2][0] ** 3 4 5 [0][1] [1][1] [2][1] ** 6 7 8 [0][2] [1][2] [2][2] */ msFr[0] = nten->measurementFrame[0][0]; msFr[3] = nten->measurementFrame[0][1]; msFr[6] = nten->measurementFrame[0][2]; msFr[1] = nten->measurementFrame[1][0]; msFr[4] = nten->measurementFrame[1][1]; msFr[7] = nten->measurementFrame[1][2]; msFr[2] = nten->measurementFrame[2][0]; msFr[5] = nten->measurementFrame[2][1]; msFr[8] = nten->measurementFrame[2][2]; } else { ELL_3M_IDENTITY_SET(msFr); } for (idx=0; idx<numGlyphs; idx++, _idx = idx) { tdata = (float*)(nten->data) + 7*idx; if (parm->verbose >= 2) { fprintf(stderr, "%s: glyph %d/%d: hello %g %g %g %g %g %g %g\n", me, idx, numGlyphs, tdata[0], tdata[1], tdata[2], tdata[3], tdata[4], tdata[5], tdata[6]); } if (!( TEN_T_EXISTS(tdata) )) { /* there's nothing we can do here */ if (parm->verbose >= 2) { fprintf(stderr, "%s: glyph %d/%d: non-existant data\n", me, idx, numGlyphs); } continue; } if (npos) { ELL_3V_COPY(pW, (float*)(npos->data) + 3*idx); if (!( AIR_EXISTS(pW[0]) && AIR_EXISTS(pW[1]) && AIR_EXISTS(pW[2]) )) { /* position doesn't exist- perhaps because its from the push library, which might kill points by setting coords to nan */ continue; } } else { NRRD_COORD_GEN(pI, shape->size, 3, _idx); /* this does take into account full orientation */ gageShapeItoW(shape, pW, pI); if (parm->nmask) { if (!( nrrdFLookup[parm->nmask->type](parm->nmask->data, idx) >= parm->maskThresh )) { if (parm->verbose >= 2) { fprintf(stderr, "%s: glyph %d/%d: doesn't meet mask thresh\n", me, idx, numGlyphs); } continue; } } } tenEigensolve_f(eval, evec, tdata); /* transform eigenvectors by measurement frame */ ELL_3MV_MUL(tmpvec, msFr, evec + 0); ELL_3V_COPY_TT(evec + 0, float, tmpvec); ELL_3MV_MUL(tmpvec, msFr, evec + 3); ELL_3V_COPY_TT(evec + 3, float, tmpvec); ELL_3MV_MUL(tmpvec, msFr, evec + 6); ELL_3V_COPY_TT(evec + 6, float, tmpvec); ELL_3V_CROSS(tmpvec, evec + 0, evec + 3); if (0 > ELL_3V_DOT(tmpvec, evec + 6)) { ELL_3V_SCALE(evec + 6, -1, evec + 6); } ELL_3M_TRANSPOSE(rotEvec, evec); if (parm->doSlice && pI[parm->sliceAxis] == parm->slicePos) { /* set sliceGray */ if (nslc) { /* we aren't masked by confidence, as anisotropy slice is */ for (duh=0; duh<parm->sliceAxis; duh++) { slcCoord[duh] = (int)(pI[duh]); } for (duh=duh<parm->sliceAxis; duh<2; duh++) { slcCoord[duh] = (int)(pI[duh+1]); } /* HEY: GLK has no idea what's going here */ slcCoord[0] = (int)(pI[0]); slcCoord[1] = (int)(pI[1]); slcCoord[2] = (int)(pI[2]); sliceGray = nrrdFLookup[nslc->type](nslc->data, slcCoord[0] + nslc->axis[0].size*slcCoord[1]); } else { if (!( tdata[0] >= parm->confThresh )) { if (parm->verbose >= 2) { fprintf(stderr, "%s: glyph %d/%d (slice): conf %g < thresh %g\n", me, idx, numGlyphs, tdata[0], parm->confThresh); } continue; } sliceGray = tenAnisoEval_f(eval, parm->sliceAnisoType); } if (parm->sliceGamma > 0) { sliceGray = AIR_AFFINE(0, sliceGray, 1, parm->sliceBias, 1); sliceGray = pow(sliceGray, 1.0/parm->sliceGamma); } else { sliceGray = AIR_AFFINE(0, sliceGray, 1, 0, 1-parm->sliceBias); sliceGray = 1.0 - pow(sliceGray, -1.0/parm->sliceGamma); } /* make slice contribution */ /* HEY: this is *NOT* aware of shape->fromOrientation */ if (glyphsLimn) { lookIdx = limnObjectLookAdd(glyphsLimn); look = glyphsLimn->look + lookIdx; ELL_4V_SET_TT(look->rgba, float, sliceGray, sliceGray, sliceGray, 1); ELL_3V_SET(look->kads, 1, 0, 0); look->spow = 0; glyphIdx = limnObjectSquareAdd(glyphsLimn, lookIdx); ELL_4M_IDENTITY_SET(mA); ell_4m_post_mul_d(mA, sRot); if (!npos) { ELL_4M_SCALE_SET(mB, shape->voxLen[0], shape->voxLen[1], shape->voxLen[2]); } ell_4m_post_mul_d(mA, mB); ELL_4M_TRANSLATE_SET(mB, pW[0], pW[1], pW[2]); ell_4m_post_mul_d(mA, mB); ELL_4M_TRANSLATE_SET(mB, originOffset[0], originOffset[1], originOffset[2]); ell_4m_post_mul_d(mA, mB); ELL_4M_COPY_TT(mA_f, float, mA); limnObjectPartTransform(glyphsLimn, glyphIdx, mA_f); } if (glyphsEcho) { esquare = echoObjectNew(glyphsEcho,echoTypeRectangle); ELL_3V_ADD2(((echoRectangle*)esquare)->origin, pW, originOffset); ELL_3V_COPY(((echoRectangle*)esquare)->edge0, edge0); ELL_3V_COPY(((echoRectangle*)esquare)->edge1, edge1); echoColorSet(esquare, AIR_CAST(echoCol_t, sliceGray), AIR_CAST(echoCol_t, sliceGray), AIR_CAST(echoCol_t, sliceGray), 1); /* this is pretty arbitrary- but I want shadows to have some effect. Previously, the material was all ambient: (A,D,S) = (1,0,0), which avoided all shadow effects. */ echoMatterPhongSet(glyphsEcho, esquare, 0.4f, 0.6f, 0, 40); echoListAdd(list, esquare); } } if (parm->onlyPositive) { if (eval[2] < 0) { /* didn't have all positive eigenvalues, its outta here */ if (parm->verbose >= 2) { fprintf(stderr, "%s: glyph %d/%d: not all evals %g %g %g > 0\n", me, idx, numGlyphs, eval[0], eval[1], eval[2]); } continue; } } if (!( tdata[0] >= parm->confThresh )) { if (parm->verbose >= 2) { fprintf(stderr, "%s: glyph %d/%d: conf %g < thresh %g\n", me, idx, numGlyphs, tdata[0], parm->confThresh); } continue; } if (!( tenAnisoEval_f(eval, parm->anisoType) >= parm->anisoThresh )) { if (parm->verbose >= 2) { fprintf(stderr, "%s: glyph %d/%d: aniso[%d] %g < thresh %g\n", me, idx, numGlyphs, parm->anisoType, tenAnisoEval_f(eval, parm->anisoType), parm->anisoThresh); } continue; } glyphAniso = tenAnisoEval_f(eval, parm->colAnisoType); /* fprintf(stderr, "%s: eret = %d; evals = %g %g %g\n", me, eret, eval[0], eval[1], eval[2]); ELL_3V_CROSS(tmp1, evec+0, evec+3); tmp2[0] = ELL_3V_LEN(tmp1); ELL_3V_CROSS(tmp1, evec+0, evec+6); tmp2[1] = ELL_3V_LEN(tmp1); ELL_3V_CROSS(tmp1, evec+3, evec+6); tmp2[2] = ELL_3V_LEN(tmp1); fprintf(stderr, "%s: crosses = %g %g %g\n", me, tmp2[0], tmp2[1], tmp2[2]); */ /* set transform (in mA) */ ELL_4M_IDENTITY_SET(mA); /* reset */ ELL_3V_SCALE(eval, parm->glyphScale, eval); /* scale by evals */ ELL_4M_SCALE_SET(mB, eval[0], eval[1], eval[2]); ell_4m_post_mul_d(mA, mB); ELL_43M_INSET(mB, rotEvec); /* rotate by evecs */ ell_4m_post_mul_d(mA, mB); ELL_4M_TRANSLATE_SET(mB, pW[0], pW[1], pW[2]); /* translate */ ell_4m_post_mul_d(mA, mB); /* set color (in R,G,B) */ cvec = evec + 3*(AIR_CLAMP(0, parm->colEvec, 2)); R = AIR_ABS(cvec[0]); /* standard mapping */ G = AIR_ABS(cvec[1]); B = AIR_ABS(cvec[2]); /* desaturate by colMaxSat */ R = AIR_AFFINE(0.0, parm->colMaxSat, 1.0, parm->colIsoGray, R); G = AIR_AFFINE(0.0, parm->colMaxSat, 1.0, parm->colIsoGray, G); B = AIR_AFFINE(0.0, parm->colMaxSat, 1.0, parm->colIsoGray, B); /* desaturate some by anisotropy */ R = AIR_AFFINE(0.0, parm->colAnisoModulate, 1.0, R, AIR_AFFINE(0.0, glyphAniso, 1.0, parm->colIsoGray, R)); G = AIR_AFFINE(0.0, parm->colAnisoModulate, 1.0, G, AIR_AFFINE(0.0, glyphAniso, 1.0, parm->colIsoGray, G)); B = AIR_AFFINE(0.0, parm->colAnisoModulate, 1.0, B, AIR_AFFINE(0.0, glyphAniso, 1.0, parm->colIsoGray, B)); /* clamp and do gamma */ R = AIR_CLAMP(0.0, R, 1.0); G = AIR_CLAMP(0.0, G, 1.0); B = AIR_CLAMP(0.0, B, 1.0); R = pow(R, parm->colGamma); G = pow(G, parm->colGamma); B = pow(B, parm->colGamma); /* which is the axis of revolution */ cl = AIR_MIN(0.99, tenAnisoEval_f(eval, tenAniso_Cl1)); cp = AIR_MIN(0.99, tenAnisoEval_f(eval, tenAniso_Cp1)); if (cl > cp) { axis = 0; qA = pow(1-cp, parm->sqdSharp); qB = pow(1-cl, parm->sqdSharp); } else { axis = 2; qA = pow(1-cl, parm->sqdSharp); qB = pow(1-cp, parm->sqdSharp); } /* add the glyph */ if (parm->verbose >= 2) { fprintf(stderr, "%s: glyph %d/%d: the glyph stays!\n", me, idx, numGlyphs); } if (glyphsLimn) { lookIdx = limnObjectLookAdd(glyphsLimn); look = glyphsLimn->look + lookIdx; ELL_4V_SET_TT(look->rgba, float, R, G, B, 1); ELL_3V_SET(look->kads, parm->ADSP[0], parm->ADSP[1], parm->ADSP[2]); look->spow = 0; switch(parm->glyphType) { case tenGlyphTypeBox: glyphIdx = limnObjectCubeAdd(glyphsLimn, lookIdx); break; case tenGlyphTypeSphere: glyphIdx = limnObjectPolarSphereAdd(glyphsLimn, lookIdx, axis, 2*parm->facetRes, parm->facetRes); break; case tenGlyphTypeCylinder: glyphIdx = limnObjectCylinderAdd(glyphsLimn, lookIdx, axis, parm->facetRes); break; case tenGlyphTypeSuperquad: default: glyphIdx = limnObjectPolarSuperquadAdd(glyphsLimn, lookIdx, axis, AIR_CAST(float, qA), AIR_CAST(float, qB), 2*parm->facetRes, parm->facetRes); break; } ELL_4M_COPY_TT(mA_f, float, mA); limnObjectPartTransform(glyphsLimn, glyphIdx, mA_f); } if (glyphsEcho) { switch(parm->glyphType) { case tenGlyphTypeBox: eglyph = echoObjectNew(glyphsEcho, echoTypeCube); /* nothing else to set */ break; case tenGlyphTypeSphere: eglyph = echoObjectNew(glyphsEcho, echoTypeSphere); echoSphereSet(eglyph, 0, 0, 0, 1); break; case tenGlyphTypeCylinder: eglyph = echoObjectNew(glyphsEcho, echoTypeCylinder); echoCylinderSet(eglyph, axis); break; case tenGlyphTypeSuperquad: default: eglyph = echoObjectNew(glyphsEcho, echoTypeSuperquad); echoSuperquadSet(eglyph, axis, qA, qB); break; } echoColorSet(eglyph, AIR_CAST(echoCol_t, R), AIR_CAST(echoCol_t, G), AIR_CAST(echoCol_t, B), 1); echoMatterPhongSet(glyphsEcho, eglyph, parm->ADSP[0], parm->ADSP[1], parm->ADSP[2], parm->ADSP[3]); inst = echoObjectNew(glyphsEcho, echoTypeInstance); ELL_4M_COPY(eM, mA); echoInstanceSet(inst, eM, eglyph); echoListAdd(list, inst); } } if (glyphsLimn) { glyphsLimn->setVertexRGBAFromLook = svRGBAfl; } if (glyphsEcho) { split = echoListSplit3(glyphsEcho, list, 10); echoObjectAdd(glyphsEcho, split); } airMopOkay(mop); return 0; }
static tenFiberContext * _tenFiberContextCommonNew(const Nrrd *vol, int useDwi, double thresh, double soft, double valueMin, int ten1method, int ten2method) { char me[]="_tenFiberContextCommonNew", err[BIFF_STRLEN]; tenFiberContext *tfx; gageKind *kind; if (!( tfx = (tenFiberContext *)calloc(1, sizeof(tenFiberContext)) )) { sprintf(err, "%s: couldn't allocate new context", me); biffAdd(TEN, err); return NULL; } if (useDwi) { Nrrd *ngrad=NULL, *nbmat=NULL; double bval=0; unsigned int *skip, skipNum; tfx->useDwi = AIR_TRUE; /* default fiber type */ tfx->fiberType = tenDwiFiberTypeUnknown; if (tenDWMRIKeyValueParse(&ngrad, &nbmat, &bval, &skip, &skipNum, vol)) { sprintf(err, "%s: trouble parsing DWI info", me ); biffAdd(TEN, err); return NULL; } if (skipNum) { sprintf(err, "%s: sorry, can't do DWI skipping here", me); biffAdd(TEN, err); return NULL; } kind = tenDwiGageKindNew(); if (tenDwiGageKindSet(kind, thresh, soft, bval, valueMin, ngrad, NULL, ten1method, ten2method, 42)) { sprintf(err, "%s: trouble setting DWI kind", me); biffAdd(TEN, err); return NULL; } } else { /* it should be a tensor volume */ tfx->useDwi = AIR_FALSE; /* default fiber type */ tfx->fiberType = tenFiberTypeUnknown; if (tenTensorCheck(vol, nrrdTypeUnknown, AIR_TRUE, AIR_TRUE)) { sprintf(err, "%s: didn't get a tensor volume", me); biffAdd(TEN, err); return NULL; } kind = tenGageKind; } if ( !(tfx->gtx = gageContextNew()) || !(tfx->pvl = gagePerVolumeNew(tfx->gtx, vol, kind)) || (gagePerVolumeAttach(tfx->gtx, tfx->pvl)) ) { sprintf(err, "%s: gage trouble", me); biffMove(TEN, err, GAGE); free(tfx); return NULL; } tfx->nin = vol; tfx->ksp = nrrdKernelSpecNew(); if (nrrdKernelSpecParse(tfx->ksp, tenDefFiberKernel)) { sprintf(err, "%s: couldn't parse tenDefFiberKernel \"%s\"", me, tenDefFiberKernel); biffMove(TEN, err, NRRD); return NULL; } if (tenFiberKernelSet(tfx, tfx->ksp->kernel, tfx->ksp->parm)) { sprintf(err, "%s: couldn't set default kernel", me); biffAdd(TEN, err); return NULL; } /* looks to GK like GK says that we must set some stop criterion */ tfx->intg = tenDefFiberIntg; tfx->anisoStopType = tenDefFiberAnisoStopType; tfx->anisoSpeedType = tenAnisoUnknown; tfx->stop = 0; tfx->anisoThresh = tenDefFiberAnisoThresh; /* so I'm not using the normal default mechanism, shoot me */ tfx->anisoSpeedFunc[0] = 0; tfx->anisoSpeedFunc[1] = 0; tfx->anisoSpeedFunc[2] = 0; tfx->maxNumSteps = tenDefFiberMaxNumSteps; tfx->minNumSteps = 0; tfx->useIndexSpace = tenDefFiberUseIndexSpace; tfx->verbose = 0; tfx->stepSize = tenDefFiberStepSize; tfx->maxHalfLen = tenDefFiberMaxHalfLen; tfx->minWholeLen = 0.0; tfx->confThresh = 0.5; /* why do I even bother setting these- they'll only get read if the right tenFiberStopSet has been called, in which case they'll be set... */ tfx->minRadius = 1; /* above lament applies here as well */ tfx->minFraction = 0.5; /* and here */ tfx->wPunct = tenDefFiberWPunct; GAGE_QUERY_RESET(tfx->query); tfx->mframe[0] = vol->measurementFrame[0][0]; tfx->mframe[1] = vol->measurementFrame[1][0]; tfx->mframe[2] = vol->measurementFrame[2][0]; tfx->mframe[3] = vol->measurementFrame[0][1]; tfx->mframe[4] = vol->measurementFrame[1][1]; tfx->mframe[5] = vol->measurementFrame[2][1]; tfx->mframe[6] = vol->measurementFrame[0][2]; tfx->mframe[7] = vol->measurementFrame[1][2]; tfx->mframe[8] = vol->measurementFrame[2][2]; if (ELL_3M_EXISTS(tfx->mframe)) { tfx->mframeUse = AIR_TRUE; ELL_3M_TRANSPOSE(tfx->mframeT, tfx->mframe); } else { tfx->mframeUse = AIR_FALSE; } tfx->gageAnisoStop = NULL; tfx->gageAnisoSpeed = NULL; tfx->ten2AnisoStop = AIR_NAN; /* ... don't really see the point of initializing the ten2 stuff here; its properly done in tenFiberTraceSet() ... */ tfx->radius = AIR_NAN; return tfx; }
int fixproj(Nrrd *nproj[3], Nrrd *nvol) { char me[]="fixproj", err[BIFF_STRLEN]; airArray *mop; Nrrd *ntmp[3], *nt; int sz[3], ii, map[3], h[3], E, mi; size_t rsz[3]; double vec[3][3], dot[3], sp[3], parm[NRRD_KERNEL_PARMS_NUM]; mop = airMopNew(); if (!( ELL_3V_EXISTS(nvol->axis[0].spaceDirection) && ELL_3V_EXISTS(nvol->axis[1].spaceDirection) && ELL_3V_EXISTS(nvol->axis[2].spaceDirection) )) { sprintf(err, "%s: space directions don't exist for all 3 axes", me); biffAdd(NINSPECT, err); airMopError(mop); return 1; } airMopAdd(mop, nt = nrrdNew(), (airMopper)nrrdNuke, airMopAlways); airMopAdd(mop, ntmp[0] = nrrdNew(), (airMopper)nrrdNuke, airMopAlways); airMopAdd(mop, ntmp[1] = nrrdNew(), (airMopper)nrrdNuke, airMopAlways); airMopAdd(mop, ntmp[2] = nrrdNew(), (airMopper)nrrdNuke, airMopAlways); /* RL AP SI */ ELL_3V_SET(vec[0], 1, 0, 0); ELL_3V_SET(vec[1], 0, 1, 0); ELL_3V_SET(vec[2], 0, 0, 1); for (ii=0; ii<3; ii++) { dot[0] = ELL_3V_DOT(vec[ii], nvol->axis[0].spaceDirection); dot[1] = ELL_3V_DOT(vec[ii], nvol->axis[1].spaceDirection); dot[2] = ELL_3V_DOT(vec[ii], nvol->axis[2].spaceDirection); dot[0] = AIR_ABS(dot[0]); dot[1] = AIR_ABS(dot[1]); dot[2] = AIR_ABS(dot[2]); map[ii] = ELL_MAX3_IDX(dot[0], dot[1], dot[2]); } ELL_3V_SET(h, 1, 0, 0); E = 0; for (ii=0; ii<3; ii++) { if (h[map[ii]] != map[h[ii]]) { if (!E) E |= nrrdAxesSwap(ntmp[ii], nproj[map[ii]], 1, 2); } else { if (!E) E |= nrrdCopy(ntmp[ii], nproj[map[ii]]); } } if (E) { sprintf(err, "%s: trouble with nrrd operations", me); biffMove(NINSPECT, err, NRRD); airMopError(mop); return 1; } E = 0; if (nvol->axis[map[0]].spaceDirection[0] > 0) { if (!E) E |= nrrdFlip(nt, ntmp[1], 0+1); if (!E) E |= nrrdCopy(ntmp[1], nt); if (!E) E |= nrrdFlip(nt, ntmp[2], 0+1); if (!E) E |= nrrdCopy(ntmp[2], nt); } if (nvol->axis[map[1]].spaceDirection[1] > 0) { if (!E) E |= nrrdFlip(nt, ntmp[0], 0+1); if (!E) E |= nrrdCopy(ntmp[0], nt); if (!E) E |= nrrdFlip(nt, ntmp[2], 1+1); if (!E) E |= nrrdCopy(ntmp[2], nt); } if (nvol->axis[map[2]].spaceDirection[2] > 0) { if (!E) E |= nrrdFlip(nt, ntmp[0], 1+1); if (!E) E |= nrrdCopy(ntmp[0], nt); if (!E) E |= nrrdFlip(nt, ntmp[1], 1+1); if (!E) E |= nrrdCopy(ntmp[1], nt); } if (E) { sprintf(err, "%s: trouble with nrrd operations", me); biffMove(NINSPECT, err, NRRD); airMopError(mop); return 1; } for (ii=0; ii<3; ii++) { sz[ii] = nvol->axis[map[ii]].size; sp[ii] = ELL_3V_LEN(nvol->axis[map[ii]].spaceDirection); } mi = ELL_MIN3_IDX(sp[0], sp[1], sp[2]); sz[0] = (int)(sz[0]*sp[0]/sp[mi]); sz[1] = (int)(sz[1]*sp[1]/sp[mi]); sz[2] = (int)(sz[2]*sp[2]/sp[mi]); parm[0] = 1; ELL_3V_SET(rsz, 3, sz[1], sz[2]); nrrdSimpleResample(nproj[0], ntmp[0], nrrdKernelBox, parm, rsz, NULL); ELL_3V_SET(rsz, 3, sz[0], sz[2]); nrrdSimpleResample(nproj[1], ntmp[1], nrrdKernelBox, parm, rsz, NULL); ELL_3V_SET(rsz, 3, sz[0], sz[1]); nrrdSimpleResample(nproj[2], ntmp[2], nrrdKernelBox, parm, rsz, NULL); airMopOkay(mop); return 0; }
int baneGkms_txfMain(int argc, char **argv, char *me, hestParm *hparm) { hestOpt *opt = NULL; char *out, *perr, err[BIFF_STRLEN]; Nrrd *nout; airArray *mop; int pret, E, res[2], vi, gi, step; float min[2], max[2], top[2], v0, g0, *data, v, g, gwidth, width, mwidth, tvl, tvr, vl, vr, tmp, maxa; hestOptAdd(&opt, "r", "Vres Gres", airTypeInt, 2, 2, res, "256 256", "resolution of the transfer function in value and gradient " "magnitude"); hestOptAdd(&opt, "min", "Vmin Gmin", airTypeFloat, 2, 2, min, "0.0 0.0", "minimum value and grad mag in txf"); hestOptAdd(&opt, "max", "Vmax Gmax", airTypeFloat, 2, 2, max, NULL, "maximum value and grad mag in txf"); hestOptAdd(&opt, "v", "base value", airTypeFloat, 1, 1, &v0, NULL, "data value at which to position bottom of triangle"); hestOptAdd(&opt, "g", "gthresh", airTypeFloat, 1, 1, &g0, "0.0", "lowest grad mag to receive opacity"); hestOptAdd(&opt, "gw", "gwidth", airTypeFloat, 1, 1, &gwidth, "0.0", "range of grad mag values over which to apply threshold " "at low gradient magnitudes"); hestOptAdd(&opt, "top", "Vtop Gtop", airTypeFloat, 2, 2, top, NULL, "data value and grad mag at center of top of triangle"); hestOptAdd(&opt, "w", "value width", airTypeFloat, 1, 1, &width, NULL, "range of values to be spanned at top of triangle"); hestOptAdd(&opt, "mw", "value width", airTypeFloat, 1, 1, &mwidth, "0", "range of values to be spanned at BOTTOM of triangle"); hestOptAdd(&opt, "step", NULL, airTypeInt, 0, 0, &step, NULL, "instead of assigning opacity inside a triangular region, " "make it more like a step function, in which opacity never " "decreases in increasing data value"); hestOptAdd(&opt, "a", "max opac", airTypeFloat, 1, 1, &maxa, "1.0", "highest opacity to assign"); hestOptAdd(&opt, "o", "opacOut", airTypeString, 1, 1, &out, NULL, "output opacity function filename"); mop = airMopNew(); airMopAdd(mop, opt, (airMopper)hestOptFree, airMopAlways); USAGE(_baneGkms_txfInfoL); PARSE(); airMopAdd(mop, opt, (airMopper)hestParseFree, airMopAlways); nout = nrrdNew(); airMopAdd(mop, nout, (airMopper)nrrdNuke, airMopAlways); E = 0; if (!E) E |= nrrdMaybeAlloc_va(nout, nrrdTypeFloat, 3, AIR_CAST(size_t, 1), AIR_CAST(size_t, res[0]), AIR_CAST(size_t, res[1])); if (!E) E |= !(nout->axis[0].label = airStrdup("A")); if (!E) E |= !(nout->axis[1].label = airStrdup("gage(scalar:v)")); if (!E) nrrdAxisInfoSet_va(nout, nrrdAxisInfoMin, AIR_NAN, (double)min[0], (double)min[1]); if (!E) nrrdAxisInfoSet_va(nout, nrrdAxisInfoMax, AIR_NAN, (double)max[0], (double)max[1]); if (!E) E |= !(nout->axis[2].label = airStrdup("gage(scalar:gm)")); if (E) { sprintf(err, "%s: trouble creating opacity function nrrd", me); biffMove(BANE, err, NRRD); airMopError(mop); return 1; } data = (float *)nout->data; tvl = top[0] - width/2; tvr = top[0] + width/2; mwidth /= 2; for (gi=0; gi<res[1]; gi++) { g = AIR_CAST(float, NRRD_CELL_POS(min[1], max[1], res[1], gi)); for (vi=0; vi<res[0]; vi++) { v = AIR_CAST(float, NRRD_CELL_POS(min[0], max[0], res[0], vi)); vl = AIR_CAST(float, AIR_AFFINE(0, g, top[1], v0-mwidth, tvl)); vr = AIR_CAST(float, AIR_AFFINE(0, g, top[1], v0+mwidth, tvr)); if (g > top[1]) { data[vi + res[0]*gi] = 0; continue; } tmp = AIR_CAST(float, (v - vl)/(0.00001 + vr - vl)); tmp = 1 - AIR_ABS(2*tmp - 1); if (step && v > (vr + vl)/2) { tmp = 1; } tmp = AIR_MAX(0, tmp); data[vi + res[0]*gi] = tmp*maxa; tmp = AIR_CAST(float, AIR_AFFINE(g0 - gwidth/2, g, g0 + gwidth/2, 0.0, 1.0)); tmp = AIR_CLAMP(0, tmp, 1); data[vi + res[0]*gi] *= tmp; } } if (nrrdSave(out, nout, NULL)) { sprintf(err, "%s: trouble saving opacity function", me); biffMove(BANE, err, NRRD); airMopError(mop); return 1; } airMopOkay(mop); return 0; }
int baneGkms_hvolMain(int argc, char **argv, char *me, hestParm *hparm) { hestOpt *opt = NULL; char *out, *perr, err[BIFF_STRLEN]; Nrrd *nin, *nout; airArray *mop; int pret, dim[3], lapl, slow, gz = AIR_FALSE; double inc[3*(1+BANE_PARM_NUM)]; baneHVolParm *hvp; NrrdIoState *nio; NrrdKernelSpec *ksp00, *ksp11, *ksp22; hestOptAdd(&opt, "s", "incV incG incH", airTypeOther, 3, 3, inc, "f:1.0 p:0.005 p:0.015", "Strategies for determining how much of the range " "of a quantity should be included and quantized in its axis " "of the histogram volume. Possibilities include:\n " "\b\bo \"f:<F>\": included range is some fraction of the " "total range, as scaled by F\n " "\b\bo \"p:<P>\": exclude the extremal P percent of " "the values\n " "\b\bo \"s:<S>\": included range is S times the standard " "deviation of the values\n " "\b\bo \"a:<min>,<max>\": range is from <min> to <max>", NULL, NULL, baneGkmsHestIncStrategy); hestOptAdd(&opt, "d", "dimV dimG dimH", airTypeInt, 3, 3, dim, "256 256 256", "Dimensions of histogram volume; number of samples along " "each axis"); hestOptAdd(&opt, "k00", "kernel", airTypeOther, 1, 1, &ksp00, "tent", "value reconstruction kernel", NULL, NULL, nrrdHestKernelSpec); hestOptAdd(&opt, "k11", "kernel", airTypeOther, 1, 1, &ksp11, "cubicd:1,0", "first derivative kernel", NULL, NULL, nrrdHestKernelSpec); hestOptAdd(&opt, "k22", "kernel", airTypeOther, 1, 1, &ksp22, "cubicdd:1,0", "second derivative kernel", NULL, NULL, nrrdHestKernelSpec); hestOptAdd(&opt, "l", NULL, airTypeInt, 0, 0, &lapl, NULL, "Use Laplacian instead of Hessian to approximate second " "directional derivative. No faster, less accurate."); hestOptAdd(&opt, "slow", NULL, airTypeInt, 0, 0, &slow, NULL, "Instead of allocating a floating point VGH volume and measuring " "V,G,H once, measure V,G,H multiple times on seperate passes " "(slower, but needs less memory)"); if (nrrdEncodingGzip->available()) { hestOptAdd(&opt, "gz", NULL, airTypeInt, 0, 0, &gz, NULL, "Use gzip compression for output histo-volume; " "much less disk space, slightly slower to read/write"); } hestOptAdd(&opt, "i", "volumeIn", airTypeOther, 1, 1, &nin, NULL, "input scalar volume for which a transfer function is needed", NULL, NULL, nrrdHestNrrd); hestOptAdd(&opt, "o", "hvolOut", airTypeString, 1, 1, &out, NULL, "output histogram volume, used by \"gkms scat\" and " "\"gkms info\""); mop = airMopNew(); airMopAdd(mop, opt, (airMopper)hestOptFree, airMopAlways); USAGE(_baneGkms_hvolInfoL); PARSE(); airMopAdd(mop, opt, (airMopper)hestParseFree, airMopAlways); nout = nrrdNew(); airMopAdd(mop, nout, (airMopper)nrrdNuke, airMopAlways); nio = nrrdIoStateNew(); airMopAdd(mop, nio, (airMopper)nrrdIoStateNix, airMopAlways); hvp = baneHVolParmNew(); airMopAdd(mop, hvp, (airMopper)baneHVolParmNix, airMopAlways); baneHVolParmGKMSInit(hvp); hvp->makeMeasrVol = !slow; fprintf(stderr, "!%s: need to be using baneHVolParmAxisSet\n", me); /* hvp->axis[0].res = dim[perm[0]]; hvp->axis[1].res = dim[perm[1]]; hvp->axis[2].res = dim[perm[2]]; hvp->axis[1].measr = lapl ? baneMeasrLapl : baneMeasrHess; for (i=0; i<=2; i++) { hvp->ax[i].inc = baneIncArray[(int)inc[(1+BANE_INC_PARM_NUM)*perm[i]]]; for (j=0; j<BANE_INC_PARM_NUM; j++) { hvp->ax[i].incParm[j] = inc[1 + j + (1+BANE_INC_PARM_NUM)*perm[i]]; } } */ hvp->k3pack = AIR_TRUE; nrrdKernelParmSet(&hvp->k[gageKernel00], hvp->kparm[gageKernel00], ksp00); nrrdKernelParmSet(&hvp->k[gageKernel11], hvp->kparm[gageKernel11], ksp11); nrrdKernelParmSet(&hvp->k[gageKernel22], hvp->kparm[gageKernel22], ksp22); if (baneMakeHVol(nout, nin, hvp)) { sprintf(err, "%s: trouble making histogram volume", me); biffAdd(BANE, err); airMopError(mop); return 1; } nio->encoding = gz ? nrrdEncodingGzip : nrrdEncodingRaw; if (nrrdSave(out, nout, nio)) { sprintf(err, "%s: error saving histogram volume", me); biffMove(BANE, err, NRRD); airMopError(mop); return 1; } airMopOkay(mop); return 0; }
int alanInit(alanContext *actx, const Nrrd *nlevInit, const Nrrd *nparmInit) { char me[]="alanInit", err[BIFF_STRLEN]; alan_t *levInit=NULL, *lev0, *parmInit=NULL, *parm; size_t I, N; if (_alanCheck(actx)) { sprintf(err, "%s: ", me); biffAdd(ALAN, err); return 1; } if (!( actx->_nlev[0] && actx->_nlev[0] && actx->nparm )) { sprintf(err, "%s: _nlev[0,1] not allocated: call alanUpdate", me); biffAdd(ALAN, err); return 1; } if (nlevInit) { if (nrrdCheck(nlevInit)) { sprintf(err, "%s: given nlevInit has problems", me); biffMove(ALAN, err, NRRD); return 1; } if (!( alan_nt == nlevInit->type && nlevInit->dim == 1 + actx->dim && actx->_nlev[0]->axis[0].size == nlevInit->axis[0].size && actx->size[0] == nlevInit->axis[1].size && actx->size[1] == nlevInit->axis[2].size && (2 == actx->dim || actx->size[2] == nlevInit->axis[3].size) )) { sprintf(err, "%s: type/size mismatch with given nlevInit", me); biffAdd(ALAN, err); return 1; } levInit = (alan_t*)(nlevInit->data); } if (nparmInit) { if (nrrdCheck(nparmInit)) { sprintf(err, "%s: given nparmInit has problems", me); biffMove(ALAN, err, NRRD); return 1; } if (!( alan_nt == nparmInit->type && nparmInit->dim == 1 + actx->dim && 3 == nparmInit->axis[0].size && actx->size[0] == nparmInit->axis[1].size && actx->size[1] == nparmInit->axis[2].size && (2 == actx->dim || actx->size[2] == nparmInit->axis[3].size) )) { sprintf(err, "%s: type/size mismatch with given nparmInit", me); biffAdd(ALAN, err); return 1; } parmInit = (alan_t*)(nparmInit->data); } #define RAND AIR_AFFINE(0, airDrandMT(), 1, -actx->randRange, actx->randRange) N = nrrdElementNumber(actx->_nlev[0])/actx->_nlev[0]->axis[0].size; lev0 = (alan_t*)(actx->_nlev[0]->data); parm = (alan_t*)(actx->nparm->data); for (I=0; I<N; I++) { if (levInit) { lev0[0 + 2*I] = levInit[0 + 2*I]; lev0[1 + 2*I] = levInit[1 + 2*I]; } else { /* NOTE: the random number stuff here is OUTSIDE the multi-threaded segment of the program- only the init thread does this */ lev0[0 + 2*I] = AIR_CAST(alan_t, actx->initA + RAND); lev0[1 + 2*I] = AIR_CAST(alan_t, actx->initB + RAND); } if (parmInit) { parm[0 + 3*I] = parmInit[0 + 3*I]; parm[1 + 3*I] = parmInit[1 + 3*I]; parm[2 + 3*I] = parmInit[2 + 3*I]; } else { parm[0 + 3*I] = actx->deltaT; parm[1 + 3*I] = actx->alpha; parm[2 + 3*I] = actx->beta; } } return 0; }