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_nth_dataset.c

Go to the documentation of this file.
00001 #include "afni.h"
00002 
00003 #ifndef ALLOW_PLUGINS
00004 #  error "Plugins not properly set up -- see machdep.h"
00005 #endif
00006 
00007 #define DSETN_VERSION   "Version 1.1 <October, 2002>"
00008 
00009 /***********************************************************************
00010   Plugin to provide extra datasets' timeseries in place of first
00011 ************************************************************************/
00012 /*----------------------------------------------------------------------
00013  * history:
00014  *
00015  * 1.1  October 28, 2002 - rickr
00016  *   - register for RECEIVE_DSETCHANGE messages
00017  *   - update global dset list from g_id list (upon message reception)
00018  *----------------------------------------------------------------------
00019 */
00020 
00021 char * DSETN_main     ( PLUGIN_interface *) ;
00022 void   DSETN_func     ( MRI_IMAGE * ) ;
00023 void   DSETN_dset_recv( int why, int np, int * ijk, void * aux ) ;
00024 
00025 static int  set_global_dsets_from_ids( void );
00026 
00027 #undef USE_WHERE
00028 
00029 static char helpstring[] =
00030    " Purpose: Control the 'Dataset#N' 1D timeseries function\n"
00031    "\n"
00032    " Dataset = a 3D+time dataset from which to extract data\n"
00033    " Color   = color to overlay in AFNI graph window\n"
00034    "\n"
00035    " Usage:\n"
00036    " 1) Choose in this plugin the 3D+time datasets you want to graph,\n"
00037    "     and their overlay colors.  Then press 'Set+Keep'.\n"
00038    " 2) In an AFNI graph window, choose 'Tran 1D' to be 'Dataset#N'.\n"
00039    "     This will cause the time series chosen here to replace the\n"
00040    "     time series of the dataset being graphed.\n"
00041    " 3) Optionally, you can set 'Double Plot' to 'Overlay' in the\n"
00042    "     AFNI graph window - this will then also show the time series\n"
00043    "     from the current AFNI graph window.\n"
00044    "\n"
00045    " Note that changes in this plugin interface are not communicated\n"
00046    " to AFNI itself until you press one of the 'Set' buttons.\n"
00047 #ifdef USE_WHERE
00048    "\n"
00049    " Justify = Left  means to put timeseries data at start of output array\n"
00050    "           Right means to put timeseries data at end of output array\n"
00051    "\n"
00052    " Fill    = Extend means to copy the last value\n"
00053    "           Zero   means to fill with zeros\n"
00054    "\n"
00055    " Justify and Fill are only used when the number of points in the input\n"
00056    " dataset doesn't match the number of points in the timeseries being replaced.\n"
00057    " Let M = length of dataset, N = length of timeseries,\n"
00058    " ts[] = timeseries array, ds[] = dataset array.\n"
00059    "\n"
00060    " Case: M < N (too little data to fill timeseries)\n"
00061    "    Left: ts[i] = ds[i]    i=0..M-1                        Data goes to left\n"
00062    "                = ds[M-1]  i=M..N-1 if Extend              edge of timeseries\n"
00063    "                = 0.0      i=M..N-1 if Zero\n"
00064    "   Right: ts[i] = ds[0]    i=0..J-1 if Extend (with J=N-M) Data goes to right\n"
00065    "                = 0.0      i=0..J-1 if Zero                edge of timeseries\n"
00066    "                = ds[i-J]  i=J..N-1\n"
00067    " Case: M > N (too much data for timeseries)\n"
00068    "    Left: ts[i] = ds[i]    i=0..N-1                        Left data to ts[]\n"
00069    "   Right: ts[i] = ds[i+J]  i=0..N-1 (with J=M-N)           Right data to ts[]\n"
00070 #endif
00071    "\n"
00072    " -- RWCox - 29 Mar 2002\n"
00073 ;
00074 
00075 #define NMAX 9  /* max number of time series */
00076 
00077 static THD_3dim_dataset *dset[NMAX] ;
00078 static MCW_idcode        g_id[NMAX] ;   /* for re-establishing dset values */
00079 static int               ovc [NMAX] ;
00080 static int               g_dset_recv = -1 ;         /* for AFNI messaging  */
00081 static int               g_valid_data = 0 ;         /* is the data usable  */
00082 
00083 #ifdef USE_WHERE
00084 static int justify = 0 ;
00085 static int fill    = 0 ;
00086 #endif
00087 
00088 /***********************************************************************
00089    Set up the interface to the user
00090 ************************************************************************/
00091 
00092 static char *lr[2] = { "Left" , "Right" } ;
00093 static char *ez[2] = { "Extend" , "Zero" } ;
00094 
00095 static PLUGIN_interface *plint=NULL ;
00096 
00097 static void DSETN_func_init(void)   /* 21 Jul 2003 */
00098 {
00099    PLUG_startup_plugin_CB( NULL , (XtPointer)plint , NULL ) ;
00100 }
00101 
00102 
00103 DEFINE_PLUGIN_PROTOTYPE
00104 
00105 PLUGIN_interface * PLUGIN_init( int ncall )
00106 {
00107    int id ;
00108 
00109 ENTRY("PLUGIN_init - Dataset#N") ;
00110 
00111    if( ncall > 0 ) RETURN( NULL );  /* only one interface */
00112 
00113    AFNI_register_nD_function ( 1 , "Dataset#N" , (generic_func *)DSETN_func ,
00114                                NEEDS_DSET_INDEX|PROCESS_MRI_IMAGE ) ;
00115    AFNI_register_nD_func_init( 1 , (generic_func *) DSETN_func_init ) ;  /* 21 Jul 2003 */
00116 
00117    plint = PLUTO_new_interface( "Dataset#N", "Controls 1D function Dataset#N",
00118                                  helpstring, PLUGIN_CALL_VIA_MENU, DSETN_main  ) ;
00119 
00120    PLUTO_add_hint( plint , "Controls 1D function Dataset#N" ) ;
00121 
00122    PLUTO_set_sequence( plint , "A:funcs:dataset#N" ) ;
00123 
00124    PLUTO_set_runlabels( plint , "Set+Keep" , "Set+Close" ) ;  /* 04 Nov 2003 */
00125 
00126    for( id=0 ; id < NMAX ; id++ ){
00127      PLUTO_add_option( plint , "Input" , "Input" , FALSE ) ;
00128      PLUTO_add_dataset(plint , "Dataset" ,
00129                                       ANAT_ALL_MASK , FUNC_ALL_MASK ,
00130                                       DIMEN_4D_MASK | BRICK_ALLREAL_MASK ) ;
00131      PLUTO_add_overlaycolor( plint , "Color" ) ;
00132    }
00133 
00134 #ifdef USE_WHERE
00135    PLUTO_add_option( plint , "Where" , "Where" , FALSE ) ;
00136    PLUTO_add_string( plint, "Justify", 2, lr, justify ) ;
00137 
00138    PLUTO_add_option( plint , "How" , "How" , FALSE ) ;
00139    PLUTO_add_string( plint, "Fill", 2, ez, fill ) ;
00140 #endif
00141 
00142    /* init the global lists */
00143    for ( id=0 ; id < NMAX ; id++ ){
00144         dset[id] = NULL;
00145         ZERO_IDCODE(g_id[id]);
00146    }
00147 
00148    RETURN( plint ) ;
00149 }
00150 
00151 /***************************************************************************
00152   Main routine for this plugin (will be called from AFNI).
00153 ****************************************************************************/
00154 
00155 char * DSETN_main( PLUGIN_interface * plint )
00156 {
00157    MCW_idcode *idc ;
00158    char *str , *tag ;
00159    int id=0 ;
00160 
00161 ENTRY( "DSETN_main" ) ;
00162 
00163    if( plint == NULL )
00164       RETURN("***********************\n"
00165              "DSETN_main:  NULL input\n"
00166              "***********************") ;
00167 
00168    for( id=0 ; id < NMAX ; id++ ){   /* 18 Mar 2004: renullification */
00169      dset[id] = NULL ;
00170      ZERO_IDCODE(g_id[id]);
00171    }
00172 
00173    id = 0 ;
00174 
00175    while( (tag=PLUTO_get_optiontag(plint)) != NULL ){
00176 
00177       /* Input */
00178 
00179       if( strcmp(tag,"Input") == 0 ){
00180         idc      = PLUTO_get_idcode(plint) ;
00181         dset[id] = PLUTO_find_dset(idc) ;
00182 
00183         if ( ! ISVALID_DSET( dset[id] ) )
00184             RETURN("******************************\n"
00185                    "DSETN_main:  bad input dataset\n"
00186                    "******************************") ;
00187 
00188         g_id[id] = *idc ;
00189         ovc [id] = PLUTO_get_overlaycolor(plint) ;
00190         id++ ; continue ;
00191       }
00192 
00193 #ifdef USE_WHERE
00194       /* Where */
00195 
00196       if( strcmp(tag,"Where") == 0 ){
00197         str = PLUTO_get_string(plint) ;
00198         justify = (strcmp(str,lr[0]) != 0) ;
00199         continue ;
00200       }
00201 
00202       /* How */
00203 
00204       if( strcmp(tag,"How") == 0 ){
00205         str = PLUTO_get_string(plint) ;
00206         fill = (strcmp(str,ez[0]) != 0) ;
00207         continue ;
00208       }
00209 #endif
00210 
00211    }
00212 
00213    if ( id <= 0 )                       /* no data - nothing to do */
00214        RETURN( NULL ) ;
00215 
00216    g_valid_data = 1 ;                   /* valid data, woohooo!    */
00217 
00218    if ( g_dset_recv < 0 )
00219        g_dset_recv = AFNI_receive_init( plint->im3d, RECEIVE_DSETCHANGE_MASK,
00220                                         DSETN_dset_recv, plint ,
00221                                        "DSETN_dset_recv" ) ;
00222    if ( g_dset_recv < 0 )
00223      RETURN("*************************************\n"
00224             "DSETN_main:  failed AFNI_receive_init\n"
00225             "*************************************") ;
00226 
00227    PLUTO_force_redisplay() ;
00228    RETURN( NULL );
00229 }
00230 
00231 /*----------------------------------------------------------------------------*/
00232 
00233 void DSETN_dset_recv( int why, int np, int * ijk, void * aux )
00234 {
00235     PLUGIN_interface * plint = (PLUGIN_interface *)aux;
00236 
00237 ENTRY( "DSETN_dset_recv" );
00238 
00239     switch ( why )
00240     {
00241         default:
00242         {
00243             fprintf( stderr, "warning: DSETN_dset_recv() called with invalid "
00244                              "why code, %d\n", why );
00245             EXRETURN;
00246         }
00247 
00248         case RECEIVE_ALTERATION:   /* may take effect before DSETCHANGE */
00249         case RECEIVE_DSETCHANGE:
00250         {
00251             /* start by noting the number of valid data sets */
00252             int num_valid = set_global_dsets_from_ids( );
00253 
00254             if ( g_valid_data != 1 || num_valid <= 0 )
00255             {
00256                 /* shut the plugin down - "he's only _mostly_ dead" */
00257 
00258                 g_valid_data = 0;
00259 
00260                 AFNI_receive_control( plint->im3d, g_dset_recv,
00261                                       EVERYTHING_SHUTDOWN, NULL );
00262                 g_dset_recv = -1;
00263                 PLUTO_popup_worker( plint,
00264                                         "Warning: plugin 'Dataset#N'\n"
00265                                         "has lost its dataset links.\n"
00266                                         "To plot 1-D overlays, please\n"
00267                                         "re-run the plugin.",
00268                                     MCW_USER_KILL | MCW_TIMER_KILL ) ;
00269             }
00270         }
00271     }
00272 
00273     EXRETURN;
00274 }
00275 
00276 /*----------------------------------------------------------------------------*/
00277 
00278 void DSETN_func( MRI_IMAGE *qim )
00279 {
00280    int id , ny , nxtop=0 , ijk , ii ;
00281    MRI_IMARR *tar ;
00282    MRI_IMAGE *tsim , *zim ;
00283    float *tsar , *dar ;
00284    int ovi[NMAX] ;
00285    char str[16+4*NMAX] ;
00286 
00287 ENTRY( "DSETN_func" );
00288 
00289    if ( g_valid_data != 1 )
00290        EXRETURN ;                                 /* nothing to do */
00291 
00292    INIT_IMARR(tar) ;
00293    ijk = AFNI_needs_dset_ijk() ;          /* voxel index from AFNI */
00294 
00295    for( id=0 ; id < NMAX ; id++ ){
00296      if( ISVALID_DSET(dset[id]) ){
00297        tsim = THD_extract_series( ijk,dset[id], 0 ) ;  /* get data */
00298        if( tsim == NULL ) continue ;
00299        ovi[IMARR_COUNT(tar)] = ovc[id] ;
00300        ADDTO_IMARR(tar,tsim) ;
00301        nxtop = MAX(nxtop,tsim->nx) ;
00302      }
00303    }
00304 
00305    ny = IMARR_COUNT(tar) ;
00306 
00307    if( ny == 0 || nxtop < 2 ){ DESTROY_IMARR(tar); EXRETURN; } /* no data */
00308 
00309    if( ny == 1 ){                                  /* one dataset */
00310      tsim = IMARR_SUBIM(tar,0); FREE_IMARR(tar);
00311      mri_move_guts(qim,tsim);
00312      sprintf(str,"color: %d",ovi[0]) ; mri_add_name(str,qim) ;
00313      EXRETURN;
00314    }
00315                                              /* multiple datasets */
00316 
00317    tsim = mri_new( nxtop , ny , MRI_float ) ;
00318    tsar = MRI_FLOAT_PTR(tsim) ;
00319    strcpy(str,"color:") ;
00320    for( id=0 ; id < ny ; id++ ){
00321       zim = IMARR_SUBIM(tar,id) ;
00322       dar = MRI_FLOAT_PTR(zim) ;
00323       memcpy( tsar , dar , sizeof(float)*zim->nx) ;
00324       if( zim->nx < nxtop ){   /* 18 Mar 2004: fill with infinity */
00325         for( ii=zim->nx ; ii < nxtop ; ii++ ) tsar[ii] = WAY_BIG ;
00326       }
00327       tsar += nxtop ;
00328       sprintf(str+strlen(str)," %d",ovi[id]) ;
00329    }
00330 
00331    DESTROY_IMARR(tar) ;
00332    mri_move_guts(qim,tsim) ; mri_add_name(str,qim) ;
00333    EXRETURN;
00334 }
00335 
00336 static int set_global_dsets_from_ids( void )
00337 {
00338     THD_3dim_dataset * dptr;
00339     int idcount, num_valid = 0;
00340 
00341 ENTRY( "set_global_dsets_from_ids" );
00342 
00343     for ( idcount = 0; idcount < NMAX; idcount++ )
00344     {
00345         if ( ! ISZERO_IDCODE( g_id[idcount] ) )
00346         {
00347             dptr = PLUTO_find_dset( &g_id[idcount] );
00348             if ( ! ISVALID_DSET( dptr ) )
00349             {
00350                 dptr = NULL;
00351                 ZERO_IDCODE( g_id[idcount] );   /* lost dataset    */
00352             }
00353             else                                /* a good one      */
00354                 num_valid++;
00355         }
00356         else                                    /* just being safe */
00357             dptr = NULL;
00358 
00359         dset[idcount] = dptr;
00360     }
00361 
00362     RETURN( num_valid );
00363 }
 

Powered by Plone

This site conforms to the following standards: