Beispiel #1
0
/*
******** unrrduCmdMain
**
** A "main" function for unu-like programs, which is very similar to
** teem/src/bin/unu.c:main(), and
** teem/src/bin/tend.c:main(), and
** teem/src/limn/test/lpu.c:main().
** With more time (and a major Teem release), this function may change,
** and those programs may use this.
**
** A sneaky but basic issue is the const-correctness of how the hestParm
** is used; we'd like to take a const hestParm* to communicate parameters
** the caller has set, but the show-stopper is that unrrduCmd->main()
** takes a non-const hestParm, and it has to be that way, because some
** unu commands alter the given hparm (which probably shouldn't happen).
** Until that's fixed, we have a non-const hestParm* coming in here.
*/
int
unrrduCmdMain(int argc, const char **argv,
              const char *cmd, const char *title,
              const unrrduCmd *const *cmdList,
              hestParm *_hparm, FILE *fusage) {
  int i, ret;
  const char *me;
  char *argv0 = NULL;
  hestParm *hparm;
  airArray *mop;

  me = argv[0];

  /* parse environment variables first, in case they break nrrdDefault*
     or nrrdState* variables in a way that nrrdSanity() should see */
  nrrdDefaultGetenv();
  nrrdStateGetenv();

  /* unu does some unu-specific environment-variable handling here */

  nrrdSanityOrDie(me);

  mop = airMopNew();
  if (_hparm) {
    hparm = _hparm;
  } else {
    hparm = hestParmNew();
    airMopAdd(mop, hparm, (airMopper)hestParmFree, airMopAlways);
    hparm->elideSingleEnumType = AIR_TRUE;
    hparm->elideSingleOtherType = AIR_TRUE;
    hparm->elideSingleOtherDefault = AIR_FALSE;
    hparm->elideSingleNonExistFloatDefault = AIR_TRUE;
    hparm->elideMultipleNonExistFloatDefault = AIR_TRUE;
    hparm->elideSingleEmptyStringDefault = AIR_TRUE;
    hparm->elideMultipleEmptyStringDefault = AIR_TRUE;
    hparm->cleverPluralizeOtherY = AIR_TRUE;
    /* learning columns from current window; if ioctl is available
    if (1) {
      struct winsize ws;
      ioctl(1, TIOCGWINSZ, &ws);
      hparm->columns = ws.ws_col - 1;
    }
    */
    hparm->columns = 78;
  }

  /* if there are no arguments, then we give general usage information */
  if (1 >= argc) {
    /* this is like unrrduUsageUnu() */
    unsigned int ii, maxlen = 0;
    char *buff, *fmt, tdash[] = "--- %s ---";
    for (ii=0; cmdList[ii]; ii++) {
      if (cmdList[ii]->hidden) {
        continue;
      }
      maxlen = AIR_MAX(maxlen, AIR_UINT(strlen(cmdList[ii]->name)));
    }
    if (!maxlen) {
      fprintf(fusage, "%s: problem: maxlen = %u\n", me, maxlen);
      airMopError(mop); return 1;
    }
    buff = AIR_CALLOC(strlen(tdash) + strlen(title) + 1, char);
    airMopAdd(mop, buff, airFree, airMopAlways);
    sprintf(buff, tdash, title);
    fmt = AIR_CALLOC(hparm->columns + strlen(buff) + 1, char); /* generous */
    airMopAdd(mop, buff, airFree, airMopAlways);
    sprintf(fmt, "%%%us\n",
            AIR_UINT((hparm->columns-strlen(buff))/2 + strlen(buff) - 1));
    fprintf(fusage, fmt, buff);

    for (ii=0; cmdList[ii]; ii++) {
      unsigned int cc, len;
      if (cmdList[ii]->hidden) {
        continue;
      }
      len = AIR_UINT(strlen(cmdList[ii]->name));
      strcpy(buff, "");
      for (cc=len; cc<maxlen; cc++)
        strcat(buff, " ");
      strcat(buff, cmd);
      strcat(buff, " ");
      strcat(buff, cmdList[ii]->name);
      strcat(buff, " ... ");
      len = strlen(buff);
      fprintf(fusage, "%s", buff);
      _hestPrintStr(fusage, len, len, hparm->columns,
                    cmdList[ii]->info, AIR_FALSE);
    }
    airMopError(mop);
    return 1;
  }
int
main(int argc, char **argv) {
  int i, ret;
  char *me, *argv0 = NULL, *err;
  hestParm *hparm;
  airArray *mop;

  me = argv[0];

  /* parse environment variables first, in case they break nrrdDefault*
     or nrrdState* variables in a way that nrrdSanity() should see */
  nrrdDefaultGetenv();
  nrrdStateGetenv();

  /* if user hasn't tried to set nrrdStateKindNoop by an environment
     variable, we set it to false, since its probably what people expect */
  if (!getenv("NRRD_STATE_KIND_NOOP")) {
    nrrdStateKindNoop = AIR_FALSE;
  }

  /* no harm done in making sure we're sane */
  if (!nrrdSanity()) {
    fprintf(stderr, "******************************************\n");
    fprintf(stderr, "******************************************\n");
    fprintf(stderr, "\n");
    fprintf(stderr, "  %s: nrrd sanity check FAILED.\n", me);
    fprintf(stderr, "\n");
    fprintf(stderr, "  This means that either nrrd can't work on this "
            "platform, or (more likely)\n");
    fprintf(stderr, "  there was an error in the compilation options "
            "and variable definitions\n");
    fprintf(stderr, "  for how Teem was built here.\n");
    fprintf(stderr, "\n");
    fprintf(stderr, "  %s\n", err = biffGetDone(NRRD));
    fprintf(stderr, "\n");
    fprintf(stderr, "******************************************\n");
    fprintf(stderr, "******************************************\n");
    free(err);
    return 1;
  }

  mop = airMopNew();
  hparm = hestParmNew();
  airMopAdd(mop, hparm, (airMopper)hestParmFree, airMopAlways);
  hparm->elideSingleEnumType = AIR_TRUE;
  hparm->elideSingleOtherType = AIR_TRUE;
  hparm->elideSingleOtherDefault = AIR_TRUE;
  hparm->elideSingleNonExistFloatDefault = AIR_TRUE;
  hparm->elideMultipleNonExistFloatDefault = AIR_TRUE;
  hparm->elideSingleEmptyStringDefault = AIR_TRUE;
  hparm->elideMultipleEmptyStringDefault = AIR_TRUE;
  hparm->columns = unrrduDefNumColumns;

  /* if there are no arguments, then we give general usage information */
  if (1 >= argc) {
    unrrduUsage("unu", hparm);
    airMopError(mop);
    exit(1);
  }
  /* else, we should see if they're asking for a command we know about */  
  for (i=0; unrrduCmdList[i]; i++) {
    if (!strcmp(argv[1], unrrduCmdList[i]->name))
      break;
  }
  /* unrrduCmdList[] is NULL-terminated */
  if (unrrduCmdList[i]) {
    /* yes, we have that command */
    /* initialize variables used by the various commands */
    argv0 = (char *)calloc(strlen(UNU) + strlen(argv[1]) + 2, sizeof(char));
    airMopMem(mop, &argv0, airMopAlways);
    sprintf(argv0, "%s %s", UNU, argv[1]);

    /* run the individual unu program, saving its exit status */
    ret = unrrduCmdList[i]->main(argc-2, argv+2, argv0, hparm);
  } else {
    fprintf(stderr, "%s: unrecognized command: \"%s\"; type \"%s\" for "
            "complete list\n", me, argv[1], me);
    ret = 1;
  }

  airMopDone(mop, ret);
  return ret;
}
Beispiel #3
0
int
main(int argc, char **argv) {
  int i, ret;
  char *me, *argv0 = NULL, *err;
  hestParm *hparm;
  airArray *mop;

  me = argv[0];

  /* parse environment variables first, in case they break nrrdDefault*
     or nrrdState* variables in a way that nrrdSanity() should see */
  nrrdDefaultGetenv();
  nrrdStateGetenv();

  /* no harm done in making sure we're sane */
  if (!nrrdSanity()) {
    fprintf(stderr, "******************************************\n");
    fprintf(stderr, "******************************************\n");
    fprintf(stderr, "\n");
    fprintf(stderr, "  %s: nrrd sanity check FAILED.\n", me);
    fprintf(stderr, "\n");
    fprintf(stderr, "  This means that either nrrd can't work on this "
            "platform, or (more likely)\n");
    fprintf(stderr, "  there was an error in the compilation options "
            "and variable definitions\n");
    fprintf(stderr, "  for how Teem was built here.\n");
    fprintf(stderr, "\n");
    fprintf(stderr, "  %s\n", err = biffGetDone(NRRD));
    fprintf(stderr, "\n");
    fprintf(stderr, "******************************************\n");
    fprintf(stderr, "******************************************\n");
    free(err);
    return 1;
  }

  mop = airMopNew();
  hparm = hestParmNew();
  airMopAdd(mop, hparm, (airMopper)hestParmFree, airMopAlways);
  hparm->elideSingleEnumType = AIR_TRUE;
  hparm->elideSingleOtherType = AIR_TRUE;
  hparm->elideSingleOtherDefault = AIR_FALSE;
  hparm->elideSingleNonExistFloatDefault = AIR_TRUE;
  hparm->elideMultipleNonExistFloatDefault = AIR_TRUE;
  hparm->elideSingleEmptyStringDefault = AIR_TRUE;
  hparm->elideMultipleEmptyStringDefault = AIR_TRUE;
  hparm->cleverPluralizeOtherY = AIR_TRUE;
  hparm->columns = 78;

  /* if there are no arguments, then we give general usage information */
  if (1 >= argc) {
    tendUsage(TEND, hparm);
    airMopError(mop);
    exit(1);
  }
  /* else, we see if its --version */
  if (!strcmp("--version", argv[1])) {
    printf("Teem version %s (%s)\n",
           airTeemVersion, airTeemReleaseDate);
    exit(0);
  }
  /* else, we should see if they're asking for a command we know about */
  for (i=0; tendCmdList[i]; i++) {
    if (!strcmp(argv[1], tendCmdList[i]->name))
      break;
    if (!strcmp("--help", argv[1])
        && !strcmp("about", tendCmdList[i]->name)) {
      break;
    }
  }
  if (tendCmdList[i]) {
    /* yes, we have that command */
    /* initialize variables used by the various commands */
    argv0 = (char *)calloc(strlen(TEND) + strlen(argv[1]) + 2, sizeof(char));
    airMopMem(mop, &argv0, airMopAlways);
    sprintf(argv0, "%s %s", TEND, argv[1]);

    /* run the individual unu program, saving its exit status */
    ret = tendCmdList[i]->main(argc-2, argv+2, argv0, hparm);
  } else {
    fprintf(stderr, "%s: unrecognized command: \"%s\"; type \"%s\" for "
            "complete list\n", me, argv[1], me);
    ret = 1;
  }

  airMopDone(mop, ret);
  return ret;
}
Beispiel #4
0
int
main(int argc, const char *argv[]) {
  gageKind *kind;
  const char *me;
  char *whatS, *err, *outS, *stackReadFormat, *stackSaveFormat;
  hestParm *hparm;
  hestOpt *hopt = NULL;
  NrrdKernelSpec *k00, *k11, *k22, *kSS, *kSSblur;
  int what, E=0, renorm, SSuniform, SSoptim, verbose, zeroZ,
    orientationFromSpacing, SSnormd;
  unsigned int iBaseDim, oBaseDim, axi, numSS, ninSSIdx, seed;
  const double *answer;
  Nrrd *nin, *nout, **ninSS=NULL;
  Nrrd *ngrad=NULL, *nbmat=NULL;
  size_t ai, ansLen, idx, xi, yi, zi, six, siy, siz, sox, soy, soz;
  double bval=0, gmc, rangeSS[2], wrlSS, idxSS=AIR_NAN,
    dsix, dsiy, dsiz, dsox, dsoy, dsoz;
  gageContext *ctx;
  gagePerVolume *pvl=NULL;
  double t0, t1, x, y, z, scale[3], rscl[3], min[3], maxOut[3], maxIn[3];
  airArray *mop;
  unsigned int hackZi, *skip, skipNum;
  double (*ins)(void *v, size_t I, double d);
  gageStackBlurParm *sbp;

  char hackKeyStr[]="TEEM_VPROBE_HACK_ZI", *hackValStr;
  int otype, hackSet;
  char stmp[4][AIR_STRLEN_SMALL];

  me = argv[0];
  /* parse environment variables first, in case they break nrrdDefault*
     or nrrdState* variables in a way that nrrdSanity() should see */
  nrrdDefaultGetenv();
  nrrdStateGetenv();
  /* no harm done in making sure we're sane */
  if (!nrrdSanity()) {
    fprintf(stderr, "******************************************\n");
    fprintf(stderr, "******************************************\n");
    fprintf(stderr, "\n");
    fprintf(stderr, "  %s: nrrd sanity check FAILED.\n", me);
    fprintf(stderr, "\n");
    fprintf(stderr, "  This means that either nrrd can't work on this "
            "platform, or (more likely)\n");
    fprintf(stderr, "  there was an error in the compilation options "
            "and variable definitions\n");
    fprintf(stderr, "  for how Teem was built here.\n");
    fprintf(stderr, "\n");
    fprintf(stderr, "  %s\n", err = biffGetDone(NRRD));
    fprintf(stderr, "\n");
    fprintf(stderr, "******************************************\n");
    fprintf(stderr, "******************************************\n");
    free(err);
    return 1;
  }

  mop = airMopNew();
  hparm = hestParmNew();
  airMopAdd(mop, hparm, AIR_CAST(airMopper, hestParmFree), airMopAlways);
  hparm->elideSingleOtherType = AIR_TRUE;
  hestOptAdd(&hopt, "i", "nin", airTypeOther, 1, 1, &nin, NULL,
             "input volume", NULL, NULL, nrrdHestNrrd);
  hestOptAdd(&hopt, "k", "kind", airTypeOther, 1, 1, &kind, NULL,
             "\"kind\" of volume (\"scalar\", \"vector\", "
             "\"tensor\", or \"dwi\")",
             NULL, NULL, meetHestGageKind);
  hestOptAdd(&hopt, "v", "verbosity", airTypeInt, 1, 1, &verbose, "1",
             "verbosity level");
  hestOptAdd(&hopt, "q", "query", airTypeString, 1, 1, &whatS, NULL,
             "the quantity (scalar, vector, or matrix) to learn by probing");
  hestOptAdd(&hopt, "s", "sclX sclY sxlZ", airTypeDouble, 3, 3, scale,
             "1.0 1.0 1.0",
             "scaling factor for resampling on each axis "
             "(>1.0 : supersampling)");
  hestOptAdd(&hopt, "k00", "kern00", airTypeOther, 1, 1, &k00,
             "tent", "kernel for gageKernel00",
             NULL, NULL, nrrdHestKernelSpec);
  hestOptAdd(&hopt, "k11", "kern11", airTypeOther, 1, 1, &k11,
             "cubicd:1,0", "kernel for gageKernel11",
             NULL, NULL, nrrdHestKernelSpec);
  hestOptAdd(&hopt, "k22", "kern22", airTypeOther, 1, 1, &k22,
             "cubicdd:1,0", "kernel for gageKernel22",
             NULL, NULL, nrrdHestKernelSpec);
  hestOptAdd(&hopt, "seed", "N", airTypeUInt, 1, 1, &seed, "42",
             "RNG seed; mostly for debugging");
  hestOptAdd(&hopt, "zz", "bool", airTypeBool, 1, 1, &zeroZ, "false",
             "enable \"zeroZ\" behavior in gage that partially "
             "implements working with 3D images as if they are 2D");

  hestOptAdd(&hopt, "ssn", "SS #", airTypeUInt, 1, 1, &numSS,
             "0", "how many scale-space samples to evaluate, or, "
             "0 to turn-off all scale-space behavior");
  hestOptAdd(&hopt, "ssr", "scale range", airTypeDouble, 2, 2, rangeSS,
             "nan nan", "range of scales in scale-space");
  hestOptAdd(&hopt, "ssrf", "SS read format", airTypeString, 1, 1,
             &stackReadFormat, "",
             "printf-style format (including a \"%u\") for the "
             "filenames from which to *read* "
             "pre-blurred volumes computed for the stack");
  hestOptAdd(&hopt, "sssf", "SS save format", airTypeString, 1, 1,
             &stackSaveFormat, "",
             "printf-style format (including a \"%u\") for the "
             "filenames in which to *save* "
             "pre-blurred volumes computed for the stack");
  hestOptAdd(&hopt, "ssw", "SS pos", airTypeDouble, 1, 1, &wrlSS, "0",
             "\"world\"-space position (true sigma) "
             "at which to sample in scale-space");
  hestOptAdd(&hopt, "kssb", "kernel", airTypeOther, 1, 1, &kSSblur,
             "dgauss:1,5", "blurring kernel, to sample scale space",
             NULL, NULL, nrrdHestKernelSpec);
  hestOptAdd(&hopt, "kssr", "kernel", airTypeOther, 1, 1, &kSS,
             "hermite", "kernel for reconstructing from scale space samples",
             NULL, NULL, nrrdHestKernelSpec);
  hestOptAdd(&hopt, "ssu", NULL, airTypeInt, 0, 0, &SSuniform, NULL,
             "do uniform samples along sigma, and not (by default) "
             "samples according to the effective diffusion scale");
  hestOptAdd(&hopt, "sso", NULL, airTypeInt, 0, 0, &SSoptim, NULL,
             "if not using \"-ssu\", use pre-computed optimal "
             "sigmas when possible");
  hestOptAdd(&hopt, "ssnd", NULL, airTypeInt, 0, 0, &SSnormd, NULL,
             "normalize derivatives by scale");

  hestOptAdd(&hopt, "rn", NULL, airTypeInt, 0, 0, &renorm, NULL,
             "renormalize kernel weights at each new sample location. "
             "\"Accurate\" kernels don't need this; doing it always "
             "makes things go slower");
  hestOptAdd(&hopt, "gmc", "min gradmag", airTypeDouble, 1, 1, &gmc,
             "0.0", "For curvature-based queries, use zero when gradient "
             "magnitude is below this");
  hestOptAdd(&hopt, "ofs", "ofs", airTypeInt, 0, 0, &orientationFromSpacing,
             NULL, "If only per-axis spacing is available, use that to "
             "contrive full orientation info");
  hestOptAdd(&hopt, "t", "type", airTypeEnum, 1, 1, &otype, "float",
             "type of output volume", NULL, nrrdType);
  hestOptAdd(&hopt, "o", "nout", airTypeString, 1, 1, &outS, "-",
             "output volume");
  hestParseOrDie(hopt, argc-1, argv+1, hparm,
                 me, probeInfo, AIR_TRUE, AIR_TRUE, AIR_TRUE);
  airMopAdd(mop, hopt, AIR_CAST(airMopper, hestOptFree), airMopAlways);
  airMopAdd(mop, hopt, AIR_CAST(airMopper, hestParseFree), airMopAlways);

  what = airEnumVal(kind->enm, whatS);
  if (!what) {
    /* 0 indeed always means "unknown" for any gageKind */
    fprintf(stderr, "%s: couldn't parse \"%s\" as measure of \"%s\" volume\n",
            me, whatS, kind->name);
    hestUsage(stderr, hopt, me, hparm);
    hestGlossary(stderr, hopt, hparm);
    airMopError(mop);
    return 1;
  }

  /* special set-up required for DWI kind */
  if (!strcmp(TEN_DWI_GAGE_KIND_NAME, kind->name)) {
    if (tenDWMRIKeyValueParse(&ngrad, &nbmat, &bval, &skip, &skipNum, nin)) {
      airMopAdd(mop, err = biffGetDone(TEN), airFree, airMopAlways);
      fprintf(stderr, "%s: trouble parsing DWI info:\n%s\n", me, err);
      airMopError(mop); return 1;
    }
    if (skipNum) {
      fprintf(stderr, "%s: sorry, can't do DWI skipping in tenDwiGage", me);
      airMopError(mop); return 1;
    }
    /* this could stand to use some more command-line arguments */
    if (tenDwiGageKindSet(kind, 50, 1, bval, 0.001, ngrad, nbmat,
                          tenEstimate1MethodLLS,
                          tenEstimate2MethodQSegLLS, seed)) {
      airMopAdd(mop, err = biffGetDone(TEN), airFree, airMopAlways);
      fprintf(stderr, "%s: trouble parsing DWI info:\n%s\n", me, err);
      airMopError(mop); return 1;
    }
  }

  /* for setting up pre-blurred scale-space samples */
  if (numSS) {
    unsigned int vi;
    sbp = gageStackBlurParmNew();
    airMopAdd(mop, sbp, (airMopper)gageStackBlurParmNix, airMopAlways);
    ninSS = AIR_CAST(Nrrd **, calloc(numSS, sizeof(Nrrd *)));
    if (!ninSS) {
      fprintf(stderr, "%s: couldn't allocate ninSS", me);
      airMopError(mop); return 1;
    }
    for (ninSSIdx=0; ninSSIdx<numSS; ninSSIdx++) {
      ninSS[ninSSIdx] = nrrdNew();
      airMopAdd(mop, ninSS[ninSSIdx], (airMopper)nrrdNuke, airMopAlways);
    }
    if (gageStackBlurParmScaleSet(sbp, numSS, rangeSS[0], rangeSS[1],
                                  SSuniform, SSoptim)
        || gageStackBlurParmKernelSet(sbp, kSSblur)
        || gageStackBlurParmRenormalizeSet(sbp, AIR_TRUE)
        || gageStackBlurParmBoundarySet(sbp, nrrdBoundaryBleed, AIR_NAN)
        || gageStackBlurParmVerboseSet(sbp, verbose)) {
      airMopAdd(mop, err = biffGetDone(GAGE), airFree, airMopAlways);
      fprintf(stderr, "%s: trouble with stack blur info:\n%s\n", me, err);
      airMopError(mop); return 1;
    }
    if (airStrlen(stackReadFormat)) {
      if (nrrdLoadMulti(ninSS, numSS,
                        stackReadFormat, 0, NULL)) {
        airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways);
        fprintf(stderr, "%s: trouble loading blurrings:\n%s\n", me, err);
        airMopError(mop); return 1;
      }
      if (gageStackBlurCheck(AIR_CAST(const Nrrd *const*, ninSS),
                             sbp, nin, kind)) {
        airMopAdd(mop, err = biffGetDone(GAGE), airFree, airMopAlways);
        fprintf(stderr, "%s: trouble:\n%s\n", me, err);
        airMopError(mop); return 1;
      }
    } else {
      if (gageStackBlur(ninSS, sbp, nin, kind)) {