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