1 /*****************************************************************************
2    Major portions of this software are copyrighted by the Medical College
3    of Wisconsin, 1994-2001, and are released under the Gnu General Public
4    License, Version 2.  See the file README.Copyright for details.
5 ******************************************************************************/
6 
7 /*
8   This file contains header information for NLfit_model.c.
9   This file was adapted from afni_plugin.h.
10 
11   File:     NLfit_model.h
12   Author:   B. Douglas Ward
13   Date:     6 June 1997
14 
15   Mod:      Increased maximum number of model parameters, and maximum number
16             of models.
17   Date:     08 August 2001
18 
19   Mod:      Added NL_get_aux_filename and NL_get_aux_val.
20   Date:     23 Jan 2006 [rickr]
21   Mod:      ...and removed them.
22   Date:     30 Jan 2006 [rickr]
23 */
24 
25 /*---------------------------------------------------------------------------*/
26 
27 #ifndef _NLFIT_MODEL_HEADER_
28 #define _NLFIT_MODEL_HEADER_
29 
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <math.h>
34 #include "mrilib.h"
35 
36 #if defined(__cplusplus) || defined(c_plusplus)
37 # define DEFINE_MODEL_PROTOTYPE \
38   extern "C" { MODEL_interface * initialize_model() ; }
39 #else
40 # define DEFINE_MODEL_PROTOTYPE
41 #endif
42 
43 
44 struct NLFIT_MODEL_array ; /* incomplete definition */
45 
46 /*******************************************************************
47    Define macros and typedefs for opening, closing, and finding
48    symbols from dynamic libraries.  This is not done the same
49    way on all Unixoid systems, unfortunately (that is to say,
50    HP-UX is different).
51 *******************************************************************/
52 
53 typedef void (*vfp)();       /* pointer to generic function */
54 
55 #ifndef VOID_FUNC
56 #define VOID_FUNC
57 typedef void void_func() ;
58 #endif
59 
60 #ifndef _AFNI_PLUGIN_HEADER_
61 
62 typedef int int_func() ;     /* generic function returning integer */
63 typedef void * vptr_func() ; /* generic function returning void *  */
64 typedef char * cptr_func() ; /* generic function returning char *  */
65 
66 /***************** The dlfcn.h and dl library ****************/
67 
68 #ifdef DYNAMIC_LOADING_VIA_DL
69 
70 #ifndef DARWIN
71 #  include <dlfcn.h>
72 #else
73 #  include "dlcompat/dlfcn.h"
74 #endif
75    typedef void * DYNAMIC_handle ;
76 
77 #  define ISVALID_DYNAMIC_handle(handle) ((handle) != (DYNAMIC_handle) 0)
78 
79 #  define DYNAMIC_OPEN(libname,handle) \
80       (handle) = dlopen( (libname) , RTLD_LAZY )
81 
82 #  define DYNAMIC_ERROR_STRING  dlerror()  /* 18 May 2001 */
83 
84 #  define DYNAMIC_CLOSE(handle) \
85       (void) dlclose( (handle) )
86 
87 #  define DYNAMIC_SYMBOL(handle,symbol,address) \
88       (address) = dlsym( (handle) , (symbol) )
89 #ifndef DYNAMIC_suffix
90 #  define DYNAMIC_suffix ".so"
91 #endif
92 #endif
93 
94 /****************** The dl.h and dld library ******************/
95 
96 #ifdef DYNAMIC_LOADING_VIA_SHL
97 #  include <dl.h>
98    typedef shl_t DYNAMIC_handle ;
99 
100 #  define ISVALID_DYNAMIC_handle(handle) ((handle) != (DYNAMIC_handle) 0)
101 
102 #  define DYNAMIC_OPEN(libname,handle) \
103       (handle) = shl_load( (libname) , BIND_DEFERRED , 0L )
104 
105 #  define DYNAMIC_ERROR_STRING strerror(errno) /* 18 May 2001 */
106 
107 #  define DYNAMIC_CLOSE(handle) \
108       (void) shl_unload( (handle) )
109 
110 #  define DYNAMIC_SYMBOL(handle,symbol,address)      \
111       do{ (address) = NULL ;                         \
112           (void) shl_findsym( &(handle) , (symbol) , \
113                               TYPE_UNDEFINED , &(address) ) ; } while(0)
114 
115 #  define DYNAMIC_suffix ".sl"
116 #endif
117 
118 #ifndef DYNAMIC_suffix
119 #  error "Plugins not properly set up -- see machdep.h"
120 #endif
121 
122 #endif
123 
124 /*****************************************************************
125    Data to define the interface between a MODEL and NLFIT
126 ******************************************************************/
127 
128 /*----- dimensions of various arrays -----*/
129 #define MAX_NAME_LENGTH  80          /* for model and file names */
130 #define MAX_PARAMETERS  100          /* maximum number of model parameters */
131 #define MAX_MODELS      100          /* maximum number of models */
132 
133 /*----- model type codes -----*/
134 #define MODEL_NOISE_TYPE   0
135 #define MODEL_SIGNAL_TYPE  1
136 
137 
138 /** macro to copy string into MODEL label array,
139     filling with blanks or truncating length, as needed **/
140 #define MODEL_LABEL_strcpy(mlab,str)                                \
141    do{ int ll=strlen((str)) , ii ;                                   \
142        if( ll >= MAX_NAME_LENGTH ) ll = MAX_NAME_LENGTH - 1 ;    \
143        for( ii=0 ; ii < ll ; ii++ ) (mlab)[ii] = (str)[ii] ;         \
144        for( ; ii < MAX_NAME_LENGTH - 1 ; ii++ ) (mlab)[ii] = ' ' ; \
145        mlab[MAX_NAME_LENGTH - 1] = '\0' ; } while(0)
146 
147 
148 typedef struct {
149   char label[MAX_NAME_LENGTH];          /* name of the model */
150   int  model_type;                      /* noise or signal model? */
151   int  params;                          /* number of parameters */
152   char plabel[MAX_PARAMETERS][MAX_NAME_LENGTH];   /* parameter labels */
153   float min_constr[MAX_PARAMETERS];   /* minimum parameter constraints */
154   float max_constr[MAX_PARAMETERS];   /* maximum parameter constraints */
155   void_func * call_func ;             /* function which implements the model */
156 } MODEL_interface ;
157 
158 
159 /**************************************************************************/
160 /***** Define data structures to hold control information for MODELs *****/
161 
162 #define NLFIT_MODEL_TYPE        1066
163 #define ISVALID_NLFIT_MODEL(pl) ((pl)!=NULL && (pl)->type==NLFIT_MODEL_TYPE)
164 
165 #define MAX_MODEL_NAME 128
166 
167 /*** one MODEL ***/
168 
169 typedef struct {
170    int type ;        /* identifier */
171 
172    char              libname[MAX_MODEL_NAME] ;
173    DYNAMIC_handle    libhandle ;
174    vptr_func       * libinit_func ;
175    MODEL_interface * interface ;
176 } NLFIT_MODEL ;
177 
178 /*** dynamic array of many MODELs ***/
179 
180 typedef struct NLFIT_MODEL_array {
181    int num , nall ;
182    NLFIT_MODEL ** modar ;
183 } NLFIT_MODEL_array ;
184 
185 /*** macros to create, add to, destroy, and free an array of MODELs ***/
186 
187 #define INC_MODEL_ARRAY 8
188 
189 /** "name" is a variable of type (NLFIT_MODEL_array *) **/
190 
191 #define INIT_MODEL_ARRAY(name)                                                \
192    do{ int iq ;                                      		              \
193      (name)       = (NLFIT_MODEL_array *) malloc(sizeof(NLFIT_MODEL_array));  \
194      (name)->num  = 0 ;                                                       \
195      (name)->nall = INC_MODEL_ARRAY ;                                         \
196      (name)->modar= (NLFIT_MODEL **)malloc(sizeof(NLFIT_MODEL*)*(name)->nall);\
197      for (iq=(name)->num; iq < (name)->nall; iq++ ) (name)->modar[iq] = NULL; \
198      } while(0)
199 
200 /** "model" is a variable of type (NLFIT_MODEL *) **/
201 
202 #define ADDTO_MODEL_ARRAY(name,model)                                         \
203    do{ int nn , iq ;                                                          \
204        if( (name)->num == (name)->nall ){                                     \
205           nn = (name)->nall = 1.1*(name)->nall + INC_MODEL_ARRAY ;            \
206           (name)->modar = realloc( (name)->modar,sizeof(NLFIT_MODEL *)*nn );  \
207           for( iq=(name)->num ; iq < (name)->nall ; iq++ )                    \
208 	    (name)->modar[iq] = NULL ;}                                       \
209        nn = (name)->num ; ((name)->num)++ ;                                   \
210        (name)->modar[nn] = (model) ;                                          \
211      } while(0)
212 
213 /** this frees all the memory associated with this array **/
214 
215 #define DESTROY_MODEL_ARRAY(name)                                      \
216    do{ int nn ;                                                         \
217        if( (name) != NULL ){                                            \
218           for( nn=0 ; nn < (name)->num ; nn++ )                         \
219              if( (name)->modar[nn] != NULL ) free( (name)->modar[nn] ) ;  \
220           free( (name)->modar ) ; free((name)) ; (name) = NULL ;         \
221        } } while(0)
222 
223 /** this just frees the control data associated
224     with this array -- the actual MODELs are not freed. **/
225 
226 #define FREE_MODEL_ARRAY(name)                                         \
227    do{ int nn ;                                                         \
228        if( (name) != NULL ){                                            \
229           free( (name)->modar ) ; free((name)) ; (name) = NULL ;         \
230        } } while(0)
231 
232 /*---------------------------------------------------------------------------*/
233 
234 /*----- Other prototypes -----*/
235 
236 extern NLFIT_MODEL_array * NLFIT_get_all_MODELs (char * dname);
237 extern NLFIT_MODEL *       NLFIT_read_MODEL (char * fname);
238 extern NLFIT_MODEL_array * NLFIT_get_many_MODELs (void);
239 
240 /*---------------------------------------------------------------------------*/
241 /*----- Array of pointers to functions that are needed by the model_conv*.c  */
242 /*----- routines.  This array is just to force loading of these functions    */
243 /*----- from libraries. ----- RW Cox (21 July 1998) -------------------------*/
244 
245 #ifndef RWC_FORCED_LOADS
246 #define RWC_FORCED_LOADS
247 
248 static vptr_func * NL_forced_loads[] = {
249    (vptr_func *) mri_read_ascii ,
250    (vptr_func *) mri_to_float ,
251    (vptr_func *) mri_transpose ,
252    (vptr_func *) mri_free ,
253 NULL } ;
254 
RWC_forced_loads(int n)255 vptr_func * RWC_forced_loads(int n){  /* this function is to try to ensure   */
256   return NL_forced_loads[n] ;         /* that the array isn't optimized away */
257 }
258 
259 #endif
260 
261 
262 /*---------------------------------------------------------------------------*/
263 
264 #endif /* _NLFIT_MODEL_HEADER_ */
265 
266 
267