00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include <stdio.h>
00036 #include <math.h>
00037 #include <stdlib.h>
00038 #if !(defined(DARWIN) || defined(FreeBSD))
00039 # include <malloc.h>
00040 #endif
00041 #include <string.h>
00042 #include <sys/types.h>
00043 #include <sys/stat.h>
00044
00045 #include "mrilib.h"
00046 #include "afni.h"
00047 #include "plug_maskcalc.h"
00048
00049 #ifndef ALLOW_PLUGINS
00050 # error "Plugins not properly set up -- see machdep.h"
00051 #endif
00052
00053 char * MASKCALC_main( PLUGIN_interface * );
00054
00055 static char grMessage[ R_MESSAGE_L ];
00056
00057 static char * gr_help_message =
00058 "maskcalc plugin - rickr";
00059
00060
00061 DEFINE_PLUGIN_PROTOTYPE
00062
00063 PLUGIN_interface * PLUGIN_init( int ncall )
00064 {
00065 PLUGIN_interface * plint;
00066
00067 if ( ncall > 0 )
00068 return NULL;
00069
00070 plint = PLUTO_new_interface( "maskcalc", "masked computations on datasets",
00071 gr_help_message, PLUGIN_CALL_VIA_MENU, MASKCALC_main );
00072
00073 PLUTO_add_hint( plint, "Wouldn't some cookies be right tasty?" );
00074
00075 PLUTO_set_sequence( plint , "z:Reynolds" ) ;
00076
00077
00078
00079 PLUTO_add_option( plint, "Function", "op_st", TRUE );
00080 PLUTO_add_hint ( plint, "function to perform on the data" );
00081 PLUTO_add_string( plint, "Operation", gr_num_ops, gr_op_strings, 0 );
00082 PLUTO_add_hint ( plint, "function to perform on the data" );
00083
00084
00085
00086 PLUTO_add_option ( plint, "Dataset", "mask_st", TRUE );
00087 PLUTO_add_hint ( plint, "dataset to be used as mask" );
00088 PLUTO_add_dataset( plint, "Mask", ANAT_ALL_MASK , FUNC_ALL_MASK,
00089 DIMEN_3D_MASK | DIMEN_4D_MASK | BRICK_SHORT_MASK );
00090 PLUTO_add_hint ( plint, "dataset to be used as mask" );
00091
00092
00093
00094 PLUTO_add_option ( plint, "Dataset", "dset_st", TRUE );
00095 PLUTO_add_hint ( plint, "computational dataset" );
00096 PLUTO_add_dataset( plint, "Dset", ANAT_ALL_MASK, FUNC_ALL_MASK,
00097 DIMEN_ALL_MASK | BRICK_SHORT_MASK );
00098 PLUTO_add_hint ( plint, "dataset to be used for computation" );
00099
00100
00101
00102 PLUTO_add_option( plint, "Output", "ofile_st", FALSE );
00103 PLUTO_add_string( plint, "Outfile", 0, NULL, 0 );
00104 PLUTO_add_hint ( plint, "file for statistical output" );
00105 PLUTO_add_string( plint, "Overwrite", gr_num_yn_strings, gr_yn_strings, 1 );
00106 PLUTO_add_hint ( plint, "option to overwrite output file" );
00107
00108
00109 PLUTO_add_option( plint, "Cutoff", "min_st", FALSE );
00110 PLUTO_add_number( plint, "Min", -10000, 10000, 1, 0, 1 );
00111 PLUTO_add_hint ( plint, "exclude values below this cutoff" );
00112
00113
00114 PLUTO_add_option( plint, "Cutoff", "max_st", FALSE );
00115 PLUTO_add_number( plint, "Max", -10000, 10000, 1, 0, 1 );
00116 PLUTO_add_hint ( plint, "exclude values above this cutoff" );
00117
00118
00119 PLUTO_add_option( plint, "Tails", "tails_st", FALSE );
00120 PLUTO_add_hint ( plint, "apply min and max as tail cutoffs" );
00121
00122
00123 PLUTO_add_option( plint, "Histogram", "bins_st", FALSE );
00124 PLUTO_add_number( plint, "Bins", 1, 1000, 0, 20, 1 );
00125 PLUTO_add_hint ( plint, "number of bins in histogram" );
00126
00127 return plint;
00128 }
00129
00130 char *
00131 MASKCALC_main ( PLUGIN_interface * plint )
00132 {
00133 r_afni_s A;
00134 mask_opt_s M;
00135 char * ret_string;
00136
00137 memset( &A, 0, sizeof( A ) );
00138 memset( &M, 0, sizeof( M ) );
00139
00140 if ( ( ret_string = process_args( &A, &M, plint ) ) != NULL )
00141 return( ret_string );
00142
00143 return( process( &A, &M ) );
00144 }
00145
00146
00147
00148
00149
00150
00151
00152 static char *
00153 process_args(
00154 r_afni_s * A,
00155 mask_opt_s * M,
00156 PLUGIN_interface * plint
00157 )
00158 {
00159 MCW_idcode * idc;
00160 char * tag, * str;
00161 int op_val;
00162
00163 A->must_be_short = 1;
00164 A->want_floats = 0;
00165 A->subs_must_equal = 0;
00166 A->max_subs = 0;
00167
00168 if ( plint == NULL )
00169 return "----------------------\n"
00170 "arguments : NULL input\n"
00171 "----------------------\n";
00172
00173 while ( ( tag = PLUTO_get_optiontag( plint ) ) != NULL )
00174 {
00175 if ( ! strcmp( tag, "op_st" ) )
00176 {
00177 str = PLUTO_get_string( plint );
00178 op_val = 1 + PLUTO_string_index( str, gr_num_ops, gr_op_strings );
00179 if ( ( op_val <= (int)no_op ) || ( op_val >= (int)last_op ) )
00180 {
00181 sprintf( grMessage, "-------------------\n"
00182 "Illegal operation : '%s'\n"
00183 "Value is : %d\n"
00184 "-------------------\n",
00185 str, M->operation );
00186 return grMessage;
00187 }
00188 M->operation = (op_enum)op_val;
00189 continue;
00190 }
00191 else if ( ! strcmp( tag, "mask_st" ) )
00192 {
00193 idc = PLUTO_get_idcode( plint );
00194 A->dset[0] = PLUTO_find_dset( idc );
00195 if ( A->dset[0] == NULL )
00196 return "----------------------\n"
00197 "arg : bad mask dataset\n"
00198 "----------------------";
00199 DSET_load( A->dset[0] );
00200 A->num_dsets++;
00201 continue;
00202 }
00203 else if ( ! strcmp( tag, "dset_st" ) )
00204 {
00205 idc = PLUTO_get_idcode( plint );
00206 A->dset[1] = PLUTO_find_dset( idc );
00207 if ( A->dset[1] == NULL )
00208 return "-----------------------\n"
00209 "arg : bad inupt dataset\n"
00210 "-----------------------";
00211 DSET_load( A->dset[1] );
00212 A->num_dsets++;
00213 continue;
00214 }
00215 else if ( ! strcmp( tag, "ofile_st" ) )
00216 {
00217 M->outfile = PLUTO_get_string( plint );
00218 str = PLUTO_get_string( plint );
00219 if ( ( *str != 'y' ) && file_exists( M->outfile, "" ) )
00220 {
00221 sprintf( grMessage,
00222 "-------------------------------\n"
00223 "output file '%s' already exists\n"
00224 "consider the 'overwrite' option\n"
00225 "-------------------------------", M->outfile );
00226 return( grMessage );
00227 }
00228 continue;
00229 }
00230 else if ( ! strcmp( tag, "min_st" ) )
00231 {
00232 M->min = PLUTO_get_number( plint );
00233 M->use_min = 1;
00234 continue;
00235 }
00236
00237 if ( ! strcmp( tag, "max_st" ) )
00238 {
00239 M->max = PLUTO_get_number( plint );
00240 M->use_max = 1;
00241 continue;
00242 }
00243
00244 if ( ! strcmp( tag, "tails_st" ) )
00245 {
00246 M->use_tails = 1;
00247 continue;
00248 }
00249
00250 if ( ! strcmp( tag, "bins_st" ) )
00251 {
00252 M->num_bins = (int)PLUTO_get_number( plint );
00253 if ( ( M->num_bins <= 0 ) || ( M->num_bins > R_MAX_BINS ) )
00254 {
00255 sprintf( grMessage, "-----------------------------\n"
00256 "Illegal number of bins : %d\n"
00257 "(must be in range [1,%d])\n"
00258 "-----------------------------",
00259 M->num_bins, R_MAX_BINS );
00260 return grMessage;
00261 }
00262
00263 continue;
00264 }
00265
00266
00267
00268 sprintf( grMessage, "-----------------------\n"
00269 "Unknown optiontag : %s\n"
00270 "-----------------------", tag );
00271 return grMessage;
00272 }
00273
00274 if ( M->use_tails && ( ! M->use_min || ! M->use_max ) )
00275 {
00276 sprintf( grMessage, "------------------------------------------\n"
00277 "'tails' option requires min and max values\n"
00278 "------------------------------------------" );
00279 return grMessage;
00280 }
00281
00282 if ( M->num_bins && ( M->operation != hist_op ) )
00283 {
00284 return "----------------------------------------------------\n"
00285 "choosing # bins applies only to the 'hist' operation\n"
00286 "----------------------------------------------------";
00287 }
00288 else if ( ! M->num_bins )
00289 M->num_bins = 20;
00290
00291 if ( ( str = fill_afni_struct( A ) ) != NULL )
00292 return str;
00293
00294 if ( M->outfile && *M->outfile )
00295 {
00296 if ( ( M->outfp = open_file( M->outfile, "w" ) ) == NULL )
00297 {
00298 sprintf( grMessage, "--------------------------------\n"
00299 "Failed to open '%s' for writing.\n"
00300 "--------------------------------",
00301 M->outfile );
00302 return grMessage;
00303 }
00304 }
00305 else
00306 M->outfp = stdout;
00307
00308 return NULL;
00309 }
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321 static char *
00322 process( r_afni_s * A, mask_opt_s * M )
00323 {
00324 char * ret_string;
00325
00326 switch ( M->operation )
00327 {
00328 case hist_op:
00329
00330 ret_string = calc_hist( A, M );
00331
00332 break;
00333
00334 case stats_op:
00335
00336 ret_string = calc_stats( A, M );
00337
00338 break;
00339
00340 default:
00341
00342 ret_string = "--------------------\n"
00343 "Error: maskcalc_p_00\n"
00344 "Invalid operation.\n"
00345 "--------------------";
00346 }
00347
00348 PURGE_DSET( A->dset[0] );
00349 PURGE_DSET( A->dset[1] );
00350
00351 if ( M->outfp != stdout )
00352 fclose( M->outfp );
00353
00354 return ret_string;
00355 }
00356
00357
00358
00359
00360
00361
00362
00363
00364 static long
00365 get_mask_size(
00366 r_afni_s * A,
00367 int index,
00368 int subbrick
00369 )
00370 {
00371 long count, size;
00372 short * ptr;
00373
00374 for ( count = 0, size = 0, ptr = A->simage[ index ][ subbrick ];
00375 count < A->nvox;
00376 count++, ptr++ )
00377 if ( *ptr )
00378 size++;
00379
00380 return size;
00381 }
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391 int short_test(
00392 const void * p1,
00393 const void * p2
00394 )
00395 {
00396 short * s1 = ( short * )p1;
00397 short * s2 = ( short * )p2;
00398
00399 if ( *s1 < *s2 )
00400 return -1;
00401
00402 return ( *s1 > *s2 );
00403 }
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414 static char *
00415 calc_hist( r_afni_s * A, mask_opt_s * M )
00416 {
00417 float * data;
00418 float * ptr;
00419 float bin_size, cum, junk;
00420
00421 long size, new_size = 0;
00422 long count;
00423 int * bins;
00424
00425 int places;
00426
00427
00428 if (( data = (float *)malloc(A->subs[1] * A->nvox * sizeof(float))) == NULL)
00429 {
00430 sprintf( grMessage, "Error: maskcalc_ch_00\n"
00431 "Failed to allocate memory for %d floats.\n",
00432 A->nvox * A->subs[1] );
00433 return grMessage;
00434 }
00435
00436 if ( ( size = mask_all_shorts_to_float( A, 1, 0, data ) ) == 0 )
00437 {
00438 sprintf( grMessage, "Error: 5090\n"
00439 "Masking shorts results in empty array.\n" );
00440 return grMessage;
00441 }
00442
00443 if ( !M->use_min && !M->use_max )
00444 assign_min_max( data, size, &M->min, &M->max );
00445 else if ( !M->use_max )
00446 {
00447 assign_min_max( data, size, &junk, &M->max );
00448
00449 if ( M->min > M->max )
00450 {
00451 sprintf( grMessage, "Error: maskcalc_ch_10\n"
00452 "Min of %f is greater than max of %f\n",
00453 M->min, M->max );
00454 return grMessage;
00455 }
00456 }
00457
00458 junk = ( fabsf( M->max ) > fabsf( M->min ) ) ?
00459 fabsf( M->max ) : fabsf( M->min );
00460
00461 if ( junk == 0 )
00462 places = 2;
00463 else
00464 {
00465 places = 4 - ( int )floor( log10( junk ) );
00466
00467 if ( places > 7 )
00468 places = 7;
00469 else if ( places < 0 )
00470 places = 0;
00471 }
00472
00473 if ( ( bins = (int *)calloc( M->num_bins, sizeof( int ) ) ) == NULL )
00474 {
00475 sprintf( grMessage, "Error: maskcalc_ch_30\n"
00476 "Failed to allocate for %d longs.\n", M->num_bins );
00477 return grMessage;
00478 }
00479
00480 bin_size = ( M->max - M->min ) / M->num_bins;
00481 bin_size += 0.000001 * bin_size;
00482 if ( bin_size == 0.0 )
00483 bin_size = 1.0e-34;
00484
00485 for ( count = 0, ptr = data; count < size; count++, ptr++ )
00486 if ( ( *ptr <= M->max ) && ( *ptr >= M->min ) )
00487 {
00488 bins[ ( int )( ( *ptr - M->min ) / bin_size ) ]++;
00489 new_size++;
00490 }
00491
00492 if ( new_size == 0 )
00493 new_size = 1;
00494
00495
00496 fprintf( M->outfp, "\n range \t #vox \t %% \t cum %%\n");
00497 fprintf( M->outfp, "------------------- \t--------\t------\t-------\n");
00498
00499 cum = 0.0;
00500 for ( count = 0; count < M->num_bins; count++ )
00501 {
00502 cum += 100.0 * bins[ count ] / new_size;
00503
00504 fprintf( M->outfp, "[%8.*f,%8.*f) \t%8d\t%6.3f\t%7.3f\n",
00505 places, M->min + count * bin_size,
00506 places, M->min + (count+1) * bin_size,
00507 bins[ count ],
00508 100.0 * bins[ count ] / new_size,
00509 cum );
00510 }
00511 fputc( '\n', M->outfp );
00512
00513 return NULL;
00514 }
00515
00516
00517
00518
00519
00520
00521
00522
00523 static void
00524 assign_min_max(
00525 float * data,
00526 long size,
00527 float * min,
00528 float * max
00529 )
00530 {
00531 float * ptr = data;
00532 long count;
00533
00534
00535 *min = *data;
00536 *max = *data;
00537
00538 for ( count = 1; count < size; count++, ptr++ )
00539 {
00540 if ( *ptr < *min )
00541 *min = *ptr;
00542
00543 if ( *ptr > *max )
00544 *max = *ptr;
00545 }
00546 }
00547
00548
00549
00550
00551
00552
00553
00554
00555 static char *
00556 calc_stats( r_afni_s * A, mask_opt_s * M )
00557 {
00558 float * data;
00559 float min, max, savemin, savemax;
00560
00561 long size;
00562 int sub;
00563
00564
00565 if ( ( data = ( float * )malloc( A->nvox * sizeof(float) ) )
00566 == NULL )
00567 {
00568 sprintf( grMessage, "Error: 5130\n"
00569 "Failed to allocate memory for %d floats.\n",
00570 A->nvox );
00571 return grMessage;
00572 }
00573
00574 print_stats_header( M->outfp );
00575
00576 for ( sub = 0; sub < A->subs[1]; sub++ )
00577 {
00578 if ( ( size = mask_shorts_to_float( A, data, sub, 0, 1 ) ) == 0 )
00579 {
00580 sprintf( grMessage, "Error: 5140\n"
00581 "Masking shorts results in empty array.\n" );
00582 return grMessage;
00583 }
00584
00585 assign_min_max( data, size, &savemin, &savemax );
00586
00587 if ( ! M->use_min && ! M->use_max )
00588 {
00589 min = savemin;
00590 max = savemax;
00591
00592 do_stats( A, data, size, min, max, sub, M->outfp, NULL, NULL, NULL);
00593 }
00594 else if ( ! M->use_max )
00595 {
00596 min = M->min;
00597 max = savemax;
00598
00599 if ( min <= max )
00600 do_stats( A, data, size, min, max, sub, M->outfp,
00601 NULL, NULL, NULL);
00602 else
00603 print_empty_stats( M->outfp );
00604 }
00605 else
00606 {
00607
00608
00609 min = savemin;
00610 max = M->min;
00611
00612 if ( min <= max )
00613 do_stats( A, data, size, min, max, sub, M->outfp,
00614 NULL, NULL, NULL);
00615 else
00616 print_empty_stats( M->outfp );
00617
00618 min = M->max;
00619 max = savemax;
00620
00621 if ( min <= max )
00622 do_stats( A, data, size, min, max, sub, M->outfp,
00623 NULL, NULL, NULL);
00624 else
00625 print_empty_stats( M->outfp );
00626 }
00627 }
00628
00629 return NULL;
00630 }
00631
00632
00633
00634
00635
00636
00637
00638
00639 static void
00640 print_stats_header ( FILE * fp )
00641 {
00642 fprintf( fp, " Sub\t vol \t%% BRIK\t min \t max "
00643 "\t mean \t SEM \t STD \t 95%% "
00644 "\t thresh # \t thresh %%\n" );
00645 fprintf( fp, "-----\t-------\t------\t------\t------"
00646 "\t------\t------\t------\t-------------"
00647 "\t----------\t---------\n" );
00648 }
00649
00650
00651
00652
00653
00654
00655
00656
00657 static void
00658 print_empty_stats ( FILE * fp )
00659 {
00660 fprintf( fp, " 0 \t 0 \t 0 \t 0 \t 0 "
00661 "\t 0 \t 0 \t 0 \t ( 0, 0 ) "
00662 "\t 0 \t 0 \n" );
00663 }
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673 static void
00674 do_stats(
00675 r_afni_s * A,
00676 float * data,
00677 long size,
00678 float min,
00679 float max,
00680 int sub,
00681 FILE * fp,
00682 long * ret_size,
00683 float * average,
00684 float * ret_var
00685 )
00686 {
00687 double sum_diff2 = 0.0;
00688 double dtmp;
00689
00690 float mean, SEM, STD;
00691 float * ptr = data;
00692 float tmp;
00693 float local_min = max, local_max = min;
00694
00695 long count;
00696 long new_size;
00697
00698
00699
00700
00701 dtmp = 0.0;
00702 new_size = 0;
00703 for ( count = 0, ptr = data; count < size; count++, ptr++ )
00704 if ( ( *ptr >= min ) && ( *ptr <= max ) )
00705 {
00706 new_size++;
00707
00708 dtmp += *ptr;
00709
00710 if ( *ptr < local_min )
00711 local_min = *ptr;
00712
00713 if ( *ptr > local_max )
00714 local_max = *ptr;
00715 }
00716
00717 if ( new_size > 0 )
00718 mean = dtmp / new_size;
00719 else
00720 mean = 0;
00721
00722
00723 sum_diff2 = 0.0;
00724 for ( count = 0, ptr = data; count < size; count++, ptr++ )
00725 if ( ( *ptr >= min ) && ( *ptr <= max ) )
00726 {
00727 tmp = *ptr - mean;
00728 sum_diff2 += tmp * tmp;
00729 }
00730
00731 if ( new_size < 2 )
00732 {
00733 STD = 0;
00734 SEM = 0;
00735 }
00736 else
00737 {
00738 STD = sqrt( sum_diff2 / ( new_size - 1 ) );
00739 SEM = STD / sqrt( new_size );
00740 }
00741
00742 fprintf( fp,
00743 "%5d\t%7ld\t %5.*f\t%6.*f\t%6.*f\t%6.*f\t%6.*f\t%6.*f\t(%-5.*f, %5.*f)"
00744 "\t %8ld \t %6.*f\n",
00745 sub, size,
00746 num_places( 100.0*size/A->nvox, 5 ), 100.0*size/A->nvox,
00747 num_places( local_min, 6 ), local_min,
00748 num_places( local_max, 6 ), local_max,
00749 num_places( mean, 6 ), mean,
00750 num_places( SEM, 6 ), SEM,
00751 num_places( STD, 6 ), STD,
00752 num_places( mean-1.96*SEM, 5 ), mean-1.96*SEM,
00753 num_places( mean+1.96*SEM, 5 ), mean+1.96*SEM,
00754 new_size,
00755 num_places( 100.0*new_size/size, 6 ), 100.0*new_size/size );
00756
00757 if ( ret_size != NULL )
00758 *ret_size = new_size;
00759
00760 if ( average != NULL )
00761 *average = mean;
00762
00763 if ( ret_var != NULL )
00764 *ret_var = STD*STD;
00765 }
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775 static int
00776 num_places(
00777 float num,
00778 int size
00779 )
00780 {
00781 float junk;
00782 int places;
00783
00784 junk = fabsf( num );
00785
00786 junk = ( junk == 0 ) ? 1.0 : junk;
00787
00788
00789
00790
00791
00792
00793 places = size - 2 - ( int )floor( log10( junk ) );
00794
00795 if ( places < 0 )
00796 places = 0;
00797 else if ( places >= size )
00798 places = size - 1;
00799
00800 return places;
00801 }
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812 static long
00813 mask_shorts_to_float(
00814 r_afni_s * A,
00815 float * data,
00816 int sub,
00817 int mask_index,
00818 int data_index
00819 )
00820 {
00821 float * fptr;
00822 short * mptr;
00823 short * sptr;
00824
00825 float factor;
00826 long count;
00827
00828
00829 fptr = data;
00830
00831 if ( A->subs[ mask_index ] > 1 )
00832 mptr = A->simage[ mask_index ][ sub ];
00833 else
00834 mptr = A->simage[ mask_index ][ 0 ];
00835
00836 sptr = A->simage[ data_index ][ sub ];
00837
00838
00839
00840
00841
00842
00843 if ( ( factor = A->factor[ data_index ][ sub ] ) == 1 )
00844 {
00845 for( count = 0; count < A->nvox; count++, mptr++, sptr++ )
00846 if ( *mptr )
00847 *fptr++ = *sptr;
00848 }
00849 else
00850 {
00851 for( count = 0; count < A->nvox; count++, mptr++, sptr++ )
00852 if ( *mptr )
00853 *fptr++ = *sptr * factor;
00854 }
00855
00856
00857 return( ( long )( fptr - data ) );
00858 }
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869 static long
00870 mask_shorts_to_short(
00871 r_afni_s * A,
00872 short * data,
00873 int sub,
00874 int mask_index,
00875 int data_index
00876 )
00877 {
00878 short * dptr;
00879 short * mptr;
00880 short * sptr;
00881
00882 long count;
00883
00884
00885 dptr = data;
00886
00887 if ( A->subs[ mask_index ] > 1 )
00888 mptr = A->simage[ mask_index ][ sub ];
00889 else
00890 mptr = A->simage[ mask_index ][ 0 ];
00891
00892 sptr = A->simage[ data_index ][ sub ];
00893
00894
00895
00896
00897
00898
00899 for( count = 0; count < A->nvox; count++, mptr++, sptr++ )
00900 if ( *mptr )
00901 *dptr++ = *sptr;
00902
00903 return( ( long )( dptr - data ) );
00904 }
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915 static long
00916 mask_all_shorts_to_float(
00917 r_afni_s * A,
00918 int data_index,
00919 int mask_index,
00920 float * data
00921 )
00922 {
00923 float * fptr;
00924 short * mptr;
00925 short * sptr;
00926
00927 float factor;
00928 long count;
00929 int sub;
00930
00931
00932 fptr = data;
00933
00934 for ( sub = 0; sub < A->subs[data_index]; sub ++ )
00935 {
00936 if ( A->subs[mask_index] == A->subs[data_index] )
00937 mptr = A->simage[ mask_index ][ sub ];
00938 else
00939 mptr = A->simage[ mask_index ][ 0 ];
00940
00941 sptr = A->simage[ data_index ][ sub ];
00942
00943
00944
00945
00946
00947
00948 if ( ( factor = A->factor[ data_index ][ sub ] ) == 1 )
00949 {
00950 for( count = 0; count < A->nvox; count++, mptr++, sptr++ )
00951 if ( *mptr )
00952 *fptr++ = *sptr;
00953 }
00954 else
00955 {
00956 for( count = 0; count < A->nvox; count++, mptr++, sptr++ )
00957 if ( *mptr )
00958 *fptr++ = *sptr * factor;
00959 }
00960 }
00961
00962 return( ( long )( fptr - data ) );
00963 }
00964
00965
00966
00967
00968
00969
00970
00971
00972 static FILE *
00973 open_file(
00974 char * file,
00975 char * mode
00976 )
00977 {
00978 return fopen( file, mode );
00979 }
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996 static int
00997 file_exists(
00998 char * filename,
00999 char * suffix
01000 )
01001 {
01002 struct stat buf;
01003 char file[ R_FILE_L + 6 ] = "";
01004 char * filep = file;
01005
01006 if ( suffix == NULL )
01007 filep = filename;
01008 else if ( ! strcmp( suffix, filename+strlen(filename)-strlen(suffix) ) )
01009 strcpy( file, filename );
01010 else if ( filename[ strlen( filename ) - 1 ] == '.' )
01011 sprintf( file, "%s%s", filename, suffix );
01012 else
01013 sprintf( file, "%s.%s", filename, suffix );
01014
01015
01016 return ( stat( filep, &buf ) == 0 );
01017 }
01018
01019
01020
01021
01022
01023
01024
01025
01026 static char *
01027 fill_afni_struct( r_afni_s * A )
01028 {
01029 u_short mus;
01030 int sub, brick;
01031
01032 for ( brick = 0; brick < A->num_dsets; brick++ )
01033 {
01034 A->subs[ brick ] = DSET_NVALS( A->dset[ brick ] );
01035
01036 if ( A->max_subs && ( A->subs[brick] > A->max_subs ) )
01037 {
01038 sprintf( grMessage, "------------------------------------\n"
01039 "Error: maskcalc_fas_00\n"
01040 "Brick #%d contains %d sub-bricks.\n"
01041 "The limit is %d.\n"
01042 "------------------------------------",
01043 brick, A->subs[brick], A->max_subs );
01044 return grMessage;
01045 }
01046
01047 if ( A->subs_must_equal && ( A->subs[brick] != A->subs[0] ) )
01048 {
01049 sprintf( grMessage, "------------------------------------\n"
01050 "Error: maskcalc_fas_02\n"
01051 "Brick #%d contains %d sub-bricks.\n"
01052 "Brick #%d contains %d sub-bricks.\n"
01053 "We are requiring them to be equal.\n"
01054 "------------------------------------",
01055 0, A->subs[0],
01056 brick, A->subs[brick] );
01057 return grMessage;
01058 }
01059
01060 if ( ( A->simage[brick] =
01061 (short **)malloc( A->subs[brick]*sizeof(short *)) ) == NULL )
01062 {
01063 return "-------------------------\n"
01064 "Error: maskcalc_fas_05\n"
01065 "memory allocation failure\n"
01066 "-------------------------";
01067 }
01068 if ( ( A->factor[brick] =
01069 (float *)malloc( A->subs[brick]*sizeof(float)) ) == NULL)
01070 {
01071 return "-------------------------\n"
01072 "Error: maskcalc_fas_10\n"
01073 "memory allocation failure\n"
01074 "-------------------------";
01075 }
01076
01077 for ( sub = 0; sub < A->subs[brick]; sub++ )
01078 {
01079 A->simage[brick][sub] = (short *)DSET_ARRAY(A->dset[brick],sub);
01080 A->factor[brick][sub] = DSET_BRICK_FACTOR(A->dset[brick],sub);
01081 if ( A->factor[brick][sub] == 0.0 )
01082 A->factor[brick][sub] = 1.0;
01083 }
01084
01085 if ( brick == 0 )
01086 {
01087 A->nx = A->dset[brick]->daxes->nxx;
01088 A->ny = A->dset[brick]->daxes->nyy;
01089 A->nz = A->dset[brick]->daxes->nzz;
01090 A->nvox = A->nx * A->ny * A->nz;
01091 }
01092 else if ( ( A->nx != A->dset[brick]->daxes->nxx ) ||
01093 ( A->ny != A->dset[brick]->daxes->nyy ) ||
01094 ( A->nz != A->dset[brick]->daxes->nzz ) )
01095 {
01096 sprintf( grMessage,
01097 "--------------------------------\n"
01098 "Error : maskcalc_fas_20\n"
01099 "Unaligned dimensions.\n"
01100 "(%d,%d,%d) != (%d,%d,%d)\n"
01101 "--------------------------------",
01102 A->dset[brick]->daxes->nxx, A->dset[brick]->daxes->nyy,
01103 A->dset[brick]->daxes->nzz, A->nx, A->ny, A->nz );
01104 return grMessage;
01105 }
01106 }
01107
01108 if ( A->want_floats && ! assign_afni_floats( A ) )
01109 return "-----------------------------\n"
01110 "Error: maskcalc_fas_30\n"
01111 "Failed to create afni fimage.\n"
01112 "-----------------------------";
01113
01114 mus = 0;
01115 A->max_u_short = 0;
01116 for ( brick = 1; brick < A->num_dsets; brick++ )
01117 for ( sub = 0; sub < A->subs[brick]; sub++ )
01118 {
01119 mus = r_get_max_u_short( (u_short *)A->simage[brick][sub], A->nvox);
01120 if ( mus > A->max_u_short )
01121 A->max_u_short = mus;
01122 }
01123
01124 return NULL;
01125 }
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135 static int
01136 assign_afni_floats( r_afni_s * A )
01137 {
01138 short * sptr;
01139 float * fptr;
01140 float factor = A->factor[1][0];
01141 int count;
01142
01143
01144 if ( ( A->fimage[1] = (float *)malloc( A->nvox * sizeof(float))) == NULL )
01145 return 0;
01146
01147 for ( count = 0, fptr = A->fimage[1], sptr = A->simage[1][0];
01148 count < A->nvox;
01149 count++, fptr++, sptr++ )
01150 *fptr = factor * *sptr;
01151
01152 return 1;
01153 }
01154
01155
01156
01157
01158
01159
01160
01161
01162 static u_short
01163 r_get_max_u_short( u_short * S, int size )
01164 {
01165 u_short * usptr, max = *S;
01166 int c = 0;
01167
01168 for ( c = 0, usptr = S; c < size; c++, usptr++ )
01169 {
01170 if ( *usptr > max )
01171 max = *usptr;
01172 }
01173
01174 return max;
01175 }
01176
01177