GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: src/ten/tendSim.c Lines: 27 76 35.5 %
Date: 2017-05-26 Branches: 1 56 1.8 %

Line Branch Exec Source
1
/*
2
  Teem: Tools to process and visualize scientific data and images             .
3
  Copyright (C) 2013, 2012, 2011, 2010, 2009  University of Chicago
4
  Copyright (C) 2008, 2007, 2006, 2005  Gordon Kindlmann
5
  Copyright (C) 2004, 2003, 2002, 2001, 2000, 1999, 1998  University of Utah
6
7
  This library is free software; you can redistribute it and/or
8
  modify it under the terms of the GNU Lesser General Public License
9
  (LGPL) as published by the Free Software Foundation; either
10
  version 2.1 of the License, or (at your option) any later version.
11
  The terms of redistributing and/or modifying this software also
12
  include exceptions to the LGPL that facilitate static linking.
13
14
  This library is distributed in the hope that it will be useful,
15
  but WITHOUT ANY WARRANTY; without even the implied warranty of
16
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17
  Lesser General Public License for more details.
18
19
  You should have received a copy of the GNU Lesser General Public License
20
  along with this library; if not, write to Free Software Foundation, Inc.,
21
  51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22
*/
23
24
#include "ten.h"
25
#include "privateTen.h"
26
27
#define INFO "Simulate DW images from a tensor field"
28
static const char *_tend_simInfoL =
29
  (INFO
30
   ".  The output will be in the same form as the input to \"tend estim\". "
31
   "The B-matrices (\"-B\") can be the output from \"tend bmat\", or the "
32
   "gradients can be given directly (\"-g\"); one of these is required. "
33
   "Note that the input tensor field (\"-i\") is the basis of the output "
34
   "per-axis fields and image orientation.  NOTE: this includes the "
35
   "measurement frame used in the input tensor field, which implies that "
36
   "the given gradients or B-matrices are already expressed in that "
37
   "measurement frame. ");
