1 /*****************************************************************************
2    Major portions of this software are copyrighted by the Medical College
3    of Wisconsin, 1994-2000, and are released under the Gnu General Public
4    License, Version 2.  See the file README.Copyright for details.
5 ******************************************************************************/
6 
7 #undef MAIN
8 
9 #include "afni.h"
10 #include "mrilib.h"
11 
12 /*--------------------------------------------------------------------
13   Find out if a timeseries is in the library;
14   if it is, return its index, otherwise return -1.
15 ----------------------------------------------------------------------*/
16 
AFNI_ts_in_library(MRI_IMAGE * tsim)17 int AFNI_ts_in_library( MRI_IMAGE *tsim )
18 {
19    int its ;
20 
21 ENTRY("AFNI_ts_in_library") ;
22 
23    if( GLOBAL_library.timeseries != NULL         &&
24       IMARR_COUNT(GLOBAL_library.timeseries) > 0 && tsim != NULL ){
25 
26       for( its=0 ; its < IMARR_COUNT(GLOBAL_library.timeseries) ; its++ )
27          if( tsim == IMARR_SUBIMAGE(GLOBAL_library.timeseries,its) )
28             RETURN(its) ;
29    }
30 
31    RETURN(-1) ;
32 }
33 
34 /*--------------------------------------------------------------------*/
35 
AFNI_tsname_in_library(char * nam)36 int AFNI_tsname_in_library( char *nam )
37 {
38 ENTRY("AFNI_tsname_in_library") ;
39 
40    if( GLOBAL_library.timeseries != NULL         &&
41       IMARR_COUNT(GLOBAL_library.timeseries) > 0 &&
42       nam != NULL && *nam != '\0'                  ){
43 
44      int its ; MRI_IMAGE *tsim ;
45 
46      for( its=0 ; its < IMARR_COUNT(GLOBAL_library.timeseries) ; its++ ){
47        tsim = IMARR_SUBIMAGE(GLOBAL_library.timeseries,its) ;
48        if( tsim != NULL && tsim->name != NULL && strcmp(nam,tsim->name) == 0 )
49          RETURN(its) ;
50      }
51    }
52 
53    RETURN(-1) ;
54 }
55 
56 /*--------------------------------------------------------------------*/
57 
AFNI_fimmer_pickref_CB(Widget wcall,XtPointer cd,MCW_choose_cbs * cbs)58 void AFNI_fimmer_pickref_CB( Widget wcall ,
59                              XtPointer cd , MCW_choose_cbs *cbs )
60 {
61    Three_D_View *im3d = (Three_D_View *) cd ;
62    int its ;
63    MRI_IMAGE *tsim ;
64 
65 ENTRY("AFNI_fimmer_pickref_CB") ;
66 
67    if( ! IM3D_VALID(im3d) || im3d->type != AFNI_3DDATA_VIEW ) EXRETURN ;
68    if( cbs->reason != mcwCR_timeseries ) EXRETURN ;  /* error */
69 
70    its = cbs->ival ;
71    if( its >= 0 && its < IMARR_COUNT(GLOBAL_library.timeseries) ){
72 
73       tsim = IMARR_SUBIMAGE(GLOBAL_library.timeseries,its) ;
74       AFNI_fimmer_setref( im3d , tsim ) ;
75       im3d->fimdata->refadd_count = 1 ;
76    }
77 
78    EXRETURN ;
79 }
80 
81 /*--------------------------------------------------------------------*/
82 
AFNI_fimmer_pickort_CB(Widget wcall,XtPointer cd,MCW_choose_cbs * cbs)83 void AFNI_fimmer_pickort_CB( Widget wcall ,
84                              XtPointer cd , MCW_choose_cbs *cbs )
85 {
86    Three_D_View *im3d = (Three_D_View *) cd ;
87    int its ;
88    MRI_IMAGE * tsim ;
89 
90 ENTRY("AFNI_fimmer_pickort_CB") ;
91 
92    if( ! IM3D_VALID(im3d) || im3d->type != AFNI_3DDATA_VIEW ) EXRETURN ;
93    if( cbs->reason != mcwCR_timeseries ) EXRETURN ;  /* error */
94 
95    its = cbs->ival ;
96    if( its >= 0 && its < IMARR_COUNT(GLOBAL_library.timeseries) ){
97 
98       tsim = IMARR_SUBIMAGE(GLOBAL_library.timeseries,its) ;
99       AFNI_fimmer_setort( im3d , tsim ) ;
100    }
101 
102    EXRETURN ;
103 }
104 
105 /*-------------------------------------------------------------------
106    Pass this a timeseries that will not be deleted!
107 ---------------------------------------------------------------------*/
108 
AFNI_fimmer_setref(Three_D_View * im3d,MRI_IMAGE * tsim)109 void AFNI_fimmer_setref( Three_D_View *im3d , MRI_IMAGE *tsim )
110 {
111    int ii ;
112 
113 ENTRY("AFNI_fimmer_setref") ;
114 
115    if( ! IM3D_VALID(im3d) || im3d->type != AFNI_3DDATA_VIEW ) EXRETURN ;
116 
117 if(PRINT_TRACING)
118 { char str[256] ;
119   sprintf(str,"setting fimref to %s",
120      (tsim==NULL) ? "Nothing" : (tsim->name==NULL) ? "NoName" : tsim->name) ;
121   STATUS(str) ; }
122 
123    if( im3d->g123 != NULL )
124      drive_MCW_grapher( im3d->g123 , graDR_addref_ts , (XtPointer) tsim ) ;
125 
126    if( im3d->g231 != NULL )
127      drive_MCW_grapher( im3d->g231 , graDR_addref_ts , (XtPointer) tsim ) ;
128 
129    if( im3d->g312 != NULL )
130      drive_MCW_grapher( im3d->g312 , graDR_addref_ts , (XtPointer) tsim ) ;
131 
132    ii = AFNI_ts_in_library( tsim ) ;
133 
134 if(PRINT_TRACING)
135 { char str[256] ; sprintf(str,"found new ref in library at ii=%d",ii) ;
136   STATUS(str) ; }
137 
138    ii = AFNI_ts_in_library( im3d->fimdata->fimref ) ;
139 
140    /* 12 Nov 1996: fix problem with freeing old
141                    ref that might be in the library */
142 
143 if(PRINT_TRACING)
144 { char str[256] ; sprintf(str,"found old ref in library at ii=%d",ii) ;
145   STATUS(str) ; }
146 
147    if( ii < 0 && im3d->fimdata->fimref != NULL ){
148       mri_free(im3d->fimdata->fimref) ;
149 STATUS("freed old ref since wasn't in library") ;
150    }
151 
152    im3d->fimdata->fimref = tsim ;
153 
154    if( DSET_GRAPHABLE(im3d->anat_now) )
155       im3d->fimdata->fimdset = im3d->anat_now ;
156 
157    ALLOW_COMPUTE_FIM(im3d) ;
158    EXRETURN ;
159 }
160 
161 /*----------------------------------------------------------------------------*/
162 
AFNI_fimmer_setort(Three_D_View * im3d,MRI_IMAGE * tsim)163 void AFNI_fimmer_setort( Three_D_View * im3d , MRI_IMAGE * tsim )
164 {
165    int ii ;
166 
167 ENTRY("AFNI_fimmer_setort") ;
168 
169    if( ! IM3D_VALID(im3d) || im3d->type != AFNI_3DDATA_VIEW ) EXRETURN ;
170 
171 if(PRINT_TRACING)
172 { char str[256] ;
173   sprintf(str,"setting fimort to %s",
174      (tsim==NULL) ? "Nothing" : (tsim->name==NULL) ? "NoName" : tsim->name) ;
175   STATUS(str) ; }
176 
177    if( im3d->g123 != NULL )
178       drive_MCW_grapher( im3d->g123 , graDR_addort_ts , (XtPointer) tsim ) ;
179 
180    if( im3d->g231 != NULL )
181       drive_MCW_grapher( im3d->g231 , graDR_addort_ts , (XtPointer) tsim ) ;
182 
183    if( im3d->g312 != NULL )
184       drive_MCW_grapher( im3d->g312 , graDR_addort_ts , (XtPointer) tsim ) ;
185 
186    ii = AFNI_ts_in_library( tsim ) ;
187 
188 if(PRINT_TRACING)
189 { char str[256] ; sprintf(str,"found new ort in library at ii=%d",ii) ;
190   STATUS(str) ; }
191 
192    ii = AFNI_ts_in_library( im3d->fimdata->fimort ) ;
193 
194    /* 12 Nov 1996: fix problem with freeing old
195                    ort that might be in the library */
196 
197 if(PRINT_TRACING)
198 { char str[256] ; sprintf(str,"found old ort in library at ii=%d",ii) ;
199   STATUS(str) ; }
200 
201    if( ii < 0 && im3d->fimdata->fimort != NULL ){
202       mri_free(im3d->fimdata->fimort) ;
203 STATUS("freed old ort since wasn't in library") ;
204    }
205 
206    im3d->fimdata->fimort = tsim ;
207 
208    if( DSET_GRAPHABLE(im3d->anat_now) )
209       im3d->fimdata->fimdset = im3d->anat_now ;
210 
211    ALLOW_COMPUTE_FIM(im3d) ;
212    EXRETURN ;
213 }
214 
215 /*-------------------------------------------------------------------
216   Set the number of points to ignore at the beginning of time
217 ---------------------------------------------------------------------*/
218 
AFNI_fimmer_setignore(Three_D_View * im3d,int new_ignore)219 void AFNI_fimmer_setignore( Three_D_View * im3d , int new_ignore )
220 {
221    int ii ;
222 
223 ENTRY("AFNI_fimmer_setignore") ;
224 
225    if( ! IM3D_VALID(im3d) || im3d->type != AFNI_3DDATA_VIEW ) EXRETURN ;
226 
227    if( im3d->g123 != NULL )
228       drive_MCW_grapher( im3d->g123 , graDR_setignore , (XtPointer)ITOP(new_ignore) ) ;
229 
230    if( im3d->g231 != NULL )
231       drive_MCW_grapher( im3d->g231 , graDR_setignore , (XtPointer)ITOP(new_ignore) ) ;
232 
233    if( im3d->g312 != NULL )
234       drive_MCW_grapher( im3d->g312 , graDR_setignore , (XtPointer)ITOP(new_ignore) ) ;
235 
236    im3d->fimdata->init_ignore = new_ignore ;
237 
238    if( DSET_GRAPHABLE(im3d->anat_now) )
239       im3d->fimdata->fimdset = im3d->anat_now ;
240 
241    ALLOW_COMPUTE_FIM(im3d) ;
242    EXRETURN ;
243 }
244 
245 /*-------------------------------------------------------------------
246   Set the polynomial ort order [27 May 1999 - RWCox]
247 ---------------------------------------------------------------------*/
248 
AFNI_fimmer_setpolort(Three_D_View * im3d,int new_polort)249 void AFNI_fimmer_setpolort( Three_D_View * im3d , int new_polort )
250 {
251    int ii ;
252 
253 ENTRY("AFNI_fimmer_setpolort") ;
254 
255    if( ! IM3D_VALID(im3d) || im3d->type != AFNI_3DDATA_VIEW ) EXRETURN ;
256 
257    if( im3d->g123 != NULL )
258       drive_MCW_grapher( im3d->g123 , graDR_polort , (XtPointer)ITOP(new_polort) ) ;
259 
260    if( im3d->g231 != NULL )
261       drive_MCW_grapher( im3d->g231 , graDR_polort , (XtPointer)ITOP(new_polort) ) ;
262 
263    if( im3d->g312 != NULL )
264       drive_MCW_grapher( im3d->g312 , graDR_polort , (XtPointer)ITOP(new_polort) ) ;
265 
266    im3d->fimdata->polort = new_polort ;
267 
268    if( DSET_GRAPHABLE(im3d->anat_now) )
269       im3d->fimdata->fimdset = im3d->anat_now ;
270 
271    ALLOW_COMPUTE_FIM(im3d) ;
272    EXRETURN ;
273 }
274 
275 
276 /*-------------------------------------------------------------------
277    Lots of CPU work in here!
278 ---------------------------------------------------------------------*/
279 
280 #ifndef FIM_THR
281 #define FIM_THR  0.0999
282 #endif
283 
284 /** Jan 1998:    code = combinations of the FIM_*_MASK values      **/
285 /** 30 May 1999: allow polort to be variable (formerly fixed at 1) **/
286 /** 08 Sep 1999: added PAVE and AVER options                       **/
287 /** 03 Jan 2000: added PTOP, TOPL, and SIGM options                **/
288 /** 01 Feb 2000: added ucode, for user written functions           **/
289 
AFNI_fimmer_compute(Three_D_View * im3d,THD_3dim_dataset * dset_time,MRI_IMAGE * ref_ts,MRI_IMAGE * ort_ts,THD_session * sess,int code,int ucode)290 THD_3dim_dataset * AFNI_fimmer_compute( Three_D_View *im3d ,
291                                         THD_3dim_dataset *dset_time ,
292                                         MRI_IMAGE *ref_ts , MRI_IMAGE *ort_ts ,
293                                         THD_session *sess , int code, int ucode )
294 {
295    THD_3dim_dataset *new_dset=NULL ;
296    char new_prefix[THD_MAX_PREFIX] ;
297    char old_prefix[THD_MAX_PREFIX] ;
298    THD_slist_find fff ;
299    int ifim , it,iv , nvox=0 , ngood_ref , ntime , it1 , dtyp , nxyz , itbot ;
300    float *vval, *tsar, *aval, *rbest, *abest, *pbest, *pval, *bbest, *bval;
301    int   *indx=NULL ;
302    short *bar ;
303    short *ibest ;  /* 15 Dec 1997 */
304    void  *ptr ;
305    float stataux[MAX_STAT_AUX] ;
306    float fthr , topval ;
307    int nx_ref , ny_ref , ivec , nnow ;
308    PCOR_references **pc_ref ;
309    PCOR_voxel_corr **pc_vc ;
310 
311    int fim_nref , nx_ort=0 , ny_ort=0 , internal_ort ;
312    float *ortar=NULL ;
313    static float * ref_vec = NULL ;
314    static int    nref_vec = -666 ;
315 
316    int ibr_best , ibr_perc , ibr_fim , ibr_corr , ibr_base , nbrik ;
317 
318    int polort = im3d->fimdata->polort , ip ;  /* 30 May 1999 */
319 
320    float top_perc = 0.0 ;                     /* 30 Aug 1999 */
321 
322    int ibr_pave , ibr_aver ;                    /* 08 Sep 1999 */
323    float *paval , *avval , *pabest , *avbest ;  /* 08 Sep 1999 */
324 
325    int ibr_ptop , ibr_topl , ibr_sigm ;             /* 03 Jan 2000 */
326    float *ptval , *tlval , *sgval ,
327          *ptbest, *tlbest, *sgbest ;
328 
329 #ifndef DONT_USE_METER
330    Widget meter = NULL ;
331    int meter_perc , meter_pold ;
332 #endif
333 
334    int nupdt      = 0 ,  /* number of updates done yet */
335        min_updt   = 5 ,  /* min number needed for display */
336        first_updt = 1 ;  /* flag to indicate that first update is yet to be displayed */
337 
338 ENTRY("AFNI_fimmer_compute") ;
339 
340    /*--- check for legal inputs ---*/
341 
342    if( ! DSET_GRAPHABLE(dset_time)    ||
343        ref_ts == NULL                 ||
344        ref_ts->kind != MRI_float      ||
345        ! IM3D_OPEN(im3d)              ||
346        im3d->type != AFNI_3DDATA_VIEW ||
347        (code == 0 && ucode == 0)      ||           /* Jan 1998 & Feb 2000 */
348        ref_ts->nx < DSET_NUM_TIMES(dset_time) ){
349 
350 if(PRINT_TRACING)
351 { char str[256] ;
352   sprintf(str,"illegal inputs: ntime=%d num_ts=%d",
353           DSET_NUM_TIMES(dset_time), (ref_ts==NULL) ? (0) : (ref_ts->nx) ) ;
354   STATUS(str) ; }
355 
356       RETURN(NULL) ;
357    }
358 
359    /** 13 Nov 1996: allow for orts **/
360 
361    if( ort_ts != NULL ){
362       nx_ort = ort_ts->nx ;
363       ny_ort = ort_ts->ny ;
364       ortar  = MRI_FLOAT_PTR(ort_ts) ;
365 
366       internal_ort = (nx_ort < DSET_NUM_TIMES(dset_time)) ;
367    } else {
368       internal_ort = 1 ;
369    }
370    fim_nref = (internal_ort) ? (polort+2) : (ny_ort+polort+2) ;
371 
372    if( nref_vec < fim_nref ){
373        ref_vec = (float *) XtRealloc( (char *)ref_vec, sizeof(float)*fim_nref ) ;
374       nref_vec = fim_nref ;
375    }
376 
377    itbot     = im3d->fimdata->init_ignore ;
378    nx_ref    = ref_ts->nx ;
379    ny_ref    = ref_ts->ny ;
380    ntime     = DSET_NUM_TIMES(dset_time) ;
381    ngood_ref = 0 ;
382    it1       = -1 ;
383    for( ivec=0 ; ivec < ny_ref ; ivec++ ){
384       tsar = MRI_FLOAT_PTR(ref_ts) + (ivec*nx_ref) ;
385       ifim = 0 ;
386       for( it=itbot ; it < ntime ; it++ ){
387          if( tsar[it] < WAY_BIG ){ ifim++ ; if( it1 < 0 ) it1 = it ; }
388       }
389 
390       if( ifim < min_updt ){
391          STATUS("ref_ts has too few good entries!") ;
392          RETURN(NULL) ;
393       }
394 
395       ngood_ref = MAX( ifim , ngood_ref ) ;
396    }
397 
398    /** at this point, ngood_ref = max number of good reference points,
399        and                  it1 = index of first point used in first reference **/
400 
401    dtyp = DSET_BRICK_TYPE(dset_time,it1) ;
402    if( ! AFNI_GOOD_FUNC_DTYPE(dtyp) ){
403       STATUS("illegal input data type!") ;
404       RETURN(NULL) ;
405    }
406 
407    /*--- Create a new prefix ---*/
408 
409    MCW_strncpy( old_prefix , DSET_PREFIX(dset_time) , THD_MAX_PREFIX-3 ) ;
410 
411    if( ! ISVALID_SESSION(sess) ){
412       sprintf( new_prefix , "%s@%d" , old_prefix , 1 ) ;
413    } else {
414       for( ifim=1 ; ifim < 99 ; ifim++ ){
415          sprintf( new_prefix , "%s@%d" , old_prefix , ifim ) ;
416          fff = THD_dset_in_session( FIND_PREFIX , new_prefix , sess ) ;
417          if( fff.dset == NULL ) break ;
418       }
419       if( ifim == 99 ){
420          STATUS("can't create new prefix!") ;
421          RETURN(NULL) ;  /* can't make a new prefix! */
422       }
423    }
424 
425 if(PRINT_TRACING)
426 { char str[256] ;
427   sprintf(str,"new prefix = %s",new_prefix) ; STATUS(str) ; }
428 
429    /*--- FIM: find values above threshold to fim ---*/
430 
431    THD_load_datablock( dset_time->dblk ) ;
432 
433    nxyz =  dset_time->dblk->diskptr->dimsizes[0]
434          * dset_time->dblk->diskptr->dimsizes[1]
435          * dset_time->dblk->diskptr->dimsizes[2] ;
436 
437    /** find the mean of the first array,
438        compute the threshold (fthr) from it,
439        make indx[i] be the 3D index of the i-th voxel above threshold **/
440 
441    switch( dtyp ){
442 
443       case MRI_short:{
444          short * dar = (short *) DSET_ARRAY(dset_time,it1) ;
445          for( iv=0,fthr=0.0 ; iv < nxyz ; iv++ ) fthr += abs(dar[iv]) ;
446          fthr = FIM_THR * fthr / nxyz ;
447 
448 if(PRINT_TRACING)
449 { char str[256] ; sprintf(str,"fthr = %g",fthr) ; STATUS(str) ; }
450 
451          for( iv=0,nvox=0 ; iv < nxyz ; iv++ )
452             if( abs(dar[iv]) > fthr ) nvox++ ;
453          indx = (int *) malloc( sizeof(int) * nvox ) ;
454          if( indx == NULL ){
455             fprintf(stderr,"\n*** indx malloc failure in AFNI_fimmer_compute\n") ;
456             RETURN(NULL) ;
457          }
458          for( iv=0,nvox=0 ; iv < nxyz ; iv++ )
459             if( abs(dar[iv]) > fthr ) indx[nvox++] = iv ;
460       }
461       break ;
462 
463       case MRI_float:{
464          float * dar = (float *) DSET_ARRAY(dset_time,it1) ;
465          for( iv=0,fthr=0.0 ; iv < nxyz ; iv++ ) fthr += fabs(dar[iv]) ;
466          fthr = FIM_THR * fthr / nxyz ;
467 
468 if(PRINT_TRACING)
469 { char str[256] ; sprintf(str,"fthr = %g",fthr) ; STATUS(str) ; }
470 
471          for( iv=0,nvox=0 ; iv < nxyz ; iv++ )
472             if( fabs(dar[iv]) > fthr ) nvox++ ;
473          indx = (int *) malloc( sizeof(int) * nvox ) ;
474          if( indx == NULL ){
475             fprintf(stderr,"\n*** indx malloc failure in AFNI_fimmer_compute\n") ;
476             RETURN(NULL) ;
477          }
478          for( iv=0,nvox=0 ; iv < nxyz ; iv++ )
479             if( fabs(dar[iv]) > fthr ) indx[nvox++] = iv ;
480       }
481       break ;
482 
483       case MRI_byte:{
484          byte * dar = (byte *) DSET_ARRAY(dset_time,it1) ;
485          for( iv=0,fthr=0.0 ; iv < nxyz ; iv++ ) fthr += dar[iv] ;
486          fthr = FIM_THR * fthr / nxyz ;
487 
488 if(PRINT_TRACING)
489 { char str[256] ; sprintf(str,"fthr = %g",fthr) ; STATUS(str) ; }
490 
491          for( iv=0,nvox=0 ; iv < nxyz ; iv++ )
492             if( dar[iv] > fthr ) nvox++ ;
493          indx = (int *) malloc( sizeof(int) * nvox ) ;
494          if( indx == NULL ){
495             fprintf(stderr,"\n*** indx malloc failure in AFNI_fimmer_compute\n") ;
496             RETURN(NULL) ;
497          }
498          for( iv=0,nvox=0 ; iv < nxyz ; iv++ )
499             if( dar[iv] > fthr ) indx[nvox++] = iv ;
500       }
501       break ;
502    }
503 
504 if(PRINT_TRACING)
505 { char str[256] ; sprintf(str,"number of voxels = %d",nvox) ; STATUS(str) ; }
506 
507    /** 10 May 2000: check if nothing was found to work on **/
508 
509    if( nvox == 0 ){
510       fprintf(stderr,"\n*** no voxels to FIM on!"
511                      "\n*** try setting the Bkg Thresh lower"
512                      "\n    [on the FIM -> Edit Ideal menu]\a\n") ;
513       free(indx) ; RETURN(NULL) ;
514    }
515 
516    /** allocate space for voxel values **/
517 
518    vval = (float *) malloc( sizeof(float) * nvox) ;
519    if( vval == NULL ){
520       fprintf(stderr,"\n*** vval malloc failure in AFNI_fimmer_compute\n") ;
521       free(indx) ; RETURN(NULL) ;
522    }
523 
524    /** compute number of output bricks **/
525 
526    ibr_fim=ibr_corr=ibr_best=ibr_perc=ibr_base = -1 ; nbrik = 0 ;
527    ibr_pave = ibr_aver = -1 ;
528    ibr_ptop = ibr_topl = ibr_sigm = -1 ;
529 
530    if( (code & FIM_ALPHA_MASK)!= 0)              { ibr_fim  = nbrik; nbrik++; }
531    if( (code & FIM_BEST_MASK) != 0 && ny_ref > 1){ ibr_best = nbrik; nbrik++; }
532    if( (code & FIM_PERC_MASK) != 0)              { ibr_perc = nbrik; nbrik++; }
533    if( (code & FIM_PAVE_MASK) != 0)              { ibr_pave = nbrik; nbrik++; }
534    if( (code & FIM_BASE_MASK) != 0)              { ibr_base = nbrik; nbrik++; }
535    if( (code & FIM_AVER_MASK) != 0)              { ibr_aver = nbrik; nbrik++; }
536    if( (code & FIM_CORR_MASK) != 0)              { ibr_corr = nbrik; nbrik++; }
537    if( (code & FIM_PTOP_MASK) != 0)              { ibr_ptop = nbrik; nbrik++; }
538    if( (code & FIM_TOPL_MASK) != 0)              { ibr_topl = nbrik; nbrik++; }
539    if( (code & FIM_SIGM_MASK) != 0)              { ibr_sigm = nbrik; nbrik++; }
540 
541    /** 01 Feb 2000: if no normal FIM stuff (code), skip to the ucode stuff **/
542 
543 if(PRINT_TRACING)
544 { char str[256] ; sprintf(str,"number of bricks = %d",nbrik) ; STATUS(str) ; }
545 
546    if( nbrik == 0 ){
547 
548 #ifndef DONT_USE_METER
549    meter = MCW_popup_meter( im3d->vwid->top_shell , METER_TOP_WIDE ) ;
550    meter_pold = 0 ;
551 #endif
552 
553       goto ucode_stuff ;  /* way below */
554    }
555 
556    /** normal case: do the normal recursive FIMming **/
557 
558 if(PRINT_TRACING)
559 { char str[256] ;
560   sprintf(str,"code of FIM_MASKs = %d",code) ; STATUS(str) ; }
561 
562    /** allocate extra space for comparing results from multiple ref vectors **/
563 
564    if( ny_ref > 1 ){
565       aval  = (float *) malloc(sizeof(float) * nvox) ;
566       rbest = (float *) malloc(sizeof(float) * nvox) ;
567       abest = (float *) malloc(sizeof(float) * nvox) ;
568       ibest = (short *) malloc(sizeof(short) * nvox) ;  /* 15 Dec 1997 */
569       pbest = (float *) malloc(sizeof(float) * nvox) ;  /* 16 Jan 1998 */
570       bbest = (float *) malloc(sizeof(float) * nvox) ;  /* 16 Jan 1998 */
571       pval  = (float *) malloc(sizeof(float) * nvox) ;  /* 16 Jan 1998 */
572       bval  = (float *) malloc(sizeof(float) * nvox) ;  /* 16 Jan 1998 */
573 
574       paval  = (float *) malloc(sizeof(float) * nvox) ; /* 08 Sep 1999 */
575       avval  = (float *) malloc(sizeof(float) * nvox) ; /* 08 Sep 1999 */
576       pabest = (float *) malloc(sizeof(float) * nvox) ; /* 16 Jan 1998 */
577       avbest = (float *) malloc(sizeof(float) * nvox) ; /* 16 Jan 1998 */
578 
579       ptval  = (float *) malloc(sizeof(float) * nvox) ; /* 03 Jan 2000 */
580       tlval  = (float *) malloc(sizeof(float) * nvox) ; /* 03 Jan 2000 */
581       sgval  = (float *) malloc(sizeof(float) * nvox) ; /* 03 Jan 2000 */
582       ptbest = (float *) malloc(sizeof(float) * nvox) ; /* 03 Jan 2000 */
583       tlbest = (float *) malloc(sizeof(float) * nvox) ; /* 03 Jan 2000 */
584       sgbest = (float *) malloc(sizeof(float) * nvox) ; /* 03 Jan 2000 */
585 
586       if( sgbest == NULL ){
587          fprintf(stderr,"\n*** 'best' malloc failure in AFNI_fimmer_compute\n") ;
588          free(vval) ; free(indx) ;
589          if( aval  != NULL ) free(aval)  ;
590          if( rbest != NULL ) free(rbest) ;
591          if( abest != NULL ) free(abest) ;
592          if( ibest != NULL ) free(ibest) ;  /* 15 Dec 1997 */
593          if( pbest != NULL ) free(pbest) ;  /* 16 Jan 1998 */
594          if( bbest != NULL ) free(bbest) ;  /* 16 Jan 1998 */
595          if( pval  != NULL ) free(pval)  ;  /* 16 Jan 1998 */
596          if( bval  != NULL ) free(bval)  ;  /* 16 Jan 1998 */
597          if( paval != NULL ) free(paval) ;  /* 08 Sep 1999 */
598          if( avval != NULL ) free(avval) ;  /* 08 Sep 1999 */
599          if( pabest!= NULL ) free(pabest);  /* 08 Sep 1999 */
600          if( avbest!= NULL ) free(avbest);  /* 08 Sep 1999 */
601          if( ptval != NULL ) free(ptval) ;  /* 03 Jan 2000 */
602          if( tlval != NULL ) free(tlval) ;  /* 03 Jan 2000 */
603          if( sgval != NULL ) free(sgval) ;  /* 03 Jan 2000 */
604          if( ptbest!= NULL ) free(ptbest);  /* 03 Jan 2000 */
605          if( tlbest!= NULL ) free(tlbest);  /* 03 Jan 2000 */
606          if( sgbest!= NULL ) free(sgbest);  /* 03 Jan 2000 */
607          RETURN(NULL) ;
608       }
609    } else {
610       aval = rbest = abest = pbest = bbest = pval = bval = NULL ;
611       paval = avval = pabest = avbest = NULL ;  /* 08 Sep 1999 */
612       ptval = tlval = ptbest = tlbest = NULL ;  /* 03 Jan 2000 */
613       sgval = sgbest = NULL ;                   /* 03 Jan 2000 */
614       ibest = NULL ;                            /* 15 Dec 1997 */
615    }
616 
617 if(PRINT_TRACING)
618 { char str[256] ;
619   sprintf(str,"nxyz = %d  nvox = %d",nxyz,nvox) ; STATUS(str) ; }
620 
621    /*--- FIM: initialize recursive updates ---*/
622 
623    pc_ref = (PCOR_references **) malloc( sizeof(PCOR_references *) * ny_ref ) ;
624    pc_vc  = (PCOR_voxel_corr **) malloc( sizeof(PCOR_voxel_corr *) * ny_ref ) ;
625 
626    if( pc_ref == NULL || pc_vc == NULL ){
627       free(vval) ; free(indx) ; free(pc_ref) ; free(pc_vc) ;
628       if( aval  != NULL ) free(aval) ;
629       if( rbest != NULL ) free(rbest) ;
630       if( abest != NULL ) free(abest) ;
631       if( ibest != NULL ) free(ibest) ;  /* 15 Dec 1997 */
632       if( pbest != NULL ) free(pbest) ;  /* 16 Jan 1998 */
633       if( bbest != NULL ) free(bbest) ;  /* 16 Jan 1998 */
634       if( pval  != NULL ) free(pval)  ;  /* 16 Jan 1998 */
635       if( bval  != NULL ) free(bval)  ;  /* 16 Jan 1998 */
636       if( paval != NULL ) free(paval) ;  /* 08 Sep 1999 */
637       if( avval != NULL ) free(avval) ;  /* 08 Sep 1999 */
638       if( pabest!= NULL ) free(pabest);  /* 08 Sep 1999 */
639       if( avbest!= NULL ) free(avbest);  /* 08 Sep 1999 */
640       if( ptval != NULL ) free(ptval) ;  /* 03 Jan 2000 */
641       if( tlval != NULL ) free(tlval) ;  /* 03 Jan 2000 */
642       if( sgval != NULL ) free(sgval) ;  /* 03 Jan 2000 */
643       if( ptbest!= NULL ) free(ptbest);  /* 03 Jan 2000 */
644       if( tlbest!= NULL ) free(tlbest);  /* 03 Jan 2000 */
645       if( sgbest!= NULL ) free(sgbest);  /* 03 Jan 2000 */
646       fprintf(stderr,"\n*** FIM initialization fails in AFNI_fimmer_compute\n") ;
647       RETURN(NULL) ;
648    }
649 
650    ifim = 0 ;
651    for( ivec=0 ; ivec < ny_ref ; ivec++ ){
652       pc_ref[ivec] = new_PCOR_references( fim_nref ) ;
653       pc_vc[ivec]  = new_PCOR_voxel_corr( nvox , fim_nref ) ;
654       if( pc_ref[ivec] == NULL || pc_vc[ivec] == NULL ) ifim++ ;
655    }
656 
657    if( ifim > 0 ){
658       for( ivec=0 ; ivec < ny_ref ; ivec++ ){
659          free_PCOR_references(pc_ref[ivec]) ;
660          free_PCOR_voxel_corr(pc_vc[ivec]) ;
661       }
662       free(vval) ; free(indx) ; free(pc_ref) ; free(pc_vc) ;
663       if( aval  != NULL ) free(aval) ;
664       if( rbest != NULL ) free(rbest) ;
665       if( abest != NULL ) free(abest) ;
666       if( ibest != NULL ) free(ibest) ;  /* 15 Dec 1997 */
667       if( pbest != NULL ) free(pbest) ;  /* 16 Jan 1998 */
668       if( bbest != NULL ) free(bbest) ;  /* 16 Jan 1998 */
669       if( pval  != NULL ) free(pval)  ;  /* 16 Jan 1998 */
670       if( bval  != NULL ) free(bval)  ;  /* 16 Jan 1998 */
671       if( paval != NULL ) free(paval) ;  /* 08 Sep 1999 */
672       if( avval != NULL ) free(avval) ;  /* 08 Sep 1999 */
673       if( pabest!= NULL ) free(pabest);  /* 08 Sep 1999 */
674       if( avbest!= NULL ) free(avbest);  /* 08 Sep 1999 */
675       if( ptval != NULL ) free(ptval) ;  /* 03 Jan 2000 */
676       if( tlval != NULL ) free(tlval) ;  /* 03 Jan 2000 */
677       if( sgval != NULL ) free(sgval) ;  /* 03 Jan 2000 */
678       if( ptbest!= NULL ) free(ptbest);  /* 03 Jan 2000 */
679       if( tlbest!= NULL ) free(tlbest);  /* 03 Jan 2000 */
680       if( sgbest!= NULL ) free(sgbest);  /* 03 Jan 2000 */
681       fprintf(stderr,"\n*** FIM initialization fails in AFNI_fimmer_compute\n") ;
682       RETURN(NULL) ;
683    }
684 
685    /*--- Make a new dataset to hold the output ---*/
686 
687 STATUS("making new dataset") ;
688 
689    new_dset = EDIT_empty_copy( dset_time ) ;
690 
691    if( nbrik == 1 && ucode == 0 ){           /* 1 brick out --> a 'fim' dataset */
692       it = EDIT_dset_items( new_dset ,
693                                ADN_prefix      , new_prefix ,
694                                ADN_malloc_type , DATABLOCK_MEM_MALLOC ,
695                                ADN_type        , ISHEAD(dset_time)
696                                                  ? HEAD_FUNC_TYPE : GEN_FUNC_TYPE ,
697                                ADN_func_type   , FUNC_FIM_TYPE ,
698                                ADN_nvals       , 1 ,
699                                ADN_datum_all   , MRI_short ,
700                                ADN_ntt         , 0 ,
701                             ADN_none ) ;
702                                              /* 2 bricks, 2nd corr --> 'fico' */
703    } else if( nbrik == 2 && ibr_corr == 1 && ucode == 0 ){
704       it = EDIT_dset_items( new_dset ,
705                                ADN_prefix      , new_prefix ,
706                                ADN_malloc_type , DATABLOCK_MEM_MALLOC ,
707                                ADN_type        , ISHEAD(dset_time)
708                                                  ? HEAD_FUNC_TYPE : GEN_FUNC_TYPE ,
709                                ADN_func_type   , FUNC_COR_TYPE ,
710                                ADN_nvals       , 2 ,
711                                ADN_datum_all   , MRI_short ,
712                                ADN_ntt         , 0 ,
713                             ADN_none ) ;
714 
715    } else if( nbrik > 0 ){                   /* otherwise --> 'fbuc' (bucket) */
716       it = EDIT_dset_items( new_dset ,
717                                ADN_prefix      , new_prefix ,
718                                ADN_malloc_type , DATABLOCK_MEM_MALLOC ,
719                                ADN_type        , ISHEAD(dset_time)
720                                                  ? HEAD_FUNC_TYPE : GEN_FUNC_TYPE ,
721                                ADN_func_type   , FUNC_BUCK_TYPE ,
722                                ADN_nvals       , nbrik ,
723                                ADN_datum_all   , MRI_short ,
724                                ADN_ntt         , 0 ,
725                             ADN_none ) ;
726    } else {
727       it = 999 ;
728    }
729 
730    if( it > 0 ){
731       fprintf(stderr,
732               "\n*** EDIT_dset_items error %d in AFNI_fimmer_compute\n",it) ;
733       THD_delete_3dim_dataset( new_dset , False ) ;
734       for( ivec=0 ; ivec < ny_ref ; ivec++ ){
735          free_PCOR_references(pc_ref[ivec]) ;
736          free_PCOR_voxel_corr(pc_vc[ivec]) ;
737       }
738       free(vval) ; free(indx) ; free(pc_ref) ; free(pc_vc) ;
739       if( aval  != NULL ) free(aval) ;
740       if( rbest != NULL ) free(rbest) ;
741       if( abest != NULL ) free(abest) ;
742       if( ibest != NULL ) free(ibest) ;  /* 15 Dec 1997 */
743       if( pbest != NULL ) free(pbest) ;  /* 16 Jan 1998 */
744       if( bbest != NULL ) free(bbest) ;  /* 16 Jan 1998 */
745       if( pval  != NULL ) free(pval)  ;  /* 16 Jan 1998 */
746       if( bval  != NULL ) free(bval)  ;  /* 16 Jan 1998 */
747       if( paval != NULL ) free(paval) ;  /* 08 Sep 1999 */
748       if( avval != NULL ) free(avval) ;  /* 08 Sep 1999 */
749       if( pabest!= NULL ) free(pabest);  /* 08 Sep 1999 */
750       if( avbest!= NULL ) free(avbest);  /* 08 Sep 1999 */
751       if( ptval != NULL ) free(ptval) ;  /* 03 Jan 2000 */
752       if( tlval != NULL ) free(tlval) ;  /* 03 Jan 2000 */
753       if( sgval != NULL ) free(sgval) ;  /* 03 Jan 2000 */
754       if( ptbest!= NULL ) free(ptbest);  /* 03 Jan 2000 */
755       if( tlbest!= NULL ) free(tlbest);  /* 03 Jan 2000 */
756       if( sgbest!= NULL ) free(sgbest);  /* 03 Jan 2000 */
757       RETURN(NULL) ;
758    }
759 
760    /* modify labels for each brick */
761 
762    if( ibr_fim >= 0 )
763       EDIT_BRICK_LABEL( new_dset , ibr_fim  , "Fit Coef" ) ;
764    if( ibr_corr >= 0 )
765       EDIT_BRICK_LABEL( new_dset , ibr_corr , "Correlation" ) ;
766    if( ibr_best >= 0 )
767       EDIT_BRICK_LABEL( new_dset , ibr_best , "Best Index" ) ;
768    if( ibr_perc >= 0 )
769       EDIT_BRICK_LABEL( new_dset , ibr_perc , "% Change" ) ;
770    if( ibr_base >= 0 )
771       EDIT_BRICK_LABEL( new_dset , ibr_base , "Baseline" ) ;
772 
773    if( ibr_pave >= 0 )
774       EDIT_BRICK_LABEL( new_dset , ibr_pave , "% From Ave" ) ;  /* 08 Sep 1999 */
775    if( ibr_aver >= 0 )
776       EDIT_BRICK_LABEL( new_dset , ibr_aver , "Average" ) ;
777 
778    if( ibr_ptop >= 0 )
779       EDIT_BRICK_LABEL( new_dset , ibr_ptop , "% From Top" ) ;  /* 03 Jan 2000 */
780    if( ibr_topl >= 0 )
781       EDIT_BRICK_LABEL( new_dset , ibr_topl , "Topline" ) ;
782    if( ibr_sigm >= 0 )
783       EDIT_BRICK_LABEL( new_dset , ibr_sigm , "Sigma Resid" ) ;
784 
785    /*-- 30 Aug 1999: set limits on percent change --*/
786 
787    if( ibr_perc >= 0 || ibr_pave >= 0 || ibr_ptop >= 0 ){
788       char * cp = my_getenv("AFNI_FIM_PERCENT_LIMIT") ;
789       if( cp != NULL ){
790          float tp = strtod(cp,NULL) ;
791          if( tp > 0.0 ) top_perc = tp ;
792       }
793    }
794 
795    /* create bricks */
796 
797 STATUS("making output bricks") ;
798 
799    for( iv=0 ; iv < new_dset->dblk->nvals ; iv++ ){
800       ptr = malloc( DSET_BRICK_BYTES(new_dset,iv) ) ;
801       mri_fix_data_pointer( ptr ,  DSET_BRICK(new_dset,iv) ) ;
802    }
803 
804    if( THD_count_databricks(new_dset->dblk) < new_dset->dblk->nvals ){
805       fprintf(stderr,
806               "\n*** failure to malloc new bricks in AFNI_fimmer_compute\n") ;
807       THD_delete_3dim_dataset( new_dset , False ) ;
808       for( ivec=0 ; ivec < ny_ref ; ivec++ ){
809          free_PCOR_references(pc_ref[ivec]) ;
810          free_PCOR_voxel_corr(pc_vc[ivec]) ;
811       }
812       free(vval) ; free(indx) ; free(pc_ref) ; free(pc_vc) ;
813       if( aval  != NULL ) free(aval) ;
814       if( rbest != NULL ) free(rbest) ;
815       if( abest != NULL ) free(abest) ;
816       if( ibest != NULL ) free(ibest) ;  /* 15 Dec 1997 */
817       if( pbest != NULL ) free(pbest) ;  /* 16 Jan 1998 */
818       if( bbest != NULL ) free(bbest) ;  /* 16 Jan 1998 */
819       if( pval  != NULL ) free(pval)  ;  /* 16 Jan 1998 */
820       if( bval  != NULL ) free(bval)  ;  /* 16 Jan 1998 */
821       if( paval != NULL ) free(paval) ;  /* 08 Sep 1999 */
822       if( avval != NULL ) free(avval) ;  /* 08 Sep 1999 */
823       if( pabest!= NULL ) free(pabest);  /* 08 Sep 1999 */
824       if( avbest!= NULL ) free(avbest);  /* 08 Sep 1999 */
825       if( ptval != NULL ) free(ptval) ;  /* 03 Jan 2000 */
826       if( tlval != NULL ) free(tlval) ;  /* 03 Jan 2000 */
827       if( sgval != NULL ) free(sgval) ;  /* 03 Jan 2000 */
828       if( ptbest!= NULL ) free(ptbest);  /* 03 Jan 2000 */
829       if( tlbest!= NULL ) free(tlbest);  /* 03 Jan 2000 */
830       if( sgbest!= NULL ) free(sgbest);  /* 03 Jan 2000 */
831       RETURN(NULL) ;
832    }
833 
834    /*---------------------------------*/
835    /*--- FIM: do recursive updates ---*/
836 
837 #ifndef DONT_USE_METER
838    meter = MCW_popup_meter( im3d->vwid->top_shell , METER_TOP_WIDE ) ;
839    meter_pold = 0 ;
840 #endif
841 
842 STATUS("starting recursive least squares") ;
843 
844    for( it=itbot ; it < ntime ; it++ ){  /* loop over time */
845 
846       nnow = 0 ;  /* number of updates done at this time point */
847 
848       for( ivec=0 ; ivec < ny_ref ; ivec++ ){  /* loop over ref vects */
849 
850          tsar = MRI_FLOAT_PTR(ref_ts) + (ivec*nx_ref) ; /* ptr to vect */
851          if( tsar[it] >= WAY_BIG ) continue ;           /* skip this */
852 
853          ref_vec[0] = 1.0 ;         /* we always supply ort for constant */
854          for( ip=1 ; ip <= polort ; ip++ )              /* 30 May 1999:    */
855             ref_vec[ip] = ref_vec[ip-1] * ((float)it) ; /* and polynomials */
856 
857          if( internal_ort ){         /* no external orts */
858             ref_vec[ip] = tsar[it] ; /* ref value */
859          } else {
860             for( iv=0 ; iv < ny_ort ; iv++ )             /* external */
861                ref_vec[iv+ip] = ortar[it + iv*nx_ort] ;  /* orts */
862 
863             ref_vec[ny_ort+ip] = tsar[it] ;              /* ref value */
864          }
865 
866 if(PRINT_TRACING)
867 { char str[256] ;
868   sprintf(str,"time index=%d  ideal[%d]=%f" , it,ivec,tsar[it] ) ;
869   STATUS(str) ; }
870 
871          /* process the ort+ref update */
872 
873          update_PCOR_references( ref_vec , pc_ref[ivec] ) ;
874 
875          /* first time thru: load data from dataset */
876 
877          if( nnow == 0 ){
878             float fac ;
879             switch( dtyp ){
880                case MRI_short:{
881                   short * dar = (short *) DSET_ARRAY(dset_time,it) ;
882                   for( iv=0; iv < nvox; iv++ ) vval[iv] = (float) dar[indx[iv]];
883                }
884                break ;
885 
886                case MRI_float:{
887                   float * dar = (float *) DSET_ARRAY(dset_time,it) ;
888                   for( iv=0; iv < nvox; iv++ ) vval[iv] = (float) dar[indx[iv]];
889                }
890                break ;
891 
892                case MRI_byte:{
893                   byte * dar = (byte *) DSET_ARRAY(dset_time,it) ;
894                   for( iv=0; iv < nvox; iv++ ) vval[iv] = (float) dar[indx[iv]];
895                }
896                break ;
897             }
898             fac = DSET_BRICK_FACTOR(dset_time,it) ;  /* 21 Jul 2004: Ooopsie. */
899             if( fac > 0.0 )
900               for( iv=0 ; iv < nvox ; iv++ ) vval[iv] *= fac ;
901          }
902 
903          /* process the data update */
904 
905          PCOR_update_float( vval , pc_ref[ivec] , pc_vc[ivec] ) ;
906          nnow++ ;  /* one more update at this time point */
907       }  /* end of loop over ref vects */
908 
909       if( nnow > 0 ) nupdt++ ;  /* number of time points that had updates */
910 
911 #ifndef DONT_USE_METER
912       meter_perc = (int) ( 100.0 * nupdt / ngood_ref ) ;
913       if( meter_perc != meter_pold ){
914          MCW_set_meter( meter , meter_perc ) ;
915          meter_pold = meter_perc ;
916       }
917 #endif
918 
919    }  /* end of loop over time */
920 
921    /*-------------------------------------------*/
922    /*--- Load final results into the dataset ---*/
923 
924    /*--- set the statistical parameters ---*/
925 
926    stataux[0] = nupdt ;               /* number of points used */
927    stataux[1] = (ny_ref==1) ? 1 : 2 ; /* number of references  */
928    stataux[2] = fim_nref - 1 ;        /* number of orts        */
929    for( iv=3 ; iv < MAX_STAT_AUX ; iv++ ) stataux[iv] = 0.0 ;
930 
931    if( ibr_corr >= 0 ){
932       if( new_dset->func_type == FUNC_COR_TYPE )
933          EDIT_dset_items( new_dset, ADN_stat_aux, stataux, ADN_none ) ;
934 
935       EDIT_BRICK_TO_FICO( new_dset, ibr_corr, stataux[0],stataux[1],stataux[2] ) ;
936    }
937 
938 #ifndef DONT_USE_METER
939 # define METERIZE(ib) do { meter_perc = (int) ( 100.0 * (ib) / nbrik ) ; \
940                            if( meter_perc != meter_pold ){               \
941                               MCW_set_meter( meter , meter_perc ) ;      \
942                               meter_pold = meter_perc ;                  \
943                            } } while(0)
944 #else
945 # define METERIZE(ib) /*nada*/
946 #endif
947 
948    /*** Compute brick arrays for new dataset ***/
949    /*  [load scale factors into stataux, too]  */
950 
951    if( ny_ref == 1 ){
952 
953    /*** Just 1 ref vector --> load values directly into dataset ***/
954 
955       if( ibr_fim >= 0 ){
956 
957 STATUS("getting 1 ref alpha") ;
958 
959          PCOR_get_coef( pc_ref[0] , pc_vc[0] , vval ) ;
960 
961          topval = 0.0 ;
962          for( iv=0 ; iv < nvox ; iv++ )
963             if( fabs(vval[iv]) > topval ) topval = fabs(vval[iv]) ;
964 
965          bar = DSET_ARRAY( new_dset , ibr_fim ) ;
966          memset( bar , 0 , sizeof(short)*nxyz ) ;
967 
968          if( topval > 0.0 ){
969             topval = MRI_TYPE_maxval[MRI_short] / topval ;
970             for( iv=0 ; iv < nvox ; iv++ )
971                bar[indx[iv]] = (short)(topval * vval[iv] + 0.499) ;
972 
973             stataux[ibr_fim] = 1.0/topval ;
974          } else {
975             stataux[ibr_fim] = 0.0 ;
976          }
977 
978          METERIZE(ibr_fim) ;
979       }
980 
981       if( ibr_corr >= 0 ){
982 
983 STATUS("getting 1 ref pcor") ;
984 
985          PCOR_get_pcor( pc_ref[0] , pc_vc[0] , vval ) ;
986 
987          bar = DSET_ARRAY( new_dset , ibr_corr ) ;
988          memset( bar , 0 , sizeof(short)*nxyz ) ;
989 
990          for( iv=0 ; iv < nvox ; iv++ )
991             bar[indx[iv]] = (short)(FUNC_COR_SCALE_SHORT * vval[iv] + 0.499) ;
992 
993          stataux[ibr_corr] = 1.0 / FUNC_COR_SCALE_SHORT ;
994 
995          METERIZE(ibr_corr) ;
996       }
997 
998       if( ibr_perc >= 0 ){
999 
1000 STATUS("getting 1 ref perc") ;
1001 
1002          PCOR_get_perc( pc_ref[0] , pc_vc[0] , vval , NULL , 0 ) ;
1003 
1004          if( top_perc > 0.0 ) EDIT_clip_float( top_perc , nvox , vval ) ;
1005 
1006          topval = 0.0 ;
1007          for( iv=0 ; iv < nvox ; iv++ )
1008             if( fabs(vval[iv]) > topval ) topval = fabs(vval[iv]) ;
1009 
1010          bar = DSET_ARRAY( new_dset , ibr_perc ) ;
1011          memset( bar , 0 , sizeof(short)*nxyz ) ;
1012 
1013          if( topval > 0.0 ){
1014             topval = MRI_TYPE_maxval[MRI_short] / topval ;
1015             for( iv=0 ; iv < nvox ; iv++ )
1016                bar[indx[iv]] = (short)(topval * vval[iv] + 0.499) ;
1017 
1018             stataux[ibr_perc] = 1.0/topval ;
1019          } else {
1020             stataux[ibr_perc] = 0.0 ;
1021          }
1022 
1023          METERIZE(ibr_perc) ;
1024       }
1025 
1026       if( ibr_pave >= 0 ){  /* 08 Sep 1999 */
1027 
1028 STATUS("getting 1 ref pave") ;
1029 
1030          PCOR_get_perc( pc_ref[0] , pc_vc[0] , vval , NULL , 1 ) ;
1031 
1032          if( top_perc > 0.0 ) EDIT_clip_float( top_perc , nvox , vval ) ;
1033 
1034          topval = 0.0 ;
1035          for( iv=0 ; iv < nvox ; iv++ )
1036             if( fabs(vval[iv]) > topval ) topval = fabs(vval[iv]) ;
1037 
1038          bar = DSET_ARRAY( new_dset , ibr_pave ) ;
1039          memset( bar , 0 , sizeof(short)*nxyz ) ;
1040 
1041          if( topval > 0.0 ){
1042             topval = MRI_TYPE_maxval[MRI_short] / topval ;
1043             for( iv=0 ; iv < nvox ; iv++ )
1044                bar[indx[iv]] = (short)(topval * vval[iv] + 0.499) ;
1045 
1046             stataux[ibr_pave] = 1.0/topval ;
1047          } else {
1048             stataux[ibr_pave] = 0.0 ;
1049          }
1050 
1051          METERIZE(ibr_pave) ;
1052       }
1053 
1054       if( ibr_ptop >= 0 ){  /* 03 Jan 2000 */
1055 
1056 STATUS("getting 1 ref ptop") ;
1057 
1058          PCOR_get_perc( pc_ref[0] , pc_vc[0] , vval , NULL , 2 ) ;
1059 
1060          if( top_perc > 0.0 ) EDIT_clip_float( top_perc , nvox , vval ) ;
1061 
1062          topval = 0.0 ;
1063          for( iv=0 ; iv < nvox ; iv++ )
1064             if( fabs(vval[iv]) > topval ) topval = fabs(vval[iv]) ;
1065 
1066          bar = DSET_ARRAY( new_dset , ibr_ptop ) ;
1067          memset( bar , 0 , sizeof(short)*nxyz ) ;
1068 
1069          if( topval > 0.0 ){
1070             topval = MRI_TYPE_maxval[MRI_short] / topval ;
1071             for( iv=0 ; iv < nvox ; iv++ )
1072                bar[indx[iv]] = (short)(topval * vval[iv] + 0.499) ;
1073 
1074             stataux[ibr_ptop] = 1.0/topval ;
1075          } else {
1076             stataux[ibr_ptop] = 0.0 ;
1077          }
1078 
1079          METERIZE(ibr_ptop) ;
1080       }
1081 
1082       if( ibr_base >= 0 ){
1083 
1084 STATUS("getting 1 ref base") ;
1085 
1086          PCOR_get_perc( pc_ref[0] , pc_vc[0] , NULL , vval , 0 ) ;
1087 
1088          topval = 0.0 ;
1089          for( iv=0 ; iv < nvox ; iv++ )
1090             if( fabs(vval[iv]) > topval ) topval = fabs(vval[iv]) ;
1091 
1092          bar = DSET_ARRAY( new_dset , ibr_base ) ;
1093          memset( bar , 0 , sizeof(short)*nxyz ) ;
1094 
1095          if( topval > 0.0 ){
1096             topval = MRI_TYPE_maxval[MRI_short] / topval ;
1097             for( iv=0 ; iv < nvox ; iv++ )
1098                bar[indx[iv]] = (short)(topval * vval[iv] + 0.499) ;
1099 
1100             stataux[ibr_base] = 1.0/topval ;
1101          } else {
1102             stataux[ibr_base] = 0.0 ;
1103          }
1104 
1105          METERIZE(ibr_base) ;
1106       }
1107 
1108       if( ibr_aver >= 0 ){  /* 08 Sep 1999 */
1109 
1110 STATUS("getting 1 ref aver") ;
1111 
1112          PCOR_get_perc( pc_ref[0] , pc_vc[0] , NULL , vval , 1 ) ;
1113 
1114          topval = 0.0 ;
1115          for( iv=0 ; iv < nvox ; iv++ )
1116             if( fabs(vval[iv]) > topval ) topval = fabs(vval[iv]) ;
1117 
1118          bar = DSET_ARRAY( new_dset , ibr_aver ) ;
1119          memset( bar , 0 , sizeof(short)*nxyz ) ;
1120 
1121          if( topval > 0.0 ){
1122             topval = MRI_TYPE_maxval[MRI_short] / topval ;
1123             for( iv=0 ; iv < nvox ; iv++ )
1124                bar[indx[iv]] = (short)(topval * vval[iv] + 0.499) ;
1125 
1126             stataux[ibr_aver] = 1.0/topval ;
1127          } else {
1128             stataux[ibr_aver] = 0.0 ;
1129          }
1130 
1131          METERIZE(ibr_aver) ;
1132       }
1133 
1134       if( ibr_topl >= 0 ){  /* 03 Jan 2000 */
1135 
1136 STATUS("getting 1 ref topl") ;
1137 
1138          PCOR_get_perc( pc_ref[0] , pc_vc[0] , NULL , vval , 2 ) ;
1139 
1140          topval = 0.0 ;
1141          for( iv=0 ; iv < nvox ; iv++ )
1142             if( fabs(vval[iv]) > topval ) topval = fabs(vval[iv]) ;
1143 
1144          bar = DSET_ARRAY( new_dset , ibr_topl ) ;
1145          memset( bar , 0 , sizeof(short)*nxyz ) ;
1146 
1147          if( topval > 0.0 ){
1148             topval = MRI_TYPE_maxval[MRI_short] / topval ;
1149             for( iv=0 ; iv < nvox ; iv++ )
1150                bar[indx[iv]] = (short)(topval * vval[iv] + 0.499) ;
1151 
1152             stataux[ibr_topl] = 1.0/topval ;
1153          } else {
1154             stataux[ibr_topl] = 0.0 ;
1155          }
1156 
1157          METERIZE(ibr_topl) ;
1158       }
1159 
1160       if( ibr_sigm >= 0 ){  /* 03 Jan 2000 */
1161 
1162 STATUS("getting 1 ref sigm") ;
1163 
1164          PCOR_get_stdev( pc_vc[0] , vval ) ;
1165 
1166          topval = 0.0 ;
1167          for( iv=0 ; iv < nvox ; iv++ )
1168             if( fabs(vval[iv]) > topval ) topval = fabs(vval[iv]) ;
1169 
1170          bar = DSET_ARRAY( new_dset , ibr_sigm ) ;
1171          memset( bar , 0 , sizeof(short)*nxyz ) ;
1172 
1173          if( topval > 0.0 ){
1174             topval = MRI_TYPE_maxval[MRI_short] / topval ;
1175             for( iv=0 ; iv < nvox ; iv++ )
1176                bar[indx[iv]] = (short)(topval * vval[iv] + 0.499) ;
1177 
1178             stataux[ibr_sigm] = 1.0/topval ;
1179          } else {
1180             stataux[ibr_sigm] = 0.0 ;
1181          }
1182 
1183          METERIZE(ibr_sigm) ;
1184       }
1185 
1186    } else {
1187 
1188    /*** Multiple references --> find best correlation at each voxel ***/
1189 
1190       /*--- get first ref results into abest and rbest (best so far) ---*/
1191 
1192 STATUS("getting first ref results") ;
1193 
1194       PCOR_get_coef( pc_ref[0] , pc_vc[0] , abest ) ;
1195       PCOR_get_pcor( pc_ref[0] , pc_vc[0] , rbest ) ;
1196       PCOR_get_perc( pc_ref[0] , pc_vc[0] , pbest , bbest , 0 ) ;
1197       PCOR_get_perc( pc_ref[0] , pc_vc[0] , pabest, avbest, 1 ) ;
1198       PCOR_get_perc( pc_ref[0] , pc_vc[0] , ptbest, tlbest, 2 ) ;
1199       PCOR_get_stdev( pc_vc[0] , sgbest ) ;
1200 
1201       for( iv=0 ; iv < nvox ; iv++ ) ibest[iv] = 1 ;  /* 15 Dec 1997 */
1202 
1203       /*--- for each succeeding ref vector,
1204             get results into aval and vval,
1205             if |vval| > |rbest|, then use that result instead ---*/
1206 
1207       for( ivec=1 ; ivec < ny_ref ; ivec++ ){
1208 
1209 STATUS(" == getting results for next ref") ;
1210 
1211          PCOR_get_coef( pc_ref[ivec] , pc_vc[ivec] , aval ) ;
1212          PCOR_get_pcor( pc_ref[ivec] , pc_vc[ivec] , vval ) ;
1213          PCOR_get_perc( pc_ref[ivec] , pc_vc[ivec] , pval , bval , 0 ) ;
1214          PCOR_get_perc( pc_ref[ivec] , pc_vc[ivec] , paval, avval, 1 ) ;
1215          PCOR_get_perc( pc_ref[ivec] , pc_vc[ivec] , ptval, tlval, 2 ) ;
1216          PCOR_get_stdev( pc_vc[ivec] , sgval ) ;
1217 
1218 STATUS(" == and finding the best results") ;
1219 
1220          for( iv=0 ; iv < nvox ; iv++ ){
1221             if( fabs(vval[iv]) > fabs(rbest[iv]) ){
1222                rbest[iv] = vval[iv] ;
1223                abest[iv] = aval[iv] ;
1224                ibest[iv] = (ivec+1) ;   /* 15 Dec 1997 */
1225                pbest[iv] = pval[iv] ;   /* Jan 1998 */
1226                bbest[iv] = bval[iv] ;
1227                pabest[iv]= paval[iv] ;  /* 08 Sep 1999 */
1228                avbest[iv]= avval[iv] ;
1229                ptbest[iv]= ptval[iv] ;  /* 03 Jan 1999 */
1230                tlbest[iv]= tlval[iv] ;
1231                sgbest[iv]= sgval[iv] ;
1232             }
1233          }
1234       }
1235 
1236       /*--- at this point, abest and rbest are the best
1237             results, so scale them into the dataset bricks ---*/
1238 
1239       /** fim brick **/
1240 
1241       if( ibr_fim >= 0 ){
1242 
1243 if(PRINT_TRACING)
1244 { char str[256]; sprintf(str,"getting ibr_fim=%d",ibr_fim); STATUS(str); }
1245 
1246          topval = 0.0 ;
1247          for( iv=0 ; iv < nvox ; iv++ )
1248             if( fabs(abest[iv]) > topval ) topval = fabs(abest[iv]) ;
1249 
1250          bar = DSET_ARRAY( new_dset , ibr_fim ) ;
1251          memset( bar , 0 , sizeof(short)*nxyz ) ;
1252 
1253          if( topval > 0.0 ){
1254             topval = MRI_TYPE_maxval[MRI_short] / topval ;
1255             for( iv=0 ; iv < nvox ; iv++ )
1256                bar[indx[iv]] = (short)(topval * abest[iv] + 0.499) ;
1257 
1258             stataux[ibr_fim] = 1.0/topval ;
1259          } else {
1260             stataux[ibr_fim] = 0.0 ;
1261          }
1262 
1263          METERIZE(ibr_fim) ;
1264       }
1265 
1266       /** threshold brick **/
1267 
1268       if( ibr_corr >= 0 ){
1269 
1270 if(PRINT_TRACING)
1271 { char str[256]; sprintf(str,"getting ibr_corr=%d",ibr_corr); STATUS(str); }
1272 
1273          bar = DSET_ARRAY( new_dset , ibr_corr ) ;
1274          memset( bar , 0 , sizeof(short)*nxyz ) ;
1275 
1276          for( iv=0 ; iv < nvox ; iv++ )
1277             bar[indx[iv]] = (short)(FUNC_COR_SCALE_SHORT * rbest[iv] + 0.499) ;
1278 
1279          stataux[ibr_corr] = 1.0 / FUNC_COR_SCALE_SHORT ;
1280 
1281          METERIZE(ibr_corr) ;
1282       }
1283 
1284       /** best index brick (15 Dec 1997) */
1285 
1286       if( ibr_best >= 0 ){
1287 
1288 if(PRINT_TRACING)
1289 { char str[256]; sprintf(str,"getting ibr_best=%d",ibr_best); STATUS(str); }
1290 
1291          bar = DSET_ARRAY( new_dset , ibr_best ) ;
1292          memset( bar , 0 , sizeof(short)*nxyz ) ;
1293          for( iv=0 ; iv < nvox ; iv++ ) bar[indx[iv]] = ibest[iv] ;
1294          stataux[ibr_best] = 0.0 ;  /* no scaling */
1295 
1296          METERIZE(ibr_best) ;
1297       }
1298 
1299       /** perc brick */
1300 
1301       if( ibr_perc >= 0 ){
1302 
1303 if(PRINT_TRACING)
1304 { char str[256]; sprintf(str,"getting ibr_perc=%d",ibr_perc); STATUS(str); }
1305 
1306          if( top_perc > 0.0 ) EDIT_clip_float( top_perc , nvox , pbest ) ;
1307 
1308          topval = 0.0 ;
1309          for( iv=0 ; iv < nvox ; iv++ )
1310             if( fabs(pbest[iv]) > topval ) topval = fabs(pbest[iv]) ;
1311 
1312          bar = DSET_ARRAY( new_dset , ibr_perc ) ;
1313          memset( bar , 0 , sizeof(short)*nxyz ) ;
1314 
1315          if( topval > 0.0 ){
1316             topval = MRI_TYPE_maxval[MRI_short] / topval ;
1317             for( iv=0 ; iv < nvox ; iv++ )
1318                bar[indx[iv]] = (short)(topval * pbest[iv] + 0.499) ;
1319 
1320             stataux[ibr_perc] = 1.0/topval ;
1321          } else {
1322             stataux[ibr_perc] = 0.0 ;
1323          }
1324 
1325          METERIZE(ibr_perc) ;
1326       }
1327 
1328       /** pave brick [08 Sep 1999] */
1329 
1330       if( ibr_pave >= 0 ){
1331 
1332 if(PRINT_TRACING)
1333 { char str[256]; sprintf(str,"getting ibr_pave=%d",ibr_pave); STATUS(str); }
1334 
1335          if( top_perc > 0.0 ) EDIT_clip_float( top_perc , nvox , pabest ) ;
1336 
1337          topval = 0.0 ;
1338          for( iv=0 ; iv < nvox ; iv++ )
1339             if( fabs(pabest[iv]) > topval ) topval = fabs(pabest[iv]) ;
1340 
1341          bar = DSET_ARRAY( new_dset , ibr_pave ) ;
1342          memset( bar , 0 , sizeof(short)*nxyz ) ;
1343 
1344          if( topval > 0.0 ){
1345             topval = MRI_TYPE_maxval[MRI_short] / topval ;
1346             for( iv=0 ; iv < nvox ; iv++ )
1347                bar[indx[iv]] = (short)(topval * pabest[iv] + 0.499) ;
1348 
1349             stataux[ibr_pave] = 1.0/topval ;
1350          } else {
1351             stataux[ibr_pave] = 0.0 ;
1352          }
1353 
1354          METERIZE(ibr_pave) ;
1355       }
1356 
1357       /** ptop brick [03 Jan 2000] */
1358 
1359       if( ibr_ptop >= 0 ){
1360 
1361 if(PRINT_TRACING)
1362 { char str[256]; sprintf(str,"getting ibr_ptop=%d",ibr_ptop); STATUS(str); }
1363 
1364          if( top_perc > 0.0 ) EDIT_clip_float( top_perc , nvox , ptbest ) ;
1365 
1366          topval = 0.0 ;
1367          for( iv=0 ; iv < nvox ; iv++ )
1368             if( fabs(ptbest[iv]) > topval ) topval = fabs(ptbest[iv]) ;
1369 
1370          bar = DSET_ARRAY( new_dset , ibr_ptop ) ;
1371          memset( bar , 0 , sizeof(short)*nxyz ) ;
1372 
1373          if( topval > 0.0 ){
1374             topval = MRI_TYPE_maxval[MRI_short] / topval ;
1375             for( iv=0 ; iv < nvox ; iv++ )
1376                bar[indx[iv]] = (short)(topval * ptbest[iv] + 0.499) ;
1377 
1378             stataux[ibr_ptop] = 1.0/topval ;
1379          } else {
1380             stataux[ibr_ptop] = 0.0 ;
1381          }
1382 
1383          METERIZE(ibr_ptop) ;
1384       }
1385 
1386       /** base brick */
1387 
1388       if( ibr_base >= 0 ){
1389 
1390 if(PRINT_TRACING)
1391 { char str[256]; sprintf(str,"getting ibr_base=%d",ibr_base); STATUS(str); }
1392 
1393          topval = 0.0 ;
1394          for( iv=0 ; iv < nvox ; iv++ )
1395             if( fabs(bbest[iv]) > topval ) topval = fabs(bbest[iv]) ;
1396 
1397          bar = DSET_ARRAY( new_dset , ibr_base ) ;
1398          memset( bar , 0 , sizeof(short)*nxyz ) ;
1399 
1400          if( topval > 0.0 ){
1401             topval = MRI_TYPE_maxval[MRI_short] / topval ;
1402             for( iv=0 ; iv < nvox ; iv++ )
1403                bar[indx[iv]] = (short)(topval * bbest[iv] + 0.499) ;
1404 
1405             stataux[ibr_base] = 1.0/topval ;
1406          } else {
1407             stataux[ibr_base] = 0.0 ;
1408          }
1409 
1410          METERIZE(ibr_base) ;
1411       }
1412 
1413       /** aver brick [08 Sep 1999] */
1414 
1415       if( ibr_aver >= 0 ){
1416 
1417 if(PRINT_TRACING)
1418 { char str[256]; sprintf(str,"getting ibr_aver=%d",ibr_aver); STATUS(str); }
1419 
1420          topval = 0.0 ;
1421          for( iv=0 ; iv < nvox ; iv++ )
1422             if( fabs(avbest[iv]) > topval ) topval = fabs(avbest[iv]) ;
1423 
1424          bar = DSET_ARRAY( new_dset , ibr_aver ) ;
1425          memset( bar , 0 , sizeof(short)*nxyz ) ;
1426 
1427          if( topval > 0.0 ){
1428             topval = MRI_TYPE_maxval[MRI_short] / topval ;
1429             for( iv=0 ; iv < nvox ; iv++ )
1430                bar[indx[iv]] = (short)(topval * avbest[iv] + 0.499) ;
1431 
1432             stataux[ibr_aver] = 1.0/topval ;
1433          } else {
1434             stataux[ibr_aver] = 0.0 ;
1435          }
1436 
1437          METERIZE(ibr_aver) ;
1438       }
1439 
1440       /** topl brick [03 Jan 2000] */
1441 
1442       if( ibr_topl >= 0 ){
1443 
1444 if(PRINT_TRACING)
1445 { char str[256]; sprintf(str,"getting ibr_topl=%d",ibr_topl); STATUS(str); }
1446 
1447          topval = 0.0 ;
1448          for( iv=0 ; iv < nvox ; iv++ )
1449             if( fabs(tlbest[iv]) > topval ) topval = fabs(tlbest[iv]) ;
1450 
1451          bar = DSET_ARRAY( new_dset , ibr_topl ) ;
1452          memset( bar , 0 , sizeof(short)*nxyz ) ;
1453 
1454          if( topval > 0.0 ){
1455             topval = MRI_TYPE_maxval[MRI_short] / topval ;
1456             for( iv=0 ; iv < nvox ; iv++ )
1457                bar[indx[iv]] = (short)(topval * tlbest[iv] + 0.499) ;
1458 
1459             stataux[ibr_topl] = 1.0/topval ;
1460          } else {
1461             stataux[ibr_topl] = 0.0 ;
1462          }
1463 
1464          METERIZE(ibr_topl) ;
1465       }
1466 
1467       /** sigm brick [03 Jan 2000]**/
1468 
1469       if( ibr_sigm >= 0 ){
1470 
1471 if(PRINT_TRACING)
1472 { char str[256]; sprintf(str,"getting ibr_sigm=%d",ibr_sigm); STATUS(str); }
1473 
1474          topval = 0.0 ;
1475          for( iv=0 ; iv < nvox ; iv++ )
1476             if( fabs(sgbest[iv]) > topval ) topval = fabs(sgbest[iv]) ;
1477 
1478          bar = DSET_ARRAY( new_dset , ibr_sigm ) ;
1479          memset( bar , 0 , sizeof(short)*nxyz ) ;
1480 
1481          if( topval > 0.0 ){
1482             topval = MRI_TYPE_maxval[MRI_short] / topval ;
1483             for( iv=0 ; iv < nvox ; iv++ )
1484                bar[indx[iv]] = (short)(topval * sgbest[iv] + 0.499) ;
1485 
1486             stataux[ibr_sigm] = 1.0/topval ;
1487          } else {
1488             stataux[ibr_sigm] = 0.0 ;
1489          }
1490 
1491          METERIZE(ibr_sigm) ;
1492       }
1493 
1494    }  /* end of multiple reference case */
1495 
1496    /*** Set the brick factors for the new dataset,
1497         no matter how it was computed above.       ***/
1498 
1499 STATUS("setting brick_fac") ;
1500 
1501    (void) EDIT_dset_items( new_dset , ADN_brick_fac , stataux , ADN_none ) ;
1502 
1503 #ifndef DONT_USE_METER
1504    MCW_set_meter( meter , 100 ) ;
1505 #endif
1506 
1507    /*--- End of recursive updates; now free temporary workspaces ---*/
1508 
1509    for( ivec=0 ; ivec < ny_ref ; ivec++ ){
1510       free_PCOR_references(pc_ref[ivec]) ;
1511       free_PCOR_voxel_corr(pc_vc[ivec]) ;
1512    }
1513    free(pc_ref) ; free(pc_vc) ;
1514    if( aval  != NULL ) free(aval) ;
1515    if( rbest != NULL ) free(rbest) ;
1516    if( abest != NULL ) free(abest) ;
1517    if( ibest != NULL ) free(ibest) ;  /* 15 Dec 1997 */
1518    if( pbest != NULL ) free(pbest) ;  /* 16 Jan 1998 */
1519    if( bbest != NULL ) free(bbest) ;  /* 16 Jan 1998 */
1520    if( pval  != NULL ) free(pval) ;   /* 16 Jan 1998 */
1521    if( bval  != NULL ) free(bval) ;   /* 16 Jan 1998 */
1522    if( paval != NULL ) free(paval) ;  /* 08 Sep 1999 */
1523    if( avval != NULL ) free(avval) ;  /* 08 Sep 1999 */
1524    if( pabest!= NULL ) free(pabest);  /* 08 Sep 1999 */
1525    if( avbest!= NULL ) free(avbest);  /* 08 Sep 1999 */
1526    if( ptval != NULL ) free(ptval) ;  /* 03 Jan 2000 */
1527    if( tlval != NULL ) free(tlval) ;  /* 03 Jan 2000 */
1528    if( sgval != NULL ) free(sgval) ;  /* 03 Jan 2000 */
1529    if( ptbest!= NULL ) free(ptbest);  /* 03 Jan 2000 */
1530    if( tlbest!= NULL ) free(tlbest);  /* 03 Jan 2000 */
1531    if( sgbest!= NULL ) free(sgbest);  /* 03 Jan 2000 */
1532 
1533    /*-----------------------------------------------------*/
1534    /*--- 01 Feb 2000: execute user specified functions ---*/
1535 
1536 ucode_stuff:
1537 
1538 #define MAXUFUN 64  /* should be at least sizeof(int) */
1539 #define MAXTS   32  /* number of timeseries to process at once */
1540 
1541    if( ucode != 0 ){
1542       MCW_function_list * rlist = &(GLOBAL_library.registered_fim) ;
1543       int uuse[MAXUFUN] , nbrik[MAXUFUN] , brik1[MAXUFUN] ;
1544       void * udata[MAXUFUN] ;
1545       generic_func * ufunc[MAXUFUN] ;
1546       int nuse , uu , newbrik , oldbrik ;
1547       FIMdata fd ;
1548       MRI_IMAGE * tsim ;
1549       float     * tsar , * val , ** vbr ;
1550       short     * sar ;
1551       int         nts , jts , nbad=0 ;
1552       MRI_IMARR * imar ;
1553 
1554       /* mark which ones to execute */
1555 
1556       for( newbrik=nuse=uu=0 ; uu < rlist->num && nuse < MAXUFUN ; uu++ ){
1557          if( (ucode & (1<<uu)) != 0 ){
1558             uuse [nuse] = uu ;
1559             ufunc[nuse] = rlist->funcs[uu] ;     /* user_func for this func */
1560             nbrik[nuse] = rlist->flags[uu] ;     /* new bricks for this func */
1561             udata[nuse] = rlist->func_data[uu] ; /* user_data for this func */
1562             brik1[nuse] = newbrik ;              /* index of 1st brick */
1563             newbrik    += nbrik[nuse] ;          /* total number of new bricks */
1564             nuse++ ;
1565          }
1566       }
1567 
1568       if( nuse == 0 ) goto final_exit ; /* shouldn't happen */
1569 
1570       /* do the initialization calls to the user_func functions */
1571 
1572       fd.ref_ts = ref_ts ;
1573       fd.ort_ts = ort_ts ;
1574       fd.nvox   = nvox   ;
1575       fd.ignore = im3d->fimdata->init_ignore ;
1576       fd.polort = polort ;
1577 
1578 #ifndef DONT_USE_METER
1579       MCW_set_meter( meter , 0 ) ; meter_pold = 0.0 ;
1580 #endif
1581 
1582       for( uu=0 ; uu < nuse ; uu++ )
1583 #if 0
1584          ufunc[uu]( ntime , NULL , udata[uu] , nbrik[uu] , (void *)(&fd) ) ;
1585 #else
1586          AFNI_CALL_fim_function( ufunc[uu] ,
1587                                  ntime, NULL, udata[uu], nbrik[uu], &fd ) ;
1588 #endif
1589 
1590       /* loop over voxels,
1591          assemble time series,
1592          call functions to put results in val[],
1593          store float outputs in vbr[][]          */
1594 
1595       vbr = (float **) malloc(sizeof(float *)*newbrik) ;
1596       for( iv=0 ; iv < newbrik ; iv++ )
1597          vbr[iv] = (float *) malloc(sizeof(float)*nvox) ;
1598 
1599       val = (float *) malloc(sizeof(float)*newbrik) ;
1600 
1601       for( iv=0 ; iv < nvox ; iv+=MAXTS ){
1602          nts  = MIN( MAXTS , nvox-iv ) ;
1603          imar = THD_extract_many_series( nts,indx+iv , dset_time ) ;
1604 
1605          for( jts=0 ; jts < nts ; jts++ ){
1606             tsim = IMARR_SUBIMAGE(imar,jts) ;                     /* data */
1607             tsar = MRI_FLOAT_PTR(tsim) ;
1608 
1609             for( uu=0 ; uu < nuse ; uu++ ){
1610 #if 0
1611                ufunc[uu]( ntime , tsar ,                          /* func */
1612                           udata[uu] , nbrik[uu] , (void *) val ) ;
1613 #else
1614                AFNI_CALL_fim_function( ufunc[uu] ,
1615                                        ntime, tsar, udata[uu], nbrik[uu], val ) ;
1616 #endif
1617 
1618                for( it=0 ; it < nbrik[uu] ; it++ )             /* storage */
1619                   vbr[it+brik1[uu]][iv+jts] = val[it] ;
1620             }
1621          }
1622 
1623          DESTROY_IMARR(imar) ;                        /* garbage disposal */
1624 
1625 #ifndef DONT_USE_METER
1626          meter_perc = (int) ( 100.0 * iv / nvox ) ;
1627          if( meter_perc != meter_pold ){
1628             MCW_set_meter( meter , meter_perc ) ;
1629             meter_pold = meter_perc ;
1630          }
1631 #endif
1632       }
1633       free(val) ;  /* no longer needed */
1634 #ifndef DONT_USE_METER
1635       MCW_set_meter( meter , 100 ) ;
1636 #endif
1637 
1638       /* if necessary, make the new dataset now */
1639 
1640       if( new_dset != NULL ){
1641          oldbrik = DSET_NVALS(new_dset) ;  /* number of bricks it has now */
1642       } else {
1643          oldbrik = 0 ;
1644 
1645          new_dset = EDIT_empty_copy( dset_time ) ;
1646 
1647          EDIT_dset_items( new_dset ,
1648                              ADN_prefix      , new_prefix ,
1649                              ADN_malloc_type , DATABLOCK_MEM_MALLOC ,
1650                              ADN_type        , ISHEAD(dset_time)
1651                                                ? HEAD_FUNC_TYPE : GEN_FUNC_TYPE ,
1652                              ADN_func_type   , FUNC_BUCK_TYPE ,
1653                              ADN_nvals       , newbrik ,
1654                              ADN_datum_all   , MRI_short ,
1655                              ADN_ntt         , 0 ,
1656                           ADN_none ) ;
1657       }
1658 
1659       /* for each output brick:
1660            make short space for it,
1661            scale and stored floats into this space ,
1662            attach it to the output dataset as a new brick */
1663 
1664       for( iv=0 ; iv < newbrik ; iv++ ){
1665          tsar   = vbr[iv] ;              /* float data */
1666          topval = 0.0 ;                  /* find range of data */
1667 
1668          nbad += thd_floatscan( nvox , tsar ) ;  /* 08 Aug 2000 */
1669 
1670          for( it=0 ; it < nvox ; it++ )
1671             if( fabs(tsar[it]) > topval ) topval = fabs(tsar[it]) ;
1672 
1673          sar = (short *) calloc(sizeof(short),nxyz) ;  /* new brick */
1674 
1675          if( topval > 0.0 ){                           /* scale to shorts */
1676             topval = MRI_TYPE_maxval[MRI_short] / topval ;
1677             for( it=0 ; it < nvox ; it++ )
1678                sar[indx[it]] = (short)(topval * tsar[it] + 0.499) ;
1679 
1680             topval = 1.0/topval ;  /* scale factor */
1681          }
1682 
1683          free(tsar) ;
1684 
1685          if( oldbrik > 0 ){
1686             EDIT_add_brick( new_dset , MRI_short , topval , sar ) ;
1687          } else {
1688             mri_fix_data_pointer( sar , DSET_BRICK(new_dset,iv) ) ;
1689             EDIT_BRICK_FACTOR( new_dset , iv , topval ) ;
1690          }
1691       }
1692       free(vbr) ;
1693 
1694       /* do the ending calls to user_func */
1695 
1696       for( uu=0 ; uu < nuse ; uu++ )
1697 #if 0
1698          ufunc[uu]( -(brik1[uu]+oldbrik) , NULL ,
1699                     udata[uu] , nbrik[uu] , (void *) new_dset ) ;
1700 #else
1701          AFNI_CALL_fim_function( ufunc[uu] ,
1702                                  -(brik1[uu]+oldbrik) , NULL ,
1703                                  udata[uu] , nbrik[uu] , new_dset ) ;
1704 #endif
1705 
1706       if( nbad > 0 )
1707          fprintf(stderr,
1708                  "++ Warning: %d bad floats computed by user fimfuncs!\n\a",
1709                  nbad ) ;
1710 
1711    } /* 01 Feb 2000: end of user_func addition to FIMming */
1712 
1713 final_exit:
1714    free(vval) ; free(indx) ;  /* can finally free these */
1715 
1716    /*--- Return new dataset ---*/
1717 
1718 #ifndef DONT_USE_METER
1719    MCW_popdown_meter(meter) ;
1720 #endif
1721 
1722    RETURN(new_dset) ;
1723 }
1724 
1725 /*--------------------------------------------------------------------------*/
1726 
1727 #ifdef USE_FUNC_FIM
AFNI_fimmer_menu_CB(Widget w,XtPointer cd,XtPointer cbs)1728 void AFNI_fimmer_menu_CB( Widget w , XtPointer cd , XtPointer cbs )
1729 {
1730    FIM_menu * fmenu = (FIM_menu *) cd ;
1731    Three_D_View * im3d = (Three_D_View *) fmenu->parent ;
1732 
1733 ENTRY("AFNI_fimmer_menu_CB") ;
1734 
1735    if( ! IM3D_OPEN(im3d) || im3d->type != AFNI_3DDATA_VIEW ) EXRETURN ;
1736 
1737    /*** Pick reference ***/
1738 
1739    if( w == fmenu->fim_pickref_pb ){
1740       if( IMARR_COUNT(GLOBAL_library.timeseries) > 0 ){
1741          int init_ts = AFNI_ts_in_library( im3d->fimdata->fimref ) ;
1742 
1743          MCW_choose_timeseries( fmenu->fim_cbut , "FIM Reference Vector" ,
1744                                 GLOBAL_library.timeseries , init_ts ,
1745                                 AFNI_fimmer_pickref_CB , (XtPointer) im3d ) ;
1746       } else {
1747          (void) MCW_popup_message(
1748                    fmenu->fim_cbut ,
1749                    "No timeseries library\nexists to pick from!" ,
1750                    MCW_USER_KILL | MCW_TIMER_KILL ) ;
1751       }
1752    }
1753 
1754    /*** Pick ort ***/
1755 
1756    else if( w == fmenu->fim_pickort_pb ){
1757       if( IMARR_COUNT(GLOBAL_library.timeseries) > 0 ){
1758          int init_ts = AFNI_ts_in_library( im3d->fimdata->fimort ) ;
1759 
1760          MCW_choose_timeseries( fmenu->fim_cbut , "FIM Ort Vector" ,
1761                                 GLOBAL_library.timeseries , init_ts ,
1762                                 AFNI_fimmer_pickort_CB , (XtPointer) im3d ) ;
1763       } else {
1764          (void) MCW_popup_message(
1765                    fmenu->fim_cbut ,
1766                    "No timeseries library\nexists to pick from!" ,
1767                    MCW_USER_KILL | MCW_TIMER_KILL ) ;
1768       }
1769    }
1770 
1771    /*** execute FIM ***/
1772 
1773    else if( w == fmenu->fim_execute_pb ){
1774       AFNI_fimmer_execute( im3d , 0 , 0 ) ;
1775    }
1776 
1777    /*** Ignore stuff ***/
1778 
1779    else if( w == fmenu->fim_ignore_down_pb ){
1780       if( im3d->fimdata->init_ignore > 0 )
1781          AFNI_fimmer_setignore( im3d , im3d->fimdata->init_ignore - 1 ) ;
1782    }
1783 
1784    else if( w == fmenu->fim_ignore_up_pb ){
1785       AFNI_fimmer_setignore( im3d , im3d->fimdata->init_ignore + 1 ) ;
1786    }
1787 
1788    else if( w == fmenu->fim_ignore_choose_pb ){
1789 #ifdef USE_OPTMENUS
1790       AFNI_fimmer_ignore_choose_CB( fmenu->fim_ignore_choose_av , im3d ) ;
1791 #else
1792       MCW_choose_integer( fmenu->fim_cbut , "Initial Ignore" ,
1793                           0 , 999 , im3d->fimdata->init_ignore ,
1794                           AFNI_fimmer_ignore_choose_CB , (XtPointer) im3d ) ;
1795 #endif
1796    }
1797 
1798    /*** Pick a time dependent dataset.
1799         This code is mostly taken from AFNI_choose_dataset_CB ***/
1800 
1801 #define STRLIST_SIZE (THD_MAX_PREFIX+12)
1802 
1803    else if( w == fmenu->fim_pickdset_pb ){
1804       static char * strlist[THD_MAX_SESSION_SIZE] ;  /* strings to choose between */
1805       static int first_call = 1 ;                    /* initialization flag */
1806 
1807       int num_str , ii , init_str=-1 , vv , jj ;
1808       THD_3dim_dataset *temp_dset = NULL;            /* temporary dataset from session list */
1809 
1810       /** initialize string array **/
1811 
1812       if( GLOBAL_library.have_dummy_dataset ){ BEEPIT ; EXRETURN ; }
1813 
1814       if( first_call ){
1815         for( ii=0 ; ii < THD_MAX_SESSION_SIZE ; ii++ )
1816           strlist[ii] = (char*)XtMalloc( sizeof(char) * (STRLIST_SIZE+1) ) ;
1817         first_call = 0 ;
1818       }
1819 
1820       /** scan through anats and find 3D+t datasets **/
1821 
1822       num_str = 0 ;
1823       vv      = im3d->vinfo->view_type ;  /* current view */
1824       for( ii=0 ; ii < im3d->ss_now->num_dsset ; ii++ ){
1825 
1826          if( DSET_GRAPHABLE(GET_SESSION_DSET(im3d->ss_now, ii, vv)) { /* template session list - 2010 */
1827             temp_dset = GET_SESSION_DSET(im3d->ss_now, ii, vv);
1828             /* im3d->ss_now->dsset_xform_table[ii][vv]) ){ */ /** have one! **/
1829             MCW_strncpy( strlist[num_str] ,
1830                          temp_dset->dblk->diskptr->prefix ,
1831                          THD_MAX_PREFIX ) ;
1832 
1833             jj = ii ;  /* most recent */
1834 
1835             if( im3d->fimdata->fimdset == temp_dset )  /* same? */
1836                init_str = num_str ;
1837 
1838             num_str ++ ;
1839          }
1840       }
1841 
1842       /** make the choice **/
1843 
1844       if( num_str <= 0 ){                    /* nothing to choose from */
1845 
1846          (void) MCW_popup_message(
1847                    fmenu->fim_cbut ,
1848                       "No time dependent (3D+time)\n"
1849                       "datasets exist to choose from!" ,
1850                    MCW_USER_KILL | MCW_TIMER_KILL ) ;
1851 
1852       } else if( num_str == 1 ){             /* Hobson's choice */
1853          if(temp_dset != NULL){
1854            im3d->fimdata->fimdset = temp_dset ;
1855            ALLOW_COMPUTE_FIM(im3d) ;
1856          }
1857 
1858       } else {                               /* an actual choice to make! */
1859 
1860          MCW_choose_strlist( fmenu->fim_cbut , "3D+time Dataset" ,
1861                              num_str , init_str , strlist ,
1862                              AFNI_fimmer_dset_choose_CB , (XtPointer) im3d ) ;
1863       }
1864    }
1865 
1866    /*** Unimplemented Button ***/
1867 
1868    else {
1869       BEEPIT ;
1870    }
1871 
1872    /*--- Done!!! ---*/
1873 
1874    EXRETURN ;
1875 }
1876 #endif
1877 
1878 /*---------------------------------------------------------------------------*/
1879 
1880 #ifdef USE_FUNC_FIM
1881 
1882 #ifdef USE_OPTMENUS
1883 void AFNI_fimmer_ignore_choose_CB( MCW_arrowval * cbs , XtPointer cd )
1884 #else
1885 void AFNI_fimmer_ignore_choose_CB( Widget wcaller, XtPointer cd, MCW_choose_cbs *cbs )
1886 #endif
1887 {
1888    Three_D_View *im3d = (Three_D_View *) cd ;
1889 
1890    if( ! IM3D_VALID(im3d) ) return ;
1891 
1892    AFNI_fimmer_setignore( im3d , cbs->ival ) ;
1893    return ;
1894 }
1895 #endif
1896 
1897 #ifdef USE_FUNC_FIM
1898 void AFNI_fimmer_dset_choose_CB( Widget wcaller , XtPointer cd , MCW_choose_cbs *cbs )
1899 {
1900    Three_D_View * im3d = (Three_D_View *) cd ;
1901    int ii , vv , num_str ;
1902 
1903    if( ! IM3D_VALID(im3d) ) return ;
1904    if( GLOBAL_library.have_dummy_dataset ){ BEEPIT ; EXRETURN ; }
1905 
1906    num_str = 0 ;
1907    vv      = im3d->vinfo->view_type ;
1908    for( ii=0 ; ii < im3d->ss_now->num_dsset ; ii++ ){
1909       if( DSET_GRAPHABLE(GET_SESSION_DSET(im3d->ss_now, ii, vv)) ){
1910          if( num_str == cbs->ival ) break ;
1911          num_str ++ ;
1912       }
1913    }
1914 
1915    if( ii < im3d->ss_now->num_dsset ){
1916       im3d->fimdata->fimdset = GET_SESSION_DSET(im3d->ss_now, ii, vv) ;
1917       ALLOW_COMPUTE_FIM(im3d) ;
1918    } else {
1919       fprintf(stderr,"\n*** Illegal choice in AFNI_fimmer_dset_choose_CB:"
1920                      "\n*** cbs->ival = %d  but num_str = %d\a\n",
1921                      cbs->ival , num_str ) ;
1922    }
1923 
1924    return ;
1925 }
1926 #endif
1927 
1928 /*---------------------------------------------------------------------------*/
1929 
1930 void AFNI_fimmer_execute( Three_D_View *im3d , int code, int ucode )
1931 {
1932    THD_3dim_dataset *new_dset , *dset_time ;
1933    MRI_IMAGE *ref_ts , *ort_ts ;
1934    THD_session *sess ;
1935    int ifunc ;
1936 
1937 ENTRY("AFNI_fimmer_execute") ;
1938 
1939    if( ! IM3D_OPEN(im3d) || im3d->type != AFNI_3DDATA_VIEW ) EXRETURN ;
1940    if( GLOBAL_library.have_dummy_dataset ){ BEEPIT ; EXRETURN ; }
1941 
1942 #if 0
1943    dset_time = im3d->anat_now ;
1944 #else
1945    dset_time = im3d->fimdata->fimdset ;
1946 #endif
1947 
1948    if( ! DSET_GRAPHABLE(dset_time) ){ BEEPIT ; EXRETURN ; }
1949 
1950    ref_ts = im3d->fimdata->fimref ;
1951    ort_ts = im3d->fimdata->fimort ;
1952    if( ref_ts == NULL ){ BEEPIT ; EXRETURN ; }
1953 
1954    sess = im3d->ss_now ;
1955    if( ! ISVALID_SESSION(sess) || sess->num_dsset >= THD_MAX_SESSION_SIZE ){
1956       BEEPIT ; EXRETURN ;
1957    }
1958 
1959    SHOW_AFNI_PAUSE ;
1960 
1961    /*--- Start lots of CPU time ---*/
1962 
1963    new_dset = AFNI_fimmer_compute( im3d, dset_time, ref_ts, ort_ts,
1964                                               sess, code,ucode ) ;
1965 
1966    /*--- End lots of CPU time ---*/
1967 
1968    if( new_dset == NULL ){
1969      SHOW_AFNI_READY ; BEEPIT ; EXRETURN ;
1970    }
1971 
1972    AFNI_fimmer_redisplay( 1 , im3d , new_dset ) ;
1973    AFNI_SEE_FUNC_ON(im3d) ;
1974 
1975    /* Sep 1999: add some history */
1976 
1977    { char his[512] ; int hh ;
1978      tross_Copy_History( dset_time , new_dset ) ;
1979      sprintf(his,"afni FIM: 3D+time=%s ignore=%d polort=%d",
1980              DSET_HEADNAME(dset_time) ,
1981              im3d->fimdata->init_ignore , im3d->fimdata->polort ) ;
1982      if( ref_ts->name != NULL ){
1983         hh = strlen(his) ; sprintf(his+hh," ref=%s",ref_ts->name) ;
1984      }
1985      if( ort_ts != NULL && ort_ts->name != NULL ){
1986         hh = strlen(his) ; sprintf(his+hh," ort=%s",ort_ts->name) ;
1987      }
1988      tross_Append_History( new_dset , his ) ;
1989    }
1990 
1991    /* 15 Nov 2007: actually add ref & ort time series data attributes */
1992 
1993    if( !AFNI_noenv("AFNI_FIM_SAVEREF") ){
1994      char *istr ;
1995      istr = mri_1D_tostring( ref_ts ) ;
1996      if( istr != NULL ){
1997        THD_set_string_atr(new_dset->dblk,"AFNI_FIM_REF",istr) ; free(istr) ;
1998      }
1999      istr = mri_1D_tostring( ort_ts ) ;
2000      if( istr != NULL ){
2001        THD_set_string_atr(new_dset->dblk,"AFNI_FIM_ORT",istr) ; free(istr) ;
2002      }
2003    }
2004 
2005    /* write to disk */
2006 
2007    DSET_overwrite(new_dset) ;
2008 
2009    /*** At this point, FIM is computed and written to disk!!! ***/
2010 
2011    AFNI_force_adoption( sess , False ) ;
2012    AFNI_make_descendants( GLOBAL_library.sslist ) ;
2013 
2014    SHOW_AFNI_READY ;
2015    EXRETURN ;
2016 }
2017 
2018 /*-----------------------------------------------------------------------------*/
2019 
2020 void AFNI_fimmer_redisplay( int first_call ,
2021                             Three_D_View * im3d , THD_3dim_dataset * new_dset )
2022 {
2023    int ifunc ;
2024    THD_session * sess = im3d->ss_now ;
2025 
2026 ENTRY("AFNI_fimmer_redisplay") ;
2027 
2028    if( first_call ){
2029 
2030 STATUS("first_call mode") ;
2031 
2032       /*** Fit the new dataset into its place in the session ***/
2033 
2034       ifunc = sess->num_dsset ;
2035       SET_SESSION_DSET(new_dset, sess, ifunc, new_dset->view_type);
2036 /*      sess->dsset_xform_table[ifunc][new_dset->view_type] = new_dset ;*/
2037       sess->num_dsset ++ ;
2038       im3d->vinfo->func_num = ifunc ;
2039 
2040 STATUS("loading statistics") ;
2041       THD_load_statistics( new_dset ) ;
2042 
2043       im3d->vinfo->fim_index = 0 ;
2044       im3d->vinfo->thr_index = 1 ;
2045       if( DSET_NVALS(new_dset) == 1 ) im3d->vinfo->thr_index = 0 ;
2046 
2047       AFNI_initialize_view( im3d->anat_now , im3d ) ;
2048 
2049    } else {
2050 
2051 STATUS("redisplay mode") ;
2052 
2053       /*** Just redisplay the new dataset ***/
2054 
2055 STATUS("loading statistics") ;
2056       THD_load_statistics( new_dset ) ;
2057       AFNI_reset_func_range( im3d ) ;
2058       AFNI_set_thr_pval( im3d ) ;
2059 
2060       AFNI_redisplay_func( im3d ) ;  /* 05 Mar 2002 */
2061    }
2062 
2063    EXRETURN ;
2064 }
2065 
2066 /*--------------------------------------------------------------------
2067   Routines to deal with widgets that are allowed to be active
2068   during 'real-time' operations.
2069 ----------------------------------------------------------------------*/
2070 
2071 void AFNI_add_interruptable( Widget w )
2072 {
2073    Window wwin , wroot , wpar ;
2074    int    ii ;
2075    Window *     wchild ;
2076    unsigned int nchild ;
2077 
2078    /* input Widget is NULL is the signal to reset everything */
2079 
2080    if( w == NULL ){
2081       if( GLOBAL_library.interruptables.windows != NULL ){ /* just toss this list */
2082          DESTROY_XTARR( GLOBAL_library.interruptables.windows ) ;
2083          GLOBAL_library.interruptables.windows = NULL ;
2084       }
2085 
2086       if( GLOBAL_library.interruptables.widgets != NULL ){ /* must reset cursors */
2087          for( ii=0 ; ii < GLOBAL_library.interruptables.widgets->num ; ii++ )
2088             MCW_set_widget_cursor( GLOBAL_library.interruptables.widgets->ar[ii] , 0 );
2089 
2090          DESTROY_XTARR( GLOBAL_library.interruptables.widgets ) ;
2091          GLOBAL_library.interruptables.widgets = NULL ;
2092       }
2093       return ;
2094    }
2095 
2096    /* non-NULL widget --> add it and its sub-windows to the list */
2097 
2098    if( ! XtIsRealized(w) ) return ;
2099    wwin = XtWindowOfObject(w) ; if( wwin == (Window) NULL ) return ;
2100 
2101    /* get list of all sub-windows into wchild */
2102 
2103    nchild = 0 ;
2104    (void) XQueryTree( XtDisplay(w) , wwin , &wroot , &wpar , &wchild , &nchild ) ;
2105 
2106    if( GLOBAL_library.interruptables.windows == NULL )       /* initialize lists */
2107       INIT_XTARR( GLOBAL_library.interruptables.windows ) ;
2108 
2109    if( GLOBAL_library.interruptables.widgets == NULL )
2110       INIT_XTARR( GLOBAL_library.interruptables.widgets ) ;
2111 
2112    ADDTO_XTARR( GLOBAL_library.interruptables.windows , wwin ) ;  /* add to lists */
2113    ADDTO_XTARR( GLOBAL_library.interruptables.widgets , w    ) ;
2114 
2115    for( ii=0 ; ii < nchild ; ii++ )
2116       ADDTO_XTARR( GLOBAL_library.interruptables.windows , wchild[ii] ) ;
2117 
2118    XFree( wchild ) ;  /* return this to Xlib */
2119 
2120    NORMAL_cursorize( w) ;
2121 
2122    return ;
2123 }
2124 
2125 /*---------------------------------------------------------------------------*/
2126 
2127 void AFNI_process_interrupts( Widget w )
2128 {
2129    Display * dis = XtDisplay(w) ;
2130    XEvent ev ;
2131    int ii , nwin ;;
2132 
2133    /* make sure server has everything from us, then make sure display is OK */
2134 
2135    XFlush( dis ) ; XmUpdateDisplay( w ) ;
2136 
2137    /* if no windows are set to allow interrupts, then go home to mother */
2138 
2139    if( GLOBAL_library.interruptables.windows      == NULL ||
2140        GLOBAL_library.interruptables.windows->num == 0      ) return ;
2141 
2142    nwin = GLOBAL_library.interruptables.windows->num ;
2143 
2144    /* check for events;
2145       if they are in a window on our list, let Xt handle them;
2146       loop until all pending events have been handled or discarded */
2147 
2148    while( XCheckMaskEvent( dis ,
2149                            ButtonPressMask  | ButtonReleaseMask |
2150                            ButtonMotionMask | PointerMotionMask |
2151                            KeyPressMask     | KeyReleaseMask     , &ev ) ){
2152 
2153       for( ii=0 ; ii < nwin ; ii++ ){
2154          if( ev.xany.window ==
2155              (Window) GLOBAL_library.interruptables.windows->ar[ii] ){
2156 
2157             XtDispatchEvent( &ev ) ;  /* was on our list! */
2158             break ;
2159          }
2160       }
2161 
2162       if( ii == nwin ) BEEPIT ;              /* beep for non-allowed event */
2163       XUngrabPointer( dis , CurrentTime ) ;  /* 17 Jun 2005 */
2164    }
2165 
2166    return ;
2167 }
2168 
2169 /*---------------------------------------------------------------------------*/
2170 
2171 #ifdef USE_FUNC_FIM
2172 void AFNI_fimmer_fix_optmenu( Three_D_View * im3d )
2173 {
2174    int igtop , ntime ;
2175 
2176 ENTRY("AFNI_fimmer_fix_optmenu") ;
2177 
2178    if( ! IM3D_VALID(im3d) || im3d->type != AFNI_3DDATA_VIEW ) EXRETURN ;
2179 
2180    /** fim ignoration **/
2181 
2182    if( im3d->fimdata->fimdset == NULL ) EXRETURN ;
2183    ntime = DSET_NUM_TIMES(im3d->fimdata->fimdset) ; if( ntime < 2 ) EXRETURN ;
2184 
2185    igtop = MIN( ntime-3 , 99 ) ;
2186    igtop = MAX( igtop , 1 ) ;
2187 
2188    if( im3d->vwid->func->fim_menu->fim_ignore_choose_av->imax != igtop ){
2189 
2190 if(PRINT_TRACING)
2191 { char str[256] ;
2192   sprintf(str,"refit 0..%d, init %d",igtop,im3d->fimdata->init_ignore) ;
2193   STATUS(str) ; }
2194 
2195       refit_MCW_optmenu( im3d->vwid->func->fim_menu->fim_ignore_choose_av ,
2196                          0 , igtop , im3d->fimdata->init_ignore, 0,
2197                          NULL , NULL ) ;
2198    } else {
2199 
2200 if(PRINT_TRACING)
2201 { char str[256] ;
2202   sprintf(str,"assign init %d",im3d->fimdata->init_ignore) ;
2203   STATUS(str) ; }
2204 
2205       AV_assign_ival( im3d->vwid->func->fim_menu->fim_ignore_choose_av ,
2206                       im3d->fimdata->init_ignore ) ;
2207    }
2208 
2209    EXRETURN ;
2210 }
2211 #endif
2212