/* ** NOTE: assumes that eval and roots have come from ** ell_3m2sub_eigenvalues_d(m) */ void _ell_3m2sub_evecs_d(double evec[9], double eval[3], int roots, const double m[9]) { double n[4]; static const char me[]="_ell_3m2sub_evecs_d"; if (ell_cubic_root_three == roots) { /* set off-diagonal entries once */ n[1] = m[1]; n[2] = m[3]; /* find first evec */ n[0] = m[0] - eval[0]; n[3] = m[3] - eval[0]; ell_2m_1d_nullspace_d(evec + 3*0, n); (evec + 3*0)[2] = 0; /* find second evec */ n[0] = m[0] - eval[1]; n[3] = m[3] - eval[1]; ell_2m_1d_nullspace_d(evec + 3*1, n); (evec + 3*1)[2] = 0; _ell_22v_enforce_orthogonality(evec + 3*0, evec + 3*1); /* make right-handed */ ELL_3V_CROSS(evec + 3*2, evec + 3*0, evec + 3*1); } else if (ell_cubic_root_single_double == roots) { /* can pick any 2D basis */ ELL_3V_SET(evec + 3*0, 1, 0, 0); ELL_3V_SET(evec + 3*1, 0, 1, 0); ELL_3V_SET(evec + 3*2, 0, 0, 1); } else { /* ell_cubic_root_single == roots, if assumptions are met */ ELL_3V_SET(evec + 3*0, AIR_NAN, AIR_NAN, 0); ELL_3V_SET(evec + 3*1, AIR_NAN, AIR_NAN, 0); ELL_3V_SET(evec + 3*2, 0, 0, 1); } if (!ELL_3M_EXISTS(evec)) { fprintf(stderr, "%s: given m = \n", me); ell_3m_print_d(stderr, m); fprintf(stderr, "%s: got roots = %s (%d) and evecs = \n", me, airEnumStr(ell_cubic_root, roots), roots); ell_3m_print_d(stderr, evec); } return; }
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; }