示例#1
0
int
probeParseKind(void *ptr, char *str, char err[AIR_STRLEN_HUGE]) {
  char me[] = "probeParseKind";
  gageKind **kindP;
  
  if (!(ptr && str)) {
    sprintf(err, "%s: got NULL pointer", me);
    return 1;
  }
  kindP = (gageKind **)ptr;
  airToLower(str);
  if (!strcmp(gageKindScl->name, str)) {
    *kindP = gageKindScl;
  } else if (!strcmp(gageKindVec->name, str)) {
    *kindP = gageKindVec;
  } else if (!strcmp(tenGageKind->name, str)) {
    *kindP = tenGageKind;
  } else if (!strcmp(TEN_DWI_GAGE_KIND_NAME, str)) {
    *kindP = tenDwiGageKindNew();
  } else {
    sprintf(err, "%s: not \"%s\", \"%s\", \"%s\", or \"%s\"", me,
            gageKindScl->name, gageKindVec->name,
            tenGageKind->name, TEN_DWI_GAGE_KIND_NAME);
    return 1;
  }

  return 0;
}
示例#2
0
int
probeParseKind(void *ptr, char *str, char err[AIR_STRLEN_HUGE]) {
  char me[] = "probeParseKind";
  gageKind **kindP;
  
  if (!(ptr && str)) {
    sprintf(err, "%s: got NULL pointer", me);
    return 1;
  }
  kindP = (gageKind **)ptr;
  airToLower(str);
  if (!strcmp("scalar", str)) {
    *kindP = gageKindScl;
  } else if (!strcmp("vector", str)) {
    *kindP = gageKindVec;
  } else if (!strcmp("tensor", str)) {
    *kindP = tenGageKind;
  } else if (!strcmp("dwi", str)) {
    *kindP = tenDwiGageKindNew();
  } else {
    sprintf(err, "%s: not \"scalar\", \"vector\", \"tensor\", or \"dwi\"", me);
    return 1;
  }

  return 0;
}
示例#3
0
gageKind *
pullGageKindParse(const char *_str) {
  char me[]="pullGageKindParse", err[BIFF_STRLEN], *str;
  gageKind *ret;
  airArray *mop;
  
  if (!_str) {
    sprintf(err, "%s: got NULL pointer", me);
    return NULL;
  }
  mop = airMopNew();
  str = airStrdup(_str);
  airMopAdd(mop, str, airFree, airMopAlways);
  airToLower(str);
  if (!strcmp(gageKindScl->name, str)) {
    ret = gageKindScl;
  } else if (!strcmp(gageKindVec->name, str)) {
    ret = gageKindVec;
  } else if (!strcmp(tenGageKind->name, str)) {
    ret = tenGageKind;
  } else /* not allowing DWIs for now */ {
    sprintf(err, "%s: not \"%s\", \"%s\", or \"%s\"", me,
            gageKindScl->name, gageKindVec->name, tenGageKind->name);
    airMopError(mop); return NULL;
  }

  airMopOkay(mop);
  return ret;
}
示例#4
0
gageKind *
_meetGageKindParse(const char *_str, int constOnly) {
  char *str;
  gageKind *ret;
  
  if (!_str) {
    return NULL;
  }
  str = airToLower(airStrdup(_str));
  if (!str) {
    return NULL;
  }
  if (!strcmp(gageKindScl->name, str)) {
    ret = gageKindScl;
  } else if (!strcmp(gageKindVec->name, str)) {
    ret = gageKindVec;
  } else if (!strcmp(tenGageKind->name, str)) {
    ret = tenGageKind;
  } else if (!constOnly && !strcmp(TEN_DWI_GAGE_KIND_NAME, str)) {
    ret = tenDwiGageKindNew();
  } else {
    ret = NULL;
  }
  airFree(str);
  return ret;
}
示例#5
0
int 
airEnumVal(const airEnum *enm, const char *str) {
  char *strCpy, test[AIR_STRLEN_SMALL];
  unsigned int ii;

  if (!str) {
    return airEnumUnknown(enm);
  }
  
  strCpy = airStrdup(str);
  if (!enm->sense) {
    airToLower(strCpy);
  }

  if (enm->strEqv) {
    /* want strlen and not airStrlen here because the strEqv array
       should be terminated by a non-null empty string */
    for (ii=0; strlen(enm->strEqv[ii]); ii++) {
      strncpy(test, enm->strEqv[ii], AIR_STRLEN_SMALL);
      test[AIR_STRLEN_SMALL-1] = '\0';
      if (!enm->sense) {
        airToLower(test);
      }
      if (!strcmp(test, strCpy)) {
        free(strCpy);
        return enm->valEqv[ii];
      }
    }
  } else {
    /* enm->strEqv NULL */
    for (ii=1; ii<=enm->M; ii++) {
      strncpy(test, enm->str[ii], AIR_STRLEN_SMALL);
      test[AIR_STRLEN_SMALL-1] = '\0';
      if (!enm->sense) {
        airToLower(test);
      }
      if (!strcmp(test, strCpy)) {
        free(strCpy);
        return enm->val ? enm->val[ii] : (int)ii; /* HEY scrutinize cast */
      }      
    }
  }

  /* else we never matched a string */
  free(strCpy);
  return airEnumUnknown(enm);
}
示例#6
0
int
airSingleSscanf(const char *str, const char *fmt, void *ptr)
{
  char *tmp;
  double val;
  int ret;

  if (!strcmp(fmt, "%e") || !strcmp(fmt, "%f") || !strcmp(fmt, "%g")
      || !strcmp(fmt, "%le") || !strcmp(fmt, "%lf") || !strcmp(fmt, "%lg"))
  {
    tmp = airStrdup(str);
    if (!tmp)
    {
      return 0;
    }
    airToLower(tmp);
    if (strstr(tmp, "nan"))
    {
      val = AIR_NAN;
    }
    else if (strstr(tmp, "-inf"))
    {
      val = AIR_NEG_INF;
    }
    else if (strstr(tmp, "inf"))
    {
      val = AIR_POS_INF;
    }
    else
    {
      /* nothing special matched; pass it off to sscanf() */
      ret = sscanf(str, fmt, ptr);
      free(tmp);
      return ret;
    }
    /* else we matched "nan", "-inf", or "inf", and set val accordingly */
    if (!strncmp(fmt, "%l", 2))
    {
      /* we were given a double pointer */
      *((double *)(ptr)) = val;
    }
    else
    {
      /* we were given a float pointer */
      *((float *)(ptr)) = (float)val;
    }
    free(tmp);
    return 1;
  }
  else
  {
    /* this is neither a float nor double */
    return sscanf(str, fmt, ptr);
  }
}
示例#7
0
int
_mossHestTransformParse (void *ptr, char *_str, char err[AIR_STRLEN_HUGE]) {
  char me[]="_mossHestTransformParse", *str;
  double **matP, tx, ty, sx, sy, angle, mat[6], shf, sha;
  airArray *mop;

  if (!(ptr && _str)) {
    sprintf(err, "%s: got NULL pointer", me);
    return 1;
  }
  matP = (double **)ptr;
  mop = airMopNew();
  *matP = (double *)calloc(6, sizeof(double));
  airMopMem(mop, matP, airMopOnError);
  str = airToLower(airStrdup(_str));
  airMopMem(mop, &str, airMopAlways);

  if (!strcmp("identity", str)) {
    mossMatIdentitySet(*matP);
    
  } else if (1 == sscanf(str, "flip:%lf", &angle)) {
    mossMatFlipSet(*matP, angle);

  } else if (2 == sscanf(str, "translate:%lf,%lf", &tx, &ty)) {
    mossMatTranslateSet(*matP, tx, ty);
  } else if (2 == sscanf(str, "t:%lf,%lf", &tx, &ty)) {
    mossMatTranslateSet(*matP, tx, ty);

  } else if (1 == sscanf(str, "rotate:%lf", &angle)) {
    mossMatRotateSet(*matP, angle);
  } else if (1 == sscanf(str, "r:%lf", &angle)) {
    mossMatRotateSet(*matP, angle);

  } else if (2 == sscanf(str, "scale:%lf,%lf", &sx, &sy)) {
    mossMatScaleSet(*matP, sx, sy);
  } else if (2 == sscanf(str, "s:%lf,%lf", &sx, &sy)) {
    mossMatScaleSet(*matP, sx, sy);

  } else if (2 == sscanf(str, "shear:%lf,%lf", &shf, &sha)) {
    mossMatShearSet(*matP, shf, sha);

  } else if (6 == sscanf(str, "%lf,%lf,%lf,%lf,%lf,%lf",
                         mat+0, mat+1, mat+2, mat+3, mat+4, mat+5)) {
    MOSS_MAT_COPY(*matP, mat);

  } else {
    sprintf(err, "%s: couldn't parse \"%s\" as a transform", me, _str);
    airMopError(mop); return 1;
  }
  
  airMopOkay(mop);
  return 0;
}
示例#8
0
/*
******** airEnumFmtDesc()
**
** Formats a description line for one element "val" of airEnum "enm",
** and puts the result in a NEWLY ALLOCATED string which is the return
** of this function.  The formatting is done via sprintf(), as governed
** by "fmt", which should contain to "%s" conversion sequences, the
** first for the string version "val", and the second for the
** description If "canon", then the canonical string representation
** will be used (the one in enm->str[]), otherwise the shortest string
** representation will be used (which differs from the canonical one
** when there is a strEqv[]/valEqv[] pair defining a shorter string)
*/
char *
airEnumFmtDesc(const airEnum *enm, int val, int canon, const char *fmt) {
  const char *desc;
  char *buff, ident[AIR_STRLEN_SMALL];
  const char *_ident;
  int i;
  size_t len;

  if (!(enm && enm->desc && fmt)) {
    return airStrdup("(airEnumDesc: invalid args)");
  }
  if (airEnumValCheck(enm, val)) {
    val = airEnumUnknown(enm);
  }
  _ident = airEnumStr(enm, val);
  if (!canon && enm->strEqv) {
    len = airStrlen(_ident);
    for (i=0; airStrlen(enm->strEqv[i]); i++) {
      if (val != enm->valEqv[i]) {
        /* this isn't a string representing the value we care about */
        continue;
      }
      if (airStrlen(enm->strEqv[i]) < len) {
        /* this one is shorter */
        len = airStrlen(enm->strEqv[i]);
        _ident = enm->strEqv[i];
      }
    }
  }
  strncpy(ident, _ident, AIR_STRLEN_SMALL);
  ident[AIR_STRLEN_SMALL-1] = '\0';
  if (!enm->sense) {
    airToLower(ident);
  }
  desc = enm->desc[_airEnumIndex(enm, val)];
  buff = AIR_CALLOC(airStrlen(fmt) + airStrlen(ident) +
                    airStrlen(desc) + 1, char);
  if (buff) {
    sprintf(buff, fmt, ident, desc);
  }
  return buff;
}
示例#9
0
文件: trv.c 项目: BRAINSia/teem
int
probeParseKind(void *ptr, char *str, char err[AIR_STRLEN_HUGE]) {
  char me[] = "probeParseKind";
  gageKind **kindP;

  if (!(ptr && str)) {
    sprintf(err, "%s: got NULL pointer", me);
    return 1;
  }
  kindP = (gageKind **)ptr;
  airToLower(str);
  if (!strcmp(gageKindScl->name, str)) {
    *kindP = gageKindScl;
  } else if (!strcmp(gageKindVec->name, str)) {
    *kindP = gageKindVec;
  } else {
    sprintf(err, "%s: not \"%s\" or \"%s\"", me,
            gageKindScl->name, gageKindVec->name);
    return 1;
  }

  return 0;
}
示例#10
0
int
_nrrdFormatVTK_read(FILE *file, Nrrd *nrrd, NrrdIoState *nio) {
  static const char me[]="_nrrdReadVTK";
  char *three[3];
  int sx, sy, sz, ret, N;
  double xm=0.0, ym=0.0, zm=0.0, xs=1.0, ys=1.0, zs=1.0;
  airArray *mop;
  unsigned int llen;

  if (!_nrrdFormatVTK_contentStartsLike(nio)) {
    biffAddf(NRRD, "%s: this doesn't look like a %s file", me,
             nrrdFormatVTK->name);
    return 1;
  }

#define GETLINE(what)                                        \
  do {                                                       \
    ret = _nrrdOneLine(&llen, nio, file);                    \
  } while (!ret && (1 == llen));                             \
  if (ret || !llen) {                                        \
    biffAddf(NRRD, "%s: couldn't get " #what " line", me);   \
    return 1;                                                \
  }

  /* read in content */
  GETLINE(content);
  if (strcmp(NRRD_UNKNOWN, nio->line)) {
    if (!(nrrd->content = airStrdup(nio->line))) {
      biffAddf(NRRD, "%s: couldn't read or copy content string", me);
      return 1;
    }
  }
  GETLINE(encoding); airToUpper(nio->line);
  if (!strcmp("ASCII", nio->line)) {
    nio->encoding = nrrdEncodingAscii;
  } else if (!strcmp("BINARY", nio->line)) {
    nio->encoding = nrrdEncodingRaw;
  } else {
    biffAddf(NRRD, "%s: encoding \"%s\" wasn't \"ASCII\" or \"BINARY\"",
             me, nio->line);
    return 1;
  }
  GETLINE(DATASET); airToUpper(nio->line);
  if (!strstr(nio->line, "STRUCTURED_POINTS")) {
    biffAddf(NRRD,
             "%s: sorry, only STRUCTURED_POINTS data is nrrd-ready", me);
    return 1;
  }
  GETLINE(DIMENSIONS); airToUpper(nio->line);
  if (!strstr(nio->line, "DIMENSIONS")
      || 3 != sscanf(nio->line, "DIMENSIONS %d %d %d", &sx, &sy, &sz)) {
    biffAddf(NRRD, "%s: couldn't parse DIMENSIONS line (\"%s\")",
             me, nio->line);
    return 1;
  }
  GETLINE(next); airToUpper(nio->line);
  while (!strstr(nio->line, "POINT_DATA")) {
    if (strstr(nio->line, "ORIGIN")) {
      if (3 != sscanf(nio->line, "ORIGIN %lf %lf %lf", &xm, &ym, &zm)) {
        biffAddf(NRRD, "%s: couldn't parse ORIGIN line (\"%s\")",
                 me, nio->line);
        return 1;
      }
    } else if (strstr(nio->line, "SPACING")) {
      if (3 != sscanf(nio->line, "SPACING %lf %lf %lf",
                      &xs, &ys, &zs)) {
        biffAddf(NRRD, "%s: couldn't parse SPACING line (\"%s\")",
                 me, nio->line);
        return 1;
      }
    } else if (strstr(nio->line, "ASPECT_RATIO")) {
      if (3 != sscanf(nio->line, "ASPECT_RATIO %lf %lf %lf",
                      &xs, &ys, &zs)) {
        biffAddf(NRRD, "%s: couldn't parse ASPECT_RATIO line (\"%s\")",
                 me, nio->line);
        return 1;
      }
    }
    GETLINE(next); airToUpper(nio->line);
  }
  if (1 != sscanf(nio->line, "POINT_DATA %d", &N)) {
    biffAddf(NRRD, "%s: couldn't parse POINT_DATA line (\"%s\")",
             me, nio->line);
    return 1;
  }
  if (N != sx*sy*sz) {
    biffAddf(NRRD,
             "%s: product of sizes (%d*%d*%d == %d) != # elements (%d)",
             me, sx, sy, sz, sx*sy*sz, N);
    return 1;
  }
  GETLINE(attribute declaration);
  mop = airMopNew();
  if (3 != airParseStrS(three, nio->line, AIR_WHITESPACE, 3, AIR_FALSE)) {
    biffAddf(NRRD,
             "%s: didn't see three words in attribute declaration \"%s\"",
             me, nio->line);
    return 1;
  }
  airMopAdd(mop, three[0], airFree, airMopAlways);
  airMopAdd(mop, three[1], airFree, airMopAlways);
  airMopAdd(mop, three[2], airFree, airMopAlways);
  airToLower(three[2]);
  if (!strcmp(three[2], "bit")) {
    if (nrrdEncodingAscii == nio->encoding) {
      fprintf(stderr, "%s: WARNING: \"bit\"-type data will be read in as "
              "unsigned char\n", me);
      nrrd->type = nrrdTypeUChar;
    } else {
      biffAddf(NRRD, "%s: can't read in \"bit\"-type data as BINARY", me);
      return 1;
    }
  } else if (!strcmp(three[2], "unsigned_char")) {
    nrrd->type = nrrdTypeUChar;
  } else if (!strcmp(three[2], "char")) {
    nrrd->type = nrrdTypeChar;
  } else if (!strcmp(three[2], "unsigned_short")) {
    nrrd->type = nrrdTypeUShort;
  } else if (!strcmp(three[2], "short")) {
    nrrd->type = nrrdTypeShort;
  } else if (!strcmp(three[2], "unsigned_int")) {
    nrrd->type = nrrdTypeUInt;
  } else if (!strcmp(three[2], "int")) {
    nrrd->type = nrrdTypeInt;
  } else if (!strcmp(three[2], "float")) {
    nrrd->type = nrrdTypeFloat;
  } else if (!strcmp(three[2], "double")) {
    nrrd->type = nrrdTypeDouble;
  } else {
    /* "unsigned_long" and "long" fall in here- I don't know what
       the VTK people mean by these types, since always mean different
       things on 32-bit versus 64-bit architectures */
    biffAddf(NRRD, "%s: type \"%s\" not recognized", me, three[2]);
    airMopError(mop); return 1;
  }
  airToUpper(three[0]);
  if (!strncmp("SCALARS", three[0], strlen("SCALARS"))) {
    GETLINE(LOOKUP_TABLE); airToUpper(nio->line);
    if (strcmp(nio->line, "LOOKUP_TABLE DEFAULT")) {
      biffAddf(NRRD,
               "%s: sorry, can only deal with default LOOKUP_TABLE", me);
      airMopError(mop); return 1;
    }
    nrrd->dim = 3;
    nrrdAxisInfoSet_va(nrrd, nrrdAxisInfoSize,
                       AIR_CAST(size_t, sx),
                       AIR_CAST(size_t, sy),
                       AIR_CAST(size_t, sz));
    nrrdAxisInfoSet_va(nrrd, nrrdAxisInfoSpacing, xs, ys, zs);
    nrrdAxisInfoSet_va(nrrd, nrrdAxisInfoMin, xm, ym, zm);
  } else if (!strncmp("VECTORS", three[0], strlen("VECTORS"))) {
    nrrd->dim = 4;
    nrrdAxisInfoSet_va(nrrd, nrrdAxisInfoSize,
                       AIR_CAST(size_t, 3),
                       AIR_CAST(size_t, sx),
                       AIR_CAST(size_t, sy),
                       AIR_CAST(size_t, sz));
    nrrdAxisInfoSet_va(nrrd, nrrdAxisInfoSpacing, AIR_NAN, xs, ys, zs);
    nrrdAxisInfoSet_va(nrrd, nrrdAxisInfoMin, AIR_NAN, xm, ym, zm);
    nrrd->axis[0].kind = nrrdKind3Vector;
  } else if (!strncmp("TENSORS", three[0], strlen("TENSORS"))) {
    nrrd->dim = 4;
    nrrdAxisInfoSet_va(nrrd, nrrdAxisInfoSize,
                       AIR_CAST(size_t, 9),
                       AIR_CAST(size_t, sx),
                       AIR_CAST(size_t, sy),
                       AIR_CAST(size_t, sz));
    nrrdAxisInfoSet_va(nrrd, nrrdAxisInfoSpacing, AIR_NAN, xs, ys, zs);
    nrrdAxisInfoSet_va(nrrd, nrrdAxisInfoMin, AIR_NAN, xm, ym, zm);
    nrrd->axis[0].kind = nrrdKind3DMatrix;
  } else {
    biffAddf(NRRD,
             "%s: sorry, can only deal with SCALARS, VECTORS, and TENSORS "
             "currently, so couldn't parse attribute declaration \"%s\"",
             me, nio->line);
    airMopError(mop); return 1;
  }
  if (!nio->skipData) {
    if (_nrrdCalloc(nrrd, nio, file)) {
      biffAddf(NRRD, "%s: couldn't allocate memory for data", me);
      return 1;
    }
    if (nio->encoding->read(file, nrrd->data, nrrdElementNumber(nrrd),
                            nrrd, nio)) {
      biffAddf(NRRD, "%s:", me);
      return 1;
    }
    if (1 < nrrdElementSize(nrrd)
        && nio->encoding->endianMatters
        && airMyEndian() != airEndianBig) {
      /* encoding exposes endianness, and its big, but we aren't */
      nrrdSwapEndian(nrrd);
    }
  } else {
    nrrd->data = NULL;
  }

  airMopOkay(mop);
  return 0;
}
示例#11
0
文件: tendEstim.c 项目: rblake/seg3d2
int
tend_estimMain(int argc, char **argv, char *me, hestParm *hparm) {
  int pret;
  hestOpt *hopt = NULL;
  char *perr, *err;
  airArray *mop;

  Nrrd **nin, *nin4d, *nbmat, *nterr, *nB0, *nout;
  char *outS, *terrS, *bmatS, *eb0S;
  float soft, scale, sigma;
  int dwiax, EE, knownB0, oldstuff, estmeth, verbose, fixneg;
  unsigned int ninLen, axmap[4], wlsi, *skip, skipNum, skipIdx;
  double valueMin, thresh;

  Nrrd *ngradKVP=NULL, *nbmatKVP=NULL;
  double bKVP, bval;

  tenEstimateContext *tec;

  hestOptAdd(&hopt, "old", NULL, airTypeInt, 0, 0, &oldstuff, NULL,
             "instead of the new tenEstimateContext code, use "
             "the old tenEstimateLinear code");
  hestOptAdd(&hopt, "sigma", "sigma", airTypeFloat, 1, 1, &sigma, "nan",
             "Rician noise parameter");
  hestOptAdd(&hopt, "v", "verbose", airTypeInt, 1, 1, &verbose, "0",
             "verbosity level");
  hestOptAdd(&hopt, "est", "estimate method", airTypeEnum, 1, 1, &estmeth,
             "lls",
             "estimation method to use. \"lls\": linear-least squares",
             NULL, tenEstimate1Method);
  hestOptAdd(&hopt, "wlsi", "WLS iters", airTypeUInt, 1, 1, &wlsi, "1",
             "when using weighted-least-squares (\"-est wls\"), how "
             "many iterations to do after the initial weighted fit.");
  hestOptAdd(&hopt, "fixneg", NULL, airTypeInt, 0, 0, &fixneg, NULL,
             "after estimating the tensor, ensure that there are no negative "
             "eigenvalues by adding (to all eigenvalues) the amount by which "
             "the smallest is negative (corresponding to increasing the "
             "non-DWI image value).");
  hestOptAdd(&hopt, "ee", "filename", airTypeString, 1, 1, &terrS, "",
             "Giving a filename here allows you to save out the tensor "
             "estimation error: a value which measures how much error there "
             "is between the tensor model and the given diffusion weighted "
             "measurements for each sample.  By default, no such error "
             "calculation is saved.");
  hestOptAdd(&hopt, "eb", "filename", airTypeString, 1, 1, &eb0S, "",
             "In those cases where there is no B=0 reference image given "
             "(\"-knownB0 false\"), "
             "giving a filename here allows you to save out the B=0 image "
             "which is estimated from the data.  By default, this image value "
             "is estimated but not saved.");
  hestOptAdd(&hopt, "t", "thresh", airTypeDouble, 1, 1, &thresh, "nan",
             "value at which to threshold the mean DWI value per pixel "
             "in order to generate the \"confidence\" mask.  By default, "
             "the threshold value is calculated automatically, based on "
             "histogram analysis.");
  hestOptAdd(&hopt, "soft", "soft", airTypeFloat, 1, 1, &soft, "0",
             "how fuzzy the confidence boundary should be.  By default, "
             "confidence boundary is perfectly sharp");
  hestOptAdd(&hopt, "scale", "scale", airTypeFloat, 1, 1, &scale, "1",
             "After estimating the tensor, scale all of its elements "
             "(but not the confidence value) by this amount.  Can help with "
             "downstream numerical precision if values are very large "
             "or small.");
  hestOptAdd(&hopt, "mv", "min val", airTypeDouble, 1, 1, &valueMin, "1.0",
             "minimum plausible value (especially important for linear "
             "least squares estimation)");
  hestOptAdd(&hopt, "B", "B-list", airTypeString, 1, 1, &bmatS, NULL,
             "6-by-N list of B-matrices characterizing "
             "the diffusion weighting for each "
             "image.  \"tend bmat\" is one source for such a matrix; see "
             "its usage info for specifics on how the coefficients of "
             "the B-matrix are ordered. "
             "An unadorned plain text file is a great way to "
             "specify the B-matrix.\n  **OR**\n "
             "Can say just \"-B kvp\" to try to learn B matrices from "
             "key/value pair information in input images.");
  hestOptAdd(&hopt, "b", "b", airTypeDouble, 1, 1, &bval, "nan",
             "\"b\" diffusion-weighting factor (units of sec/mm^2)");
  hestOptAdd(&hopt, "knownB0", "bool", airTypeBool, 1, 1, &knownB0, NULL,
             "Determines of the B=0 non-diffusion-weighted reference image "
             "is known, or if it has to be estimated along with the tensor "
             "elements.\n "
             "\b\bo if \"true\": in the given list of diffusion gradients or "
             "B-matrices, there are one or more with zero norm, which are "
             "simply averaged to find the B=0 reference image value\n "
             "\b\bo if \"false\": there may or may not be diffusion-weighted "
             "images among the input; the B=0 image value is going to be "
             "estimated along with the diffusion model");
  hestOptAdd(&hopt, "i", "dwi0 dwi1", airTypeOther, 1, -1, &nin, "-",
             "all the diffusion-weighted images (DWIs), as seperate 3D nrrds, "
             "**OR**: One 4D nrrd of all DWIs stacked along axis 0",
             &ninLen, NULL, nrrdHestNrrd);
  hestOptAdd(&hopt, "o", "nout", airTypeString, 1, 1, &outS, "-",
             "output tensor volume");

  mop = airMopNew();
  airMopAdd(mop, hopt, (airMopper)hestOptFree, airMopAlways);
  USAGE(_tend_estimInfoL);
  JUSTPARSE();
  airMopAdd(mop, hopt, (airMopper)hestParseFree, airMopAlways);

  nout = nrrdNew();
  airMopAdd(mop, nout, (airMopper)nrrdNuke, airMopAlways);
  nbmat = nrrdNew();
  airMopAdd(mop, nbmat, (airMopper)nrrdNuke, airMopAlways);

  /* figure out B-matrix */
  if (strcmp("kvp", airToLower(bmatS))) {
    /* its NOT coming from key/value pairs */
    if (!AIR_EXISTS(bval)) {
      fprintf(stderr, "%s: need to specify scalar b-value\n", me);
      airMopError(mop); return 1;
    }
    if (nrrdLoad(nbmat, bmatS, NULL)) {
      airMopAdd(mop, err=biffGetDone(NRRD), airFree, airMopAlways);
      fprintf(stderr, "%s: trouble loading B-matrix:\n%s\n", me, err);
      airMopError(mop); return 1;
    }
    nin4d = nin[0];
    skip = NULL;
    skipNum = 0;
  } else {
    /* it IS coming from key/value pairs */
    if (1 != ninLen) {
      fprintf(stderr, "%s: require a single 4-D DWI volume for "
              "key/value pair based calculation of B-matrix\n", me);
      airMopError(mop); return 1;
    }
    if (oldstuff) {
      if (knownB0) {
        fprintf(stderr, "%s: sorry, key/value-based DWI info not compatible "
                "with older implementation of knownB0\n", me);
        airMopError(mop); return 1;
      }
    }
    if (tenDWMRIKeyValueParse(&ngradKVP, &nbmatKVP, &bKVP,
                              &skip, &skipNum, nin[0])) {
      airMopAdd(mop, err=biffGetDone(TEN), airFree, airMopAlways);
      fprintf(stderr, "%s: trouble parsing DWI info:\n%s\n", me, err);
      airMopError(mop); return 1;
    }
    if (AIR_EXISTS(bval)) {
      fprintf(stderr, "%s: WARNING: key/value pair derived b-value %g "
              "over-riding %g from command-line", me, bKVP, bval);
    }
    bval = bKVP;
    if (ngradKVP) {
      airMopAdd(mop, ngradKVP, (airMopper)nrrdNuke, airMopAlways);
      if (tenBMatrixCalc(nbmat, ngradKVP)) {
        airMopAdd(mop, err=biffGetDone(TEN), airFree, airMopAlways);
        fprintf(stderr, "%s: trouble finding B-matrix:\n%s\n", me, err);
        airMopError(mop); return 1;
      }
    } else {
      airMopAdd(mop, nbmatKVP, (airMopper)nrrdNuke, airMopAlways);
      if (nrrdConvert(nbmat, nbmatKVP, nrrdTypeDouble)) {
        airMopAdd(mop, err=biffGetDone(NRRD), airFree, airMopAlways);
        fprintf(stderr, "%s: trouble converting B-matrix:\n%s\n", me, err);
        airMopError(mop); return 1;
      }
    }
    /* this will work because of the impositions of tenDWMRIKeyValueParse */
    dwiax = ((nrrdKindList == nin[0]->axis[0].kind ||
              nrrdKindVector == nin[0]->axis[0].kind)
             ? 0
             : ((nrrdKindList == nin[0]->axis[1].kind ||
                 nrrdKindVector == nin[0]->axis[1].kind)
                ? 1
                : ((nrrdKindList == nin[0]->axis[2].kind ||
                    nrrdKindVector == nin[0]->axis[2].kind)
                   ? 2
                   : 3)));
    if (0 == dwiax) {
      nin4d = nin[0];
    } else {
      axmap[0] = dwiax;
      axmap[1] = 1 > dwiax ? 1 : 0;
      axmap[2] = 2 > dwiax ? 2 : 1;
      axmap[3] = 3 > dwiax ? 3 : 2;
      nin4d = nrrdNew();
      airMopAdd(mop, nin4d, (airMopper)nrrdNuke, airMopAlways);
      if (nrrdAxesPermute(nin4d, nin[0], axmap)) {
        airMopAdd(mop, err=biffGetDone(NRRD), airFree, airMopAlways);
        fprintf(stderr, "%s: trouble creating DWI volume:\n%s\n", me, err);
        airMopError(mop); return 1;
      }
    }
  }

  nterr = NULL;
  nB0 = NULL;
  if (!oldstuff) {
    if (1 != ninLen) {
      fprintf(stderr, "%s: sorry, currently need single 4D volume "
              "for new implementation\n", me);
      airMopError(mop); return 1;
    }
    if (!AIR_EXISTS(thresh)) {
      if (tend_estimThresholdFind(&thresh, nbmat, nin4d)) {
        airMopAdd(mop, err=biffGetDone(TEN), airFree, airMopAlways);
        fprintf(stderr, "%s: trouble finding threshold:\n%s\n", me, err);
        airMopError(mop); return 1;
      }
      /* HACK to lower threshold a titch */
      thresh *= 0.93;
      fprintf(stderr, "%s: using mean DWI threshold %g\n", me, thresh);
    }
    tec = tenEstimateContextNew();
    tec->progress = AIR_TRUE;
    airMopAdd(mop, tec, (airMopper)tenEstimateContextNix, airMopAlways);
    EE = 0;
    if (!EE) tenEstimateVerboseSet(tec, verbose);
    if (!EE) tenEstimateNegEvalShiftSet(tec, fixneg);
    if (!EE) EE |= tenEstimateMethodSet(tec, estmeth);
    if (!EE) EE |= tenEstimateBMatricesSet(tec, nbmat, bval, !knownB0);
    if (!EE) EE |= tenEstimateValueMinSet(tec, valueMin);
    for (skipIdx=0; skipIdx<skipNum; skipIdx++) {
      /* fprintf(stderr, "%s: skipping %u\n", me, skip[skipIdx]); */
      if (!EE) EE |= tenEstimateSkipSet(tec, skip[skipIdx], AIR_TRUE);
    }
    switch(estmeth) {
    case tenEstimate1MethodLLS:
      if (airStrlen(terrS)) {
        tec->recordErrorLogDwi = AIR_TRUE;
        /* tec->recordErrorDwi = AIR_TRUE; */
      }
      break;
    case tenEstimate1MethodNLS:
      if (airStrlen(terrS)) {
        tec->recordErrorDwi = AIR_TRUE;
      }
      break;
    case tenEstimate1MethodWLS:
      if (!EE) tec->WLSIterNum = wlsi;
      if (airStrlen(terrS)) {
        tec->recordErrorDwi = AIR_TRUE;
      }
      break;
    case tenEstimate1MethodMLE:
      if (!(AIR_EXISTS(sigma) && sigma > 0.0)) {
        fprintf(stderr, "%s: can't do %s w/out sigma > 0 (not %g)\n",
                me, airEnumStr(tenEstimate1Method, tenEstimate1MethodMLE),
                sigma);
        airMopError(mop); return 1;
      }
      if (!EE) EE |= tenEstimateSigmaSet(tec, sigma);
      if (airStrlen(terrS)) {
        tec->recordLikelihoodDwi = AIR_TRUE;
      }
      break;
    }
    if (!EE) EE |= tenEstimateThresholdSet(tec, thresh, soft);
    if (!EE) EE |= tenEstimateUpdate(tec);
    if (EE) {
      airMopAdd(mop, err=biffGetDone(TEN), airFree, airMopAlways);
      fprintf(stderr, "%s: trouble setting up estimation:\n%s\n", me, err);
      airMopError(mop); return 1;
    }
    if (tenEstimate1TensorVolume4D(tec, nout, &nB0,
                                   airStrlen(terrS) 
                                   ? &nterr 
                                   : NULL, 
                                   nin4d, nrrdTypeFloat)) {
      airMopAdd(mop, err=biffGetDone(TEN), airFree, airMopAlways);
      fprintf(stderr, "%s: trouble doing estimation:\n%s\n", me, err);
      airMopError(mop); return 1;
    }
    if (airStrlen(terrS)) {
      airMopAdd(mop, nterr, (airMopper)nrrdNuke, airMopAlways);
    }
  } else {
    EE = 0;
    if (1 == ninLen) {
      EE = tenEstimateLinear4D(nout, airStrlen(terrS) ? &nterr : NULL, &nB0,
                               nin4d, nbmat, knownB0, thresh, soft, bval);
    } else {
      EE = tenEstimateLinear3D(nout, airStrlen(terrS) ? &nterr : NULL, &nB0,
                               (const Nrrd**)nin, ninLen, nbmat,
                               knownB0, thresh, soft, bval);
    }
    if (EE) {
      airMopAdd(mop, err=biffGetDone(TEN), airFree, airMopAlways);
      fprintf(stderr, "%s: trouble making tensor volume:\n%s\n", me, err);
      airMopError(mop); return 1;
    }
  }
  if (nterr) {
    /* it was allocated by tenEstimate*, we have to clean it up */
    airMopAdd(mop, nterr, (airMopper)nrrdNuke, airMopAlways);
  }
  if (nB0) {
    /* it was allocated by tenEstimate*, we have to clean it up */
    airMopAdd(mop, nB0, (airMopper)nrrdNuke, airMopAlways);
  }
  if (1 != scale) {
    if (tenSizeScale(nout, nout, scale)) {
      airMopAdd(mop, err=biffGetDone(TEN), airFree, airMopAlways);
      fprintf(stderr, "%s: trouble doing scaling:\n%s\n", me, err);
      airMopError(mop); return 1;
    }
  }
  if (nterr) {
    if (nrrdSave(terrS, nterr, NULL)) {
      airMopAdd(mop, err=biffGetDone(NRRD), airFree, airMopAlways);
      fprintf(stderr, "%s: trouble writing error image:\n%s\n", me, err);
      airMopError(mop); return 1;
    }
  }
  if (!knownB0 && airStrlen(eb0S)) {
    if (nrrdSave(eb0S, nB0, NULL)) {
      airMopAdd(mop, err=biffGetDone(NRRD), airFree, airMopAlways);
      fprintf(stderr, "%s: trouble writing estimated B=0 image:\n%s\n",
              me, err);
      airMopError(mop); return 1;
    }
  }

  if (nrrdSave(outS, nout, NULL)) {
    airMopAdd(mop, err=biffGetDone(NRRD), airFree, airMopAlways);
    fprintf(stderr, "%s: trouble writing:\n%s\n", me, err);
    airMopError(mop); return 1;
  }

  airMopOkay(mop);
  return 0;
}
示例#12
0
/*
******** meetPullVolParse
**
** parses a string to extract all the information necessary to create
** the pullVolume (this function originated in Deft/src/main-pull.c)
*/
int
meetPullVolParse(meetPullVol *mpv, const char *_str) {
  static const char me[]="meetPullVolParse";
#define VFMT_SHRT "<fileName>:<kind>:<volName>"
#define SFMT "<minScl>-<#smp>-<maxScl>[-no|u]"
#define VFMT_LONG "<fileName>:<kind>:" SFMT ":<volName>"
  char *str, *ctok, *clast=NULL, *dtok, *dlast=NULL;
  airArray *mop;
  int wantSS;

  if (!(mpv && _str)) {
    biffAddf(MEET, "%s: got NULL pointer", me);
    return 1;
  }
  if (!( str = airStrdup(_str) )) {
    biffAddf(MEET, "%s: couldn't strdup input", me);
    return 1;
  }

  mop = airMopNew();
  airMopAdd(mop, str, airFree, airMopAlways);
  if (!( 3 == airStrntok(str, ":") || 4 == airStrntok(str, ":") )) {
    biffAddf(MEET, "%s: didn't get 3 or 4 \":\"-separated tokens in \"%s\"; "
             "not of form " VFMT_SHRT " or " VFMT_LONG , me, _str);
    airMopError(mop); return 1;
  }
  /* mpv->nin is set elsewhere */
  wantSS = (4 == airStrntok(str, ":"));

  ctok = airStrtok(str, ":", &clast);
  if (!(mpv->fileName = airStrdup(ctok))) {
    biffAddf(MEET, "%s: couldn't strdup fileName", me);
    airMopError(mop); return 1;
  }
  airMopAdd(mop, &(mpv->fileName), (airMopper)airSetNull, airMopOnError);
  airMopAdd(mop, mpv->fileName, airFree, airMopOnError);
  ctok = airStrtok(NULL, ":", &clast);
  if (!(mpv->kind = meetConstGageKindParse(ctok))) {
    biffAddf(MEET, "%s: couldn't parse \"%s\" as kind", me, ctok);
    airMopError(mop); return 1;
  }
  if (wantSS) {
    int haveFlags;
    ctok = airStrtok(NULL, ":", &clast);
    if (!( 3 == airStrntok(ctok, "-") || 4 == airStrntok(ctok, "-") )) {
      biffAddf(MEET, "%s: didn't get 3 or 4 \"-\"-separated tokens in \"%s\"; "
               "not of form SFMT" , me, ctok);
      airMopError(mop); return 1;
    }
    haveFlags = (4 == airStrntok(ctok, "-"));
    dtok = airStrtok(ctok, "-", &dlast);
    if (1 != sscanf(dtok, "%lg", &(mpv->rangeSS[0]))) {
      biffAddf(MEET, "%s: couldn't parse \"%s\" as min scale", me, dtok);
      airMopError(mop); return 1;
    }
    dtok = airStrtok(NULL, "-", &dlast);
    if (1 != sscanf(dtok, "%u", &(mpv->numSS))) {
      biffAddf(MEET, "%s: couldn't parse \"%s\" as # scale samples", me, dtok);
      airMopError(mop); return 1;
    }
    if (!( mpv->numSS >= 2 )) {
      biffAddf(MEET, "%s: need # scale samples >= 2 (not %u)", me, mpv->numSS);
      airMopError(mop); return 1;
    }
    dtok = airStrtok(NULL, "-", &dlast);
    if (1 != sscanf(dtok, "%lg", &(mpv->rangeSS[1]))) {
      biffAddf(MEET, "%s: couldn't parse \"%s\" as max scale", me, dtok);
      airMopError(mop); return 1;
    }
    /* initialize things as if there were no flags */
    mpv->derivNormSS = AIR_FALSE;
    mpv->uniformSS = AIR_FALSE;
    mpv->optimSS = AIR_FALSE;
    mpv->derivNormBiasSS = 0.0;
    if (haveFlags) {
      char *flags, *bias;
      /* look for various things in flags */
      flags = airToLower(airStrdup(airStrtok(NULL, "-", &dlast)));
      airMopAdd(mop, flags, airFree, airMopAlways);
      if (strchr(flags, 'n')) {
        mpv->derivNormSS = AIR_TRUE;
      }
      if (strchr(flags, 'u')) {
        mpv->uniformSS = AIR_TRUE;
      }
      if (strchr(flags, 'o')) {
        mpv->optimSS = AIR_TRUE;
      }
      if (mpv->optimSS && mpv->uniformSS) {
        biffAddf(MEET, "%s: can't have both optimal ('o') and uniform ('u') "
                 "flags set in \"%s\"", me, flags);
        airMopError(mop); return 1;
      }
      if ((bias = strchr(flags, '+'))) {
        /* indicating a bias, unfortunately only a positive one is
           possible here, because of the way that other fields are
           tokenized by '-' */
        bias++;
        if (1 != sscanf(bias, "%lf", &(mpv->derivNormBiasSS))) {
          biffAddf(MEET, "%s: couldn't parse bias \"%s\"", me, bias);
          airMopError(mop); return 1;
        }
      }
    }
    /* mpv->ninSS and mpv->posSS are allocated and filled elsewhere */
    mpv->ninSS = NULL;
    mpv->posSS = NULL;
    /* we don't actually create nrrds nor load the volumes here,
       because we don't know cachePath, and because we might want
       different pullVolumes to share the same underlying Nrrds */
  } else {
    /* no scale-space stuff wanted */
    mpv->numSS = 0;
    mpv->rangeSS[0] = mpv->rangeSS[1] = AIR_NAN;
    mpv->ninSS = NULL;
    mpv->posSS = NULL;
  }
  ctok = airStrtok(NULL, ":", &clast);
  if (!(mpv->volName = airStrdup(ctok))) {
    biffAddf(MEET, "%s: couldn't strdup volName", me);
    airMopError(mop); return 1;
  }
  airMopAdd(mop, &(mpv->volName), (airMopper)airSetNull, airMopOnError);
  airMopAdd(mop, mpv->volName, airFree, airMopOnError);

  if (strchr(ctok, '-')) {
    biffAddf(MEET, "%s: you probably don't want \"-\" in volume name \"%s\"; "
             "forgot last \":\" in scale sampling specification?", me, ctok);
    airMopError(mop); return 1;
  }

  airMopOkay(mop);
  return 0;
}
示例#13
0
/*
******** miteShadeSpecParse
**
** set up a miteShadeSpec based on a string.  Valid forms are:
**
**   none
**   phong:<vector>
**   litten:<vector>,<vector>,<scalar>,<scalar>
**
** where <vector> and <scalar> are specifications of 3-vector and scalar
** parsable by miteVariableParse
*/
int
miteShadeSpecParse(miteShadeSpec *shpec, char *shadeStr) {
  static const char me[]="miteShadeSpecParse";
  char *buff, *qstr, *tok, *state;
  airArray *mop;
  int ansLength;

  mop = airMopNew();
  if (!( shpec && airStrlen(shadeStr) )) {
    biffAddf(MITE, "%s: got NULL pointer and/or empty string", me);
    airMopError(mop); return 1;
  }
  buff = airToLower(airStrdup(shadeStr));
  if (!buff) {
    biffAddf(MITE, "%s: couldn't strdup shading spec", me);
    airMopError(mop); return 1;
  }
  airMopAdd(mop, buff, airFree, airMopAlways);
  shpec->method = miteShadeMethodUnknown;
  if (!strcmp("none", buff)) {
    shpec->method = miteShadeMethodNone;
  } else if (buff == strstr(buff, "phong:")) {
    shpec->method = miteShadeMethodPhong;
    qstr = buff + strlen("phong:");
    if (miteVariableParse(shpec->vec0, qstr)) {
      biffAddf(MITE, "%s: couldn't parse \"%s\" as shading vector", me, qstr);
      airMopError(mop); return 1;
    }
    ansLength = shpec->vec0->kind->table[shpec->vec0->item].answerLength;
    if (3 != ansLength) {
      biffAddf(MITE, "%s: \"%s\" isn't a vector (answer length is %d, not 3)",
               me, qstr, ansLength);
      airMopError(mop); return 1;
    }
    shpec->method = miteShadeMethodPhong;
  } else if (buff == strstr(buff, "litten:")) {
    qstr = buff + strlen("litten:");
    /* ---- first vector */
    tok = airStrtok(qstr, ",", &state);
    if (miteVariableParse(shpec->vec0, tok)) {
      biffAddf(MITE, "%s: couldn't parse \"%s\" as first lit-tensor vector",
               me, tok);
      airMopError(mop); return 1;
    }
    ansLength = shpec->vec0->kind->table[shpec->vec0->item].answerLength;
    if (3 != ansLength) {
      biffAddf(MITE, "%s: \"%s\" isn't a vector (answer length is %d, not 3)",
               me, qstr, ansLength);
      airMopError(mop); return 1;
    }
    /* ---- second vector */
    tok = airStrtok(qstr, ",", &state);
    if (miteVariableParse(shpec->vec1, tok)) {
      biffAddf(MITE, "%s: couldn't parse \"%s\" as second lit-tensor vector",
               me, tok);
      airMopError(mop); return 1;
    }
    ansLength = shpec->vec1->kind->table[shpec->vec1->item].answerLength;
    if (3 != ansLength) {
      biffAddf(MITE, "%s: \"%s\" isn't a vector (answer length is %d, not 3)",
               me, qstr, ansLength);
      airMopError(mop); return 1;
    }
    /* ---- first scalar */
    tok = airStrtok(qstr, ",", &state);
    if (miteVariableParse(shpec->scl0, tok)) {
      biffAddf(MITE, "%s: couldn't parse \"%s\" as first lit-tensor scalar",
               me, tok);
      airMopError(mop); return 1;
    }
    ansLength = shpec->scl0->kind->table[shpec->scl0->item].answerLength;
    if (1 != ansLength) {
      biffAddf(MITE, "%s: \"%s\" isn't a scalar (answer length is %d, not 1)",
               me, qstr, ansLength);
      airMopError(mop); return 1;
    }
    /* ---- second scalar */
    tok = airStrtok(qstr, ",", &state);
    if (miteVariableParse(shpec->scl1, tok)) {
      biffAddf(MITE, "%s: couldn't parse \"%s\" as second lit-tensor scalar",
               me, tok);
      airMopError(mop); return 1;
    }
    ansLength = shpec->scl1->kind->table[shpec->scl1->item].answerLength;
    if (1 != ansLength) {
      biffAddf(MITE, "%s: \"%s\" isn't a scalar (answer length is %d, not 1)",
               me, qstr, ansLength);
      airMopError(mop); return 1;
    }
    shpec->method = miteShadeMethodLitTen;
  } else {
    biffAddf(MITE, "%s: shading specification \"%s\" not understood",
             me, shadeStr);
    airMopError(mop); return 1;
  }
  airMopOkay(mop);
  return 0;
}