| File: | src/bin/gprobe.c |
| Location: | line 848, column 5 |
| Description: | Value stored to 'six' is never read |
| 1 | /* |
| 2 | Teem: Tools to process and visualize scientific data and images . |
| 3 | Copyright (C) 2013, 2012, 2011, 2010, 2009 University of Chicago |
| 4 | Copyright (C) 2008, 2007, 2006, 2005 Gordon Kindlmann |
| 5 | Copyright (C) 2004, 2003, 2002, 2001, 2000, 1999, 1998 University of Utah |
| 6 | |
| 7 | This library is free software; you can redistribute it and/or |
| 8 | modify it under the terms of the GNU Lesser General Public License |
| 9 | (LGPL) as published by the Free Software Foundation; either |
| 10 | version 2.1 of the License, or (at your option) any later version. |
| 11 | The terms of redistributing and/or modifying this software also |
| 12 | include exceptions to the LGPL that facilitate static linking. |
| 13 | |
| 14 | This library is distributed in the hope that it will be useful, |
| 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 17 | Lesser General Public License for more details. |
| 18 | |
| 19 | You should have received a copy of the GNU Lesser General Public License |
| 20 | along with this library; if not, write to Free Software Foundation, Inc., |
| 21 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
| 22 | */ |
| 23 | |
| 24 | |
| 25 | #include <stdio.h> |
| 26 | |
| 27 | #include <teem/biff.h> |
| 28 | #include <teem/hest.h> |
| 29 | #include <teem/nrrd.h> |
| 30 | #include <teem/gage.h> |
| 31 | #include <teem/ten.h> |
| 32 | #include <teem/meet.h> |
| 33 | |
| 34 | static void |
| 35 | printans(FILE *file, const double *ans, unsigned int len) { |
| 36 | unsigned int ai; |
| 37 | |
| 38 | AIR_UNUSED(file)(void)(file); |
| 39 | for (ai=0; ai<len; ai++) { |
| 40 | if (ai) { |
| 41 | printf(", "); |
| 42 | } |
| 43 | printf("%g", ans[ai]); |
| 44 | } |
| 45 | } |
| 46 | |
| 47 | static int |
| 48 | gridProbe(gageContext *ctx, gagePerVolume *pvl, int what, |
| 49 | Nrrd *nout, int typeOut, Nrrd *_ngrid, |
| 50 | int indexSpace, int verbose, int clamp, int scaleIsTau, |
| 51 | double eft, double eftVal) { |
| 52 | char me[]="gridProbe"; |
| 53 | Nrrd *ngrid; |
| 54 | airArray *mop; |
| 55 | double *grid, pos[4]; |
| 56 | const double *answer; |
| 57 | unsigned int ansLen, dim, aidx, baseDim, gridDim; |
| 58 | size_t sizeOut[NRRD_DIM_MAX16], coordOut[NRRD_DIM_MAX16], II, NN; |
| 59 | double (*ins)(void *v, size_t I, double d); |
| 60 | char stmp[2][AIR_STRLEN_SMALL(128+1)]; |
| 61 | |
| 62 | if (!(ctx && pvl && nout && _ngrid)) { |
| 63 | biffAddf(GAGEgageBiffKey, "%s: got NULL pointer", me); |
| 64 | return 1; |
| 65 | } |
| 66 | if (airEnumValCheck(nrrdType, typeOut)) { |
| 67 | biffAddf(GAGEgageBiffKey, "%s: type %d not valid", me, typeOut); |
| 68 | return 1; |
| 69 | } |
| 70 | if (!gagePerVolumeIsAttached(ctx, pvl)) { |
| 71 | biffAddf(GAGEgageBiffKey, "%s: given pvl not attached to context", me); |
| 72 | return 1; |
| 73 | } |
| 74 | if (!(2 == _ngrid->dim)) { |
| 75 | biffAddf(GAGEgageBiffKey, "%s: ngrid must be 2 (not %u)", me, _ngrid->dim); |
| 76 | return 1; |
| 77 | } |
| 78 | if ((ctx->stackPos && _ngrid->axis[0].size != 5) |
| 79 | || (!ctx->stackPos && _ngrid->axis[0].size != 4)) { |
| 80 | biffAddf(GAGEgageBiffKey, "%s: if %susing stack, need " |
| 81 | "ngrid->axis[0].size = %u = 1 + %u (not %u)", me, |
| 82 | (ctx->stackPos ? "" : "not "), |
| 83 | (ctx->stackPos ? 4 : 3) + 1, |
| 84 | (ctx->stackPos ? 4 : 3), |
| 85 | AIR_UINT(_ngrid->axis[0].size)((unsigned int)(_ngrid->axis[0].size))); |
| 86 | return 1; |
| 87 | } |
| 88 | |
| 89 | mop = airMopNew(); |
| 90 | ngrid = nrrdNew(); |
| 91 | airMopAdd(mop, ngrid, (airMopper)nrrdNuke, airMopAlways); |
| 92 | if (ctx->stackPos) { |
| 93 | if (nrrdConvert(ngrid, _ngrid, nrrdTypeDouble)) { |
| 94 | biffMovef(GAGEgageBiffKey, NRRDnrrdBiffKey, "%s: trouble converting ngrid", me); |
| 95 | airMopError(mop); return 1; |
| 96 | } |
| 97 | } else { |
| 98 | Nrrd *ntmp; |
| 99 | ptrdiff_t minIdx[2], maxIdx[2]; |
| 100 | minIdx[0] = minIdx[1] = 0; |
| 101 | maxIdx[0] = 4; /* pad by one sample */ |
| 102 | maxIdx[1] = AIR_CAST(ptrdiff_t, _ngrid->axis[1].size-1)((ptrdiff_t)(_ngrid->axis[1].size-1)); /* no padding */ |
| 103 | ntmp = nrrdNew(); |
| 104 | airMopAdd(mop, ntmp, (airMopper)nrrdNuke, airMopAlways); |
| 105 | if (nrrdConvert(ntmp, _ngrid, nrrdTypeDouble) |
| 106 | || nrrdPad_nva(ngrid, ntmp, minIdx, maxIdx, nrrdBoundaryPad, 0.0)) { |
| 107 | biffMovef(GAGEgageBiffKey, NRRDnrrdBiffKey, "%s: trouble converting/padding ngrid", me); |
| 108 | airMopError(mop); return 1; |
| 109 | } |
| 110 | } |
| 111 | grid = AIR_CAST(double *, ngrid->data)((double *)(ngrid->data)); |
| 112 | gridDim = AIR_ROUNDUP_UI(grid[0])((unsigned int)(floor((grid[0])+0.5))); |
| 113 | if (gridDim + 1 != ngrid->axis[1].size) { |
| 114 | biffAddf(GAGEgageBiffKey, "%s: ngrid->axis[1].size = %u but expected %u = 1 + %u", |
| 115 | me, AIR_UINT(ngrid->axis[1].size)((unsigned int)(ngrid->axis[1].size)), |
| 116 | 1 + gridDim, gridDim); |
| 117 | airMopError(mop); return 1; |
| 118 | } |
| 119 | answer = gageAnswerPointer(ctx, pvl, what); |
| 120 | ansLen = pvl->kind->table[what].answerLength; |
| 121 | baseDim = 1 == ansLen ? 0 : 1; |
| 122 | dim = baseDim + gridDim; |
| 123 | if (dim > NRRD_DIM_MAX16) { |
| 124 | biffAddf(GAGEgageBiffKey, "%s: output dimension %u unreasonable", me, dim); |
| 125 | airMopError(mop); return 1; |
| 126 | } |
| 127 | if (ansLen > 1) { |
| 128 | sizeOut[0] = ansLen; |
| 129 | coordOut[0] = 0; |
| 130 | } |
| 131 | NN = 1; |
| 132 | for (aidx=0; aidx<gridDim; aidx++) { |
| 133 | sizeOut[aidx + baseDim] = AIR_ROUNDUP_UI(grid[0 + 5*(aidx+1)])((unsigned int)(floor((grid[0 + 5*(aidx+1)])+0.5))); |
| 134 | NN *= sizeOut[aidx + baseDim]; |
| 135 | coordOut[aidx + baseDim] = 0; |
| 136 | } |
| 137 | if (nrrdMaybeAlloc_nva(nout, typeOut, dim, sizeOut)) { |
| 138 | biffMovef(GAGEgageBiffKey, NRRDnrrdBiffKey, "%s: couldn't allocate output", me); |
| 139 | airMopError(mop); return 1; |
| 140 | } |
| 141 | ins = nrrdDInsert[nout->type]; |
| 142 | for (II=0; II<NN; II++) { |
| 143 | int E; |
| 144 | if (verbose && 3 == gridDim |
| 145 | && !coordOut[0+baseDim] && !coordOut[1+baseDim]) { |
| 146 | if (verbose > 1) { |
| 147 | fprintf(stderr__stderrp, "z = "); |
| 148 | } |
| 149 | fprintf(stderr__stderrp, " %s/%s", |
| 150 | airSprintSize_t(stmp[0], coordOut[2+baseDim]), |
| 151 | airSprintSize_t(stmp[1], sizeOut[2+baseDim])); |
| 152 | fflush(stderr__stderrp); |
| 153 | if (verbose > 1) { |
| 154 | fprintf(stderr__stderrp, "\n"); |
| 155 | } |
| 156 | } |
| 157 | ELL_4V_COPY(pos, grid + 1 + 5*0)((pos)[0] = (grid + 1 + 5*0)[0], (pos)[1] = (grid + 1 + 5*0)[ 1], (pos)[2] = (grid + 1 + 5*0)[2], (pos)[3] = (grid + 1 + 5* 0)[3]); |
| 158 | for (aidx=0; aidx<gridDim; aidx++) { |
| 159 | ELL_4V_SCALE_ADD2(pos, 1, pos,((pos)[0] = (1)*(pos)[0] + (((double)(coordOut[aidx + baseDim ])))*(grid + 1 + 5*(1+aidx))[0], (pos)[1] = (1)*(pos)[1] + (( (double)(coordOut[aidx + baseDim])))*(grid + 1 + 5*(1+aidx))[ 1], (pos)[2] = (1)*(pos)[2] + (((double)(coordOut[aidx + baseDim ])))*(grid + 1 + 5*(1+aidx))[2], (pos)[3] = (1)*(pos)[3] + (( (double)(coordOut[aidx + baseDim])))*(grid + 1 + 5*(1+aidx))[ 3]) |
| 160 | AIR_CAST(double, coordOut[aidx + baseDim]),((pos)[0] = (1)*(pos)[0] + (((double)(coordOut[aidx + baseDim ])))*(grid + 1 + 5*(1+aidx))[0], (pos)[1] = (1)*(pos)[1] + (( (double)(coordOut[aidx + baseDim])))*(grid + 1 + 5*(1+aidx))[ 1], (pos)[2] = (1)*(pos)[2] + (((double)(coordOut[aidx + baseDim ])))*(grid + 1 + 5*(1+aidx))[2], (pos)[3] = (1)*(pos)[3] + (( (double)(coordOut[aidx + baseDim])))*(grid + 1 + 5*(1+aidx))[ 3]) |
| 161 | grid + 1 + 5*(1+aidx))((pos)[0] = (1)*(pos)[0] + (((double)(coordOut[aidx + baseDim ])))*(grid + 1 + 5*(1+aidx))[0], (pos)[1] = (1)*(pos)[1] + (( (double)(coordOut[aidx + baseDim])))*(grid + 1 + 5*(1+aidx))[ 1], (pos)[2] = (1)*(pos)[2] + (((double)(coordOut[aidx + baseDim ])))*(grid + 1 + 5*(1+aidx))[2], (pos)[3] = (1)*(pos)[3] + (( (double)(coordOut[aidx + baseDim])))*(grid + 1 + 5*(1+aidx))[ 3]); |
| 162 | } |
| 163 | if (scaleIsTau && ctx->stackPos) { |
| 164 | /* have to convert given tau values to sigma */ |
| 165 | pos[3] = airSigmaOfTau(pos[3]); |
| 166 | } |
| 167 | /* |
| 168 | printf("%s: %u -> (%u %u) -> %g %g %g %g (%s)\n", me, |
| 169 | AIR_UINT(II), |
| 170 | AIR_UINT(coordOut[0+baseDim]), |
| 171 | AIR_UINT(coordOut[1+baseDim]), |
| 172 | pos[0], pos[1], pos[2], pos[3], |
| 173 | indexSpace ? "index" : "world"); |
| 174 | */ |
| 175 | E = (ctx->stackPos |
| 176 | ? gageStackProbeSpace(ctx, pos[0], pos[1], pos[2], pos[3], |
| 177 | indexSpace, clamp) |
| 178 | : gageProbeSpace(ctx, pos[0], pos[1], pos[2], |
| 179 | indexSpace, clamp)); |
| 180 | if (E) { |
| 181 | biffAddf(GAGEgageBiffKey, "%s: trouble at II=%s =(%g,%g,%g,%g):\n%s\n(%d)\n", me, |
| 182 | airSprintSize_t(stmp[0], II), |
| 183 | pos[0], pos[1], pos[2], pos[3], |
| 184 | ctx->errStr, ctx->errNum); |
| 185 | airMopError(mop); return 1; |
| 186 | } |
| 187 | if (1 == ansLen) { |
| 188 | ins(nout->data, II, (ctx->edgeFrac > eft |
| 189 | ? eftVal |
| 190 | : *answer)); |
| 191 | } else { |
| 192 | for (aidx=0; aidx<ansLen; aidx++) { |
| 193 | ins(nout->data, aidx + ansLen*II, (ctx->edgeFrac > eft |
| 194 | ? eftVal |
| 195 | : answer[aidx])); |
| 196 | } |
| 197 | } |
| 198 | NRRD_COORD_INCR(coordOut, sizeOut, dim, baseDim)if ((baseDim) < (dim)) { (coordOut)[(baseDim)]++; { unsigned int ddd; for (ddd=0; ddd+1 < ((dim)-(baseDim)) && ((coordOut)+(baseDim))[ddd] >= ((sizeOut)+(baseDim))[ddd] ; ddd++) { ((coordOut)+(baseDim))[ddd] = 0; ((coordOut)+(baseDim ))[ddd+1]++; } if ((dim)-(baseDim)) { ((coordOut)+(baseDim))[ ((dim)-(baseDim))-1] = ((((coordOut)+(baseDim))[((dim)-(baseDim ))-1]) < (((sizeOut)+(baseDim))[((dim)-(baseDim))-1]-1) ? ( ((coordOut)+(baseDim))[((dim)-(baseDim))-1]) : (((sizeOut)+(baseDim ))[((dim)-(baseDim))-1]-1)); } }; }; |
| 199 | } |
| 200 | if (verbose && verbose <= 1) { |
| 201 | fprintf(stderr__stderrp, "\n"); |
| 202 | } |
| 203 | |
| 204 | if (!indexSpace) { |
| 205 | /* set the output space directions, but (being conservative/cautious) |
| 206 | only do so when grid had specified world-space positions */ |
| 207 | /* HEY: untested! whipped up out of frustration for GLK Bonn talk */ |
| 208 | nout->spaceDim = 3; |
| 209 | if (baseDim) { |
| 210 | nrrdSpaceVecSetNaN(nout->axis[0].spaceDirection); |
| 211 | } |
| 212 | nrrdSpaceVecCopy(nout->spaceOrigin, grid + 1 + 5*0); |
| 213 | for (aidx=0; aidx<gridDim; aidx++) { |
| 214 | nrrdSpaceVecCopy(nout->axis[baseDim+aidx].spaceDirection, |
| 215 | grid + 1 + 5*(1+aidx)); |
| 216 | } |
| 217 | } |
| 218 | airMopOkay(mop); |
| 219 | return 0; |
| 220 | } |
| 221 | |
| 222 | static const char *probeInfo = |
| 223 | ("Shows off the functionality of the gage library. " |
| 224 | "Uses gageProbe() to query various kinds of volumes " |
| 225 | "to learn various measured or derived quantities."); |
| 226 | |
| 227 | int |
| 228 | main(int argc, const char *argv[]) { |
| 229 | gageKind *kind; |
| 230 | const char *me; |
| 231 | char *whatS, *err, *outS, *stackFnameFormat; |
| 232 | hestParm *hparm; |
| 233 | hestOpt *hopt = NULL((void*)0); |
| 234 | NrrdKernelSpec *k00, *k11, *k22, *kSS, *kSSblur; |
| 235 | int what, E=0, renorm, uniformSS, optimSS, verbose, zeroZ, |
| 236 | orientationFromSpacing, probeSpaceIndex, normdSS; |
| 237 | unsigned int iBaseDim, oBaseDim, axi, numSS, seed; |
| 238 | const double *answer; |
| 239 | Nrrd *nin, *_npos, *npos, *_ngrid, *ngrid, *nout, **ninSS=NULL((void*)0); |
| 240 | Nrrd *ngrad=NULL((void*)0), *nbmat=NULL((void*)0); |
| 241 | size_t six, siy, siz, sox, soy, soz; |
| 242 | double bval=0, eps, gmc, rangeSS[2], *pntPos, scale[3], posSS, biasSS, |
| 243 | dsix, dsiy, dsiz, dsox, dsoy, dsoz, edgeFracInfo[2]; |
| 244 | gageContext *ctx; |
| 245 | gagePerVolume *pvl=NULL((void*)0); |
| 246 | double t0, t1, rscl[3], min[3], maxOut[3], maxIn[3]; |
| 247 | airArray *mop; |
| 248 | #define NON_SBP_OPT_NUM5 5 |
| 249 | unsigned int ansLen, *skip, skipNum, pntPosNum, |
| 250 | nonSbpOpi[NON_SBP_OPT_NUM5], nsi; |
| 251 | gageStackBlurParm *sbpIN, *sbpCL, *sbp; |
| 252 | int otype, clamp, scaleIsTau; |
| 253 | char stmp[4][AIR_STRLEN_SMALL(128+1)]; |
| 254 | |
| 255 | me = argv[0]; |
| 256 | /* parse environment variables first, in case they break nrrdDefault* |
| 257 | or nrrdState* variables in a way that nrrdSanity() should see */ |
| 258 | nrrdDefaultGetenv(); |
| 259 | nrrdStateGetenv(); |
| 260 | /* no harm done in making sure we're sane */ |
| 261 | if (!nrrdSanity()) { |
| 262 | fprintf(stderr__stderrp, "******************************************\n"); |
| 263 | fprintf(stderr__stderrp, "******************************************\n"); |
| 264 | fprintf(stderr__stderrp, "\n"); |
| 265 | fprintf(stderr__stderrp, " %s: nrrd sanity check FAILED.\n", me); |
| 266 | fprintf(stderr__stderrp, "\n"); |
| 267 | fprintf(stderr__stderrp, " This means that either nrrd can't work on this " |
| 268 | "platform, or (more likely)\n"); |
| 269 | fprintf(stderr__stderrp, " there was an error in the compilation options " |
| 270 | "and variable definitions\n"); |
| 271 | fprintf(stderr__stderrp, " for how Teem was built here.\n"); |
| 272 | fprintf(stderr__stderrp, "\n"); |
| 273 | fprintf(stderr__stderrp, " %s\n", err = biffGetDone(NRRDnrrdBiffKey)); |
| 274 | fprintf(stderr__stderrp, "\n"); |
| 275 | fprintf(stderr__stderrp, "******************************************\n"); |
| 276 | fprintf(stderr__stderrp, "******************************************\n"); |
| 277 | free(err); |
| 278 | return 1; |
| 279 | } |
| 280 | |
| 281 | mop = airMopNew(); |
| 282 | hparm = hestParmNew(); |
| 283 | airMopAdd(mop, hparm, AIR_CAST(airMopper, hestParmFree)((airMopper)(hestParmFree)), airMopAlways); |
| 284 | hparm->elideSingleOtherType = AIR_TRUE1; |
| 285 | hestOptAdd(&hopt, "i", "nin", airTypeOther, 1, 1, &nin, NULL((void*)0), |
| 286 | "input volume", NULL((void*)0), NULL((void*)0), nrrdHestNrrd); |
| 287 | hestOptAdd(&hopt, "k", "kind", airTypeOther, 1, 1, &kind, NULL((void*)0), |
| 288 | "\"kind\" of volume (\"scalar\", \"vector\", " |
| 289 | "\"tensor\", or \"dwi\")", |
| 290 | NULL((void*)0), NULL((void*)0), meetHestGageKind); |
| 291 | hestOptAdd(&hopt, "v", "verbosity", airTypeInt, 1, 1, &verbose, "1", |
| 292 | "verbosity level"); |
| 293 | hestOptAdd(&hopt, "q", "query", airTypeString, 1, 1, &whatS, NULL((void*)0), |
| 294 | "the quantity (scalar, vector, or matrix) to learn by probing"); |
| 295 | hestOptAdd(&hopt, "gmc", "min gradmag", airTypeDouble, 1, 1, &gmc, |
| 296 | "0.0", "For curvature-based queries, use zero when gradient " |
| 297 | "magnitude is below this"); |
| 298 | hestOptAdd(&hopt, "ofs", "ofs", airTypeInt, 0, 0, &orientationFromSpacing, |
| 299 | NULL((void*)0), "If only per-axis spacing is available, use that to " |
| 300 | "contrive full orientation info"); |
| 301 | hestOptAdd(&hopt, "seed", "N", airTypeUInt, 1, 1, &seed, "42", |
| 302 | "RNG seed; mostly for debugging"); |
| 303 | hestOptAdd(&hopt, "c", "bool", airTypeBool, 1, 1, &clamp, "false", |
| 304 | "clamp positions as part of probing"); |
| 305 | hestOptAdd(&hopt, "ev", "thresh val", airTypeDouble, 2, 2, |
| 306 | edgeFracInfo, "1 0", |
| 307 | "if using position clamping (with \"-c true\"), the fraction " |
| 308 | "of values invented for the kernel support, or \"edge frac\" " |
| 309 | "is saved per probe (0 means kernel support was entirely within " |
| 310 | "data; 1 means everything was invented). " |
| 311 | "If this frac exceeds the first \"thresh\" " |
| 312 | "value given here, then the saved value for the probe will be " |
| 313 | "the second value \"val\" given here"); |
| 314 | hestOptAdd(&hopt, "zz", "bool", airTypeBool, 1, 1, &zeroZ, "false", |
| 315 | "enable \"zeroZ\" behavior in gage that partially " |
| 316 | "implements working with 3D images as if they are 2D"); |
| 317 | |
| 318 | hestOptAdd(&hopt, "k00", "kern00", airTypeOther, 1, 1, &k00, |
| 319 | "tent", "kernel for gageKernel00", |
| 320 | NULL((void*)0), NULL((void*)0), nrrdHestKernelSpec); |
| 321 | hestOptAdd(&hopt, "k11", "kern11", airTypeOther, 1, 1, &k11, |
| 322 | "cubicd:1,0", "kernel for gageKernel11", |
| 323 | NULL((void*)0), NULL((void*)0), nrrdHestKernelSpec); |
| 324 | hestOptAdd(&hopt, "k22", "kern22", airTypeOther, 1, 1, &k22, |
| 325 | "cubicdd:1,0", "kernel for gageKernel22", |
| 326 | NULL((void*)0), NULL((void*)0), nrrdHestKernelSpec); |
| 327 | hestOptAdd(&hopt, "rn", NULL((void*)0), airTypeInt, 0, 0, &renorm, NULL((void*)0), |
| 328 | "renormalize kernel weights at each new sample location. " |
| 329 | "\"Accurate\" kernels don't need this; doing it always " |
| 330 | "makes things go slower"); |
| 331 | |
| 332 | nsi = 0; |
| 333 | nonSbpOpi[nsi++] = |
| 334 | hestOptAdd(&hopt, "ssn", "SS #", airTypeUInt, 1, 1, &numSS, |
| 335 | "0", "how many scale-space samples to evaluate, or, " |
| 336 | "0 to turn-off all scale-space behavior"); |
| 337 | nonSbpOpi[nsi++] = |
| 338 | hestOptAdd(&hopt, "ssr", "scale range", airTypeDouble, 2, 2, rangeSS, |
| 339 | "nan nan", "range of scales in scale-space"); |
| 340 | nonSbpOpi[nsi++] = |
| 341 | hestOptAdd(&hopt, "ssu", NULL((void*)0), airTypeInt, 0, 0, &uniformSS, NULL((void*)0), |
| 342 | "do uniform samples along sigma, and not (by default) " |
| 343 | "samples according to the effective diffusion scale"); |
| 344 | nonSbpOpi[nsi++] = |
| 345 | hestOptAdd(&hopt, "sso", NULL((void*)0), airTypeInt, 0, 0, &optimSS, NULL((void*)0), |
| 346 | "if not using \"-ssu\", use pre-computed optimal " |
| 347 | "sigmas when possible"); |
| 348 | nonSbpOpi[nsi++] = |
| 349 | hestOptAdd(&hopt, "kssb", "kernel", airTypeOther, 1, 1, &kSSblur, |
| 350 | "dgauss:1,5", "blurring kernel, to sample scale space", |
| 351 | NULL((void*)0), NULL((void*)0), nrrdHestKernelSpec); |
| 352 | if (nsi != NON_SBP_OPT_NUM5) { |
| 353 | fprintf(stderr__stderrp, "%s: PANIC nsi %u != %u", me, nsi, NON_SBP_OPT_NUM5); |
| 354 | exit(1); |
| 355 | } |
| 356 | hestOptAdd(&hopt, "sbp", "blur spec", airTypeOther, 1, 1, &sbpCL, "", |
| 357 | "complete specification of stack blur parms; " |
| 358 | "over-rides all previous \"ss\" options", |
| 359 | NULL((void*)0), NULL((void*)0), gageHestStackBlurParm); |
| 360 | /* These two options are needed even if sbp is used, because they are *not* |
| 361 | part of the gageStackBlurParm. In meet, this info is handled by the |
| 362 | extraFlag/extraParm construct, which is not available here */ |
| 363 | hestOptAdd(&hopt, "ssnd", NULL((void*)0), airTypeInt, 0, 0, &normdSS, NULL((void*)0), |
| 364 | "normalize derivatives by scale"); |
| 365 | hestOptAdd(&hopt, "ssnb", "bias", airTypeDouble, 1, 1, &biasSS, "0.0", |
| 366 | "bias on scale-based derivative normalization"); |
| 367 | |
| 368 | hestOptAdd(&hopt, "ssf", "SS read/save format", airTypeString, 1, 1, |
| 369 | &stackFnameFormat, "", |
| 370 | "printf-style format (including a \"%u\") for the " |
| 371 | "filenames from which to read " |
| 372 | "pre-blurred volumes computed for the stack, if they " |
| 373 | "exist and match the stack parameters, and where to save " |
| 374 | "them if they had to be re-computed. Leave this as empty " |
| 375 | "string to disable this."); |
| 376 | |
| 377 | hestOptAdd(&hopt, "kssr", "kernel", airTypeOther, 1, 1, &kSS, |
| 378 | "hermite", "kernel for reconstructing from scale space samples", |
| 379 | NULL((void*)0), NULL((void*)0), nrrdHestKernelSpec); |
| 380 | hestOptAdd(&hopt, "sit", "sit", airTypeBool, 1, 1, &scaleIsTau, "false", |
| 381 | "in some places, scale should be interpreted as tau, not " |
| 382 | "sigma. Currently limited to grid probing (via \"-pg\")"); |
| 383 | |
| 384 | hestOptAdd(&hopt, "s", "sclX sclY sxlZ", airTypeDouble, 3, 3, scale, |
| 385 | "1 1 1", |
| 386 | "scaling factor for resampling on each axis " |
| 387 | "(>1.0 : supersampling); use \"-ssp\" (and \"-psi\")" |
| 388 | "to specify scale position of sampling"); |
| 389 | hestOptAdd(&hopt, "ssp", "pos", airTypeDouble, 1, 1, &posSS, "0", |
| 390 | "when using scale-space, scale-position at which to probe"); |
| 391 | hestOptAdd(&hopt, "pg", "nrrd", airTypeOther, 1, 1, &_ngrid, "", |
| 392 | "overrides \"-s\": " |
| 393 | "2-D nrrd which specifies origin and direction vectors " |
| 394 | "for sampling grid", NULL((void*)0), NULL((void*)0), nrrdHestNrrd); |
| 395 | hestOptAdd(&hopt, "pi", "nrrd", airTypeOther, 1, 1, &_npos, "", |
| 396 | "overrides \"-pv\": probes at this list of 3-vec or " |
| 397 | "4-vec positions", NULL((void*)0), NULL((void*)0), nrrdHestNrrd); |
| 398 | hestOptAdd(&hopt, "pp", "pos", airTypeDouble, 3, 4, &pntPos, |
| 399 | "nan nan nan", |
| 400 | "overrides \"-pi\": only sample at this specified point", |
| 401 | &pntPosNum); |
| 402 | hestOptAdd(&hopt, "eps", "epsilon", airTypeDouble, 1, 1, &eps, "0", |
| 403 | "if non-zero, and if query is a scalar, and if using \"pp\" " |
| 404 | "to query at a single point, then do epsilon offset probes " |
| 405 | "to calculate discrete differences, to find the numerical " |
| 406 | "gradient and hessian (for debugging)"); |
| 407 | hestOptAdd(&hopt, "psi", "p", airTypeBool, 1, 1, &probeSpaceIndex, "false", |
| 408 | "whether the probe location specification (by any of " |
| 409 | "the four previous flags) are in index space"); |
| 410 | |
| 411 | hestOptAdd(&hopt, "t", "type", airTypeEnum, 1, 1, &otype, "float", |
| 412 | "type of output volume", NULL((void*)0), nrrdType); |
| 413 | hestOptAdd(&hopt, "o", "nout", airTypeString, 1, 1, &outS, "-", |
| 414 | "output volume"); |
| 415 | hestParseOrDie(hopt, argc-1, argv+1, hparm, |
| 416 | me, probeInfo, AIR_TRUE1, AIR_TRUE1, AIR_TRUE1); |
| 417 | airMopAdd(mop, hopt, AIR_CAST(airMopper, hestOptFree)((airMopper)(hestOptFree)), airMopAlways); |
| 418 | airMopAdd(mop, hopt, AIR_CAST(airMopper, hestParseFree)((airMopper)(hestParseFree)), airMopAlways); |
| 419 | |
| 420 | what = airEnumVal(kind->enm, whatS); |
| 421 | if (!what) { |
| 422 | /* 0 indeed always means "unknown" for any gageKind */ |
| 423 | fprintf(stderr__stderrp, "%s: couldn't parse \"%s\" as measure of \"%s\" volume\n", |
| 424 | me, whatS, kind->name); |
| 425 | hestUsage(stderr__stderrp, hopt, me, hparm); |
| 426 | hestGlossary(stderr__stderrp, hopt, hparm); |
| 427 | airMopError(mop); return 1; |
| 428 | } |
| 429 | |
| 430 | /* special set-up required for DWI kind */ |
| 431 | if (!strcmp(TEN_DWI_GAGE_KIND_NAME"dwi", kind->name)) { |
| 432 | if (tenDWMRIKeyValueParse(&ngrad, &nbmat, &bval, &skip, &skipNum, nin)) { |
| 433 | airMopAdd(mop, err = biffGetDone(TENtenBiffKey), airFree, airMopAlways); |
| 434 | fprintf(stderr__stderrp, "%s: trouble parsing DWI info:\n%s\n", me, err); |
| 435 | airMopError(mop); return 1; |
| 436 | } |
| 437 | if (skipNum) { |
| 438 | fprintf(stderr__stderrp, "%s: sorry, can't do DWI skipping in tenDwiGage", me); |
| 439 | airMopError(mop); return 1; |
| 440 | } |
| 441 | /* this could stand to use some more command-line arguments */ |
| 442 | if (tenDwiGageKindSet(kind, 50, 1, bval, 0.001, ngrad, nbmat, |
| 443 | tenEstimate1MethodLLS, |
| 444 | tenEstimate2MethodQSegLLS, seed)) { |
| 445 | airMopAdd(mop, err = biffGetDone(TENtenBiffKey), airFree, airMopAlways); |
| 446 | fprintf(stderr__stderrp, "%s: trouble parsing DWI info:\n%s\n", me, err); |
| 447 | airMopError(mop); return 1; |
| 448 | } |
| 449 | } |
| 450 | |
| 451 | /* for setting up pre-blurred scale-space samples */ |
| 452 | if (numSS || sbpCL) { |
| 453 | unsigned int vi; |
| 454 | int recompute, gotOld; |
| 455 | |
| 456 | if (sbpCL) { |
| 457 | /* we got the whole stack blar parm here */ |
| 458 | gotOld = AIR_FALSE0; |
| 459 | for (nsi=0; nsi<NON_SBP_OPT_NUM5; nsi++) { |
| 460 | gotOld |= (hestSourceUser == hopt[nonSbpOpi[nsi]].source); |
| 461 | } |
| 462 | if (gotOld) { |
| 463 | fprintf(stderr__stderrp, "%s: with new -sbp option; can't also use older " |
| 464 | "scale-space options (used", me); |
| 465 | for (nsi=0; nsi<NON_SBP_OPT_NUM5; nsi++) { |
| 466 | if (hestSourceUser == hopt[nonSbpOpi[nsi]].source) { |
| 467 | fprintf(stderr__stderrp, " -%s", hopt[nonSbpOpi[nsi]].flag); |
| 468 | } |
| 469 | } |
| 470 | fprintf(stderr__stderrp, ")\n"); |
| 471 | airMopError(mop); return 1; |
| 472 | } |
| 473 | if (gageStackBlurManage(&ninSS, &recompute, sbpCL, |
| 474 | stackFnameFormat, AIR_TRUE1, NULL((void*)0), |
| 475 | nin, kind)) { |
| 476 | airMopAdd(mop, err = biffGetDone(GAGEgageBiffKey), airFree, airMopAlways); |
| 477 | fprintf(stderr__stderrp, "%s: trouble getting volume stack:\n%s\n", me, err); |
| 478 | airMopError(mop); return 1; |
| 479 | } |
| 480 | if (sbpCL->verbose > 2) { |
| 481 | fprintf(stderr__stderrp, "%s: sampling scale range %g--%g via %s:\n", me, |
| 482 | sbpCL->sigmaRange[0], sbpCL->sigmaRange[1], |
| 483 | airEnumStr(gageSigmaSampling, sbpCL->sigmaSampling)); |
| 484 | for (vi=0; vi<sbpCL->num; vi++) { |
| 485 | fprintf(stderr__stderrp, " sigma[%u] = %g\n", vi, sbpCL->sigma[vi]); |
| 486 | } |
| 487 | } |
| 488 | sbp = sbpCL; |
| 489 | } else { |
| 490 | /* old way of doing things; depending on many separate options |
| 491 | to set numSS, rangeSS, uniformSS, optimSS, etc */ |
| 492 | sbpIN = gageStackBlurParmNew(); |
| 493 | airMopAdd(mop, sbpIN, (airMopper)gageStackBlurParmNix, airMopAlways); |
| 494 | if (gageStackBlurParmVerboseSet(sbpIN, verbose) |
| 495 | || gageStackBlurParmScaleSet(sbpIN, numSS, rangeSS[0], rangeSS[1], |
| 496 | uniformSS, optimSS) |
| 497 | || gageStackBlurParmKernelSet(sbpIN, kSSblur) |
| 498 | || gageStackBlurParmRenormalizeSet(sbpIN, AIR_TRUE1) |
| 499 | || gageStackBlurParmBoundarySet(sbpIN, nrrdBoundaryBleed, AIR_NAN(airFloatQNaN.f)) |
| 500 | || gageStackBlurManage(&ninSS, &recompute, sbpIN, |
| 501 | stackFnameFormat, AIR_TRUE1, NULL((void*)0), |
| 502 | nin, kind)) { |
| 503 | airMopAdd(mop, err = biffGetDone(GAGEgageBiffKey), airFree, airMopAlways); |
| 504 | fprintf(stderr__stderrp, "%s: trouble getting volume stack:\n%s\n", me, err); |
| 505 | airMopError(mop); return 1; |
| 506 | } |
| 507 | if (verbose > 2) { |
| 508 | fprintf(stderr__stderrp, "%s: sampling scale range %g--%g %suniformly:\n", me, |
| 509 | rangeSS[0], rangeSS[1], uniformSS ? "" : "non-"); |
| 510 | for (vi=0; vi<numSS; vi++) { |
| 511 | fprintf(stderr__stderrp, " scalePos[%u] = %g\n", vi, sbpIN->sigma[vi]); |
| 512 | } |
| 513 | } |
| 514 | sbp = sbpIN; |
| 515 | } |
| 516 | airMopAdd(mop, ninSS, airFree, airMopAlways); |
| 517 | } else { |
| 518 | ninSS = NULL((void*)0); |
| 519 | sbpIN = NULL((void*)0); |
| 520 | sbp = NULL((void*)0); |
| 521 | } |
| 522 | |
| 523 | /*** |
| 524 | **** Except for the gageProbe() call in the inner loop below, |
| 525 | **** and the gageContextNix() call at the very end, all the gage |
| 526 | **** calls which set up (and take down) the context and state are here. |
| 527 | ***/ |
| 528 | ctx = gageContextNew(); |
| 529 | airMopAdd(mop, ctx, AIR_CAST(airMopper, gageContextNix)((airMopper)(gageContextNix)), airMopAlways); |
| 530 | gageParmSet(ctx, gageParmGradMagCurvMin, gmc); |
| 531 | gageParmSet(ctx, gageParmVerbose, verbose); |
| 532 | gageParmSet(ctx, gageParmTwoDimZeroZ, zeroZ); |
| 533 | gageParmSet(ctx, gageParmRenormalize, renorm ? AIR_TRUE1 : AIR_FALSE0); |
| 534 | gageParmSet(ctx, gageParmCheckIntegrals, AIR_TRUE1); |
| 535 | gageParmSet(ctx, gageParmOrientationFromSpacing, orientationFromSpacing); |
| 536 | E = 0; |
| 537 | if (!E) E |= !(pvl = gagePerVolumeNew(ctx, nin, kind)); |
| 538 | if (!E) E |= gageKernelSet(ctx, gageKernel00, k00->kernel, k00->parm); |
| 539 | if (!E) E |= gageKernelSet(ctx, gageKernel11, k11->kernel, k11->parm); |
| 540 | if (!E) E |= gageKernelSet(ctx, gageKernel22, k22->kernel, k22->parm); |
| 541 | if (sbp) { |
| 542 | gagePerVolume **pvlSS; |
| 543 | gageParmSet(ctx, gageParmStackUse, AIR_TRUE1); |
| 544 | gageParmSet(ctx, gageParmStackNormalizeDeriv, normdSS); |
| 545 | gageParmSet(ctx, gageParmStackNormalizeDerivBias, biasSS); |
| 546 | if (!E) E |= !(pvlSS = AIR_CAST(gagePerVolume **,((gagePerVolume **)(calloc(sbp->num, sizeof(gagePerVolume * )))) |
| 547 | calloc(sbp->num, sizeof(gagePerVolume *)))((gagePerVolume **)(calloc(sbp->num, sizeof(gagePerVolume * ))))); |
| 548 | if (!E) airMopAdd(mop, pvlSS, (airMopper)airFree, airMopAlways); |
| 549 | if (!E) E |= gageStackPerVolumeNew(ctx, pvlSS, |
| 550 | AIR_CAST(const Nrrd*const*, ninSS)((const Nrrd*const*)(ninSS)), |
| 551 | sbp->num, kind); |
| 552 | if (!E) E |= gageStackPerVolumeAttach(ctx, pvl, pvlSS, |
| 553 | sbp->sigma, sbp->num); |
| 554 | if (!E) E |= gageKernelSet(ctx, gageKernelStack, kSS->kernel, kSS->parm); |
| 555 | } else { |
| 556 | if (!E) E |= gagePerVolumeAttach(ctx, pvl); |
| 557 | } |
| 558 | if (!E) E |= gageQueryItemOn(ctx, pvl, what); |
| 559 | if (!E) E |= gageUpdate(ctx); |
| 560 | if (E) { |
| 561 | airMopAdd(mop, err = biffGetDone(GAGEgageBiffKey), airFree, airMopAlways); |
| 562 | fprintf(stderr__stderrp, "%s: trouble:\n%s\n", me, err); |
| 563 | airMopError(mop); return 1; |
| 564 | } |
| 565 | answer = gageAnswerPointer(ctx, pvl, what); |
| 566 | ansLen = kind->table[what].answerLength; |
| 567 | /*** |
| 568 | **** end gage setup. |
| 569 | ***/ |
| 570 | if (verbose) { |
| 571 | fprintf(stderr__stderrp, "%s: kernel support = %d^3 samples\n", me, |
| 572 | 2*ctx->radius); |
| 573 | } |
| 574 | |
| 575 | if (ELL_3V_EXISTS(pntPos)((((int)(!(((pntPos)[0]) - ((pntPos)[0]))))) && (((int )(!(((pntPos)[1]) - ((pntPos)[1]))))) && (((int)(!((( pntPos)[2]) - ((pntPos)[2]))))))) { |
| 576 | /* only interested in a single point, make sure we have the right |
| 577 | info about the point WRT scale stuff */ |
| 578 | if (sbp) { |
| 579 | if (!(4 == pntPosNum && ELL_4V_EXISTS(pntPos)((((int)(!(((pntPos)[0]) - ((pntPos)[0]))))) && (((int )(!(((pntPos)[1]) - ((pntPos)[1]))))) && (((int)(!((( pntPos)[2]) - ((pntPos)[2]))))) && (((int)(!(((pntPos )[3]) - ((pntPos)[3])))))))) { |
| 580 | fprintf(stderr__stderrp, "%s: need a 4-vec position with scale-space", me); |
| 581 | airMopError(mop); return 1; |
| 582 | } |
| 583 | } else { |
| 584 | if (!(3 == pntPosNum)) { |
| 585 | fprintf(stderr__stderrp, "%s: need a 3-vec position (w/out scale-space)", me); |
| 586 | airMopError(mop); return 1; |
| 587 | } |
| 588 | } |
| 589 | if (sbp |
| 590 | ? gageStackProbeSpace(ctx, |
| 591 | pntPos[0], pntPos[1], pntPos[2], pntPos[3], |
| 592 | probeSpaceIndex, clamp) |
| 593 | : gageProbeSpace(ctx, |
| 594 | pntPos[0], pntPos[1], pntPos[2], |
| 595 | probeSpaceIndex, clamp)) { |
| 596 | fprintf(stderr__stderrp, "%s: trouble probing: (errNum %d) %s\n", me, |
| 597 | ctx->errNum, ctx->errStr); |
| 598 | airMopError(mop); return 1; |
| 599 | } |
| 600 | if (sbp) { |
| 601 | printf("%s: %s(%s:%g,%g,%g,%g) = ", me, airEnumStr(kind->enm, what), |
| 602 | probeSpaceIndex ? "index" : "world", |
| 603 | pntPos[0], pntPos[1], pntPos[2], pntPos[3]); |
| 604 | } else { |
| 605 | printf("%s: %s(%s:%g,%g,%g) = ", me, airEnumStr(kind->enm, what), |
| 606 | probeSpaceIndex ? "index" : "world", |
| 607 | pntPos[0], pntPos[1], pntPos[2]); |
| 608 | } |
| 609 | printans(stdout__stdoutp, answer, ansLen); |
| 610 | printf("\n"); |
| 611 | /* we're done, get out of here */ |
| 612 | /* except if we're supposed to debug derivatives */ |
| 613 | if (eps && 1 == ansLen) { |
| 614 | double v[3][3][3], fes, ee; |
| 615 | int xo, yo, zo; |
| 616 | if (probeSpaceIndex) { |
| 617 | fprintf(stderr__stderrp, "\n%s: WARNING!!: not probing in world-space (via " |
| 618 | "\"-wsp\") likely leads to errors in estimated " |
| 619 | "derivatives\n\n", me); |
| 620 | } |
| 621 | gageParmSet(ctx, gageParmVerbose, 0); |
| 622 | #define PROBE(x, y, z)((sbp ? gageStackProbeSpace(ctx, x, y, z, posSS, probeSpaceIndex , clamp) : gageProbeSpace(ctx, x, y, z, probeSpaceIndex, clamp )),answer[0]) \ |
| 623 | ((sbp \ |
| 624 | ? gageStackProbeSpace(ctx, x, y, z, posSS, \ |
| 625 | probeSpaceIndex, clamp) \ |
| 626 | : gageProbeSpace(ctx, x, y, z, probeSpaceIndex, \ |
| 627 | clamp)),answer[0]) |
| 628 | for (xo=0; xo<=2; xo++) { |
| 629 | for (yo=0; yo<=2; yo++) { |
| 630 | for (zo=0; zo<=2; zo++) { |
| 631 | v[xo][yo][zo] = PROBE(pntPos[0] + (xo-1)*eps,((sbp ? gageStackProbeSpace(ctx, pntPos[0] + (xo-1)*eps, pntPos [1] + (yo-1)*eps, pntPos[2] + (zo-1)*eps, posSS, probeSpaceIndex , clamp) : gageProbeSpace(ctx, pntPos[0] + (xo-1)*eps, pntPos [1] + (yo-1)*eps, pntPos[2] + (zo-1)*eps, probeSpaceIndex, clamp )),answer[0]) |
| 632 | pntPos[1] + (yo-1)*eps,((sbp ? gageStackProbeSpace(ctx, pntPos[0] + (xo-1)*eps, pntPos [1] + (yo-1)*eps, pntPos[2] + (zo-1)*eps, posSS, probeSpaceIndex , clamp) : gageProbeSpace(ctx, pntPos[0] + (xo-1)*eps, pntPos [1] + (yo-1)*eps, pntPos[2] + (zo-1)*eps, probeSpaceIndex, clamp )),answer[0]) |
| 633 | pntPos[2] + (zo-1)*eps)((sbp ? gageStackProbeSpace(ctx, pntPos[0] + (xo-1)*eps, pntPos [1] + (yo-1)*eps, pntPos[2] + (zo-1)*eps, posSS, probeSpaceIndex , clamp) : gageProbeSpace(ctx, pntPos[0] + (xo-1)*eps, pntPos [1] + (yo-1)*eps, pntPos[2] + (zo-1)*eps, probeSpaceIndex, clamp )),answer[0]); |
| 634 | } |
| 635 | } |
| 636 | } |
| 637 | printf("%s: approx gradient(%s) at (%g,%g,%g) = %f %f %f\n", me, |
| 638 | airEnumStr(kind->enm, what), pntPos[0], pntPos[1], pntPos[2], |
| 639 | (v[2][1][1] - v[0][1][1])/(2*eps), |
| 640 | (v[1][2][1] - v[1][0][1])/(2*eps), |
| 641 | (v[1][1][2] - v[1][1][0])/(2*eps)); |
| 642 | fes = 4*eps*eps; |
| 643 | ee = eps*eps; |
| 644 | printf("%s: approx hessian(%s) at (%g,%g,%g) = \n" |
| 645 | "%f %f %f\n" |
| 646 | " %f %f\n" |
| 647 | " %f\n", me, |
| 648 | airEnumStr(kind->enm, what), pntPos[0], pntPos[1], pntPos[2], |
| 649 | (v[0][1][1] - 2*v[1][1][1] + v[2][1][1])/ee, |
| 650 | (v[2][2][1] - v[0][2][1] - v[2][0][1] + v[0][0][1])/fes, |
| 651 | (v[2][1][2] - v[0][1][2] - v[2][1][0] + v[0][1][0])/fes, |
| 652 | (v[1][2][1] - 2*v[1][1][1] + v[1][0][1])/ee, |
| 653 | (v[1][2][2] - v[1][0][2] - v[1][2][0] + v[1][0][0])/fes, |
| 654 | (v[1][1][2] - 2*v[1][1][1] + v[1][1][0])/ee); |
| 655 | } |
| 656 | airMopOkay(mop); return 0; |
| 657 | } |
| 658 | |
| 659 | if (_npos) { |
| 660 | /* given a nrrd of probe locations */ |
| 661 | double *pos, (*ins)(void *v, size_t I, double d); |
| 662 | size_t II, NN; |
| 663 | unsigned int aidx; |
| 664 | if (!(2 == _npos->dim |
| 665 | && (3 == _npos->axis[0].size || 4 == _npos->axis[0].size))) { |
| 666 | fprintf(stderr__stderrp, "%s: need npos 2-D 3-by-N or 4-by-N " |
| 667 | "(not %u-D %u-by-N)\n", me, _npos->dim, |
| 668 | AIR_UINT(_npos->axis[0].size)((unsigned int)(_npos->axis[0].size))); |
| 669 | airMopError(mop); return 1; |
| 670 | } |
| 671 | if ((sbp && 3 == _npos->axis[0].size) |
| 672 | || (!sbp && 4 == _npos->axis[0].size)) { |
| 673 | fprintf(stderr__stderrp, "%s: have %u point coords but %s using scale-space\n", |
| 674 | me, AIR_UINT(_npos->axis[0].size)((unsigned int)(_npos->axis[0].size)), |
| 675 | sbp ? "are" : "are not"); |
| 676 | airMopError(mop); return 1; |
| 677 | } |
| 678 | NN = _npos->axis[1].size; |
| 679 | npos = nrrdNew(); |
| 680 | airMopAdd(mop, npos, AIR_CAST(airMopper, nrrdNuke)((airMopper)(nrrdNuke)), airMopAlways); |
| 681 | nout = nrrdNew(); |
| 682 | airMopAdd(mop, nout, AIR_CAST(airMopper, nrrdNuke)((airMopper)(nrrdNuke)), airMopAlways); |
| 683 | if (nrrdConvert(npos, _npos, nrrdTypeDouble) |
| 684 | || nrrdMaybeAlloc_va(nout, otype, 2, |
| 685 | AIR_CAST(size_t, ansLen)((size_t)(ansLen)), |
| 686 | AIR_CAST(size_t, NN)((size_t)(NN)))) { |
| 687 | airMopAdd(mop, err = biffGetDone(NRRDnrrdBiffKey), airFree, airMopAlways); |
| 688 | fprintf(stderr__stderrp, "%s: trouble with npos or nout:\n%s\n", me, err); |
| 689 | airMopError(mop); return 1; |
| 690 | } |
| 691 | |
| 692 | pos = AIR_CAST(double *, npos->data)((double *)(npos->data)); |
| 693 | ins = nrrdDInsert[nout->type]; |
| 694 | for (II=0; II<NN; II++) { |
| 695 | if (sbp) { |
| 696 | gageStackProbeSpace(ctx, pos[0], pos[1], pos[2], pos[3], |
| 697 | probeSpaceIndex, clamp); |
| 698 | } else { |
| 699 | gageProbeSpace(ctx, pos[0], pos[1], pos[2], |
| 700 | probeSpaceIndex, clamp); |
| 701 | } |
| 702 | if (1 == ansLen) { |
| 703 | ins(nout->data, II, (ctx->edgeFrac > edgeFracInfo[0] |
| 704 | ? edgeFracInfo[1] |
| 705 | : *answer)); |
| 706 | } else { |
| 707 | for (aidx=0; aidx<ansLen; aidx++) { |
| 708 | ins(nout->data, aidx + ansLen*II, (ctx->edgeFrac > edgeFracInfo[0] |
| 709 | ? edgeFracInfo[1] |
| 710 | : answer[aidx])); |
| 711 | } |
| 712 | } |
| 713 | /* |
| 714 | if (sbp) { |
| 715 | printf("%s: %s(%s:%g,%g,%g,%g) = ", me, airEnumStr(kind->enm, what), |
| 716 | probeSpaceIndex ? "index" : "world", |
| 717 | pos[0], pos[1], pos[2], pos[3]); |
| 718 | } else { |
| 719 | printf("%s: %s(%s:%g,%g,%g) = ", me, airEnumStr(kind->enm, what), |
| 720 | probeSpaceIndex ? "index" : "world", |
| 721 | pos[0], pos[1], pos[2]); |
| 722 | } |
| 723 | printans(stdout, answer, ansLen); |
| 724 | printf("\n"); |
| 725 | */ |
| 726 | pos += _npos->axis[0].size; |
| 727 | } |
| 728 | if (nrrdSave(outS, nout, NULL((void*)0))) { |
| 729 | airMopAdd(mop, err = biffGetDone(NRRDnrrdBiffKey), airFree, airMopAlways); |
| 730 | fprintf(stderr__stderrp, "%s: trouble saving output:\n%s\n", me, err); |
| 731 | airMopError(mop); |
| 732 | return 1; |
| 733 | } |
| 734 | |
| 735 | /* we're done, get out of here */ |
| 736 | airMopOkay(mop); |
| 737 | exit(0); |
| 738 | } |
| 739 | |
| 740 | /* else, we're sampling on some kind of grid */ |
| 741 | ngrid = nrrdNew(); |
| 742 | airMopAdd(mop, ngrid, (airMopper)nrrdNuke, airMopAlways); |
| 743 | iBaseDim = kind->baseDim; |
| 744 | oBaseDim = 1 == ansLen ? 0 : 1; |
| 745 | if (!_ngrid) { |
| 746 | /* did not get a grid, have to use "-s" args to define it */ |
| 747 | double *grid; |
| 748 | size_t gridSize[NRRD_DIM_MAX16]; |
| 749 | six = nin->axis[0+iBaseDim].size; |
| 750 | siy = nin->axis[1+iBaseDim].size; |
| 751 | siz = nin->axis[2+iBaseDim].size; |
| 752 | dsix = AIR_CAST(double, six)((double)(six)); |
| 753 | dsiy = AIR_CAST(double, siy)((double)(siy)); |
| 754 | dsiz = AIR_CAST(double, siz)((double)(siz)); |
| 755 | sox = AIR_CAST(size_t, scale[0]*dsix)((size_t)(scale[0]*dsix)); |
| 756 | soy = AIR_CAST(size_t, scale[1]*dsiy)((size_t)(scale[1]*dsiy)); |
| 757 | soz = AIR_CAST(size_t, scale[2]*dsiz)((size_t)(scale[2]*dsiz)); |
| 758 | dsox = AIR_CAST(double, sox)((double)(sox)); |
| 759 | dsoy = AIR_CAST(double, soy)((double)(soy)); |
| 760 | dsoz = AIR_CAST(double, soz)((double)(soz)); |
| 761 | rscl[0] = dsix/dsox; |
| 762 | rscl[1] = dsiy/dsoy; |
| 763 | rscl[2] = dsiz/dsoz; |
| 764 | if (verbose) { |
| 765 | fprintf(stderr__stderrp, "%s: creating %u x %s x %s x %s output\n", me, |
| 766 | ansLen, |
| 767 | airSprintSize_t(stmp[1], sox), |
| 768 | airSprintSize_t(stmp[2], soy), |
| 769 | airSprintSize_t(stmp[3], soz)); |
| 770 | fprintf(stderr__stderrp, "%s: effective scaling is %g %g %g\n", me, |
| 771 | rscl[0], rscl[1], rscl[2]); |
| 772 | } |
| 773 | gridSize[0] = sbp ? 5 : 4; |
| 774 | gridSize[1] = 4; |
| 775 | if (nrrdMaybeAlloc_nva(ngrid, nrrdTypeDouble, 2, gridSize)) { |
| 776 | airMopAdd(mop, err = biffGetDone(NRRDnrrdBiffKey), airFree, airMopAlways); |
| 777 | fprintf(stderr__stderrp, "%s: trouble making ngrid:\n%s\n", me, err); |
| 778 | airMopError(mop); return 1; |
| 779 | } |
| 780 | grid = AIR_CAST(double *, ngrid->data)((double *)(ngrid->data)); |
| 781 | if (nrrdCenterCell == ctx->shape->center) { |
| 782 | ELL_3V_SET(min, -0.5, -0.5, -0.5)((min)[0] = (-0.5), (min)[1] = (-0.5), (min)[2] = (-0.5)); |
| 783 | ELL_3V_SET(maxOut, dsox-0.5, dsoy-0.5, dsoz-0.5)((maxOut)[0] = (dsox-0.5), (maxOut)[1] = (dsoy-0.5), (maxOut) [2] = (dsoz-0.5)); |
| 784 | ELL_3V_SET(maxIn, dsix-0.5, dsiy-0.5, dsiz-0.5)((maxIn)[0] = (dsix-0.5), (maxIn)[1] = (dsiy-0.5), (maxIn)[2] = (dsiz-0.5)); |
| 785 | } else { |
| 786 | ELL_3V_SET(min, 0, 0, 0)((min)[0] = (0), (min)[1] = (0), (min)[2] = (0)); |
| 787 | ELL_3V_SET(maxOut, dsox-1, dsoy-1, dsoz-1)((maxOut)[0] = (dsox-1), (maxOut)[1] = (dsoy-1), (maxOut)[2] = (dsoz-1)); |
| 788 | ELL_3V_SET(maxIn, dsix-1, dsiy-1, dsiz-1)((maxIn)[0] = (dsix-1), (maxIn)[1] = (dsiy-1), (maxIn)[2] = ( dsiz-1)); |
| 789 | } |
| 790 | ELL_4V_SET(grid + gridSize[0]*0, 3,((grid + gridSize[0]*0)[0] = (3), (grid + gridSize[0]*0)[1] = ((nrrdCenterCell == (ctx->shape->center) ? ( ((double) (((maxIn[0])))-(((min[0]))))*((double)(((0)) + 0.5)-(0)) / (( double)(((sox)))-(0)) + (((min[0])))) : ( ((double)(((maxIn[0 ])))-(((min[0]))))*((double)(((0)))-(0)) / ((double)(((sox))- 1)-(0)) + (((min[0])))))), (grid + gridSize[0]*0)[2] = ((nrrdCenterCell == (ctx->shape->center) ? ( ((double)(((maxIn[1])))-(( (min[1]))))*((double)(((0)) + 0.5)-(0)) / ((double)(((soy)))- (0)) + (((min[1])))) : ( ((double)(((maxIn[1])))-(((min[1]))) )*((double)(((0)))-(0)) / ((double)(((soy))-1)-(0)) + (((min[ 1])))))), (grid + gridSize[0]*0)[3] = ((nrrdCenterCell == (ctx ->shape->center) ? ( ((double)(((maxIn[2])))-(((min[2]) )))*((double)(((0)) + 0.5)-(0)) / ((double)(((soz)))-(0)) + ( ((min[2])))) : ( ((double)(((maxIn[2])))-(((min[2]))))*((double )(((0)))-(0)) / ((double)(((soz))-1)-(0)) + (((min[2]))))))) |
| 791 | NRRD_POS(ctx->shape->center, min[0], maxIn[0], sox, 0),((grid + gridSize[0]*0)[0] = (3), (grid + gridSize[0]*0)[1] = ((nrrdCenterCell == (ctx->shape->center) ? ( ((double) (((maxIn[0])))-(((min[0]))))*((double)(((0)) + 0.5)-(0)) / (( double)(((sox)))-(0)) + (((min[0])))) : ( ((double)(((maxIn[0 ])))-(((min[0]))))*((double)(((0)))-(0)) / ((double)(((sox))- 1)-(0)) + (((min[0])))))), (grid + gridSize[0]*0)[2] = ((nrrdCenterCell == (ctx->shape->center) ? ( ((double)(((maxIn[1])))-(( (min[1]))))*((double)(((0)) + 0.5)-(0)) / ((double)(((soy)))- (0)) + (((min[1])))) : ( ((double)(((maxIn[1])))-(((min[1]))) )*((double)(((0)))-(0)) / ((double)(((soy))-1)-(0)) + (((min[ 1])))))), (grid + gridSize[0]*0)[3] = ((nrrdCenterCell == (ctx ->shape->center) ? ( ((double)(((maxIn[2])))-(((min[2]) )))*((double)(((0)) + 0.5)-(0)) / ((double)(((soz)))-(0)) + ( ((min[2])))) : ( ((double)(((maxIn[2])))-(((min[2]))))*((double )(((0)))-(0)) / ((double)(((soz))-1)-(0)) + (((min[2]))))))) |
| 792 | NRRD_POS(ctx->shape->center, min[1], maxIn[1], soy, 0),((grid + gridSize[0]*0)[0] = (3), (grid + gridSize[0]*0)[1] = ((nrrdCenterCell == (ctx->shape->center) ? ( ((double) (((maxIn[0])))-(((min[0]))))*((double)(((0)) + 0.5)-(0)) / (( double)(((sox)))-(0)) + (((min[0])))) : ( ((double)(((maxIn[0 ])))-(((min[0]))))*((double)(((0)))-(0)) / ((double)(((sox))- 1)-(0)) + (((min[0])))))), (grid + gridSize[0]*0)[2] = ((nrrdCenterCell == (ctx->shape->center) ? ( ((double)(((maxIn[1])))-(( (min[1]))))*((double)(((0)) + 0.5)-(0)) / ((double)(((soy)))- (0)) + (((min[1])))) : ( ((double)(((maxIn[1])))-(((min[1]))) )*((double)(((0)))-(0)) / ((double)(((soy))-1)-(0)) + (((min[ 1])))))), (grid + gridSize[0]*0)[3] = ((nrrdCenterCell == (ctx ->shape->center) ? ( ((double)(((maxIn[2])))-(((min[2]) )))*((double)(((0)) + 0.5)-(0)) / ((double)(((soz)))-(0)) + ( ((min[2])))) : ( ((double)(((maxIn[2])))-(((min[2]))))*((double )(((0)))-(0)) / ((double)(((soz))-1)-(0)) + (((min[2]))))))) |
| 793 | NRRD_POS(ctx->shape->center, min[2], maxIn[2], soz, 0))((grid + gridSize[0]*0)[0] = (3), (grid + gridSize[0]*0)[1] = ((nrrdCenterCell == (ctx->shape->center) ? ( ((double) (((maxIn[0])))-(((min[0]))))*((double)(((0)) + 0.5)-(0)) / (( double)(((sox)))-(0)) + (((min[0])))) : ( ((double)(((maxIn[0 ])))-(((min[0]))))*((double)(((0)))-(0)) / ((double)(((sox))- 1)-(0)) + (((min[0])))))), (grid + gridSize[0]*0)[2] = ((nrrdCenterCell == (ctx->shape->center) ? ( ((double)(((maxIn[1])))-(( (min[1]))))*((double)(((0)) + 0.5)-(0)) / ((double)(((soy)))- (0)) + (((min[1])))) : ( ((double)(((maxIn[1])))-(((min[1]))) )*((double)(((0)))-(0)) / ((double)(((soy))-1)-(0)) + (((min[ 1])))))), (grid + gridSize[0]*0)[3] = ((nrrdCenterCell == (ctx ->shape->center) ? ( ((double)(((maxIn[2])))-(((min[2]) )))*((double)(((0)) + 0.5)-(0)) / ((double)(((soz)))-(0)) + ( ((min[2])))) : ( ((double)(((maxIn[2])))-(((min[2]))))*((double )(((0)))-(0)) / ((double)(((soz))-1)-(0)) + (((min[2]))))))); |
| 794 | ELL_4V_SET(grid + gridSize[0]*1, dsox,((grid + gridSize[0]*1)[0] = (dsox), (grid + gridSize[0]*1)[1 ] = (( ((double)(maxIn[0])-(min[0]))*((double)(1)) / ((double )(maxOut[0])-(min[0])) )), (grid + gridSize[0]*1)[2] = (0), ( grid + gridSize[0]*1)[3] = (0)) |
| 795 | AIR_DELTA(min[0], 1, maxOut[0], min[0], maxIn[0]),((grid + gridSize[0]*1)[0] = (dsox), (grid + gridSize[0]*1)[1 ] = (( ((double)(maxIn[0])-(min[0]))*((double)(1)) / ((double )(maxOut[0])-(min[0])) )), (grid + gridSize[0]*1)[2] = (0), ( grid + gridSize[0]*1)[3] = (0)) |
| 796 | 0,((grid + gridSize[0]*1)[0] = (dsox), (grid + gridSize[0]*1)[1 ] = (( ((double)(maxIn[0])-(min[0]))*((double)(1)) / ((double )(maxOut[0])-(min[0])) )), (grid + gridSize[0]*1)[2] = (0), ( grid + gridSize[0]*1)[3] = (0)) |
| 797 | 0)((grid + gridSize[0]*1)[0] = (dsox), (grid + gridSize[0]*1)[1 ] = (( ((double)(maxIn[0])-(min[0]))*((double)(1)) / ((double )(maxOut[0])-(min[0])) )), (grid + gridSize[0]*1)[2] = (0), ( grid + gridSize[0]*1)[3] = (0)); |
| 798 | ELL_4V_SET(grid + gridSize[0]*2, dsoy,((grid + gridSize[0]*2)[0] = (dsoy), (grid + gridSize[0]*2)[1 ] = (0), (grid + gridSize[0]*2)[2] = (( ((double)(maxIn[1])-( min[1]))*((double)(1)) / ((double)(maxOut[1])-(min[1])) )), ( grid + gridSize[0]*2)[3] = (0)) |
| 799 | 0,((grid + gridSize[0]*2)[0] = (dsoy), (grid + gridSize[0]*2)[1 ] = (0), (grid + gridSize[0]*2)[2] = (( ((double)(maxIn[1])-( min[1]))*((double)(1)) / ((double)(maxOut[1])-(min[1])) )), ( grid + gridSize[0]*2)[3] = (0)) |
| 800 | AIR_DELTA(min[1], 1, maxOut[1], min[1], maxIn[1]),((grid + gridSize[0]*2)[0] = (dsoy), (grid + gridSize[0]*2)[1 ] = (0), (grid + gridSize[0]*2)[2] = (( ((double)(maxIn[1])-( min[1]))*((double)(1)) / ((double)(maxOut[1])-(min[1])) )), ( grid + gridSize[0]*2)[3] = (0)) |
| 801 | 0)((grid + gridSize[0]*2)[0] = (dsoy), (grid + gridSize[0]*2)[1 ] = (0), (grid + gridSize[0]*2)[2] = (( ((double)(maxIn[1])-( min[1]))*((double)(1)) / ((double)(maxOut[1])-(min[1])) )), ( grid + gridSize[0]*2)[3] = (0)); |
| 802 | ELL_4V_SET(grid + gridSize[0]*3, dsoz,((grid + gridSize[0]*3)[0] = (dsoz), (grid + gridSize[0]*3)[1 ] = (0), (grid + gridSize[0]*3)[2] = (0), (grid + gridSize[0] *3)[3] = (( ((double)(maxIn[2])-(min[2]))*((double)(1)) / ((double )(maxOut[2])-(min[2])) ))) |
| 803 | 0,((grid + gridSize[0]*3)[0] = (dsoz), (grid + gridSize[0]*3)[1 ] = (0), (grid + gridSize[0]*3)[2] = (0), (grid + gridSize[0] *3)[3] = (( ((double)(maxIn[2])-(min[2]))*((double)(1)) / ((double )(maxOut[2])-(min[2])) ))) |
| 804 | 0,((grid + gridSize[0]*3)[0] = (dsoz), (grid + gridSize[0]*3)[1 ] = (0), (grid + gridSize[0]*3)[2] = (0), (grid + gridSize[0] *3)[3] = (( ((double)(maxIn[2])-(min[2]))*((double)(1)) / ((double )(maxOut[2])-(min[2])) ))) |
| 805 | AIR_DELTA(min[2], 1, maxOut[2], min[2], maxIn[2]))((grid + gridSize[0]*3)[0] = (dsoz), (grid + gridSize[0]*3)[1 ] = (0), (grid + gridSize[0]*3)[2] = (0), (grid + gridSize[0] *3)[3] = (( ((double)(maxIn[2])-(min[2]))*((double)(1)) / ((double )(maxOut[2])-(min[2])) ))); |
| 806 | if (sbp) { |
| 807 | if (!probeSpaceIndex) { |
| 808 | double idxSS = AIR_NAN(airFloatQNaN.f); |
| 809 | unsigned int vi; |
| 810 | /* there's actually work to do here, weirdly: gageProbe can |
| 811 | either work in index space, or in world space, but the |
| 812 | vprobe-style sampling is index-space-centric, so we have to |
| 813 | convert the world-space stack position to index space, to be |
| 814 | consistent with the way that the grid sampling will be |
| 815 | defined. So, we have to actually replicate work that is done |
| 816 | by _gageProbeSpace() in converting from world to index space */ |
| 817 | /* HEY: the way that idxSS is set is very strange */ |
| 818 | for (vi=0; vi<sbp->num-1; vi++) { |
| 819 | if (AIR_IN_CL(sbp->sigma[vi], posSS, sbp->sigma[vi+1])((sbp->sigma[vi]) <= (posSS) && (posSS) <= ( sbp->sigma[vi+1]))) { |
| 820 | idxSS = vi + AIR_AFFINE(sbp->sigma[vi], posSS, sbp->sigma[vi+1],( ((double)(1)-(0))*((double)(posSS)-(sbp->sigma[vi])) / ( (double)(sbp->sigma[vi+1])-(sbp->sigma[vi])) + (0)) |
| 821 | 0, 1)( ((double)(1)-(0))*((double)(posSS)-(sbp->sigma[vi])) / ( (double)(sbp->sigma[vi+1])-(sbp->sigma[vi])) + (0)); |
| 822 | if (verbose > 1) { |
| 823 | fprintf(stderr__stderrp, "%s: scale pos %g -> idx %g = %u + %g\n", me, |
| 824 | posSS, idxSS, vi, |
| 825 | AIR_AFFINE(sbp->sigma[vi], posSS, sbp->sigma[vi+1],( ((double)(1)-(0))*((double)(posSS)-(sbp->sigma[vi])) / ( (double)(sbp->sigma[vi+1])-(sbp->sigma[vi])) + (0)) |
| 826 | 0, 1)( ((double)(1)-(0))*((double)(posSS)-(sbp->sigma[vi])) / ( (double)(sbp->sigma[vi+1])-(sbp->sigma[vi])) + (0))); |
| 827 | } |
| 828 | break; |
| 829 | } |
| 830 | } |
| 831 | if (vi == sbp->num-1) { |
| 832 | fprintf(stderr__stderrp, "%s: scale pos %g outside range %g=%g, %g=%g\n", me, |
| 833 | posSS, rangeSS[0], sbp->sigma[0], |
| 834 | rangeSS[1], sbp->sigma[sbp->num-1]); |
| 835 | airMopError(mop); return 1; |
| 836 | } |
| 837 | grid[4 + 5*0] = idxSS; |
| 838 | } else { |
| 839 | grid[4 + 5*0] = posSS; |
| 840 | } |
| 841 | grid[4 + 5*1] = 0; |
| 842 | grid[4 + 5*2] = 0; |
| 843 | grid[4 + 5*3] = 0; |
| 844 | } |
| 845 | } else { |
| 846 | /* we did get a grid, here we only copy from _ngrid to ngrid, |
| 847 | and let further massaging be done in gridProbe below */ |
| 848 | six = siy = siz = 0; |
Value stored to 'six' is never read | |
| 849 | sox = soy = soz = 0; |
| 850 | if (nrrdCopy(ngrid, _ngrid)) { |
| 851 | airMopAdd(mop, err = biffGetDone(NRRDnrrdBiffKey), airFree, airMopAlways); |
| 852 | fprintf(stderr__stderrp, "%s: trouble copying ngrid:\n%s\n", me, err); |
| 853 | airMopError(mop); return 1; |
| 854 | } |
| 855 | } |
| 856 | |
| 857 | /* probe onto grid */ |
| 858 | nout = nrrdNew(); |
| 859 | airMopAdd(mop, nout, (airMopper)nrrdNuke, airMopAlways); |
| 860 | gageParmSet(ctx, gageParmVerbose, verbose); |
| 861 | t0 = airTime(); |
| 862 | if (gridProbe(ctx, pvl, what, nout, otype, ngrid, |
| 863 | (_ngrid |
| 864 | ? probeSpaceIndex /* user specifies grid space */ |
| 865 | : AIR_TRUE1), /* copying vprobe index-space behavior */ |
| 866 | verbose, clamp, scaleIsTau, |
| 867 | edgeFracInfo[0], edgeFracInfo[1])) { |
| 868 | /* note hijacking of GAGE key */ |
| 869 | airMopAdd(mop, err = biffGetDone(GAGEgageBiffKey), airFree, airMopAlways); |
| 870 | fprintf(stderr__stderrp, "%s: trouble probing on grid:\n%s\n", me, err); |
| 871 | airMopError(mop); return 1; |
| 872 | } |
| 873 | t1 = airTime(); |
| 874 | if (verbose) { |
| 875 | fprintf(stderr__stderrp, "probe rate = %g KHz\n", |
| 876 | AIR_CAST(double, nrrdElementNumber(nout)/ansLen)((double)(nrrdElementNumber(nout)/ansLen)) |
| 877 | / (1000.0*(t1-t0))); |
| 878 | } |
| 879 | |
| 880 | /* massage output some */ |
| 881 | nrrdContentSet_va(nout, "gprobe", nin, "%s", airEnumStr(kind->enm, what)); |
| 882 | if (!_ngrid) { |
| 883 | /* did not get a grid, have to emulate vprobe per-axis behavior */ |
| 884 | for (axi=0; axi<3; axi++) { |
| 885 | nout->axis[axi+oBaseDim].label = |
| 886 | airStrdup(nin->axis[axi+iBaseDim].label); |
| 887 | nout->axis[axi+oBaseDim].center = ctx->shape->center; |
| 888 | } |
| 889 | nrrdBasicInfoCopy(nout, nin, (NRRD_BASIC_INFO_DATA_BIT(1<< 1) |
| 890 | | NRRD_BASIC_INFO_TYPE_BIT(1<< 2) |
| 891 | | NRRD_BASIC_INFO_BLOCKSIZE_BIT(1<< 3) |
| 892 | | NRRD_BASIC_INFO_DIMENSION_BIT(1<< 4) |
| 893 | | NRRD_BASIC_INFO_CONTENT_BIT(1<< 5) |
| 894 | | NRRD_BASIC_INFO_SPACEORIGIN_BIT(1<<10) |
| 895 | | NRRD_BASIC_INFO_OLDMIN_BIT(1<<12) |
| 896 | | NRRD_BASIC_INFO_OLDMAX_BIT(1<<13) |
| 897 | | NRRD_BASIC_INFO_COMMENTS_BIT(1<<14) |
| 898 | | NRRD_BASIC_INFO_KEYVALUEPAIRS_BIT(1<<15))); |
| 899 | if (ctx->shape->fromOrientation) { |
| 900 | if (nin->space) { |
| 901 | nrrdSpaceSet(nout, nin->space); |
| 902 | } else { |
| 903 | nrrdSpaceDimensionSet(nout, nin->spaceDim); |
| 904 | } |
| 905 | nrrdSpaceVecCopy(nout->spaceOrigin, nin->spaceOrigin); |
| 906 | for (axi=0; axi<3; axi++) { |
| 907 | double tmp; |
| 908 | nrrdSpaceVecScale(nout->axis[axi+oBaseDim].spaceDirection, |
| 909 | rscl[axi], |
| 910 | nin->axis[axi+iBaseDim].spaceDirection); |
| 911 | tmp = AIR_AFFINE(min[axi], 0, maxOut[axi], min[axi], maxIn[axi])( ((double)(maxIn[axi])-(min[axi]))*((double)(0)-(min[axi])) / ((double)(maxOut[axi])-(min[axi])) + (min[axi])); |
| 912 | nrrdSpaceVecScaleAdd2(nout->spaceOrigin, |
| 913 | 1.0, nout->spaceOrigin, |
| 914 | tmp, nin->axis[axi+iBaseDim].spaceDirection); |
| 915 | } |
| 916 | } else { |
| 917 | for (axi=0; axi<3; axi++) { |
| 918 | nout->axis[axi+oBaseDim].spacing = |
| 919 | rscl[axi]*nin->axis[axi+iBaseDim].spacing; |
| 920 | } |
| 921 | } |
| 922 | } |
| 923 | |
| 924 | if (nrrdSave(outS, nout, NULL((void*)0))) { |
| 925 | airMopAdd(mop, err = biffGetDone(NRRDnrrdBiffKey), airFree, airMopAlways); |
| 926 | fprintf(stderr__stderrp, "%s: trouble saving output:\n%s\n", me, err); |
| 927 | airMopError(mop); |
| 928 | return 1; |
| 929 | } |
| 930 | |
| 931 | airMopOkay(mop); |
| 932 | return 0; |
| 933 | } |