6

私は現在、次のコード ( http://pastebin.com/zTHUrmyx ) がどのように機能するかを理解しようとしています。現在、私のアプローチは、ソフトウェアをデバッグでコンパイルし、gdb を使用してコードをステップスルーすることです。

ただし、「ステップ」が常に何が起こっているかを教えてくれるとは限らないという問題に直面しています。私にとって特に不明なのは、私がEXECUTE {...}足を踏み入れることができないものです。

コードが何をしているのかを知るにはどうすればよいですか?

   1     /*
   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 <d.tournier@brain.org.au>
  23     * fix -prs option handling
  24     * remove MR::DICOM_DW_gradients_PRS flag
  25
  26     15-10-2008 J-Donald Tournier <d.tournier@brain.org.au>
  27     * add -layout option to manipulate data ordering within the image file
  28
  29     14-02-2010 J-Donald Tournier <d.tournier@brain.org.au>
  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 }
4

1 に答える 1

3

コメントで指摘されているEXECUTEように、マクロのようであり、コンテキストから関数ヘッダー (そして、いくつかのグローバル変数や関数など、もう少しかもしれません) が明らかであるため、中括弧内の部分は関数本体です。

の定義にたどり着くにはEXECUTE、ヘッダーを調べる必要があります。

ただし、デバッグ中にコードの一部に到達できる場合は、その時点でstringまたはを挿入して、文字列化されたバージョンの を与えることができます。これにより、コード内のその位置でプリプロセッサが出力するものは何でも取得できます。char[]EXECUTEEXECUTE

#define STR(x) #x
#define STRINGIFY(x) STR(x)
char c[] = STRINGIFY(EXECUTE);

2 つのマクロは、任意のマクロの内容を文字列リテラルとして取得するための既知の小さなマクロ トリックです。試してみて、デバッガーで char 配列を調べて、execute の内容を取得してください。

ここでの私のワイルドな推測:EXECUTEはメイン関数またはその代替であり、プログラムが期待する引数と、それに渡すことができるコマンド ライン オプションを記述しますOPTIONSARGUMENTSこれらのマクロと、使用される関数と変数の一部 ( get_optionsargument) は、コマンド ライン オプションに関する使用法、評価、およびユーザー情報を容易にする小さなフレームワークの一部です。

于 2013-04-18T07:09:54.830 に答える