38
39
int
40
tend_simMain(int argc, const char **argv, const char *me,
41
             hestParm *hparm) {
42
  int pret;
43
2
  hestOpt *hopt = NULL;
44
1
  char *perr, *err;
45
  tenEstimateContext *tec;
46
  airArray *mop;
47
48
1
  int E, oldstuff, seed, keyValueSet, outType, preOutType;
49
1
  Nrrd *nin, *nT2, *nbmat, *ngrad, *nout, *ntmp;
50
1
  char *outS;
51
1
  float b, sigma;
52
53
  /* maybe this can go in tend.c, but for some reason its explicitly
54
     set to AIR_FALSE there */
55
1
  hparm->elideSingleOtherDefault = AIR_TRUE;
56
57
1
  hestOptAdd(&hopt, "old", NULL, airTypeInt, 0, 0, &oldstuff, NULL,
58
             "don't use the new tenEstimateContext functionality");
59
1
  hestOptAdd(&hopt, "sigma", "sigma", airTypeFloat, 1, 1, &sigma, "0.0",
60
             "Rician noise parameter");
61
1
  hestOptAdd(&hopt, "seed", "seed", airTypeInt, 1, 1, &seed, "42",
62
             "seed value for RNG which creates noise");
63
1
  hestOptAdd(&hopt, "g", "grad list", airTypeOther, 1, 1, &ngrad, "",
64
             "gradient list, one row per diffusion-weighted image",
65
1
             NULL, NULL, nrrdHestNrrd);
66
1
  hestOptAdd(&hopt, "B", "B matrix", airTypeOther, 1, 1, &nbmat, "",
67
             "B matrix, one row per diffusion-weighted image.  Using this "
68
             "overrides the gradient list input via \"-g\"",
69
1
             NULL, NULL, nrrdHestNrrd);
70
1
  hestOptAdd(&hopt, "r", "reference field", airTypeOther, 1, 1, &nT2, NULL,
71
             "reference anatomical scan, with no diffusion weighting",
72
1
             NULL, NULL, nrrdHestNrrd);
73
1
  hestOptAdd(&hopt, "i", "tensor field", airTypeOther, 1, 1, &nin, "-",
74
1
             "input diffusion tensor field", NULL, NULL, nrrdHestNrrd);
75
1
  hestOptAdd(&hopt, "b", "b", airTypeFloat, 1, 1, &b, "1000",
76
             "b value for simulated scan");
77
1
  hestOptAdd(&hopt, "kvp", NULL, airTypeInt, 0, 0, &keyValueSet, NULL,
78
             "generate key/value pairs in the NRRD header corresponding "
79
             "to the input b-value and gradients or B-matrices.  ");
80
1
  hestOptAdd(&hopt, "t", "type", airTypeEnum, 1, 1, &outType, "float",
81
             "output type of DWIs",
82
1
             NULL, nrrdType);
83
1
  hestOptAdd(&hopt, "o", "nout", airTypeString, 1, 1, &outS, "-",
84
             "output image (floating point)");
85
86
1
  mop = airMopNew();
87
1
  airMopAdd(mop, hopt, (airMopper)hestOptFree, airMopAlways);
88
2
  USAGE(_tend_simInfoL);
89
  PARSE();
90
  airMopAdd(mop, hopt, (airMopper)hestParseFree, airMopAlways);
91
92
  nout = nrrdNew();
93
  airMopAdd(mop, nout, (airMopper)nrrdNuke, airMopAlways);
94
95
  if (!( nbmat || ngrad )) {
96
    fprintf(stderr, "%s: got neither B-matrix (\"-B\") "
97
            "or gradient list (\"-g\")\n", me);
98
    airMopError(mop); return 1;
99
  }
100
  if (!oldstuff) {
101
    airSrandMT(seed);
102
    tec = tenEstimateContextNew();
103
    airMopAdd(mop, tec, (airMopper)tenEstimateContextNix, airMopAlways);
104
    preOutType = (nrrdTypeFloat == outType
105
                  ? nrrdTypeFloat
106
                  : nrrdTypeDouble);
107
    E = 0;
108
    if (!E) E |= tenEstimateMethodSet(tec, tenEstimate1MethodLLS);
109
    if (!E) E |= tenEstimateValueMinSet(tec, 0.0001);
110
    if (nbmat) {
111
      if (!E) E |= tenEstimateBMatricesSet(tec, nbmat, b, AIR_TRUE);
112
    } else {
113
      if (!E) E |= tenEstimateGradientsSet(tec, ngrad, b, AIR_TRUE);
114
    }
115
    if (!E) E |= tenEstimateThresholdSet(tec, 0, 0);
116
    if (!E) E |= tenEstimateUpdate(tec);
117
    if (!E) E |= tenEstimate1TensorSimulateVolume(tec,
118
                                                  nout, sigma, b,
119
                                                  nT2, nin,
120
                                                  preOutType,
121
                                                  keyValueSet);
122
    if (E) {
123
      airMopAdd(mop, err=biffGetDone(TEN), airFree, airMopAlways);
124
      fprintf(stderr, "%s: trouble making DWI volume (new):\n%s\n", me, err);
125
      airMopError(mop); return 1;
126
    }
127
    if (preOutType != outType) {
128
      ntmp = nrrdNew();
129
      airMopAdd(mop, ntmp, (airMopper)nrrdNuke, airMopAlways);
130
      E = 0;
131
      if (!E) E |= nrrdCopy(ntmp, nout);
132
      if (!E) E |= nrrdConvert(nout, ntmp, outType);
133
      if (E) {
134
        airMopAdd(mop, err=biffGetDone(NRRD), airFree, airMopAlways);
135
        fprintf(stderr, "%s: trouble making output volume:\n%s\n", me, err);
136
        airMopError(mop); return 1;
137
      }
138
    }
139
  } else {
140
    if (!nbmat) {
141
      fprintf(stderr, "%s: need B-matrices for old code\n", me);
142
      airMopError(mop); return 1;
143
    }
144
    if (tenSimulate(nout, nT2, nin, nbmat, b)) {
145
      airMopAdd(mop, err=biffGetDone(TEN), airFree, airMopAlways);
146
      fprintf(stderr, "%s: trouble making DWI volume:\n%s\n", me, err);
147
      airMopError(mop); return 1;
148
    }
149
  }
150
  if (nrrdSave(outS, nout, NULL)) {
151
    airMopAdd(mop, err=biffGetDone(NRRD), airFree, airMopAlways);
152
    fprintf(stderr, "%s: trouble writing:\n%s\n", me, err);
153
    airMopError(mop); return 1;
154
  }
155
156
  airMopOkay(mop);
157
  return 0;
158
1
}
159
TEND_CMD(sim, INFO);