跳转到内容

MINC/软件开发/MINC1-体素循环示例

来自维基教科书,开放的书籍,为开放的世界

这是来自 Peter Neelin 的一个老文档的转储,很久以前了

[编辑 | 编辑源代码]

基本思路是,你用一个输入文件列表、一个输出文件列表和一个要调用的函数调用 voxel_loop

   /* figure out input files */
   num_outputs = 2;
   output_files = &argv[argc - num_output_files];
   num_inputs = argc - num_outputs - 1;
   input_files = &argv[1];

   /* Set up program_data pointer */
   program_data = MALLOC(sizeof(*program_data));
   program_data->field1 = junk;

   /* Set up loop options. You can just pass it NULL if the defaults
      are okay, but I put some here as examples. */
   loop_options = create_loop_options();
   set_loop_verbose(loop_options, TRUE);
   set_loop_clobber(loop_options, FALSE);
   set_loop_datatype(loop_options, NC_SHORT, TRUE, 0.0, 32000.0);
   set_loop_copy_all_header(loop_options, FALSE);
   set_loop_buffer_size(loop_options, (long) 1024 * max_buffer_size_in_kb);

   /* Do it */
   voxel_loop(num_inputs, input_files, num_outputs, output_files, 
              history_string, loop_options, 
              voxel_function, (void *) program_data);

   /* Free loop options */
   free_loop_options(loop_options);

/******************************************************************/

#define INVALID_DATA (-DBL_MAX)

void voxel_function(void *caller_data, long num_voxels, 
                    int input_num_buffers, int input_vector_length, 
                    double *input_data[],
                    int output_num_buffers, int output_vector_length, 
                    double *output_data[],
                    Loop_Info *loop_info)
/* ARGSUSED */
{
   Program_Data *program_data;
   long ivox, num_values;
   int ibuff;
   double sum1, sum2, value;

   /* Get pointer to program data */
   program_data = (Program_Data *) caller_data;
   num_values = num_voxels * input_vector_length;

   /* Do the good stuff */
   for (ivox=0; ivox < num_values; ivox++) {

      sum1 = sum2 = 0.0;
      for (ibuff=0; ibuff < input_num_buffers; ibuff++) {

         /* Do something useful with the data! */
         value = input_data[ibuff][ivox];
         if (value != INVALID_DATA) {
            sum1++;
            sum2 += value;
         }

      }

      output_data[0] = sum1;
      output_data[1] = (sum1 > 0.0 ? sum2/sum1 : INVALID_DATA);

   }

   return;
}
<syntaxhighlight>

Of course, this is a bad example, since I am loading in a buffer for
each volume and then looping over all the buffers just once. For a lot
of input files I am doing a great deal of unnecessary buffering. For
the case where you have one pass through the data, you should set the
loop option

<syntaxhighlight lang="c">
   set_loop_accumulate(loop_options, TRUE, num_extra_buffers, 
                       start_function, end_function);

这会导致 voxel_loop 调用 voxel 函数,但只有一个缓冲区(但每个文件调用一次)。这个想法是,你把 ibuff 循环放在外面。但是,现在你需要在缓冲区中跟踪 sum1 和 sum2 - 好吧,就用输出缓冲区来做这个。如果你只有一个输出文件并且需要两个缓冲区怎么办?然后将 num_extra_buffers 设置为 1 - 加上一个输出缓冲区,就会有 2 个可用的缓冲区(只有第一个缓冲区被写入)。函数 start_function 和 end_function 用于初始化和对输出缓冲区执行最终计算。请记住确保在 end_function 之后,你的最终数据位于前 num_outputs 个缓冲区中,因为这些数据会被写入。

华夏公益教科书