Example #1
0
void
tenQGLInterpTwoEvalK(double oeval[3],
                     const double evalA[3], const double evalB[3],
                     const double tt) {
  double RThZA[3], RThZB[3], oRThZ[3], bb;

  tenTripleConvertSingle_d(RThZA, tenTripleTypeRThetaZ,
                           evalA, tenTripleTypeEigenvalue);
  tenTripleConvertSingle_d(RThZB, tenTripleTypeRThetaZ,
                           evalB, tenTripleTypeEigenvalue);
  if (rr1 > rr0) {
    /* the bb calculation below could blow up, so we recurse
       with flipped order */
    tenQGLInterpTwoEvalK(oeval, evalB, evalA, 1-tt);
  } else {
    rr = AIR_LERP(tt, rr0, rr1);
    zz = AIR_LERP(tt, zz0, zz1);
    bb = rr0 ? (rr1/rr0 - 1) : 0;
    /* bb can't be positive, because rr1 <= rr0 enforced above, so below
       is really test for -0.001 < bb <= 0  */
    if (bb > -0.0001) {
      double dth;
      dth = th1 - th0;
      /* rr0 and rr1 are similar, use stable approximation */
      th = th0 + tt*(dth
                     + (0.5 - tt/2)*dth*bb
                     + (-1.0/12 - tt/4 + tt*tt/3)*dth*bb*bb
                     + (1.0/24 + tt/24 + tt*tt/6 - tt*tt*tt/4)*dth*bb*bb*bb);
    } else {
      /* use original formula */
      /* have to clamp value of b so that log() values don't explode */
      bb = AIR_MAX(bb, -1 + 100*FLT_EPSILON);
      th = th0 + (th1 - th0)*log(1 + bb*tt)/log(1 + bb);
    }
    tenTripleConvertSingle_d(oeval, tenTripleTypeEigenvalue,
                             oRThZ, tenTripleTypeRThetaZ);
    /*
    fprintf(stderr, "%s: (b = %g) %g %g %g <-- %g %g %g\n", "blah", bb,
            oeval[0], oeval[1], oeval[2],
            oRThZ[0], oRThZ[1], oRThZ[2]);
    */
  }
}
Example #2
0
/*
** its in here that we scale from "energy gradient" to "force"
*/
double
_pullPointEnergyTotal(pullTask *task, pullBin *bin, pullPoint *point,
                      /* output */
                      double force[4]) {
  char me[]="_pullPointEnergyTotal";
  double enrIm, enrPt, egradIm[4], egradPt[4], energy;
    
  ELL_4V_SET(egradIm, 0, 0, 0, 0); /* sssh */
  ELL_4V_SET(egradPt, 0, 0, 0, 0); /* sssh */
  enrIm = _energyFromImage(task, point, 
                           force ? egradIm : NULL);
  enrPt = _energyFromPoints(task, bin, point,
                            force ? egradPt : NULL);
  energy = AIR_LERP(task->pctx->alpha, enrIm, enrPt);
  /*
  fprintf(stderr, "!%s(%u): energy = lerp(%g, im %g, pt %g) = %g\n", me,
          point->idtag, task->pctx->alpha, enrIm, enrPt, energy);
  */
  if (force) {
    ELL_4V_LERP(force, task->pctx->alpha, egradIm, egradPt);
    ELL_4V_SCALE(force, -1, force);
    /*
    fprintf(stderr, "!%s(%u): egradIm = %g %g %g %g\n", me, point->idtag,
            egradIm[0], egradIm[1], egradIm[2], egradIm[3]);
    fprintf(stderr, "!%s(%u): egradPt = %g %g %g %g\n", me, point->idtag,
            egradPt[0], egradPt[1], egradPt[2], egradPt[3]);
    fprintf(stderr, "!%s(%u): ---> force = %g %g %g %g\n", me,
            point->idtag, force[0], force[1], force[2], force[3]);
    */
  }
  if (task->pctx->wall) {
    unsigned int axi;
    double frc;
    for (axi=0; axi<4; axi++) {
      frc = task->pctx->bboxMin[axi] - point->pos[axi];
      if (frc < 0) {
        /* not below min */
        frc = task->pctx->bboxMax[axi] - point->pos[axi];
        if (frc > 0) {
          /* not above max */
          frc = 0;
        }
      } 
      energy += task->pctx->wall*frc*frc/2;
      if (force) {
        force[axi] += task->pctx->wall*frc;
      }
    }
  }
  if (!AIR_EXISTS(energy)) {
    fprintf(stderr, "!%s(%u): HEY! non-exist energy %g\n", me, point->idtag,
            energy);
  }
  return energy;
}
Example #3
0
static double _nrrdTernaryOpLerp(double a, double b, double c) {
  /* we do something more than the simple lerp here because
     we want to facilitate usage as something which can get around
     non-existent values (b and c as NaN or Inf) without
     getting polluted by them. */

  if (0.0 == a) {
    return b;
  } else if (1.0 == a) {
    return c;
  } else {
    return AIR_LERP(a, b, c);
  }
}
/*
** parm[0]: lerp between 1 and the stuff below
** parm[1]: "t": (parm[1],0) is control point between (0,0) and (1,1)
** parm[2]: "d": parabolic blend between parm[1]-parm[2] and parm[1]+parm[2]
*/
void
_tenFiberAnisoSpeed(double *step, double xx, double parm[3]) {
  double aa, dd, tt, yy;

  tt = parm[1];
  dd = parm[2];
  aa = 1.0/(DBL_EPSILON + 4*dd*(1.0-tt));
  yy = xx - tt + dd;
  xx = (xx < tt - dd
        ? 0
        : (xx < tt + dd
           ? aa*yy*yy
           : (xx - tt)/(1 - tt)));
  xx = AIR_LERP(parm[0], 1, xx);
  ELL_3V_SCALE(step, xx, step);
}
Example #5
0
static void
simulate(double *dwiSim, const double *parm, const tenExperSpec *espec) {
  unsigned int ii;
  double th0, frac, th1, vec0[3], vec1[3];

  /* not used: b0 = parm[0]; */
  th0 = parm[1];
  frac = parm[2];
  th1 = parm[3];
  ELL_3V_SET(vec0, cos(th0), sin(th0), 0.0);
  ELL_3V_SET(vec1, cos(th1), sin(th1), 0.0);
  for (ii=0; ii<espec->imgNum; ii++) {
    double dot0, dot1;
    dot0 = ELL_3V_DOT(vec0, espec->grad + 3*ii);
    dot1 = ELL_3V_DOT(vec1, espec->grad + 3*ii);
    dwiSim[ii] = AIR_LERP(frac, dot0, dot1);
  }
  return;
}
Example #6
0
void
tenQGLInterpTwo(double oten[7],
                const double tenA[7], const double tenB[7],
                int ptype, double tt, tenInterpParm *tip) {
  double oeval[3], evalA[3], evalB[3], oevec[9], evecA[9], evecB[9], cc;

  AIR_UNUSED(tip);
  tenEigensolve_d(evalA, evecA, tenA);
  tenEigensolve_d(evalB, evecB, tenB);
  cc = AIR_LERP(tt, tenA[0], tenB[0]);

  if (tenInterpTypeQuatGeoLoxK == ptype) {
    tenQGLInterpTwoEvalK(oeval, evalA, evalB, tt);
  } else {
    tenQGLInterpTwoEvalR(oeval, evalA, evalB, tt);
  }
  tenQGLInterpTwoEvec(oevec, evecA, evecB, tt);
  tenMakeSingle_d(oten, cc, oeval, oevec);

  return;
}
Example #7
0
void
tend_helixDoit(Nrrd *nout, double bnd,
               double orig[3], double i2w[9], double mf[9],
               double r, double R, double S, double angle, int incrtwist,
               double ev[3], double bgEval) {
  int sx, sy, sz, xi, yi, zi;
  double th, t0, t1, t2, t3, v1, v2,
    wpos[3], vpos[3], mfT[9],
    W2H[9], H2W[9], H2C[9], C2H[9], fv[3], rv[3], uv[3], mA[9], mB[9], inside,
    tmp[3], len;
  float *out;

  sx = nout->axis[1].size;
  sy = nout->axis[2].size;
  sz = nout->axis[3].size;
  out = (float*)nout->data;
  ELL_3M_TRANSPOSE(mfT, mf);
  for (zi=0; zi<sz; zi++) {
    fprintf(stderr, "zi = %d/%d\n", zi, sz);
    for (yi=0; yi<sy; yi++) {
      for (xi=0; xi<sx; xi++) {
        ELL_3V_SET(tmp, xi, yi, zi);
        ELL_3MV_MUL(vpos, i2w, tmp);
        ELL_3V_INCR(vpos, orig);

#define WPOS(pos, th) ELL_3V_SET((pos),R*cos(th), R*sin(th), S*(th)/(2*AIR_PI))
#define VAL(th) (WPOS(wpos, th), ELL_3V_DIST(wpos, vpos))
#define RR 0.61803399
#define CC (1.0-RR)
#define SHIFT3(a,b,c,d) (a)=(b); (b)=(c); (c)=(d)
#define SHIFT2(a,b,c)   (a)=(b); (b)=(c)
        
        th = atan2(vpos[1], vpos[0]);
        th += 2*AIR_PI*floor(0.5 + vpos[2]/S - th/(2*AIR_PI));
        if (S*th/(2*AIR_PI) > vpos[2]) {
          t0 = th - AIR_PI; t3 = th;
        } else {
          t0 = th; t3 = th + AIR_PI;
        }
        t1 = RR*t0 + CC*t3;
        t2 = CC*t0 + RR*t3;
        v1 = VAL(t1);
        v2 = VAL(t2);
        while ( t3-t0 > 0.000001*(AIR_ABS(t1)+AIR_ABS(t2)) ) {
          if (v1 < v2) {
            SHIFT3(t3, t2, t1, CC*t0 + RR*t2);
            SHIFT2(v2, v1, VAL(t1));
          } else {
            SHIFT3(t0, t1, t2, RR*t1 + CC*t3);
            SHIFT2(v1, v2, VAL(t2));
          }
        }
        /* t1 (and t2) are now the th for which the point on the helix
           (R*cos(th), R*sin(th), S*(th)/(2*AIR_PI)) is closest to vpos */

        WPOS(wpos, t1);
        ELL_3V_SUB(wpos, vpos, wpos);
        ELL_3V_SET(fv, -R*sin(t1), R*cos(t1), S/AIR_PI);  /* helix tangent */
        ELL_3V_NORM(fv, fv, len);
        ELL_3V_COPY(rv, wpos);
        ELL_3V_NORM(rv, rv, len);
        len = ELL_3V_DOT(rv, fv);
        ELL_3V_SCALE(tmp, -len, fv);
        ELL_3V_ADD2(rv, rv, tmp);
        ELL_3V_NORM(rv, rv, len);  /* rv now normal to helix, closest to 
                                      pointing to vpos */
        ELL_3V_CROSS(uv, rv, fv);
        ELL_3V_NORM(uv, uv, len);  /* (rv,fv,uv) now right-handed frame */
        ELL_3MV_ROW0_SET(W2H, uv); /* as is (uv,rv,fv) */
        ELL_3MV_ROW1_SET(W2H, rv);
        ELL_3MV_ROW2_SET(W2H, fv);
        ELL_3M_TRANSPOSE(H2W, W2H);
        inside = 0.5 - 0.5*airErf((ELL_3V_LEN(wpos)-r)/(bnd + 0.0001));
        if (incrtwist) {
          th = angle*ELL_3V_LEN(wpos)/r;
        } else {
          th = angle;
        }
        ELL_3M_ROTATE_Y_SET(H2C, th);
        ELL_3M_TRANSPOSE(C2H, H2C);
        ELL_3M_SCALE_SET(mA,
                         AIR_LERP(inside, bgEval, ev[1]),
                         AIR_LERP(inside, bgEval, ev[2]),
                         AIR_LERP(inside, bgEval, ev[0]));
        ELL_3M_MUL(mB, mA, H2C);
        ELL_3M_MUL(mA, mB, W2H);
        ELL_3M_MUL(mB, mA, mf);
        ELL_3M_MUL(mA, C2H, mB);
        ELL_3M_MUL(mB, H2W, mA);
        ELL_3M_MUL(mA, mfT, mB);
        
        TEN_M2T_TT(out, float, mA);
        out[0] = 1.0;
        out += 7;
      }
    }
  }
  return;
}
Example #8
0
/*
** parm vector:
**   0      1      2     3       4      5      (6)
** step  K_perp  K_tan  lerp  X_ring  Y_ring
*/
void
_coilKindScalarFilterModifiedCurvatureRings(coil_t *delta,
                                            int xi, int yi, int zi,
                                            coil_t **iv3, double spacing[3],
                                            double parm[COIL_PARMS_NUM]) {
  coil_t forwX[3], backX[3], forwY[3], backY[3], forwZ[3], backZ[3],
    grad[3], gm, eps, KK, LL, denom, rspX, rspY, rspZ, lerp;
  double bas0[3], bas1[3], bas2[3], len, norm[3], sk;

  AIR_UNUSED(zi);

  ELL_3V_SET(bas0, 0, 0, 1);
  ELL_3V_SET(bas1, xi - parm[4], yi - parm[5], 0);
  ELL_3V_NORM(bas1, bas1, len);
  ELL_3V_CROSS(bas2, bas0, bas1);

  rspX = AIR_CAST(coil_t, 1.0/spacing[0]);
  rspY = AIR_CAST(coil_t, 1.0/spacing[1]);
  rspZ = AIR_CAST(coil_t, 1.0/spacing[2]);

  _coilKindScalar3x3x3Gradients(forwX, backX,
                                forwY, backY,
                                forwZ, backZ,
                                iv3,
                                rspX, rspY, rspZ);
  grad[0] = rspX*(iv3[2][4] - iv3[0][4]);
  grad[1] = rspY*(iv3[1][5] - iv3[1][3]);
  grad[2] = rspZ*(iv3[1][7] - iv3[1][1]);
  gm = AIR_CAST(coil_t, ELL_3V_LEN(grad));

  if (gm) {
    double tc, rcsq;
    ELL_3V_SCALE(norm, 1.0/gm, grad);
    tc = ELL_3V_DOT(norm, bas2);
    rcsq = 1 - tc*tc;
    sk = AIR_LERP(rcsq, parm[1], parm[2]);
  } else {
    sk = parm[1];
  }

  /* compute fluxes */
  eps = 0.0000000001f;
  KK = AIR_CAST(coil_t, sk*sk);
  LL = ELL_3V_DOT(forwX, forwX);
  denom = AIR_CAST(coil_t, 1.0/(eps + sqrt(LL)));
  forwX[0] *= _COIL_CONDUCT(LL, KK)*denom;
  LL = ELL_3V_DOT(forwY, forwY);
  denom = AIR_CAST(coil_t, 1.0/(eps + sqrt(LL)));
  forwY[1] *= _COIL_CONDUCT(LL, KK)*denom;
  LL = ELL_3V_DOT(forwZ, forwZ);
  denom = AIR_CAST(coil_t, 1.0/(eps + sqrt(LL)));
  forwZ[2] *= _COIL_CONDUCT(LL, KK)*denom;
  LL = ELL_3V_DOT(backX, backX);
  denom = AIR_CAST(coil_t, 1.0/(eps + sqrt(LL)));
  backX[0] *= _COIL_CONDUCT(LL, KK)*denom;
  LL = ELL_3V_DOT(backY, backY);
  denom = AIR_CAST(coil_t, 1.0/(eps + sqrt(LL)));
  backY[1] *= _COIL_CONDUCT(LL, KK)*denom;
  LL = ELL_3V_DOT(backZ, backZ);
  denom = AIR_CAST(coil_t, 1.0/(eps + sqrt(LL)));
  backZ[2] *= _COIL_CONDUCT(LL, KK)*denom;

  lerp = AIR_CAST(coil_t, parm[2]);
  delta[0] = (lerp*_coilLaplacian3(iv3, spacing)
              + (1-lerp)*gm*(rspX*(forwX[0] - backX[0])
                             + rspY*(forwY[1] - backY[1])
                             + rspZ*(forwZ[2] - backZ[2])));
  delta[0] *= AIR_CAST(coil_t, parm[0]);
}
Example #9
0
File: mod.c Project: BRAINSia/teem
static int
theFunc(Nrrd *nout, const Nrrd *nin, int func, funcParm *parm) {
  static const char me[]="theFunc";
  float *tin, *tout, eval[3], evec[9], weight[3], size, mean;
  size_t NN, II;
  unsigned int ri;

  if (!AIR_IN_OP(funcUnknown, func, funcLast)) {
    biffAddf(TEN, "%s: given func %d out of range [%d,%d]", me, func,
             funcUnknown+1, funcLast-1);
    return 1;
  }
  if (!(nout && nin && parm)) {
    biffAddf(TEN, "%s: got NULL pointer", me);
    return 1;
  }
  if (tenTensorCheck(nin, nrrdTypeFloat, AIR_FALSE, AIR_TRUE)) {
    biffAddf(TEN, "%s: didn't get a tensor nrrd", me);
    return 1;
  }
  if (nout != nin) {
    if (nrrdCopy(nout, nin)) {
      biffMovef(TEN, NRRD, "%s: couldn't allocate output", me);
      return 1;
    }
  }

  tin = (float*)(nin->data);
  tout = (float*)(nout->data);
  NN = nrrdElementNumber(nin)/7;
  switch(func) {
  case funcSizeNormalize:
    ELL_3V_COPY_TT(weight, float, parm->weight);
    size = weight[0] + weight[1] + weight[2];
    if (!size) {
      biffAddf(TEN, "%s: some of eigenvalue weights is zero", me);
      return 1;
    }
    weight[0] /= size;
    weight[1] /= size;
    weight[2] /= size;
    for (II=0; II<=NN-1; II++) {
      tenEigensolve_f(eval, evec, tin);
      size = (weight[0]*AIR_ABS(eval[0])
              + weight[1]*AIR_ABS(eval[1])
              + weight[2]*AIR_ABS(eval[2]));
      ELL_3V_SET_TT(eval, float,
                    AIR_AFFINE(0, parm->amount, 1,
                               eval[0], parm->target*eval[0]/size),
                    AIR_AFFINE(0, parm->amount, 1,
                               eval[1], parm->target*eval[1]/size),
                    AIR_AFFINE(0, parm->amount, 1,
                               eval[2], parm->target*eval[2]/size));
      tenMakeSingle_f(tout, tin[0], eval, evec);
      tin += 7;
      tout += 7;
    }
    break;
  case funcSizeScale:
    for (II=0; II<=NN-1; II++) {
      TEN_T_SET_TT(tout, float,
                   tin[0],
                   parm->amount*tin[1],
                   parm->amount*tin[2],
                   parm->amount*tin[3],
                   parm->amount*tin[4],
                   parm->amount*tin[5],
                   parm->amount*tin[6]);
      tin += 7;
      tout += 7;
    }
    break;
  case funcAnisoScale:
    for (II=0; II<=NN-1; II++) {
      tenEigensolve_f(eval, evec, tin);
      if (parm->fixDet) {
        eval[0] = AIR_MAX(eval[0], 0.00001f);
        eval[1] = AIR_MAX(eval[1], 0.00001f);
        eval[2] = AIR_MAX(eval[2], 0.00001f);
        ELL_3V_SET_TT(eval, float, log(eval[0]), log(eval[1]), log(eval[2]));
      }
      mean = (eval[0] + eval[1] + eval[2])/3.0f;
      ELL_3V_SET_TT(eval, float,
                    AIR_LERP(parm->scale, mean, eval[0]),
                    AIR_LERP(parm->scale, mean, eval[1]),
                    AIR_LERP(parm->scale, mean, eval[2]));
      if (parm->fixDet) {
        ELL_3V_SET_TT(eval, float, exp(eval[0]), exp(eval[1]), exp(eval[2]));
      }
      if (eval[2] < 0 && parm->makePositive) {
        eval[0] = AIR_MAX(eval[0], 0.0f);
        eval[1] = AIR_MAX(eval[1], 0.0f);
        eval[2] = AIR_MAX(eval[2], 0.0f);
      }
      tenMakeSingle_f(tout, tin[0], eval, evec);
      tin += 7;
      tout += 7;
    }
    break;
  case funcEigenvalueClamp:
    for (II=0; II<=NN-1; II++) {
      tenEigensolve_f(eval, evec, tin);
      if (AIR_EXISTS(parm->min)) {
        ELL_3V_SET_TT(eval, float,
                      AIR_MAX(eval[0], parm->min),
                      AIR_MAX(eval[1], parm->min),
                      AIR_MAX(eval[2], parm->min));
      }
      if (AIR_EXISTS(parm->max)) {
        ELL_3V_SET_TT(eval, float,
                      AIR_MIN(eval[0], parm->max),
                      AIR_MIN(eval[1], parm->max),
                      AIR_MIN(eval[2], parm->max));
      }
      tenMakeSingle_f(tout, tin[0], eval, evec);
      tin += 7;
      tout += 7;
    }