Пример #1
0
/*
******** gageQuerySet()
**
** sets a query in a pervolume.  Does recursive expansion of query
** to cover all prerequisite measures.  
**
** Sets: pvl->query
**
** the gageContext is not actually used here, but I'm cautiously
** including it in case its used in the future.
*/
int
gageQuerySet(gageContext *ctx, gagePerVolume *pvl, gageQuery query) {
  char me[]="gageQuerySet", err[BIFF_STRLEN];
  gageQuery lastQuery;
  int pi, ii;
  
  AIR_UNUSED(ctx);
  if (!( pvl )) {
    sprintf(err, "%s: got NULL pointer", me);
    biffAdd(GAGE, err); return 1;
  }
  GAGE_QUERY_COPY(pvl->query, query);
  if (pvl->verbose) {
    fprintf(stderr, "%s: original ", me);
    gageQueryPrint(stderr, pvl->kind, pvl->query);
  }
  /* recursive expansion of prerequisites */
  do {
    GAGE_QUERY_COPY(lastQuery, pvl->query);
    ii = pvl->kind->itemMax+1;
    do {
      ii--;
      if (GAGE_QUERY_ITEM_TEST(pvl->query, ii)) {
        for (pi=0; pi<GAGE_ITEM_PREREQ_MAXNUM; pi++) {
          if (0 != pvl->kind->table[ii].prereq[pi]) {
            GAGE_QUERY_ITEM_ON(pvl->query, pvl->kind->table[ii].prereq[pi]);
          }
        }
      }
    } while (ii);
  } while (!GAGE_QUERY_EQUAL(pvl->query, lastQuery));
  if (pvl->verbose) {
    fprintf(stderr, "%s: expanded ", me);
    gageQueryPrint(stderr, pvl->kind, pvl->query);
  }

  /* doing this kind of error checking here is not really
     the way gage should work-- it should be done at the 
     time of gageUpdate()-- but the novelty of pvl->data
     encourages putting new smarts at superficial levels
     instead of deeper levels */
  if (!pvl->data) {
    for (ii=1; ii<=pvl->kind->itemMax; ii++) {
      if (GAGE_QUERY_ITEM_TEST(pvl->query, ii)
          && pvl->kind->table[ii].needData) {
        sprintf(err, "%s: item %d (%s) needs data, but pvl->data is NULL", 
                me, ii, airEnumStr(pvl->kind->enm, ii));
        biffAdd(GAGE, err); return 1;
      }
    }
  }

  pvl->flag[gagePvlFlagQuery] = AIR_TRUE;

  return 0;
}
Пример #2
0
/*
******** miteQueryAdd()
**
** This looks a given gageItemSpec and sets the bits in the
** gageKindScl and tenGageKind queries that are required to calculate
** the quantity
**
** NOTE: This does NOT initialize the query{Scl,Vec,Ten}: it
** just adds on new items to the existing queries
**
** HEY: this is really unfortunate: each new gage type use for
** volume rendering in mite will have to explicitly added as
** arguments here, which is part of the reason that mite may end
** up explicitly depending on the libraries supplying those gageKinds
** (like how mite now must depend on ten)
**
** The queryMite argument is a little odd- its not a real gage kind,
** but we use it to organize which of the miteVal quantities we take
** the time to compute in miteSample().
*/
void
miteQueryAdd(gageQuery queryScl, gageQuery queryVec,
             gageQuery queryTen, gageQuery queryMite,
             gageItemSpec *isp) {
  static const char me[]="miteQueryAdd";

  if (NULL == isp->kind) {
    /* nothing to add */
  } else if (gageKindScl == isp->kind) {
    GAGE_QUERY_ITEM_ON(queryScl, isp->item);
  } else if (gageKindVec == isp->kind) {
    GAGE_QUERY_ITEM_ON(queryVec, isp->item);
  } else if (tenGageKind == isp->kind) {
    GAGE_QUERY_ITEM_ON(queryTen, isp->item);
  } else if (miteValGageKind == isp->kind) {
    /* regardless of whether the mite query requires scl, vec, or ten
       queries, we add it to the quantites that have to be computed
       per-sample */
    GAGE_QUERY_ITEM_ON(queryMite, isp->item);
    /* HEY: some these have useful analogs for tensor data, but I
       won't be able to express them.  This means that while Phong
       shading of *scalar* volumes can be implemented with transfer
       functions, it is currently not possible in *tensor* volumes
       (for instance, using the gradient of fractional anisotropy) */
    switch(isp->item) {
    case miteValVrefN:
    case miteValNdotV:
    case miteValNdotL:
      /* the "N" can be a normalized vector from any of the
         available kinds (except miteValGageKind!), and its
         associated query will be handled elsewhere, so there's
         nothing to add here */
      break;
    case miteValGTdotV:
      GAGE_QUERY_ITEM_ON(queryScl, gageSclGeomTens);
      break;
    case miteValVdefT:
      GAGE_QUERY_ITEM_ON(queryTen, tenGageTensor);
    case miteValVdefTdotV:
      GAGE_QUERY_ITEM_ON(queryTen, tenGageTensor);
      break;
    }
  } else {
    fprintf(stderr, "%s: PANIC: unrecognized non-NULL gageKind\n", me);
    exit(1);
  }
  return;
}
Пример #3
0
int
gageQueryItemOn(gageContext *ctx, gagePerVolume *pvl, int item) {
  char me[]="gageQueryItemOn", err[BIFF_STRLEN];

  if (!( pvl )) {
    sprintf(err, "%s: got NULL pointer", me);
    biffAdd(GAGE, err); return 1;
  }

  if (airEnumValCheck(pvl->kind->enm, item)) {
    sprintf(err, "%s: %d not a valid %s value", me,
            item, pvl->kind->enm->name);
    biffAdd(GAGE, err); return 1;
  }
  GAGE_QUERY_ITEM_ON(pvl->query, item);
  if (gageQuerySet(ctx, pvl, pvl->query)) {
    sprintf(err, "%s: trouble", me);
    biffAdd(GAGE, err); return 1;
  }

  return 0;
}
Пример #4
0
int
tenFiberAnisoSpeedSet(tenFiberContext *tfx, int aniso,
                      double lerp, double thresh, double soft) {
  char me[]="tenFiberAnisoSpeedSet", err[BIFF_STRLEN];
  int anisoGage;

  if (!tfx) {
    sprintf(err, "%s: got NULL pointer", me);
    biffAdd(TEN, err); return 1;
  }
  
  if (tfx->useDwi) {
    fprintf(stderr, "!%s: sorry, can't yet work on DWIs; bye.\n", me);
    exit(1);
  }
  
  if (airEnumValCheck(tenAniso, aniso)) {
    sprintf(err, "%s: aniso %d not valid", me, aniso);
    biffAdd(TEN, err); return 1;
  }
  switch(aniso) {
  case tenAniso_FA:
    anisoGage = tenGageFA;
    break;
  case tenAniso_Cl1:
    anisoGage = tenGageCl1;
    break;
  case tenAniso_Cp1:
    anisoGage = tenGageCp1;
    break;
  case tenAniso_Ca1:
    anisoGage = tenGageCa1;
    break;
  case tenAniso_Cl2:
    anisoGage = tenGageCl2;
    break;
  case tenAniso_Cp2:
    anisoGage = tenGageCp2;
    break;
  case tenAniso_Ca2:
    anisoGage = tenGageCa2;
    break;
  default:
    sprintf(err, "%s: sorry, currently don't have fast %s computation "
            "via gage", me, airEnumStr(tenAniso, tfx->anisoStopType));
    biffAdd(TEN, err); return 1;
    break;
  }
  tfx->anisoSpeedType = aniso;
  if (tfx->useDwi) {
    /* actually, finding anisotropy in the context of 2-tensor
       tracking is not currently done by gage */
  } else {
    GAGE_QUERY_ITEM_ON(tfx->query, anisoGage);
    tfx->gageAnisoSpeed = gageAnswerPointer(tfx->gtx, tfx->pvl, anisoGage);
  }
  tfx->anisoSpeedFunc[0] = lerp;
  tfx->anisoSpeedFunc[1] = thresh;
  tfx->anisoSpeedFunc[2] = soft;

  return 0;
}
Пример #5
0
/*
******** tenFiberStopSet
**
** how to set stop criteria and their parameters.  a little tricky because
** of the use of varargs
**
** valid calls:
** tenFiberStopSet(tfx, tenFiberStopLength, double max)
** tenFiberStopSet(tfx, tenFiberStopMinLength, double min)
** tenFiberStopSet(tfx, tenFiberStopAniso, int anisoType, double anisoThresh)
** tenFiberStopSet(tfx, tenFiberStopNumSteps, unsigned int num)
** tenFiberStopSet(tfx, tenFiberStopMinNumSteps, unsigned int num)
** tenFiberStopSet(tfx, tenFiberStopConfidence, double conf)
** tenFiberStopSet(tfx, tenFiberStopRadius, double radius)
** tenFiberStopSet(tfx, tenFiberStopBounds)
** tenFiberStopSet(tfx, tenFiberStopFraction, double fraction)
** tenFiberStopSet(tfx, tenFiberStopStub)
*/
int
tenFiberStopSet(tenFiberContext *tfx, int stop, ...) {
  char me[]="tenFiberStopSet", err[BIFF_STRLEN];
  va_list ap;
  int ret=0;
  int anisoGage;

  if (!tfx) {
    sprintf(err, "%s: got NULL pointer", me);
    biffAdd(TEN, err); return 1;
  }
  va_start(ap, stop);
  switch(stop) {
  case tenFiberStopAniso:
    tfx->anisoStopType = va_arg(ap, int);
    tfx->anisoThresh = va_arg(ap, double);
    if (!(AIR_IN_OP(tenAnisoUnknown, tfx->anisoStopType, tenAnisoLast))) {
      sprintf(err, "%s: given aniso stop type %d not valid", me,
              tfx->anisoStopType);
      biffAdd(TEN, err); ret = 1; goto end;
    }
    if (!(AIR_EXISTS(tfx->anisoThresh))) {
      sprintf(err, "%s: given aniso threshold doesn't exist", me);
      biffAdd(TEN, err); ret = 1; goto end;
    }
    if (tfx->useDwi) {
      /* the tensor of which we measure anisotropy can come from lots of
         places, not just a 1-tensor gage item, so there's no specific 
         item to turn on here... */
      tfx->gageAnisoStop = NULL;
    } else { /* using tensors */
      switch(tfx->anisoStopType) {
      case tenAniso_FA:
        anisoGage = tenGageFA;
        break;
      case tenAniso_Cl1:
        anisoGage = tenGageCl1;
        break;
      case tenAniso_Cp1:
        anisoGage = tenGageCp1;
        break;
      case tenAniso_Ca1:
        anisoGage = tenGageCa1;
        break;
      case tenAniso_Clpmin1:
        anisoGage = tenGageClpmin1;
        break;
      case tenAniso_Cl2:
        anisoGage = tenGageCl2;
        break;
      case tenAniso_Cp2:
        anisoGage = tenGageCp2;
        break;
      case tenAniso_Ca2:
        anisoGage = tenGageCa2;
        break;
      case tenAniso_Clpmin2:
        anisoGage = tenGageClpmin2;
        break;
      default:
        sprintf(err, "%s: sorry, currently don't have fast %s computation "
                "via gage", me, airEnumStr(tenAniso, tfx->anisoStopType));
        biffAdd(TEN, err); ret = 1; goto end;
        break;
      }
      /* NOTE: we are no longer computing ALL anisotropy measures ...
         GAGE_QUERY_ITEM_ON(tfx->query, tenGageAniso);
      */
      GAGE_QUERY_ITEM_ON(tfx->query, anisoGage);
      tfx->gageAnisoStop = gageAnswerPointer(tfx->gtx, tfx->pvl, anisoGage);
      /*
      fprintf(stderr, "!%s: stopping on aniso %s < %g\n", me,
              airEnumStr(tenAniso, tfx->anisoStopType), tfx->anisoThresh);
      */
    }
    break;
  case tenFiberStopLength:
    tfx->maxHalfLen = va_arg(ap, double);
    if (!( AIR_EXISTS(tfx->maxHalfLen) && tfx->maxHalfLen > 0.0 )) {
      sprintf(err, "%s: given maxHalfLen %g doesn't exist or isn't > 0.0",
              me, tfx->maxHalfLen);
      biffAdd(TEN, err); ret = 1; goto end;
    }
    /* no query modifications needed */
    break;
  case tenFiberStopMinLength:
    tfx->minWholeLen = va_arg(ap, double);
    if (!( AIR_EXISTS(tfx->minWholeLen) && tfx->minWholeLen >= 0.0 )) {
      sprintf(err, "%s: given minWholeLen %g doesn't exist or isn't >= 0.0",
              me, tfx->minWholeLen);
      biffAdd(TEN, err); ret = 1; goto end;
    }
    /* no query modifications needed */
    break;
  case tenFiberStopNumSteps:
    tfx->maxNumSteps = va_arg(ap, unsigned int);
    if (!( tfx->maxNumSteps > 0 )) {
      sprintf(err, "%s: given maxNumSteps isn't > 0.0", me);
      biffAdd(TEN, err); ret = 1; goto end;
    }
    /* no query modifications needed */
    break;
  case tenFiberStopMinNumSteps:
    tfx->minNumSteps = va_arg(ap, unsigned int);
    /* no query modifications needed */
    break;
  case tenFiberStopConfidence:
    tfx->confThresh = va_arg(ap, double);
    if (!( AIR_EXISTS(tfx->confThresh) )) {
      sprintf(err, "%s: given confThresh doesn't exist", me);
      biffAdd(TEN, err); ret = 1; goto end;
    }
    GAGE_QUERY_ITEM_ON(tfx->query, tenGageTensor);
    break;
  case tenFiberStopRadius:
    tfx->minRadius = va_arg(ap, double);
    if (!( AIR_EXISTS(tfx->minRadius) )) {
      sprintf(err, "%s: given minimum radius doesn't exist", me);
      biffAdd(TEN, err); ret = 1; goto end;
    }
    /* no query modifications needed */
    break;
  case tenFiberStopBounds:
    /* nothing to set; always used as a stop criterion */
    break;
  case tenFiberStopFraction:
    if (!tfx->useDwi) {
      sprintf(err, "%s: can only use %s-based termination in DWI tractography",
              me, airEnumStr(tenFiberStop, tenFiberStopFraction));
      biffAdd(TEN, err); ret = 1; goto end;
    }
    tfx->minFraction = va_arg(ap, double);
    if (!( AIR_EXISTS(tfx->minFraction) )) {
      sprintf(err, "%s: given minimum fraction doesn't exist", me);
      biffAdd(TEN, err); ret = 1; goto end;
    }
    /* no query modifications needed */
    break;
  case tenFiberStopStub:
    /* no var-args to grab */
    /* no query modifications needed */
    break;
  default:
    sprintf(err, "%s: stop criterion %d not recognized", me, stop);
    biffAdd(TEN, err); ret = 1; goto end;
  }
  tfx->stop = tfx->stop | (1 << stop);
 end:
  va_end(ap);
  return ret;
}
Пример #6
0
int
tenFiberTypeSet(tenFiberContext *tfx, int ftype) {
  char me[]="tenFiberTypeSet", err[BIFF_STRLEN];

  if (!tfx) {
    sprintf(err, "%s: got NULL pointer", me);
    biffAdd(TEN, err); return 1;
  }
  if (tfx->useDwi) {
    fprintf(stderr, "!%s(%d)--- hello\n", me, ftype);
    switch (ftype) {
    case tenDwiFiberType1Evec0:
      GAGE_QUERY_ITEM_ON(tfx->query, tenDwiGageTensorLLS);
      tfx->gageTen = gageAnswerPointer(tfx->gtx, tfx->pvl,
                                       tenDwiGageTensorLLS);
      tfx->gageTen2 = NULL;
      break;
    case tenDwiFiberType2Evec0:
      GAGE_QUERY_ITEM_ON(tfx->query, tenDwiGage2TensorPeled);
      tfx->gageTen = NULL;
      tfx->gageTen2 = gageAnswerPointer(tfx->gtx, tfx->pvl,
                                        tenDwiGage2TensorPeled);
      break;
    case tenDwiFiberType12BlendEvec0:
      GAGE_QUERY_ITEM_ON(tfx->query, tenDwiGageTensorLLS);
      tfx->gageTen = gageAnswerPointer(tfx->gtx, tfx->pvl,
                                       tenDwiGageTensorLLS);
      GAGE_QUERY_ITEM_ON(tfx->query, tenDwiGage2TensorPeled);
      tfx->gageTen2 = gageAnswerPointer(tfx->gtx, tfx->pvl,
                                        tenDwiGage2TensorPeled);
      break;
    default:
      sprintf(err, "%s: unimplemented %s %d", me,
              tenDwiFiberType->name, ftype); 
      biffAdd(TEN, err); return 1;
      break;
    }
    tfx->gageEval = NULL;
    tfx->gageEvec = NULL;
  } else {
    /* working with tensor volume */
    switch(ftype) {
    case tenFiberTypeEvec0:
      GAGE_QUERY_ITEM_ON(tfx->query, tenGageEvec0);
      /* HEY: COPY AND PASTE */
      tfx->gageEvec 
        = gageAnswerPointer(tfx->gtx, tfx->pvl,
                            (tenFiberTypeEvec0 == tfx->fiberType
                             ? tenGageEvec0
                             : (tenFiberTypeEvec1 == tfx->fiberType
                                ? tenGageEvec1
                                : tenGageEvec2)));
      break;
    case tenFiberTypeEvec1:
      GAGE_QUERY_ITEM_ON(tfx->query, tenGageEvec1);
      /* HEY: COPY AND PASTE */
      tfx->gageEvec 
        = gageAnswerPointer(tfx->gtx, tfx->pvl,
                            (tenFiberTypeEvec0 == tfx->fiberType
                             ? tenGageEvec0
                             : (tenFiberTypeEvec1 == tfx->fiberType
                                ? tenGageEvec1
                                : tenGageEvec2)));
      break;
    case tenFiberTypeEvec2:
      GAGE_QUERY_ITEM_ON(tfx->query, tenGageEvec2);
      /* HEY: COPY AND PASTE */
      tfx->gageEvec 
        = gageAnswerPointer(tfx->gtx, tfx->pvl,
                            (tenFiberTypeEvec0 == ftype
                             ? tenGageEvec0
                             : (tenFiberTypeEvec1 == ftype
                                ? tenGageEvec1
                                : tenGageEvec2)));
      break;
    case tenFiberTypeTensorLine:
      GAGE_QUERY_ITEM_ON(tfx->query, tenGageTensor);
      GAGE_QUERY_ITEM_ON(tfx->query, tenGageEval0);
      GAGE_QUERY_ITEM_ON(tfx->query, tenGageEval1);
      GAGE_QUERY_ITEM_ON(tfx->query, tenGageEval2);
      GAGE_QUERY_ITEM_ON(tfx->query, tenGageEvec0);
      GAGE_QUERY_ITEM_ON(tfx->query, tenGageEvec1);
      GAGE_QUERY_ITEM_ON(tfx->query, tenGageEvec2);
      break;
    case tenFiberTypePureLine:
      GAGE_QUERY_ITEM_ON(tfx->query, tenGageTensor);
      break;
    case tenFiberTypeZhukov:
      sprintf(err, "%s: sorry, Zhukov oriented tensors not implemented", me);
      biffAdd(TEN, err); return 1;
      break;
    default:
      sprintf(err, "%s: fiber type %d not recognized", me, ftype);
      biffAdd(TEN, err); return 1;
      break;
    }  /* switch */
    if (tenFiberTypeEvec0 == ftype
        || tenFiberTypeEvec1 == ftype
        || tenFiberTypeEvec2 == ftype
        || tenFiberTypeTensorLine == ftype) {
      tfx->gageTen = gageAnswerPointer(tfx->gtx, tfx->pvl, tenGageTensor);
      tfx->gageEval = gageAnswerPointer(tfx->gtx, tfx->pvl, tenGageEval0);
      tfx->gageEvec 
        = gageAnswerPointer(tfx->gtx, tfx->pvl,
                            (tenFiberTypeEvec0 == ftype
                             ? tenGageEvec0
                             : (tenFiberTypeEvec1 == ftype
                                ? tenGageEvec1
                                : (tenFiberTypeEvec2 == ftype
				   ? tenGageEvec2
				   : tenGageEvec))));
      tfx->gageTen2 = NULL;
    }
    tfx->ten2Which = 0;
  }
  tfx->fiberType = ftype;

  return 0;
}