跳轉到內容

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 個緩衝區中,因為這些資料會被寫入。

華夏公益教科書