Skip to content

AFNI/NIfTI Server

Sections
Personal tools
You are here: Home » AFNI » Documentation

Doxygen Source Code Documentation


Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals   Search  

plug_vol2surf.c

Go to the documentation of this file.
00001 /***********************************************************************
00002  * plug_vol2surf.c              - plugin interface to vol2surf computation
00003  *
00004  * Provide an interface to the global v2s_plugin_opts structure.
00005  *
00006  * - R. Reynolds
00007  ***********************************************************************
00008 */
00009 
00010 #include "afni.h"
00011 #include "vol2surf.h"
00012 
00013 #ifndef ALLOW_PLUGINS
00014 #  error "Plugins not properly set up -- see machdep.h"
00015 #endif
00016 
00017 static char * PV2S_main( PLUGIN_interface * );
00018 
00019 static char g_help[] = 
00020     " This plugin provides an interface to the vol2surf options used by afni\n"
00021     " for the display of the Overlay dataset values on the surfaces in suma.\n"
00022     " \n"
00023     " For each Local Domain Parent that afni has received from suma, vol2surf\n"
00024     " computes a node color overlay and sends it to suma.  This is computed\n"
00025     " by mapping afni's Overlay data across the 1 or 2 surfaces of each given\n"
00026     " LDP (Local Domain Parent).\n"
00027     " \n"
00028     " By default, each LDP gets a color list based on:\n"
00029     " \n"
00030     "   o  if only 1 surface for this LDP     : intersection of the surface\n"
00031     "      and afni's Overlay sub-brick, subject to afni's color bar and\n"
00032     "      thresholding (afni voxels that do not survive the threshold take\n"
00033     "      no part in the mapping)\n"
00034     " \n"
00035     "   o  if 2 or more surfaces for this LDP : intersection of the midpoint\n"
00036     "      of the first 2 surfaces received from suma (for this LDP) and the\n"
00037     "      Overlay sub-brick in afni, again subject to afni's color bar and\n"
00038     "      thresholding\n"
00039     " \n"
00040     " These defaults are for surfaces that have _not_ been chosen via the\n"
00041     " plugin interface.  Surfaces chosen via the plugin are, of course,\n"
00042     " mapped as the user specifies.  Note that to recreate the defaults, use\n"
00043     " the 'mask' function for 1 surface, and the midpoint function for more\n"
00044     " than 1.  The 'num steps' and 'seg index' will not be applicable.\n"
00045     " \n"
00046     " ---\n"
00047     " \n"
00048     " The minimum choices that must be made are on the 'function' line:\n"
00049     " 'use vol2surf?' (should be 'yes' :), and 'map func' (should be valid).\n"
00050     " \n"
00051     " ** Note that as a plugin, surfaces will be unknown at initialization\n"
00052     "    time.  Therefore the interface is via afni's surface index list.\n"
00053     "    To see the surface index list, set the debug level to 2, and then\n"
00054     "    press 'Set+Keep'.  Part of the text output to the _terminal window_\n"
00055     "    will be '+d valid surface indices and labels: ...'.\n"
00056     " \n"
00057     " ** For detailed infomation, please try the command: '3dVol2Surf -help'.\n"
00058     " \n"
00059     " ----------------------------- options --------------------------------\n"
00060     " function:\n"
00061     " \n"
00062     "   use vol2surf? : choose 'yes' to make the plugin options active\n"
00063     "   map func      : choose a function to apply to values along node pair\n"
00064     "                   segments, embedded in the AFNI volume\n"
00065     "   seg index     : apply all values along a each segment, or only those\n"
00066     "                   from unique voxels\n"
00067     "   num steps     : the number of evenly spaced points each segment will\n"
00068     "                   be divided into\n"
00069     " \n"
00070     " surf pair 0:\n"
00071     " \n"
00072     "   apply?        : if no, skip this surface (pair)\n"
00073     "   surf_A        : choose the afni surface index for surface A\n"
00074     "   use B?        : form segments by joining nodes from surface A with\n"
00075     "                   nodes on surface B (an alternate choice is to use\n"
00076     "                   only surface A, along with its normals)\n"
00077     "   surf_B        : choose the afni surface index for surface B\n"
00078     " \n"
00079     " surf pair 1:\n"
00080     " \n"
00081     "   apply?        : if no, skip this surface (pair)\n"
00082     "   surf_A        : choose the afni surface index for surface A\n"
00083     "   use B?        : form segments by joining nodes from surface A with\n"
00084     "                   nodes on surface B (an alternate choice is to use\n"
00085     "                   only surface A, along with its normals)\n"
00086     "   surf_B        : choose the afni surface index for surface B\n"
00087     " \n"
00088     " normals:\n"
00089     " \n"
00090     "   use normals?  : segments are formed from each node from surface A\n"
00091     "                   along its normal, and of length 'norm len'\n"
00092     "   norm len      : this will be the length of each segment\n"
00093     "   norm dir      : choose what to do with the normal directions:\n"
00094     "                     check   : let vol2surf try to decide\n"
00095     "                     keep    : keep the default directions\n"
00096     "                     reverse : reverse the default directions\n"
00097     " \n"
00098     " offsets:\n"
00099     " \n"
00100     "   NOTE - segments are considered directed from the node on surface A\n"
00101     "          in the direction of surface B (or the normal), so if f_p1 is\n"
00102     "          positive each segment gets shorter (going toward surface B),\n"
00103     "          but if f_pn is positive each segment gets longer (still moving\n"
00104     "          in the direction from surface A to surface B)\n"
00105     " \n"
00106     "   f_p1_mm       : move each segment starting point this number of\n"
00107     "                   millimeters toward surface B\n"
00108     "   f_pn_mm       : move each segment ending point this number of\n"
00109     "                   millimeters farther from surface A\n"
00110     "   f_p1_fr       : move each segment starting point this fraction of the\n"
00111     "                   distance toward surface B\n"
00112     "   f_pn_fr       : move each segment ending point this fraction of the\n"
00113     "                   distance farther from surface A\n"
00114     " \n"
00115     " out of range:\n"
00116     " \n"
00117     "   oob nodes?    : whether to still output results for those nodes which\n"
00118     "                   are out-of-bounds (i.e. outside the bounding box of\n"
00119     "                   the AFNI overlay dataset)\n"
00120     "   oob value     : if out-of-bounds nodes are output, this value will be\n"
00121     "                   given to them\n"
00122     "   oom nodes?    : whether to still output results for those nodes which\n"
00123     "                   are out-of-mask (i.e. masked by the threshold brick)\n"
00124     "   oob value     : if out-of-mask nodes are output, this value will be\n"
00125     "                   given to them\n"
00126     " output:\n"
00127     " \n"
00128     "   first node    : starting index for nodes to output\n"
00129     "   last node     : ending index for nodes to output (0 means 'nodes-1')\n"
00130     "                   (sorry, that means you cannot output from 0 to 0)\n"
00131     "   outfile.1D    : also send the results to this file (in 1D format)\n"
00132     "   outfile.niml  : also send the results to this file (in niml format)\n"
00133     " \n"
00134     " debug level:\n"
00135     " \n"
00136     "   level         : provide this level of debug output (0-5)\n"
00137     "   node          : provide additional debug output for this node\n"
00138     " \n"
00139     " \n"
00140     " Author: R Reynolds\n"
00141     " \n"
00142     " ----------------------------------------------------------------------\n"
00143     "   History:\n"
00144     " \n"
00145     "   1.0  9 September 2004 [rickr]\n"
00146     "     - initial version\n"
00147     " \n"
00148     "   1.1  16 September 2004 [rickr]\n"
00149     "     - init gp_index to -1 (set it in afni)\n"
00150     "     - allow the user to keep or reverse normal directions\n"
00151     " \n"
00152     "   1.2  29 September 2004 [rickr]\n"
00153     "     - now set global ready if all is well\n"
00154     "     - clear norms if not in use\n"
00155     "     - name all local functions PV2S_*\n"
00156     "     - if debug > 0, display chosen surfaces in terminal\n"
00157     "     - if debug > 1, display all possible surfaces in terminal\n"
00158     " \n"
00159     "   1.3  08 October 2004 [rickr]\n"
00160     "     - Global changes for new LDP processing:\n"
00161     "     - added second surface pair to GUI\n"
00162     "     - made small help and hint changes\n"
00163     "     - fixed receive order of fr and mm offsets (mm was fr)\n"
00164     "     - verify that surface pairs have matching LDPs\n"
00165     "     - added PV2S_disp_afni_surfaces() to list all surfaces w/indices\n"
00166     " \n"
00167     "   1.4  25 October 2004 [rickr]\n"
00168     "     - make sure the surface pairs are actually different\n"
00169     "     - make sure surfaces have the same number of nodes\n"
00170     "     - process all parameters, but only complain if 'ready'\n"
00171     "     - always pass along debug/dnode\n"
00172     " \n"
00173     "   1.5  11 December 2004 [rickr]\n"
00174     "     - describe the default vol2surf operation in this Help\n"
00175     " \n"
00176     "   1.5a 22 March 2005 [rickr]\n"
00177     "     - removed all tabs\n"
00178         ;
00179 
00180 #define P_MAP_NAMES_NVALS      12       /* should match enum for global maps */
00181 #define P_NY_NVALS              2
00182 #define P_KEEP_NVALS            3
00183 #define P_STEP_NVALS            2
00184 
00185 static char * gp_ny_list[]   = { "no", "yes" };
00186 static char * gp_keep_list[] = { "check", "keep", "reverse" };
00187 static char * gp_step_list[] = { "voxel", "node" };
00188 
00189 typedef struct
00190 {
00191     v2s_plugin_opts  * vpo;
00192     char             * hist;
00193     char            ** maps;
00194 } pv2s_globals;
00195 
00196 static pv2s_globals globs;      /* these are just pointers to afni globals */
00197 
00198 /* local functions */
00199 static int PV2S_check_surfaces(PLUGIN_interface * plint, int sa, int sb,
00200                                char *mesg, int debug);
00201 static int PV2S_disp_afni_surfaces(PLUGIN_interface * plint);
00202 static int PV2S_init_plugin_opts(pv2s_globals * g);
00203 static int PV2S_process_args(PLUGIN_interface * plint,pv2s_globals * g,
00204                              char *mesg);
00205 
00206 /* for ease of error reporting */
00207 #define PV2S_BAIL_VALUE(buf,str,val)                                   \
00208         do { sprintf((buf),  "-------------------------------------\n"  \
00209                              "%s\n"                                     \
00210                              "bad value = %d\n"                         \
00211                              "-------------------------------------",   \
00212                              (str), (val) ); } while (0)
00213 
00214 DEFINE_PLUGIN_PROTOTYPE                 /* for C++ compilation */
00215 
00216 PLUGIN_interface * PLUGIN_init( int ncall )
00217 {
00218     PLUGIN_interface * plint;
00219     void             * void_vpo;
00220 
00221 ENTRY("vol2surf: PLUGIN_init");
00222 
00223     if ( ncall > 0 ) RETURN(NULL);      /* only one interface */
00224 
00225     /* might be temporary */
00226     if ( PLUTO_set_v2s_addrs(&void_vpo, &globs.maps, &globs.hist) )
00227     {
00228         fprintf(stderr,"** plug_v2s: failed to init globals\n");
00229         RETURN(NULL);
00230     }
00231 
00232     /* using a void pointer so we don't have to put vol2surf.h in afni.h */
00233     globs.vpo = (v2s_plugin_opts *)void_vpo;
00234 
00235     PV2S_init_plugin_opts(&globs);
00236 
00237     plint = PLUTO_new_interface("Vol2Surf",
00238                 "configure afni's volume to surface options",
00239                 g_help, PLUGIN_CALL_VIA_MENU, PV2S_main);
00240 
00241     PLUTO_add_hint     (plint, "configure vol2surf options");
00242     PLUTO_set_sequence (plint, "A:afnicontrol:surf");
00243     PLUTO_set_runlabels(plint, "Set+Keep", "Set+Close");
00244 
00245     /* first input : do we use vol2surf? */
00246     PLUTO_add_option( plint, "function", "op_st", TRUE );
00247     PLUTO_add_hint  ( plint, "decide whether to use vol2surf" );
00248     PLUTO_add_string( plint, "use vol2surf? ", P_NY_NVALS, gp_ny_list, 0 );
00249     PLUTO_add_hint  ( plint, "use vol2surf (or basic intersection)" );
00250     PLUTO_add_string( plint, "map func",P_MAP_NAMES_NVALS,globs.maps,0);
00251     PLUTO_add_hint  ( plint, "choose a filter to apply to segment values" );
00252     PLUTO_add_string( plint, "seg index",P_STEP_NVALS,gp_step_list,0);
00253     PLUTO_add_hint  ( plint, "along segments, count only distinct voxels?");
00254     PLUTO_add_number( plint, "num steps", 0, 100, 0, 2, 1 );
00255     PLUTO_add_hint  ( plint, "number of steps to divide each segment into" );
00256 
00257     /* choose surface indices for surf pair 0                   */
00258     /*   - note that we do not yet have surfaces to choose from */
00259     PLUTO_add_option( plint, "surf pair 0", "surf pair 0", TRUE );
00260     PLUTO_add_hint  ( plint, "choose first surface index(es)" );
00261     PLUTO_add_string( plint, "apply? ", P_NY_NVALS, gp_ny_list, 1 );
00262     PLUTO_add_hint  ( plint, "decide whether to apply surface(s)" );
00263     PLUTO_add_number( plint, "surf_A", 0, 50, 0, 0, 1 );
00264     PLUTO_add_hint  ( plint, "choose surface A index" );
00265     PLUTO_add_string( plint, "use B? ", P_NY_NVALS, gp_ny_list, 0 );
00266     PLUTO_add_hint  ( plint, "decide whether to use surface B" );
00267     PLUTO_add_number( plint, "surf_B", 0, 50, 0, 1, 1 );
00268     PLUTO_add_hint  ( plint, "choose surface B index" );
00269 
00270     /* choose surface indices for surf pair 1                   */
00271     /*   - note that we do not yet have surfaces to choose from */
00272     PLUTO_add_option( plint, "surf pair 1", "surf pair 1", TRUE );
00273     PLUTO_add_hint  ( plint, "choose second surface index(es)" );
00274     PLUTO_add_string( plint, "apply? ", P_NY_NVALS, gp_ny_list, 0 );
00275     PLUTO_add_hint  ( plint, "decide whether to apply surface(s)" );
00276     PLUTO_add_number( plint, "surf_A", 0, 50, 0, 2, 1 );
00277     PLUTO_add_hint  ( plint, "choose surface A index" );
00278     PLUTO_add_string( plint, "use B? ", P_NY_NVALS, gp_ny_list, 0 );
00279     PLUTO_add_hint  ( plint, "decide whether to use surface B" );
00280     PLUTO_add_number( plint, "surf_B", 0, 50, 0, 3, 1 );
00281     PLUTO_add_hint  ( plint, "choose surface B index" );
00282 
00283     /* menu for using normals */
00284     PLUTO_add_option( plint, "normals", "normals", FALSE );
00285     PLUTO_add_hint  ( plint, "control use of normals (instead of surf_B)" );
00286     PLUTO_add_string( plint, "use normals? ", P_NY_NVALS, gp_ny_list, 0 );
00287     PLUTO_add_hint  ( plint, "should normals be used to simulate surf_B?" );
00288     PLUTO_add_number( plint, "norm len", -100, 100, 1, 10, 1 );
00289     PLUTO_add_hint  ( plint, "what (signed) length should the normals be?" );
00290     PLUTO_add_string( plint, "norm dir", P_KEEP_NVALS, gp_keep_list, 0 );
00291     PLUTO_add_hint  ( plint, "check normal direction, or keep or reverse it" );
00292 
00293     /* segment offsets */
00294     PLUTO_add_option( plint, "offsets", "offsets", FALSE );
00295     PLUTO_add_hint  ( plint,"offset segment endpoints, directed from p1 to pn");
00296     PLUTO_add_number( plint, "f_p1_mm", -100, 100, 1, 0, 1 );
00297     PLUTO_add_hint  ( plint, "move p1 towards pn, in millimeters" );
00298     PLUTO_add_number( plint, "f_pn_mm", -100, 100, 1, 0, 1 );
00299     PLUTO_add_hint  ( plint, "move pn farther from p1, in millimeters" );
00300     PLUTO_add_number( plint, "f_p1_fr", -100, 100, 1, 0, 1 );
00301     PLUTO_add_hint  ( plint, "move p1 towards pn, by this segment fraction" );
00302     PLUTO_add_number( plint, "f_pn_fr", -100, 100, 1, 0, 1 );
00303     PLUTO_add_hint  ( plint, "move pn farther from p1, by this fraction" );
00304 
00305     /* out of bounds or mask */
00306     PLUTO_add_option( plint, "out of range", "oor", FALSE );
00307     PLUTO_add_hint  ( plint, "what to do when out of bounds or mask" );
00308     PLUTO_add_string( plint, "oob nodes?", P_NY_NVALS, gp_ny_list, 0 );
00309     PLUTO_add_hint  ( plint, "keep out-of-bounds nodes? (outside the dataset)");
00310     PLUTO_add_number( plint, "oob value", 0, 0, 0, -2, 1 );
00311     PLUTO_add_hint  ( plint, "value to apply when out of dataset bounds" );
00312     PLUTO_add_string( plint, "oom nodes?", P_NY_NVALS, gp_ny_list, 0 );
00313     PLUTO_add_hint  ( plint, "keep out-of-mask nodes? (below threshold)");
00314     PLUTO_add_number( plint, "oom value", 0, 0, 0, -1, 1 );
00315     PLUTO_add_hint  ( plint, "value for masked out nodes" );
00316 
00317     /* choose node processing range */
00318     PLUTO_add_option( plint, "output", "output", FALSE );
00319     PLUTO_add_hint  ( plint, "select node range and output files" );
00320     PLUTO_add_number( plint, "first node", 0, 0, 0, 0, 1 );
00321     PLUTO_add_hint  ( plint, "starting node to process (zero based)" );
00322     PLUTO_add_number( plint, "last node", 0, 0, 0, 0, 1 );
00323     PLUTO_add_hint  ( plint, "end node to process (zero based)" );
00324     PLUTO_add_string( plint, "outfile.1D", 0, NULL, 14 );
00325     PLUTO_add_hint  ( plint, "name for 1D output file - will overwrite!" );
00326     PLUTO_add_string( plint, "outfile.niml", 0, NULL, 14 );
00327     PLUTO_add_hint  ( plint, "name for niml output file - will overwrite!" );
00328 
00329     /* debugging level */
00330     PLUTO_add_option( plint, "debug level", "debug level", FALSE );
00331     PLUTO_add_hint  ( plint, "choose debug level (and debug node)" );
00332     PLUTO_add_number( plint, "level", 0, 5, 0, 0, 1 );
00333     PLUTO_add_hint  ( plint, "debug level - how much to print to terminal" );
00334     PLUTO_add_number( plint, "node", 0, 0, 0, -1, 1 );
00335     PLUTO_add_hint  ( plint, "particular node to print debug infomation for" );
00336 
00337     RETURN(plint);
00338 }
00339 
00340 char * PV2S_main ( PLUGIN_interface * plint )
00341 {
00342     pv2s_globals * g;
00343     static char    message[2048];       /* use this to output failures */
00344 
00345 ENTRY("PV2S_main");
00346 
00347     g = &globs;                 /* to have only one global access */
00348     message[0] = '\0';          /* init to empty string */
00349 
00350     g->vpo->ready = 0;
00351 
00352     if ( (PV2S_process_args(plint, g, message) != 0) && message[0] )
00353         RETURN(message);
00354 
00355     RETURN(NULL);
00356 }
00357 
00358 /* base defaults to local and duplicate to global */
00359 static int PV2S_init_plugin_opts(pv2s_globals * g)
00360 {
00361 ENTRY("PV2S_init_plugin_opts");
00362     memset(g->vpo, 0, sizeof(*g->vpo));
00363 
00364     g->vpo->ready =  0;         /* flag as "not ready to go" */
00365     g->vpo->use0  =  0;
00366     g->vpo->use1  =  0;
00367     g->vpo->s0A   = -1;
00368     g->vpo->s0B   = -1;
00369     g->vpo->s1A   = -1;
00370     g->vpo->s1B   = -1;
00371 
00372     g->vpo->sopt.gp_index      = -1;
00373     g->vpo->sopt.dnode         = -1;
00374     g->vpo->sopt.outfile_1D    = NULL;
00375     g->vpo->sopt.outfile_niml  = NULL;
00376 
00377     RETURN(0);
00378 }
00379 
00380 
00381 
00382 static int PV2S_process_args(PLUGIN_interface * plint, pv2s_globals * g,
00383                              char * mesg)
00384 {
00385     THD_session     * ss;
00386     v2s_plugin_opts   lvpo;
00387     v2s_opts_t      * sopt;
00388     float             fval;
00389     char            * tag, * str;
00390     int               val, ready = 0;
00391 
00392 ENTRY("PV2S_process_args");
00393 
00394     /* do we have a valid 3D view and session? */
00395     if ( !IM3D_OPEN(plint->im3d) || !plint->im3d->ss_now )
00396     {
00397         sprintf(mesg, "----------------------------------------------\n"
00398                       "strange failure: invalid 3D view or session???\n"
00399                       "----------------------------------------------");
00400         RETURN(-1);
00401     }
00402 
00403     /* to a quick check to be sure we are talking with suma */
00404     ss = plint->im3d->ss_now;
00405     if (ss && ss->su_num < 1)
00406     {
00407         sprintf(mesg, "-----------------------------------------\n"
00408                       "no surfaces: is afni 'talking' with suma?\n"
00409                       "-----------------------------------------");
00410         RETURN(1);
00411     }
00412 
00413     /* copy current values, and make local changes while checking */
00414     lvpo = *g->vpo;
00415     sopt = &lvpo.sopt;          /* just for typing */
00416 
00417     while ( (tag = PLUTO_get_optiontag(plint)) != NULL )
00418     {
00419         if ( sopt->debug > 2 )
00420             fprintf(stderr,"+d received option tag: %s\n", tag);
00421 
00422         if ( ! strcmp(tag, "op_st") )
00423         {
00424             str = PLUTO_get_string(plint);
00425             val = PLUTO_string_index(str, P_NY_NVALS, gp_ny_list);
00426 
00427             if ( (val < 0) || (val >= P_NY_NVALS) )
00428             {
00429                 PV2S_BAIL_VALUE(mesg,"bad NY vals", val);
00430                 RETURN(1);
00431             }
00432             ready = val;                /* this is the interface to "ready" */
00433 
00434             /* now get map */
00435             str = PLUTO_get_string(plint);
00436             val = PLUTO_string_index(str, P_MAP_NAMES_NVALS, g->maps);
00437             if ( ready && val == E_SMAP_INVALID )
00438             {
00439                 sprintf( mesg,  "--------------------------------\n"
00440                                 "please choose a mapping function\n"
00441                                 "--------------------------------" );
00442                 RETURN(1);
00443             }
00444             else if (ready && ((val < E_SMAP_INVALID) || (val >= E_SMAP_FINAL)))
00445             {
00446                 PV2S_BAIL_VALUE(mesg, "illegal 'map func'", val);
00447                 RETURN(1);
00448             }
00449             sopt->map = val;
00450 
00451             /* now get step index */
00452             str = PLUTO_get_string(plint);
00453             val = PLUTO_string_index(str, P_STEP_NVALS, gp_step_list);
00454             sopt->f_index = val > 0 ? 1 : 0;    /* be sure */
00455 
00456             val = (int)PLUTO_get_number(plint); /* num steps */
00457             if (ready && ((val <= 0) || (val >= V2S_STEPS_TOOOOO_BIG)))
00458             {
00459                 PV2S_BAIL_VALUE(mesg, "steps too big", val);
00460                 RETURN(1);
00461             }
00462             sopt->f_steps = val;
00463         }
00464         else if ( ! strcmp(tag, "surf pair 0") )
00465         {
00466             lvpo.use0 = 0;
00467             str = PLUTO_get_string(plint);
00468             if ( PLUTO_string_index(str, P_NY_NVALS, gp_ny_list) != 0 )
00469             {
00470                 lvpo.use0 = 1;
00471                 lvpo.s0A = (int)PLUTO_get_number(plint);
00472                 lvpo.s0B = -1;  /* first assume to not use surf_B */
00473                 str = PLUTO_get_string(plint);
00474                 if ( PLUTO_string_index(str, P_NY_NVALS, gp_ny_list) != 0 )
00475                     lvpo.s0B = (int)PLUTO_get_number(plint);
00476             }
00477         }
00478         else if ( ! strcmp(tag, "surf pair 1") )
00479         {
00480             lvpo.use1 = 0;
00481             str = PLUTO_get_string(plint);
00482             if ( PLUTO_string_index(str, P_NY_NVALS, gp_ny_list) != 0 )
00483             {
00484                 lvpo.use1 = 1;
00485                 lvpo.s1A = (int)PLUTO_get_number(plint);
00486                 lvpo.s1B = -1;  /* first assume to not use surf_B */
00487                 str = PLUTO_get_string(plint);
00488                 if ( PLUTO_string_index(str, P_NY_NVALS, gp_ny_list) != 0 )
00489                     lvpo.s1B = (int)PLUTO_get_number(plint);
00490             }
00491         }
00492         else if ( ! strcmp(tag, "normals") )
00493         {
00494             str = PLUTO_get_string(plint);
00495             if ( PLUTO_string_index(str, P_NY_NVALS, gp_ny_list) != 0 )
00496             {
00497                 sopt->use_norms = 1;
00498                 sopt->norm_len = PLUTO_get_number(plint);
00499 
00500                 str = PLUTO_get_string(plint);
00501                 val = PLUTO_string_index(str, P_KEEP_NVALS, gp_keep_list);
00502                 if      ( val == 1 ) sopt->norm_dir = V2S_NORM_KEEP;
00503                 else if ( val == 2 ) sopt->norm_dir = V2S_NORM_REVERSE;
00504                 else                 sopt->norm_dir = V2S_NORM_DEFAULT;
00505             }
00506             else
00507                 sopt->use_norms = 0;
00508         }
00509         else if ( ! strcmp(tag, "offsets") )
00510         {
00511             int test = 0;
00512 
00513             sopt->f_p1_mm = PLUTO_get_number(plint);
00514             sopt->f_pn_mm = PLUTO_get_number(plint);
00515             sopt->f_p1_fr = PLUTO_get_number(plint);
00516             sopt->f_pn_fr = PLUTO_get_number(plint);
00517 
00518             /* check for consistency */
00519             if ( sopt->f_p1_fr != 0 || sopt->f_pn_fr != 0 ) test |= 1;
00520             if ( sopt->f_p1_mm != 0 || sopt->f_pn_mm != 0 ) test |= 2;
00521             if ( ready && test > 2 )  /* i.e. == 3 */
00522             {
00523                 sprintf( mesg,  "---------------------------------\n"
00524                                 "use only one pair of f*_mm, f*_fr\n"
00525                                 "to change normal lengths     \n"
00526                                 "---------------------------------" );
00527                 RETURN(1);
00528             }
00529         }
00530         else if ( ! strcmp(tag, "oor") )
00531         {
00532             /* out of bounds ... */
00533             str  = PLUTO_get_string(plint);
00534             val  = PLUTO_string_index(str, P_NY_NVALS, gp_ny_list);
00535             fval = PLUTO_get_number(plint);
00536             if ( val != 0 )
00537             {
00538                 sopt->oob.show  = 1;
00539                 sopt->oob.value = fval;
00540             }
00541             else
00542                 sopt->oob.show  = 0;
00543 
00544             /* out of mask ... */
00545             str  = PLUTO_get_string(plint);
00546             val  = PLUTO_string_index(str, P_NY_NVALS, gp_ny_list);
00547             fval = PLUTO_get_number(plint);
00548             if ( val != 0 )
00549             {
00550                 sopt->oom.show  = 1;
00551                 sopt->oom.value = fval;
00552             }
00553             else
00554                 sopt->oom.show  = 0;
00555         }
00556         else if ( ! strcmp(tag, "output") )
00557         {
00558             sopt->first_node = (int)PLUTO_get_number(plint);
00559             sopt->last_node  = (int)PLUTO_get_number(plint);
00560             if ( ready &&  sopt->first_node > sopt->last_node )
00561             {
00562                 sprintf( mesg,  "-----------------------------\n"
00563                                 "illegal node range values:   \n"
00564                                 "first (%d) > last (%d)       \n"
00565                                 "-----------------------------",
00566                                 sopt->first_node, sopt->last_node );
00567                 RETURN(1);
00568             }
00569 
00570             /* get output filenames */
00571             if ( sopt->outfile_1D )   free(sopt->outfile_1D);
00572             if ( sopt->outfile_niml ) free(sopt->outfile_niml);
00573             sopt->outfile_1D = sopt->outfile_niml = NULL;
00574 
00575             str = PLUTO_get_string(plint);
00576             if ( strlen(str) > 0 )
00577             {
00578                 sopt->outfile_1D = (char *)calloc(strlen(str)+1,sizeof(char));
00579                 strcpy(sopt->outfile_1D, str);
00580             }
00581 
00582             str = PLUTO_get_string(plint);
00583             if ( strlen(str) > 0 )
00584             {
00585                 sopt->outfile_niml = (char *)calloc(strlen(str)+1,sizeof(char));
00586                 strcpy(sopt->outfile_niml, str);
00587             }
00588         }
00589         else if ( ! strcmp(tag, "debug level") )
00590         {
00591             sopt->debug = (int)PLUTO_get_number(plint);
00592             sopt->dnode = (int)PLUTO_get_number(plint);
00593         }
00594         else
00595         {
00596             sprintf( mesg,  "---------------------------\n"
00597                             "Unknown option tag : %s\n"
00598                             "---------------------------", tag );
00599             RETURN(1);
00600         }
00601     }
00602 
00603     if ( sopt->debug > 1 )
00604     {
00605         disp_v2s_plugin_opts( "plug_vol2surf options done : ", &lvpo );
00606         disp_v2s_opts_t( "  surface options : ", sopt );
00607     }
00608 
00609     /* should we just run away?  always adjust debugging first... */
00610     g->vpo->sopt.debug = lvpo.sopt.debug;
00611     g->vpo->sopt.dnode = lvpo.sopt.dnode;
00612 
00613     if ( lvpo.use0 == 0 && lvpo.use1 == 0 ) ready = 0;
00614 
00615     if ( ! ready )
00616     {
00617         if ( sopt->debug > 0 )
00618             PV2S_disp_afni_surfaces(plint);
00619         RETURN(1);
00620     }
00621 
00622     if ( ! v2s_is_good_map(sopt->map, 1) )
00623     {
00624         sprintf( mesg,  "-------------------------------------------\n"
00625                         "mapping function is invalid in this context\n"
00626                         "index %d, name '%s'\n"
00627                         "-------------------------------------------",
00628                 sopt->map,
00629                 (sopt->map < E_SMAP_INVALID || sopt->map >= E_SMAP_FINAL) ?
00630                 "out-of-range" : g->maps[sopt->map] );
00631         RETURN(1);
00632     }
00633 
00634     /* verify surface consistency */
00635     if ( lvpo.use0 )
00636     {
00637         if ( PV2S_check_surfaces(plint, lvpo.s0A, lvpo.s0B, mesg, sopt->debug) )
00638             RETURN(1);
00639         if ( lvpo.s0A == lvpo.s0B ) 
00640         {
00641             sprintf( mesg,  "--------------------------------\n"
00642                             "error: for pair 0, surfA = surfB\n"
00643                             "--------------------------------" );
00644             RETURN(1);
00645         }
00646     }
00647     if ( lvpo.use1 )
00648     {
00649         if ( PV2S_check_surfaces(plint, lvpo.s1A, lvpo.s1B, mesg, sopt->debug) )
00650             RETURN(1);
00651         if ( lvpo.s1A == lvpo.s1B ) 
00652         {
00653             sprintf( mesg,  "--------------------------------\n"
00654                             "error: for pair 1, surfA = surfB\n"
00655                             "--------------------------------" );
00656             RETURN(1);
00657         }
00658     }
00659 
00660     /* if the user wan't normals, they can only supply one surface per pair */
00661     if ( sopt->use_norms && ((lvpo.use0 && lvpo.s0B >= 0) ||
00662                              (lvpo.use1 && lvpo.s1B >= 0)) )
00663     {
00664         sprintf( mesg,  "----------------------------------------\n"
00665                         "cannot use normals while using surface B\n"
00666                         "----------------------------------------" );
00667         RETURN(1);
00668     }
00669 
00670     if ( sopt->debug > 0 )
00671         PV2S_disp_afni_surfaces(plint);
00672 
00673     /* for now, only output nodes and a single data column */
00674     sopt->skip_cols = V2S_SKIP_ALL ^ V2S_SKIP_NODES;
00675 
00676     if ( ready )                /* then copy changes over old values */
00677     {
00678         *g->vpo = lvpo;
00679         g->vpo->ready = 1;
00680     }
00681 
00682     RETURN(0);
00683 }
00684 
00685 static int PV2S_check_surfaces(PLUGIN_interface * plint, int sa, int sb,
00686                                char * mesg, int debug)
00687 {
00688     THD_session * ss;
00689 
00690 ENTRY("PV2S_check_surfaces");
00691 
00692     ss = plint->im3d->ss_now;
00693 
00694     if ( ss->su_num < 1 )
00695     {
00696         PV2S_BAIL_VALUE(mesg, "Not enough surfaces in session.\n", ss->su_num);
00697         RETURN(1);
00698     }
00699 
00700     /* verify that the surface indices are valid */
00701     if ( sa < 0 )
00702     {
00703         PV2S_BAIL_VALUE(mesg, "surf_A has invalid index", sa);
00704         RETURN(1);
00705     }
00706 
00707     if ( sa >= ss->su_num )
00708     {
00709         PV2S_BAIL_VALUE(mesg, "surf_A beyond valid index", ss->su_num - 1);
00710         RETURN(1);
00711     }
00712 
00713     if ( sb >= ss->su_num )
00714     {
00715         PV2S_BAIL_VALUE(mesg, "surf_B beyond valid index", ss->su_num - 1);
00716         RETURN(1);
00717     }
00718 
00719     if ( sb >= 0 )
00720     {
00721         /* then check that surf_A and surf_B share LDP */
00722         if (strncmp(ss->su_surf[sa]->idcode_ldp,ss->su_surf[sb]->idcode_ldp,32))
00723         {
00724             char * la = ss->su_surf[sa]->label_ldp;
00725             char * lb = ss->su_surf[sb]->label_ldp;
00726             if ( ! *la ) la = "undefined";
00727             if ( ! *lb ) lb = "undefined";
00728             sprintf(mesg, "---------------------------------------\n"
00729                           "Error: Surf_A and Surf_B have different\n"
00730                           "       local domain parents\n"
00731                           "LDP #%d = '%s', LDP #%d = '%s'\n"
00732                           "---------------------------------------",
00733                           sa, la, sb, lb);
00734             RETURN(1);
00735         }
00736 
00737         /* and that they have the same number of nodes */
00738         if ( ss->su_surf[sa]->num_ixyz != ss->su_surf[sb]->num_ixyz )
00739         {
00740             sprintf(mesg, "------------------------------------------------\n"
00741                           "Big problem: Surf_A and Surf_B have different\n"
00742                           "    numbers of nodes!  They cannot share an LDP.\n"
00743                           "    SurfA: '%s', %d nodes\n"
00744                           "    SurfB: '%s', %d nodes\n"
00745                           "------------------------------------------------",
00746                           ss->su_surf[sa]->label, ss->su_surf[sa]->num_ixyz,
00747                           ss->su_surf[sb]->label, ss->su_surf[sb]->num_ixyz);
00748             RETURN(1);
00749         }
00750     }
00751 
00752     if ( debug > 0 && ss->su_surf )
00753     {
00754         if ( ss->su_surf[sa] )      /* we have checked sa >= 0, above */
00755             fprintf(stderr,"+d surf_A label: '%s'\n",
00756                 *ss->su_surf[sa]->label ? ss->su_surf[sa]->label : "not set");
00757         else
00758             fprintf(stderr,"** surf_A (#%d) pointer not set??\n", sa);
00759 
00760         if ( sb < 0 )
00761             fprintf(stderr,"-d surf_B not in use\n");
00762         else if ( ss->su_surf[sb] )
00763             fprintf(stderr,"+d surf_B label: '%s'\n",
00764                 *ss->su_surf[sb]->label ? ss->su_surf[sb]->label : "not set");
00765         else
00766             fprintf(stderr,"** surf_B (#%d) pointer not set??\n", sb);
00767     }
00768 
00769     RETURN(0);
00770 }
00771 
00772 static int PV2S_disp_afni_surfaces(PLUGIN_interface * plint)
00773 {
00774     THD_session * ss;
00775     char        * ldp, * label;
00776     int           c;
00777 
00778 ENTRY("disp_afni_surfaces");
00779 
00780     ss = plint->im3d->ss_now;
00781 
00782     if ( ss->su_surf <= 0 )
00783         RETURN(0);
00784 
00785     fprintf(stderr,"-d --------------------------------------\n");
00786     fprintf(stderr,"   afni surface indices, labels and LDPs:\n");
00787     for ( c = 0; c < ss->su_num; c++ )
00788     {
00789         label = ss->su_surf[c]->label;
00790         ldp   = ss->su_surf[c]->label_ldp;
00791         if ( ! *label ) label = "undefined";
00792         if ( ! *ldp   ) ldp   = "undefined";
00793 
00794         fprintf(stderr,"   index %2d, label '%s', LDP '%s'\n",
00795                     c, label, ldp );
00796     }
00797 
00798     RETURN(0);
00799 }
 

Powered by Plone

This site conforms to the following standards: