Tell me more ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

I am trying to understand the following code: http://pastebin.com/zTHUrmyx I have compiled the code and am trying to use gdb to step through the code.

Specifically, I'm trying to understand EXECUTE on line 119 and which is defined in app.h http://pastebin.com/6ZnAKxDC however, gdb seems not to be able to step into this call so I cannot see what is happening there.

To me it seems EXECUTE creates two classes MyApp and App and then app.run (argc, argv); \ but I am unable to find the definition of this run method.

How do I figure out what is going on in this code?

Much appreciated!

/*
   2     Copyright 2008 Brain Research Institute, Melbourne, Australia
   3
   4     Written by J-Donald Tournier, 27/06/08.
   5
   6     This file is part of MRtrix.
   7
   8     MRtrix is free software: you can redistribute it and/or modify
   9     it under the terms of the GNU General Public License as published by
  10     the Free Software Foundation, either version 3 of the License, or
  11     (at your option) any later version.
  12
  13     MRtrix is distributed in the hope that it will be useful,
  14     but WITHOUT ANY WARRANTY; without even the implied warranty of
  15     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16     GNU General Public License for more details.
  17
  18     You should have received a copy of the GNU General Public License
  19     along with MRtrix.  If not, see <http://www.gnu.org/licenses/>.
  20
  21
  22     15-10-2008 J-Donald Tournier <[email protected]>
  23     * fix -prs option handling
  24     * remove MR::DICOM_DW_gradients_PRS flag
  25
  26     15-10-2008 J-Donald Tournier <[email protected]>
  27     * add -layout option to manipulate data ordering within the image file
  28
  29     14-02-2010 J-Donald Tournier <[email protected]>
  30     * fix -coord option so that the "end" keyword can be used
  31
  32
  33 */
  34
  35 #include "app.h"
  36 #include "image/position.h"
  37 #include "image/axis.h"
  38 #include "math/linalg.h"
  39
  40 using namespace std;
  41 using namespace MR;
  42
  43 SET_VERSION_DEFAULT;
  44
  45 DESCRIPTION = {
  46   "perform conversion between different file types and optionally extract a subset of the input image.",
  47   "If used correctly, this program can be a very useful workhorse. In addition to converting images between different formats, it can be used to extract specific studies from a data set, extract a specific region of interest, flip the images, or to scale the intensity of the images.",
  48   NULL
  49 };
  50
  51 ARGUMENTS = {
  52   Argument ("input", "input image", "the input image.").type_image_in (),
  53   Argument ("ouput", "output image", "the output image.").type_image_out (),
  54   Argument::End
  55 };
  56
  57
  58 const gchar* type_choices[] = { "REAL", "IMAG", "MAG", "PHASE", "COMPLEX", NULL };
  59 const gchar* data_type_choices[] = { "FLOAT32", "FLOAT32LE", "FLOAT32BE", "FLOAT64", "FLOAT64LE", "FLOAT64BE",
  60     "INT32", "UINT32", "INT32LE", "UINT32LE", "INT32BE", "UINT32BE",
  61     "INT16", "UINT16", "INT16LE", "UINT16LE", "INT16BE", "UINT16BE",
  62     "CFLOAT32", "CFLOAT32LE", "CFLOAT32BE", "CFLOAT64", "CFLOAT64LE", "CFLOAT64BE",
  63     "INT8", "UINT8", "BIT", NULL };
  64
  65 OPTIONS = {
  66   Option ("coord", "select coordinates", "extract data only at the coordinates specified.", false, true)
  67     .append (Argument ("axis", "axis", "the axis of interest").type_integer (0, INT_MAX, 0))
  68     .append (Argument ("coord", "coordinates", "the coordinates of interest").type_sequence_int()),
  69
  70   Option ("vox", "voxel size", "change the voxel dimensions.")
  71     .append (Argument ("sizes", "new dimensions", "A comma-separated list of values. Only those values specified will be changed. For example: 1,,3.5 will change the voxel size along the x & z axes, and leave the y-axis voxel size unchanged.")
  72         .type_sequence_float ()),
  73
  74   Option ("datatype", "data type", "specify output image data type.")
  75     .append (Argument ("spec", "specifier", "the data type specifier.").type_choice (data_type_choices)),
  76
  77   Option ("scale", "scaling factor", "apply scaling to the intensity values.")
  78     .append (Argument ("factor", "factor", "the factor by which to multiply the intensities.").type_float (NAN, NAN, 1.0)),
  79
  80   Option ("offset", "offset", "apply offset to the intensity values.")
  81     .append (Argument ("bias", "bias", "the value of the offset.").type_float (NAN, NAN, 0.0)),
  82
  83   Option ("zero", "replace NaN by zero", "replace all NaN values with zero."),
  84
  85   Option ("output", "output type", "specify type of output")
  86     .append (Argument ("type", "type", "type of output.")
  87         .type_choice (type_choices)),
  88
  89   Option ("layout", "data layout", "specify the layout of the data in memory. The actual layout produced will depend on whether the output image format can support it.")
  90     .append (Argument ("spec", "specifier", "the data layout specifier.").type_string ()),
  91
  92   Option ("prs", "DW gradient specified as PRS", "assume that the DW gradients are specified in the PRS frame (Siemens DICOM only)."),
  93
  94   Option::End
  95 };
  96
  97
  98
  99 inline bool next (Image::Position& ref, Image::Position& other, const std::vector<int>* pos)
 100 {
 101   int axis = 0;
 102   do {
 103     ref.inc (axis);
 104     if (ref[axis] < ref.dim(axis)) {
 105       other.set (axis, pos[axis][ref[axis]]);
 106       return (true);
 107     }
 108     ref.set (axis, 0);
 109     other.set (axis, pos[axis][0]);
 110     axis++;
 111   } while (axis < ref.ndim());
 112   return (false);
 113 }
 114
 115
 116
 117
 118
 119 EXECUTE {
 120   std::vector<OptBase> opt = get_options (1); // vox
 121   std::vector<float> vox;
 122   if (opt.size())
 123     vox = parse_floats (opt[0][0].get_string());
 124
 125
 126   opt = get_options (3); // scale
 127   float scale = 1.0;
 128   if (opt.size()) scale = opt[0][0].get_float();
 129
 130   opt = get_options (4); // offset
 131   float offset = 0.0;
 132   if (opt.size()) offset = opt[0][0].get_float();
 133
 134   opt = get_options (5); // zero
 135   bool replace_NaN = opt.size();
 136
 137   opt = get_options (6); // output
 138   Image::OutputType output_type = Image::Default;
 139   if (opt.size()) {
 140     switch (opt[0][0].get_int()) {
 141       case 0: output_type = Image::Real; break;
 142       case 1: output_type = Image::Imaginary; break;
 143       case 2: output_type = Image::Magnitude; break;
 144       case 3: output_type = Image::Phase; break;
 145       case 4: output_type = Image::RealImag; break;
 146     }
 147   }
 148
 149
 150
 151
 152   Image::Object &in_obj (*argument[0].get_image());
 153
 154   Image::Header header (in_obj);
 155
 156   if (output_type == 0) {
 157     if (in_obj.is_complex()) output_type = Image::RealImag;
 158     else output_type = Image::Default;
 159   }
 160
 161   if (output_type == Image::RealImag) header.data_type = DataType::CFloat32;
 162   else if (output_type == Image::Phase) header.data_type = DataType::Float32;
 163   else header.data_type.unset_flag (DataType::ComplexNumber);
 164
 165  
 166   opt = get_options (2); // datatype
 167   if (opt.size()) header.data_type.parse (data_type_choices[opt[0][0].get_int()]);
 168
 169   for (guint n = 0; n < vox.size(); n++)
 170     if (isfinite (vox[n])) header.axes.vox[n] = vox[n];
 171
 172   opt = get_options (7); // layout
 173   if (opt.size()) {
 174     std::vector<Image::Axis> ax = parse_axes_specifier (header.axes, opt[0][0].get_string());
 175     if (ax.size() != (guint) header.axes.ndim())
 176       throw Exception (String("specified layout \"") + opt[0][0].get_string() + "\" does not match image dimensions");
 177
 178     for (guint i = 0; i < ax.size(); i++) {
 179       header.axes.axis[i] = ax[i].axis;
 180       header.axes.forward[i] = ax[i].forward;
 181     }
 182   }
 183
 184
 185   opt = get_options (8); // prs
 186   if (opt.size() && header.DW_scheme.rows() && header.DW_scheme.columns()) {
 187     for (guint row = 0; row < header.DW_scheme.rows(); row++) {
 188       double tmp = header.DW_scheme(row, 0);
 189       header.DW_scheme(row, 0) = header.DW_scheme(row, 1);
 190       header.DW_scheme(row, 1) = tmp;
 191       header.DW_scheme(row, 2) = -header.DW_scheme(row, 2);
 192     }
 193   }
 194
 195   std::vector<int> pos[in_obj.ndim()];
 196
 197   opt = get_options (0); // coord
 198   for (guint n = 0; n < opt.size(); n++) {
 199     int axis = opt[n][0].get_int();
 200     if (pos[axis].size()) throw Exception ("\"coord\" option specified twice for axis " + str (axis));
 201     pos[axis] = parse_ints (opt[n][1].get_string(), header.dim(axis)-1);
 202     header.axes.dim[axis] = pos[axis].size();
 203   }
 204
 205   for (int n = 0; n < in_obj.ndim(); n++) {
 206     if (pos[n].empty()) {
 207       pos[n].resize (in_obj.dim(n));
 208       for (guint i = 0; i < pos[n].size(); i++) pos[n][i] = i;
 209     }
 210   }
 211
 212
 213   in_obj.apply_scaling (scale, offset);
 214
 215
 216
 217
 218
 219
 220   Image::Position in (in_obj);
 221   Image::Position out (*argument[1].get_image (header));
 222
 223   for (int n = 0; n < in.ndim(); n++) in.set (n, pos[n][0]);
 224
 225   ProgressBar::init (out.voxel_count(), "copying data...");
 226
 227   do {
 228
 229     float re, im = 0.0;
 230     in.get (output_type, re, im);
 231     if (replace_NaN) if (gsl_isnan (re)) re = 0.0;
 232     out.re (re);
 233
 234     if (output_type == Image::RealImag) {
 235       if (replace_NaN) if (gsl_isnan (im)) im = 0.0;
 236       out.im (im);
 237     }
 238
 239     ProgressBar::inc();
 240   } while (next (out, in, pos));
 241
 242   ProgressBar::done();
 243 }
 244
 245
 246
 247
 248
share|improve this question
Welcome to Code Review! Unfortunately, questions about understanding code are off-topic here, as explained in the faq. I'm sorry that you were directed here by an incorrect comment on Stack Overflow. I have voted to reopen your question there. – codesparkle Apr 18 at 12:44

closed as off topic by codesparkle Apr 18 at 12:44

Questions on Code Review Stack Exchange are expected to relate to code review request within the scope defined in the FAQ. Consider editing the question or leaving comments for improvement if you believe the question can be reworded to fit within the scope. Read more about closed questions here.

Browse other questions tagged or ask your own question.