Mercurial > hg > minc-tools
changeset 762:b2f1414a8e0c
check_in_all
author | david <david> |
---|---|
date | Mon, 20 Feb 1995 13:12:07 +0000 |
parents | d27396a00a66 |
children | 7986daa84189 |
files | volume_io/Documentation/volume_io.tex volume_io/Geometry/gaussian.c volume_io/Geometry/inverse.c volume_io/MNI_formats/thin_plate_spline.c volume_io/Testing/reorder_volume.c volume_io/Volumes/output_mnc.c volume_io/Volumes/volumes.c |
diffstat | 7 files changed, 307 insertions(+), 140 deletions(-) [+] |
line wrap: on
line diff
--- a/volume_io/Documentation/volume_io.tex +++ b/volume_io/Documentation/volume_io.tex @@ -2280,6 +2280,13 @@ \name{Transform}. {\bf\begin{verbatim} +#define Transform_elem( transform, i, j ) +\end{verbatim}} + +\desc{Is used to set or retrieve the value of the \name{i}'th row and +\name{j}'th column of the transform, where $0 <= i,j <= 3$.} + +{\bf\begin{verbatim} public void make_identity_transform( Transform *transform ) \end{verbatim}} @@ -2372,7 +2379,9 @@ \end{verbatim}} \desc{Creates a general transform consisting of a single linear -transform, specified by \name{linear\_transform}.} +transform, specified by \name{linear\_transform}. If a \name{NULL} is +passed as the argument \name{linear\-\_transform}, then an identity +transform is created.} {\bf\begin{verbatim} public void create_thin_plate_transform( @@ -2409,6 +2418,37 @@ the general transform.} {\bf\begin{verbatim} +typedef void (*User_transform_function)( void *user_data, + Real x, + Real y, + Real z, + Real *x_trans, + Real *y_trans, + Real *z_trans ); + +public void create_user_transform( + General_transform *transform, + void *user_data, + size_t size_user_data, + User_transform_function transform_function, + User_transform_function inverse_transform_function ) +\end{verbatim}} + +\desc{Creates a user defined transformation, by copying the user data +(\name{size\-\_user\-\_data} bytes of data starting at +\name{user\_data}). Two function pointers are also required, to +specify the method of transforming points and inversely transforming +points. These functions are of the type +\name{User\-\_transform\-\_function}, which is specified above.} + +{\bf\begin{verbatim} +public void delete_general_transform( + General_transform *transform ) +\end{verbatim}} + +\desc{Frees up the memory stored in the general transform structure.} + +{\bf\begin{verbatim} public Transform_types get_transform_type( General_transform *transform ) \end{verbatim}} @@ -2427,6 +2467,87 @@ with the routines specific to linear transforms, described earlier. Otherwise prints an error message.} +{\bf\begin{verbatim} +public void concat_general_transforms( + General_transform *first, + General_transform *second, + General_transform *result ) +\end{verbatim}} + +\desc{Concatenates two general transforms. If both transforms are of +type \name{LINEAR}, then the result is also of this type, being the +matrix product of the two. Otherwise, the resulting transform is +simply the concatenation of the two transforms.} + +{\bf\begin{verbatim} +public int get_n_concated_transforms( + General_transform *transform ) +\end{verbatim}} + +\desc{Returns the number of concatenated transforms in the given +transform. If the type of the transform is +\name{CONCATENATED\_TRANSFORM}, then the number returned is the number +of transforms, otherwise it is one.} + +{\bf\begin{verbatim} +public General_transform *get_nth_general_transform( + General_transform *transform, + int n ) +\end{verbatim}} + +\desc{If the transform is of type \name{CONCATENATED\_TRANSFORM}, then +a pointer to the \name{n}'th transform is returned, where \name{n} +is greater than or equal to zero and less than the number of +transforms in the concatenated transform.} + +\section{Using General Transforms} + +{\bf\begin{verbatim} +public void general_transform_point( + General_transform *transform, + Real x, + Real y, + Real z, + Real *x_transformed, + Real *y_transformed, + Real *z_transformed ) +\end{verbatim}} + +\desc{Transforms a three dimensional point by a general transform, +passing back the result in the last three arguments.} + +{\bf\begin{verbatim} +public void general_inverse_transform_point( + General_transform *transform, + Real x, + Real y, + Real z, + Real *x_transformed, + Real *y_transformed, + Real *z_transformed ) +\end{verbatim}} + +\desc{Transforms a three dimensional point by the inverse of the +general transform, passing back the result in the last three arguments.} + +{\bf\begin{verbatim} +public void copy_general_transform( + General_transform *transform, + General_transform *copy ) +\end{verbatim}} + +\desc{Creates a copy of the general transform, allocating memory +within the structure as required.} + +{\bf\begin{verbatim} +public void create_inverse_general_transform( + General_transform *transform, + General_transform *inverse ) +\end{verbatim}} + +\desc{Creates a new general transform that is the inverse of the given +one.} + \section{Reading and Writing General Transforms} General transforms are stored in files in an ascii format devised at
--- a/volume_io/Geometry/gaussian.c +++ b/volume_io/Geometry/gaussian.c @@ -10,20 +10,22 @@ int n_values, Real **values ) { - int i, j, k, p, v; - Real **a, *s, val, best_val, m, *tmp, scale_factor; + int i, j, k, p, v, *row, tmp; + Real **a, **solution, *s, val, best_val, m, scale_factor; BOOLEAN success; - ALLOC( a, n ); - for_less( i, 0, n ) - ALLOC( a[i], n ); - + ALLOC( row, n ); + ALLOC2D( a, n, n ); + ALLOC2D( solution, n, n_values ); ALLOC( s, n ); for_less( i, 0, n ) { + row[i] = i; for_less( j, 0, n ) a[i][j] = coefs[i][j]; + for_less( j, 0, n_values ) + solution[i][j] = values[j][i]; } for_less( i, 0, n ) @@ -41,11 +43,11 @@ for_less( i, 0, n-1 ) { p = i; - best_val = a[i][i] / s[i]; + best_val = a[row[i]][i] / s[row[i]]; best_val = ABS( best_val ); - for_less( j, i, n ) + for_less( j, i+1, n ) { - val = a[j][i] / s[j]; + val = a[row[j]][i] / s[row[j]]; val = ABS( val ); if( val > best_val ) { @@ -54,7 +56,7 @@ } } - if( a[p][i] == 0.0 ) + if( a[row[p]][i] == 0.0 ) { success = FALSE; break; @@ -62,42 +64,52 @@ if( i != p ) { - tmp = a[i]; - a[i] = a[p]; - a[p] = tmp; + tmp = row[i]; + row[i] = row[p]; + row[p] = tmp; } for_less( j, i+1, n ) { - m = a[j][i] / a[i][i]; + m = a[row[j]][i] / a[row[i]][i]; for_less( k, i+1, n ) - a[j][k] -= m * a[i][k]; + a[row[j]][k] -= m * a[row[i]][k]; for_less( v, 0, n_values ) - values[v][j] -= m * values[v][i]; + solution[row[j]][v] -= m * solution[row[i]][v]; } } - if( success && a[n-1][n-1] == 0.0 ) + if( success && a[row[n-1]][n-1] == 0.0 ) success = FALSE; - for( i = n-1; i >= 0; --i ) + if( success ) { - for_less( j, i+1, n ) + for( i = n-1; i >= 0; --i ) { - scale_factor = a[i][j]; + for_less( j, i+1, n ) + { + scale_factor = a[row[i]][j]; + for_less( v, 0, n_values ) + solution[row[i]][v] -= scale_factor * solution[row[j]][v]; + } + for_less( v, 0, n_values ) - values[v][i] -= scale_factor * values[v][j]; + solution[row[i]][v] /= a[row[i]][i]; } - for_less( v, 0, n_values ) - values[v][i] /= a[i][i]; + for_less( i, 0, n ) + { + for_less( v, 0, n_values ) + { + values[v][i] = solution[row[i]][v]; + } + } } - for_less( i, 0, n ) - FREE( a[i] ); - FREE( a ); - + FREE2D( a ); + FREE2D( solution ); FREE( s ); + FREE( row ); return( success ); } @@ -122,6 +134,8 @@ Real **matrix, Real **inverse ) { + Real tmp; + BOOLEAN success; int i, j; for_less( i, 0, n ) @@ -131,6 +145,21 @@ inverse[i][i] = 1.0; } - return( scaled_maximal_pivoting_gaussian_elimination( n, matrix, - n, inverse ) ); + success = scaled_maximal_pivoting_gaussian_elimination( n, matrix, + n, inverse ); + + if( success ) + { + for_less( i, 0, n-1 ) + { + for_less( j, i+1, n ) + { + tmp = inverse[i][j]; + inverse[i][j] = inverse[j][i]; + inverse[j][i] = tmp; + } + } + } + + return( success ); }
--- a/volume_io/Geometry/inverse.c +++ b/volume_io/Geometry/inverse.c @@ -1,6 +1,6 @@ #ifndef lint -static char rcsid[] = "$Header: /private-cvsroot/minc/volume_io/Geometry/inverse.c,v 1.4 1994-11-25 14:19:29 david Exp $"; +static char rcsid[] = "$Header: /private-cvsroot/minc/volume_io/Geometry/inverse.c,v 1.5 1995-02-20 13:12:07 david Exp $"; #endif #include <internal_volume_io.h> @@ -22,37 +22,28 @@ Transform *transform, Transform *inverse ) { - int i, j, ind[5]; - float **t, **inv, col[5], d; + int i, j; + Real **t, **inv; Transform ident; + BOOLEAN success; /* --- copy the transform to a numerical recipes type matrix */ - ALLOC2D( t, 5, 5 ); - ALLOC2D( inv, 5, 5 ); + ALLOC2D( t, 4, 4 ); + ALLOC2D( inv, 4, 4 ); for_less( i, 0, 4 ) { for_less( j, 0, 4 ) { - t[i+1][j+1] = Transform_elem(*transform,i,j); + t[i][j] = Transform_elem(*transform,i,j); } } - ludcmp( t, 4, ind, &d ); + success = invert_square_matrix( 4, t, inv ); - if( d != 0.0 ) + if( success ) { - for_inclusive( j, 1, 4 ) - { - for_inclusive( i, 1, 4 ) - col[i] = 0.0; - col[j] = 1.0; - lubksb( t, 4, ind, col ); - for_inclusive( i, 1, 4 ) - inv[i][j] = col[i]; - } - /* --- copy the resulting numerical recipes matrix to the output argument */ @@ -60,7 +51,7 @@ { for_less( j, 0, 4 ) { - Transform_elem(*inverse,i,j) = inv[i+1][j+1]; + Transform_elem(*inverse,i,j) = inv[i][j]; } } @@ -73,9 +64,11 @@ print( "Error in compute_transform_inverse\n" ); } } + else + make_identity_transform( inverse ); FREE2D( t ); FREE2D( inv ); - return( d != 0.0 ); + return( success ); }
--- a/volume_io/MNI_formats/thin_plate_spline.c +++ b/volume_io/MNI_formats/thin_plate_spline.c @@ -1,6 +1,6 @@ #ifndef lint -static char rcsid[] = "$Header: /private-cvsroot/minc/volume_io/MNI_formats/thin_plate_spline.c,v 1.4 1994-11-25 14:20:26 david Exp $"; +static char rcsid[] = "$Header: /private-cvsroot/minc/volume_io/MNI_formats/thin_plate_spline.c,v 1.5 1995-02-20 13:12:27 david Exp $"; #endif /* ----------------------------- MNI Header ----------------------------------- @@ -26,7 +26,7 @@ private void mnewt(int ntrial,float x[], int dim, float tolx, float tolf, float **bdefor, float **INVMLY, int num_marks); private void - usrfun(float x[], float **alpha, float bet[], float **bdefor, float **INVMLY, + usrfun(float x[], Real **alpha, Real bet[], float **bdefor, float **INVMLY, int num_marks, int dim, float *xout); private float return_r(float *cor1, float *cor2, int dim); private float FU(float r, int dim); @@ -48,7 +48,7 @@ INVMLY to 'in' to get 'out' @METHOD : @GLOBALS : none -@CALLS : return_r, vector, free_vector +@CALLS : return_r @CREATED : Mon Apr 5 09:00:54 EST 1993 @MODIFIED : ---------------------------------------------------------------------------- */ @@ -188,31 +188,28 @@ either summed variable increments tolx or summed function values tolf @GLOBALS : none -@CALLS : ludcmp, lubksb, usrfun +@CALLS : usrfun @CREATED : Mon Apr 5 09:00:54 EST 1993 @MODIFIED : ---------------------------------------------------------------------------- */ -#define FREERETURN {FREE2D(alpha);FREE(bet);FREE(indx);return;} +#define FREERETURN {FREE2D(alpha);FREE(bet);return;} private void mnewt(int ntrial,float x[], int dim, float tolx, float tolf, float **bdefor, float **INVMLY, int num_marks) { - int k,i,*indx; - float - errx,errf,d, - *bet,**alpha, - xout[N_DIMENSIONS]; + int k,i; + Real *bet, **alpha; + float errx,errf, xout[N_DIMENSIONS]; xout[0] = x[0]; /* assume that the result is equal to the input, */ xout[1] = x[1]; /* as if the transformation was identity */ if (dim>2) xout[2] = x[2]; - ALLOC( indx, dim + 1 ); - ALLOC( bet, dim + 1 ); - ALLOC2D( alpha, dim + 1, dim + 1 ); + ALLOC( bet, dim ); + ALLOC2D( alpha, dim, dim ); for (k=1;k<=ntrial;k++) { /* usrfun will build the matrix coefficients for @@ -220,14 +217,16 @@ usrfun(x, alpha, bet, bdefor, INVMLY, num_marks, dim, xout); errf=0.0; /* Check for function convergence */ - for (i=1;i<=dim;i++) errf += fabs(bet[i]); + for (i=1;i<=dim;i++) errf += fabs(bet[i-1]); if (errf <= tolf) FREERETURN - ludcmp(alpha,dim,indx,&d); /* Solve the linear eqs using LU decomposition */ - lubksb(alpha,dim,indx,bet); + + if( !solve_linear_system( dim, alpha, bet, bet ) ) + FREERETURN; + errx=0.0; for (i=1;i<=dim;i++) { /* check for root convergence */ - errx += fabs(bet[i]); - x[i-1] += bet[i]; /* Update the solution */ + errx += fabs(bet[i-1]); + x[i-1] += bet[i-1]; /* Update the solution */ } if (errx <= tolx) FREERETURN } @@ -261,7 +260,7 @@ ---------------------------------------------------------------------------- */ private void - usrfun(float x[], float **alpha, float bet[], float **bdefor, float **INVMLY, + usrfun(float x[], Real **alpha, Real bet[], float **bdefor, float **INVMLY, int num_marks, int dim, float *xout) /* NOTE: Now this function will only work for 3-D case */ @@ -271,8 +270,8 @@ ALLOC( d, num_marks ); - for (i=1; i<=dim; i++){ /* build up the matrix of linear parameters */ - for (j=1; j<=dim; j++){ + for (i=0; i<dim; i++){ /* build up the matrix of linear parameters */ + for (j=0; j<dim; j++){ alpha[i][j] = 0; } } @@ -281,25 +280,25 @@ for (i=0; i<num_marks; i++) /* build distances array */ d[i] = return_r( x, bdefor[i], dim ); - for (i = 1; i<= dim; i++){ /* Estimate the linear parameters for the error function */ - for (j = 1; j <= dim; j++){ + for (i = 0; i< dim; i++){ /* Estimate the linear parameters for the error function */ + for (j = 0; j < dim; j++){ alpha[i][j] = 0; - for (k = 1; k <= num_marks; k++){ - alpha[i][j] += (x[j-1] - bdefor[k-1][j-1])/d[k-1] *INVMLY[k-1][i-1]; + for (k = 0; k < num_marks; k++){ + alpha[i][j] += (x[j] - bdefor[k][j])/d[k] *INVMLY[k][i]; } - alpha[i][j] += INVMLY[k+j-1][i-1]; + alpha[i][j] += INVMLY[k+j][i]; } } - for (i=1; i<=dim; i++){ + for (i=0; i<dim; i++){ bet[i] = 0; - for (k=1; k<=num_marks; k++){ - bet[i] += d[k-1]*INVMLY[k-1][i-1]; + for (k=0; k<num_marks; k++){ + bet[i] += d[k]*INVMLY[k][i]; } - bet[i] += INVMLY[k-1][i-1] + - INVMLY[k+1-1][i-1]*x[0] + - INVMLY[k+2-1][i-1]*x[1] + - INVMLY[k+3-1][i-1]*x[2] - xout[i-1]; + bet[i] += INVMLY[k][i] + + INVMLY[k+1][i]*x[0] + + INVMLY[k+2][i]*x[1] + + INVMLY[k+3][i]*x[2] - xout[i]; bet[i] = -bet[i]; }
--- a/volume_io/Testing/reorder_volume.c +++ b/volume_io/Testing/reorder_volume.c @@ -5,17 +5,16 @@ char *argv[] ) { int i, a, n_dims, v, n_volumes, sizes[MAX_DIMENSIONS]; - int sizes_2d[MAX_DIMENSIONS]; char *input_filename, *output_filename, *string; char *in_dim_names[MAX_DIMENSIONS]; char *out_dim_names[MAX_DIMENSIONS]; - Real amount_done, value; + Real amount_done; Real real_min, real_max; STRING dim_names[MAX_DIMENSIONS]; Volume volume; General_transform transform; Minc_file in_file, out_file; - minc_output_options options, *options_ptr; + minc_output_options options; volume_input_struct volume_input; nc_type data_type; BOOLEAN signed_flag; @@ -66,8 +65,6 @@ { /*--- determine the output order */ - options_ptr = &options; - for_less( i, 0, N_DIMENSIONS ) { string = argv[a]; @@ -87,6 +84,8 @@ } } + /*--- open and close volume as 3D to get correct transform */ + (void) start_volume_input( input_filename, N_DIMENSIONS, out_dim_names, NC_UNSPECIFIED, FALSE, 0.0, 0.0, TRUE, &volume, (minc_input_options *) NULL,
--- a/volume_io/Volumes/output_mnc.c +++ b/volume_io/Volumes/output_mnc.c @@ -2,7 +2,7 @@ #include <internal_volume_io.h> #ifndef lint -static char rcsid[] = "$Header: /private-cvsroot/minc/volume_io/Volumes/output_mnc.c,v 1.21 1995-02-13 13:14:27 david Exp $"; +static char rcsid[] = "$Header: /private-cvsroot/minc/volume_io/Volumes/output_mnc.c,v 1.22 1995-02-20 13:12:24 david Exp $"; #endif #define INVALID_AXIS -1 @@ -114,7 +114,7 @@ Vector axes[MAX_DIMENSIONS]; static STRING default_dim_names[] = { MIzspace, MIyspace, MIxspace }; char *file_dim_names[MAX_VAR_DIMS]; - Transform transform; + Transform transform, t, inverse; char **vol_dimension_names; minc_output_options default_options; @@ -264,9 +264,16 @@ } } - start[X] = DOT_POINT_VECTOR( origin, axes[X] ); - start[Y] = DOT_POINT_VECTOR( origin, axes[Y] ); - start[Z] = DOT_POINT_VECTOR( origin, axes[Z] ); + make_identity_transform( &t ); + set_transform_x_axis( &t, &axes[X] ); + set_transform_y_axis( &t, &axes[Y] ); + set_transform_z_axis( &t, &axes[Z] ); + + (void) compute_transform_inverse( &t, &inverse ); + + transform_point( &inverse, + Point_x(origin), Point_y(origin), Point_z(origin), + &start[X], &start[Y], &start[Z] ); for_less( d, 0, n_dimensions ) {
--- a/volume_io/Volumes/volumes.c +++ b/volume_io/Volumes/volumes.c @@ -3,7 +3,7 @@ #include <float.h> #ifndef lint -static char rcsid[] = "$Header: /private-cvsroot/minc/volume_io/Volumes/volumes.c,v 1.38 1995-02-17 09:46:24 david Exp $"; +static char rcsid[] = "$Header: /private-cvsroot/minc/volume_io/Volumes/volumes.c,v 1.39 1995-02-20 13:12:21 david Exp $"; #endif char *XYZ_dimension_names[] = { MIxspace, MIyspace, MIzspace }; @@ -997,6 +997,42 @@ recompute_world_transform( volume ); } +private void reorder_voxel_to_xyz( + Volume volume, + Real voxel[], + Real xyz[] ) +{ + int c, axis; + + for_less( c, 0, N_DIMENSIONS ) + { + axis = volume->spatial_axes[c]; + if( axis >= 0 ) + xyz[c] = voxel[axis]; + else + xyz[c] = 0.0; + } +} + +private void reorder_xyz_to_voxel( + Volume volume, + Real xyz[], + Real voxel[] ) +{ + int c, axis, n_dims; + + n_dims = get_volume_n_dimensions( volume ); + for_less( c, 0, n_dims ) + voxel[c] = 0.0; + + for_less( c, 0, N_DIMENSIONS ) + { + axis = volume->spatial_axes[c]; + if( axis >= 0 ) + voxel[axis] = xyz[c]; + } +} + /* ----------------------------- MNI Header ----------------------------------- @NAME : convert_voxel_to_world @INPUT : volume @@ -1021,27 +1057,14 @@ Real *y_world, Real *z_world ) { - Real x_voxel, y_voxel, z_voxel; - - if( volume->spatial_axes[0] >= 0 ) - x_voxel = voxel[volume->spatial_axes[0]]; - else - x_voxel = 0.0; + Real xyz[N_DIMENSIONS]; - if( volume->spatial_axes[1] >= 0 ) - y_voxel = voxel[volume->spatial_axes[1]]; - else - y_voxel = 0.0; - - if( volume->spatial_axes[2] >= 0 ) - z_voxel = voxel[volume->spatial_axes[2]]; - else - z_voxel = 0.0; + reorder_voxel_to_xyz( volume, voxel, xyz ); /* apply linear transform */ general_transform_point( &volume->voxel_to_world_transform, - x_voxel, y_voxel, z_voxel, + xyz[X], xyz[Y], xyz[Z], x_world, y_world, z_world ); } @@ -1090,9 +1113,9 @@ /* ----------------------------- MNI Header -----------------------------------@NAME : convert_voxel_normal_vector_to_world @INPUT : volume - x_voxel - y_voxel - z_voxel + voxel_vector0 + voxel_vector1 + voxel_vector2 @OUTPUT : x_world y_world z_world @@ -1105,15 +1128,22 @@ ---------------------------------------------------------------------------- */ public void convert_voxel_normal_vector_to_world( Volume volume, - Real x_voxel, - Real y_voxel, - Real z_voxel, + Real voxel_vector0, + Real voxel_vector1, + Real voxel_vector2, Real *x_world, Real *y_world, Real *z_world ) { + Real voxel[N_DIMENSIONS], xyz[N_DIMENSIONS]; Transform *inverse; + voxel[0] = voxel_vector0; + voxel[1] = voxel_vector1; + voxel[2] = voxel_vector2; + + reorder_voxel_to_xyz( volume, voxel, xyz ); + if( get_transform_type( &volume->voxel_to_world_transform ) != LINEAR ) handle_internal_error( "Cannot get normal vector of nonlinear xforms."); @@ -1122,15 +1152,15 @@ /* transform vector by transpose of inverse transformation */ - *x_world = Transform_elem(*inverse,0,0) * x_voxel + - Transform_elem(*inverse,1,0) * y_voxel + - Transform_elem(*inverse,2,0) * z_voxel; - *y_world = Transform_elem(*inverse,0,1) * x_voxel + - Transform_elem(*inverse,1,1) * y_voxel + - Transform_elem(*inverse,2,1) * z_voxel; - *z_world = Transform_elem(*inverse,0,2) * x_voxel + - Transform_elem(*inverse,1,2) * y_voxel + - Transform_elem(*inverse,2,2) * z_voxel; + *x_world = Transform_elem(*inverse,0,0) * xyz[X] + + Transform_elem(*inverse,1,0) * xyz[Y] + + Transform_elem(*inverse,2,0) * xyz[Z]; + *y_world = Transform_elem(*inverse,0,1) * xyz[X] + + Transform_elem(*inverse,1,1) * xyz[Y] + + Transform_elem(*inverse,2,1) * xyz[Z]; + *z_world = Transform_elem(*inverse,0,2) * xyz[X] + + Transform_elem(*inverse,1,2) * xyz[Y] + + Transform_elem(*inverse,2,2) * xyz[Z]; } /* ----------------------------- MNI Header ----------------------------------- @@ -1220,26 +1250,15 @@ Real z_world, Real voxel[] ) { - int c; - Real x_voxel, y_voxel, z_voxel; + Real xyz[N_DIMENSIONS]; /* apply linear transform */ general_inverse_transform_point( &volume->voxel_to_world_transform, - x_world, y_world, z_world, - &x_voxel, &y_voxel, &z_voxel ); - - for_less( c, 0, get_volume_n_dimensions(volume) ) - voxel[c] = 0.0; + x_world, y_world, z_world, + &xyz[X], &xyz[Y], &xyz[Z] ); - if( volume->spatial_axes[0] >= 0 ) - voxel[volume->spatial_axes[0]] = x_voxel; - - if( volume->spatial_axes[1] >= 0 ) - voxel[volume->spatial_axes[1]] = y_voxel; - - if( volume->spatial_axes[2] >= 0 ) - voxel[volume->spatial_axes[2]] = z_voxel; + reorder_xyz_to_voxel( volume, xyz, voxel ); } /* ----------------------------- MNI Header -----------------------------------