MINC/軟體開發/MINC1-體素迴圈示例
外觀
基本思路是,你用一個輸入檔案列表、一個輸出檔案列表和一個要呼叫的函式呼叫 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 個緩衝區中,因為這些資料會被寫入。