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 个缓冲区中,因为这些数据会被写入。