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 #include "mrilib.h"
8
9 /** Error messaging **/
10
11 #undef EDERR
12 #define EDERR(str) \
13 do{ ERROR_message("EDIT_dset_items[%d]: %s\n",ncall,str); errnum++; } while(0)
14
15 #undef EDERR_int
16 #define EDERR_int(str,zqq) \
17 do{ ERROR_message("EDIT_dset_items[%d]: %s : %d\n",ncall,str,zqq); errnum++; } while(0)
18
19
20 /* Remove +view.BRIK ness ZSS Feb 2012 */
21 #define STRING_DEVIEW_DEEXT_BRICK(fname) { \
22 if (STRING_HAS_SUFFIX((fname),"+orig.BRIK") || \
23 STRING_HAS_SUFFIX((fname),"+acpc.BRIK") || \
24 STRING_HAS_SUFFIX((fname),"+tlrc.BRIK") ) { /* ZSS Nov 2011 */ \
25 (fname)[ll-10] = '\0' ; \
26 } else if (STRING_HAS_SUFFIX((fname),"+orig.BRIK.gz") || \
27 STRING_HAS_SUFFIX((fname),"+acpc.BRIK.gz") || \
28 STRING_HAS_SUFFIX((fname),"+tlrc.BRIK.gz") ) {/* ZSS Feb 2012 */ \
29 (fname)[ll-13] = '\0' ; \
30 } \
31 }
32
33 /*-----------------------------------------------------------------------*/
34 /*! Edit some internals of a dataset. Notice that it is possible to
35 create a dataset which is inconsistent. Note also that some operations
36 cannot be performed on a dataset containing actual data -- for example,
37 you cannot change the types of sub-bricks if they already are attached
38 to data arrays!
39
40 This routine uses the <stdarg.h> variable argument interface.
41 The first argument is a pointer to the dataset to edit.
42 All succeeding arguments are pairs indicating which internal item
43 to edit, and the new value for that item. The first entry of a pair
44 must be one of the ADN_ entries defined in editvol.h. The type of the
45 second entry of a pair depends on the particular item.
46 [*** WARNING: due to C automatic 'type promotion', you cannot use
47 float as the type to extract from the list -- you must use double!]
48
49 Finally, the end of the argument list is found by the last argument
50 being the special code ADN_none (0).
51
52 The return value is the number of errors detected (hopefully, 0).
53 -------------------------------------------------------------------------*/
54
EDIT_dset_items(THD_3dim_dataset * dset,...)55 int EDIT_dset_items( THD_3dim_dataset *dset , ... )
56 {
57 va_list vararg_ptr ;
58 int flag_arg , errnum = 0 ;
59 int redo_bricks , redo_daxes , redo_taxis , ii ;
60 void *dummy ;
61 int iarg ;
62 static int ncall=0 ; /* 20 Dec 2005 */
63
64 /**----- variables to flag and store presence of arguments -----**/
65
66 int new_prefix = 0; char * prefix = NULL ;
67 int new_directory_name= 0; char * directory_name = NULL ;
68 int new_brick_fac = 0; float * brick_fac = NULL ;
69 int new_malloc_type = 0; int malloc_type = ILLEGAL_TYPE;
70 int new_datum_all = 0; int datum_all = ILLEGAL_TYPE;
71 int new_datum_array = 0; int * datum_array = NULL ;
72 int new_nvals = 0; int nvals = 0 ;
73 int new_nxyz = 0; THD_ivec3 nxyz ;
74 int new_xyzdel = 0; THD_fvec3 xyzdel ;
75 int new_xyzorg = 0; THD_fvec3 xyzorg ;
76 int new_xyzorient = 0; THD_ivec3 xyzorient ;
77 int new_to_dicomm = 0; THD_mat33 to_dicomm ;
78 int new_ntt = 0; int ntt = 0 ;
79 int new_ttorg = 0; float ttorg = 0.0 ;
80 int new_ttdel = 0; float ttdel = 0.0 ;
81 int new_ttdur = 0; float ttdur = 0.0 ;
82 int new_nsl = 0; int nsl = 0 ;
83 int new_zorg_sl = 0; float zorg_sl = 0.0 ;
84 int new_dz_sl = 0; float dz_sl = 0.0 ;
85 int new_toff_sl = 0; float * toff_sl = NULL ;
86 int new_type = 0; int type = ILLEGAL_TYPE;
87 int new_view_type = 0; int view_type = ILLEGAL_TYPE;
88 int new_func_type = 0; int func_type = ILLEGAL_TYPE;
89 int new_label1 = 0; char * label1 = NULL ;
90 int new_label2 = 0; char * label2 = NULL ;
91 int new_self_name = 0; char * self_name = NULL ;
92 int new_warp_parent = 0; THD_3dim_dataset *warp_parent = NULL ;
93 int new_anat_parent = 0; THD_3dim_dataset *anat_parent = NULL ;
94 int new_stat_aux = 0; float * stat_aux = NULL ;
95 int new_warp = 0; THD_warp * warp = NULL ;
96 int new_tunits = 0; int tunits = ILLEGAL_TYPE;
97 int new_keywords = 0; char * keywords = NULL ;
98
99 /* 30 Nov 1997 */
100
101 int new_brick_label_one = 0 ; char * brick_label_one = NULL ;
102 int brick_label_one_iv = -1 ;
103
104 int new_brick_fac_one = 0 ; float brick_fac_one = 0.0 ;
105 int brick_fac_one_iv = -1 ;
106
107 int new_brick_stataux_one = 0 ; float * brick_stataux_one = NULL ;
108 int brick_stataux_one_iv = -1 ;
109
110 int new_brick_keywords_one = 0 ; char * brick_keywords_one = NULL ;
111 int brick_keywords_one_iv = -1 ;
112
113 /* 19 Dec 2005 */
114
115 int new_ijk_to_dicom = 0; mat44 ijk_to_dicom ;
116
117 /* 14 July 2006 - check compression mode for NIFTI separately */
118 /* 1 June 2021 - never auto-compress NIFTI [rickr] */
119 /* int cmode = COMPRESS_NOFILE; */
120
121 int new_smode=STORAGE_UNDEFINED; /* ZSS Feb 2012 */
122
123
124 /****---------------------- Sanity Check ----------------------****/
125
126 ENTRY("EDIT_dset_items") ;
127
128 ncall++ ; /* 20 Dec 2005: to keep track of number of calls for EDERR */
129
130 if( ! ISVALID_3DIM_DATASET(dset) ){ /* bad data */
131 EDERR("invalid input dataset"); RETURN(errnum);
132 }
133
134 /****----------- Scan input argument list;
135 - Load data into locals (va_arg);
136 - Check for legal values;
137 - Flag its presence (the new_ variables);
138 - Carry out simple processing that doesn't
139 depend on the presence of other arguments. ---------****/
140
141 va_start( vararg_ptr , dset ) ; /** Initialize arg reading **/
142 iarg = 1 ;
143 memset(&ijk_to_dicom, 0, sizeof(mat44));
144 memset(&xyzorient, 0, sizeof(THD_ivec3));
145 memset(&xyzorg, 0, sizeof(THD_fvec3));
146 memset(&xyzdel, 0, sizeof(THD_fvec3));
147 memset(&nxyz, 0, sizeof(THD_ivec3));
148 do{
149 flag_arg = va_arg( vararg_ptr , int ) ; /** Get next arg **/
150 if( flag_arg == ADN_none ) break ; /** No more args! **/
151 #if 0
152 fprintf(stderr,"EDIT_dset_items: iarg=%d flag_arg=%d\n",iarg,flag_arg) ;
153 #endif
154 iarg++ ;
155
156 switch( flag_arg ){
157
158 default:{
159 int iv ;
160 char str[128] ;
161
162 /** 30 Nov 1997: check for special cases **/
163
164 iv = flag_arg - ADN_brick_label_one ;
165 if( iv >= 0 && iv < ADN_ONE_STEP ){
166 brick_label_one_iv = iv ;
167 brick_label_one = va_arg( vararg_ptr , char * ) ;
168 if( brick_label_one != NULL ) new_brick_label_one = 1 ;
169 break ; /* exit switch */
170 }
171
172 iv = flag_arg - ADN_brick_fac_one ;
173 if( iv >= 0 && iv < ADN_ONE_STEP ){
174 brick_fac_one_iv = iv ;
175 brick_fac_one = va_arg( vararg_ptr , double ) ;
176 new_brick_fac_one = 1 ;
177 break ; /* exit switch */
178 }
179
180 iv = flag_arg - ADN_brick_stataux_one ;
181 if( iv >= 0 && iv < ADN_ONE_STEP ){
182 brick_stataux_one_iv = iv ;
183 brick_stataux_one = va_arg( vararg_ptr , float * ) ;
184 if( brick_stataux_one != NULL ) new_brick_stataux_one = 1 ;
185 break ; /* exit switch */
186 }
187
188 iv = flag_arg - ADN_brick_keywords_replace_one ;
189 if( iv >= 0 && iv < ADN_ONE_STEP ){
190 brick_keywords_one_iv = iv ;
191 brick_keywords_one = va_arg( vararg_ptr , char * ) ;
192 new_brick_keywords_one = 1 ;
193 break ; /* exit switch */
194 }
195
196 iv = flag_arg - ADN_brick_keywords_append_one ;
197 if( iv >= 0 && iv < ADN_ONE_STEP ){
198 brick_keywords_one_iv = iv ;
199 brick_keywords_one = va_arg( vararg_ptr , char * ) ;
200 new_brick_keywords_one = 2 ;
201 break ; /* exit switch */
202 }
203
204 /** not a special case? error! **/
205
206 sprintf(str,"illegal opcode = %d at arg #%d",flag_arg,iarg) ;
207 EDERR(str) ; if( errnum > 9 ) RETURN(errnum) ;
208 dummy = va_arg( vararg_ptr , void * ) ; /* skip next arg */
209 }
210 break ;
211
212 /** these two commands affect the disk file names **/
213
214 case ADN_prefix: /* processed later */
215 prefix = va_arg( vararg_ptr , char * ) ;
216 if( prefix != NULL ) {
217 new_prefix = 1 ;
218 new_smode = storage_mode_from_prefix(prefix);
219 if (dset->dblk && dset->dblk->diskptr) {
220 /* if defined by prefix, apply, else if current is not a
221 surface, clear (i.e. assume AFNI type) */
222 if (new_smode != STORAGE_UNDEFINED)
223 dset->dblk->diskptr->storage_mode = new_smode;
224 else if ( ! is_surface_storage_mode(DSET_STORAGE_MODE(dset)) )
225 dset->dblk->diskptr->storage_mode = STORAGE_BY_BRICK;
226 }
227 } else EDERR("illegal new prefix") ;
228 break ;
229
230 case ADN_directory_name: /* processed later */
231 directory_name = va_arg( vararg_ptr , char * ) ;
232 if( directory_name != NULL ) new_directory_name = 1 ;
233 else EDERR("illegal new directory_name") ;
234 break ;
235
236 /** change the memory allocation type (mmap or malloc) **/
237
238 case ADN_malloc_type: /* processed now */
239 malloc_type = va_arg( vararg_ptr , int ) ;
240 if( ISVALID_MEM_CODE(malloc_type) ){
241 new_malloc_type = 1 ;
242 THD_force_malloc_type( dset->dblk , malloc_type ) ;
243 }
244 else EDERR("illegal new malloc_type") ;
245 break ;
246
247 /** these commands affect the data in the bricks **/
248
249 case ADN_brick_fac: /* processed later */
250 brick_fac = va_arg( vararg_ptr , float * ) ;
251 new_brick_fac = 1 ;
252 break ;
253
254 case ADN_datum_all: /* processed later */
255 datum_all = va_arg( vararg_ptr , int ) ;
256 if( AFNI_GOOD_DTYPE(datum_all) ) new_datum_all = 1 ;
257 else EDERR("illegal new datum_all") ;
258 break ;
259
260 case ADN_datum_array: /* processed later */
261 datum_array = va_arg( vararg_ptr , int * ) ;
262 if( datum_array != NULL ) new_datum_array = 1 ;
263 else EDERR("illegal new datum_array") ;
264 break ;
265
266 case ADN_nvals: /* processed later */
267 nvals = va_arg( vararg_ptr , int ) ;
268 if( nvals > 0 ) new_nvals = 1 ;
269 else EDERR("illegal new nvals") ;
270 break ;
271
272 /** these commands affect the spatial axes,
273 which may also influence size of the data bricks **/
274
275 case ADN_ijk_to_dicom: /* processed later [19 Dec 2005] */
276 ijk_to_dicom = va_arg( vararg_ptr , mat44 ) ;
277 if( ISVALID_MAT44(ijk_to_dicom) ) new_ijk_to_dicom = 1 ;
278 else EDERR("illegal new ijk_to_dicom") ;
279 break ;
280
281 case ADN_nxyz: /* processed later */
282 nxyz = va_arg( vararg_ptr , THD_ivec3 ) ;
283 if( nxyz.ijk[0] >= 1 && nxyz.ijk[1] >= 1 && nxyz.ijk[2] >= 1 )
284 new_nxyz = 1 ;
285 else
286 EDERR("illegal new nxyz") ;
287 break ;
288
289 case ADN_xyzdel: /* processed later */
290 xyzdel = va_arg( vararg_ptr , THD_fvec3 ) ;
291 if( xyzdel.xyz[0]!=0.0 && xyzdel.xyz[1]!=0.0 && xyzdel.xyz[2]!=0.0 )
292 new_xyzdel = 1 ;
293 else EDERR("illegal new xyzdel") ;
294 break ;
295
296 case ADN_xyzorg: /* processed later */
297 xyzorg = va_arg( vararg_ptr , THD_fvec3 ) ;
298 new_xyzorg = 1 ;
299 break ;
300
301 case ADN_xyzorient: /* processed later */
302 xyzorient = va_arg( vararg_ptr , THD_ivec3 ) ;
303 if( xyzorient.ijk[0] >= FIRST_ORIENT_TYPE &&
304 xyzorient.ijk[0] <= LAST_ORIENT_TYPE &&
305 xyzorient.ijk[1] >= FIRST_ORIENT_TYPE &&
306 xyzorient.ijk[1] <= LAST_ORIENT_TYPE &&
307 xyzorient.ijk[2] >= FIRST_ORIENT_TYPE &&
308 xyzorient.ijk[2] <= LAST_ORIENT_TYPE &&
309 ORIENT_xyzint[xyzorient.ijk[0]]
310 + ORIENT_xyzint[xyzorient.ijk[1]]
311 + ORIENT_xyzint[xyzorient.ijk[2]] == 6 )
312
313 new_xyzorient = 1 ;
314 else EDERR("illegal new xyzorient") ;
315 break ;
316
317 case ADN_to_dicomm: /* illegal at this time */
318 EDERR("to_dicomm not implemented") ;
319 break ;
320
321 /** these commands affect the time axis of the dataset **/
322
323 case ADN_ntt: /* processed later */
324 ntt = va_arg( vararg_ptr , int ) ;
325 if( ntt >= 0 ) new_ntt = 1 ;
326 else EDERR("illegal new taxis ntt") ;
327 break ;
328
329 case ADN_tunits: /* processed later */
330 tunits = va_arg( vararg_ptr , int ) ;
331 if( tunits >= 0 ) new_tunits = 1 ;
332 else EDERR("illegal new taxis tunits") ;
333 break ;
334
335 case ADN_nsl: /* processed later */
336 nsl = va_arg( vararg_ptr , int ) ;
337 if( nsl >= 0 ) new_nsl = 1 ;
338 else EDERR("illegal new taxis nsl") ;
339 break ;
340
341 case ADN_ttorg: /* processed later */
342 ttorg = (float) va_arg( vararg_ptr , double ) ;
343 new_ttorg = 1 ;
344 break ;
345
346 case ADN_ttdel: /* processed later */
347 ttdel = (float) va_arg( vararg_ptr , double ) ;
348 new_ttdel = 1 ;
349 break ;
350
351 case ADN_ttdur: /* processed later */
352 ttdur = (float) va_arg( vararg_ptr , double ) ;
353 new_ttdur = 1 ;
354 break ;
355
356 case ADN_zorg_sl: /* processed later */
357 zorg_sl = (float) va_arg( vararg_ptr , double ) ;
358 new_zorg_sl = 1 ;
359 break ;
360
361 case ADN_dz_sl: /* processed later */
362 dz_sl = (float) va_arg( vararg_ptr , double ) ;
363 if( dz_sl != 0.0 ) new_dz_sl = 1 ;
364 else EDERR("illegal new taxis dz_sl") ;
365 break ;
366
367 case ADN_toff_sl: /* processed later */
368 toff_sl = va_arg( vararg_ptr , float * ) ;
369 new_toff_sl = 1 ;
370 break ;
371
372 /** these commands affect the interpretation of the dataset
373 (e.g., is it functional or anatomical, which view type, ...) **/
374
375 case ADN_type: /* processed later */
376 type = va_arg( vararg_ptr , int ) ;
377 if( type >= FIRST_3DIM_TYPE && type <= LAST_3DIM_TYPE )
378 new_type = 1 ;
379 else EDERR("illegal new type") ;
380 break ;
381
382 case ADN_view_type: /* processed later */
383 view_type = va_arg( vararg_ptr , int ) ;
384 if( view_type >= FIRST_VIEW_TYPE && view_type <= LAST_VIEW_TYPE ) {
385 new_view_type = 1 ;
386 if (dset->dblk && dset->dblk->diskptr) { /* ZSS Feb 2012 */
387 dset->dblk->diskptr->storage_mode = STORAGE_BY_BRICK;
388 }
389 } else EDERR("illegal new view_type") ;
390 break ;
391
392 case ADN_func_type: /* processed later */
393 func_type = va_arg( vararg_ptr , int ) ;
394 if( func_type >= 0 ) new_func_type = 1 ;
395 else EDERR("illegal new func_type") ;
396 break ;
397
398 /** auxiliary statistical data, for interpretation of functions **/
399
400 case ADN_stat_aux: /* processed now */
401 stat_aux = va_arg( vararg_ptr , float * ) ;
402 if( stat_aux != NULL ){
403 new_stat_aux = 1 ;
404 for( ii=0 ; ii < MAX_STAT_AUX ; ii++ )
405 dset->stat_aux[ii] = stat_aux[ii] ;
406 } else EDERR("illegal new stat_aux") ;
407 break ;
408
409 /** dataset keywords **/
410
411 case ADN_keywords_replace: /* processed now */
412 keywords = va_arg( vararg_ptr , char * ) ;
413 new_keywords = 1 ;
414 THD_store_dataset_keywords( dset , keywords ) ;
415 break ;
416
417 case ADN_keywords_append: /* processed now */
418 keywords = va_arg( vararg_ptr , char * ) ;
419 new_keywords = 1 ;
420 THD_append_dataset_keywords( dset , keywords ) ;
421 break ;
422
423 /** various labeling options **/
424
425 case ADN_label1: /* processed now */
426 label1 = va_arg( vararg_ptr , char * ) ;
427 if( label1 != NULL ){
428 MCW_strncpy( dset->label1 , label1 , THD_MAX_LABEL ) ;
429 new_label1 = 1 ;
430 }
431 else EDERR("illegal new label1") ;
432 break ;
433
434 case ADN_label2: /* processed now */
435 label2 = va_arg( vararg_ptr , char * ) ;
436 if( label2 != NULL ){
437 MCW_strncpy( dset->label2 , label2 , THD_MAX_LABEL ) ;
438 new_label2 = 1 ;
439 }
440 else EDERR("illegal new label2") ;
441 break ;
442
443 case ADN_self_name: /* processed now */
444 self_name = va_arg( vararg_ptr , char * ) ;
445 if( self_name != NULL ){
446 MCW_strncpy( dset->self_name , self_name , THD_MAX_NAME ) ;
447 new_self_name = 1 ;
448 }
449 else EDERR("illegal new self_name") ;
450 break ;
451
452 /** relationships to other datasets **/
453
454 case ADN_warp_parent: /* processed now */
455 warp_parent = va_arg( vararg_ptr , THD_3dim_dataset * ) ;
456 if( ISVALID_3DIM_DATASET(warp_parent) ){
457 new_warp_parent = 1 ;
458 dset->warp_parent = warp_parent ;
459 MCW_strncpy(dset->warp_parent_name,warp_parent->self_name,THD_MAX_NAME) ;
460 dset->warp_parent_idcode = warp_parent->idcode ;
461 }
462 else EDERR("illegal new warp_parent") ;
463 break ;
464
465 case ADN_warp: /* processed now */
466 warp = va_arg( vararg_ptr , THD_warp * ) ;
467 if( ISVALID_WARP(warp) ){
468 new_warp = 1 ;
469 if( dset->warp == NULL ) dset->warp = myRwcNew(THD_warp) ;
470 *(dset->warp) =* warp ;
471 } else EDERR("illegal new warp") ;
472 break ;
473
474 case ADN_anat_parent: /* processed now */
475 anat_parent = va_arg( vararg_ptr , THD_3dim_dataset * ) ;
476 if( ISVALID_3DIM_DATASET(anat_parent) ){
477 new_anat_parent = 1 ;
478 dset->anat_parent = anat_parent ;
479 MCW_strncpy(dset->anat_parent_name,anat_parent->self_name,THD_MAX_NAME) ;
480 dset->anat_parent_idcode = anat_parent->idcode ;
481 }
482 else EDERR("illegal new anat_parent") ;
483 break ;
484
485 case ADN_anatpar_idcode:{ /* processed now [13 Dec 1999] */
486 MCW_idcode * idc ;
487 idc = va_arg( vararg_ptr , MCW_idcode * ) ;
488 if( idc != NULL )
489 dset->anat_parent_idcode = *idc ;
490 else
491 EDERR("illegal new anatpar_idcode") ;
492 }
493 break ;
494
495 } /*- end of switch on flag_arg -*/
496
497 iarg++ ;
498 } while( 1 ) ; /* end of loop over arguments */
499 va_end( vararg_ptr ) ;
500 if( errnum > 0 ) RETURN(errnum) ;
501
502 /**** carry out edits that were flagged above ****/
503
504 /**---------- Need to reset the disk filename? ------------**/
505 /** 22 Nov 2002: remove +orig etc. from prefix, if present **/
506
507 if( new_prefix || new_directory_name || new_view_type ){
508 char *nprefix = THD_deplus_prefix( prefix ) ;
509 int smode ;
510
511 THD_init_diskptr_names( dset->dblk->diskptr ,
512 directory_name , NULL ,
513 nprefix , view_type , True ) ;
514
515 /* if the storage mode has been specified via the prefix, apply it */
516 /* 21 Aug 2008 [rickr] */
517 smode = storage_mode_from_filename(prefix);
518 if( smode != STORAGE_UNDEFINED )
519 dset->dblk->diskptr->storage_mode = smode;
520
521 if( DSET_IS_1D(dset) || DSET_IS_3D(dset) ){ /* 21 Mar 2003 */
522 char *fname = dset->dblk->diskptr->brick_name ;
523 int ll = strlen(fname) ;
524 STRING_DEVIEW_DEEXT_BRICK(fname);
525 if( DSET_IS_1D(dset) || (DSET_NY(dset)==1 && DSET_NZ(dset)==1) ) {
526 if( !STRING_HAS_SUFFIX(fname,".1D") &&
527 !STRING_HAS_SUFFIX(fname,".1D.dset")) strcat(fname,".1D");
528 fname = dset->dblk->diskptr->prefix ; /* also adjust prefix */
529 if( !STRING_HAS_SUFFIX(fname,".1D") &&
530 !STRING_HAS_SUFFIX(fname,".1D.dset")) strcat(fname,".1D");
531 } else {
532 strcat(fname,".3D");
533 }
534 }
535
536 if( DSET_IS_NIML(dset) ){ /* 07 Jun 2006 [rickr] */
537 char *fname = dset->dblk->diskptr->brick_name ;
538 int ll = strlen(fname) ;
539 STRING_DEVIEW_DEEXT_BRICK(fname);
540 if( !STRING_HAS_SUFFIX(fname,".niml") ) strcat(fname,".niml");
541 fname = dset->dblk->diskptr->prefix ; /* also adjust prefix */
542 if( !STRING_HAS_SUFFIX(fname,".niml") ) strcat(fname,".niml");
543 }
544
545 if( DSET_IS_NI_SURF_DSET(dset) ){ /* 28 Jun 2006 [rickr] */
546 char *fname = dset->dblk->diskptr->brick_name ;
547 int ll = strlen(fname) ;
548 STRING_DEVIEW_DEEXT_BRICK(fname);
549 fname = dset->dblk->diskptr->brick_name ;
550 if( !STRING_HAS_SUFFIX(fname,".niml.dset") ) strcat(fname,".niml.dset");
551 fname = dset->dblk->diskptr->prefix ; /* also adjust prefix */
552 if( !STRING_HAS_SUFFIX(fname,".niml.dset") ) strcat(fname,".niml.dset");
553 }
554
555 if( DSET_IS_GIFTI(dset) ){ /* 13 Feb 2008 [rickr] */
556 char *fname = dset->dblk->diskptr->brick_name ;
557 int ll = strlen(fname) ;
558 STRING_DEVIEW_DEEXT_BRICK(fname);
559 if( ! STRING_HAS_SUFFIX(fname,".gii") &&
560 ! STRING_HAS_SUFFIX(fname,".gii.dset") )
561 strcat(fname,".gii");
562 fname = dset->dblk->diskptr->prefix ; /* also adjust prefix */
563 if( ! STRING_HAS_SUFFIX(fname,".gii") &&
564 ! STRING_HAS_SUFFIX(fname,".gii.dset") )
565 strcat(fname,".gii");
566 }
567
568 /** output of NIfTI-1.1 dataset: 06 May 2005 **/
569 /* if the prefix ends in .nii or .nii.gz, change filename in brick_name */
570 if( nprefix != NULL && ( STRING_HAS_SUFFIX(nprefix,".nii") ||
571 STRING_HAS_SUFFIX(nprefix,".nii.gz") ) ){
572 char *fname = dset->dblk->diskptr->brick_name ;
573 int gzpre = STRING_HAS_SUFFIX(nprefix,".nii.gz") ;
574 int ll = strlen(fname) ; /* for DEVIEW macro */
575 STRING_DEVIEW_DEEXT_BRICK(fname) ;
576
577 /* make sure brick_name suffix matches that of prefix */
578 /* if gzpre, include .nii.gz, else include .nii */
579 /* no automatic compression for NIFTI 1 Jun 2021 [rickr] */
580
581 if ( gzpre && ! STRING_HAS_SUFFIX(fname,".nii.gz") )
582 strcat(fname,".nii.gz") ;
583 else if ( ! gzpre && ! STRING_HAS_SUFFIX(fname,".nii") )
584 strcat(fname,".nii");
585
586 if (dset->dblk->diskptr->header_name) { /* ZSS: April 26 2012 */
587 /* header_name should be just like brick_name */
588 strcpy(dset->dblk->diskptr->header_name, fname);
589 }
590 }
591
592 /** NIfTI-1.1 with .hdr suffix (2 file format) [08 May 2008] **/
593
594 if( nprefix != NULL && STRING_HAS_SUFFIX(nprefix,".hdr") ){
595
596 char *fname = dset->dblk->diskptr->brick_name ;
597 int ll = strlen(fname) ;
598 STRING_DEVIEW_DEEXT_BRICK(fname);
599 if( !strcmp(fname+ll-14,".hdr") ) fname[ll-14] = '\0';
600 if (dset->dblk->diskptr->header_name) {/* and adjust header name
601 ZSS April 26 2012 */
602 strcpy(dset->dblk->diskptr->header_name, fname);
603 strcat(dset->dblk->diskptr->header_name,".hdr") ;
604 }
605 if( !STRING_HAS_SUFFIX(fname,".img") ) strcat(fname,".img") ;
606
607 /* and override the BRICK mode */
608 dset->dblk->diskptr->storage_mode = STORAGE_BY_NIFTI;
609 }
610
611 if( nprefix != NULL ) free(nprefix) ;
612 }
613
614 /**----------- Need to reconfigure the spatial axes? -----------**/
615 /** Much of this code is from routine THD_3dim_from_block **/
616
617 redo_daxes = ( new_xyzorg || new_xyzdel || new_xyzorient ) ;
618
619 redo_bricks = ( new_datum_all || new_datum_array ||
620 new_nvals || new_nxyz ) ;
621
622 if( new_nvals && nvals == 1 ){ /* 02 Dec 2009 */
623 new_ntt = 1 ; ntt = 0 ;
624 }
625
626 /*----- ye newe waye for ye axes change [19 Dec 2005] -----*/
627
628 /* check for conflicts */
629
630 if( new_xyzorg && new_ijk_to_dicom )
631 EDERR("can't set ijk_to_dicom and xyzorg at same time");
632 if( new_xyzdel && new_ijk_to_dicom )
633 EDERR("can't set ijk_to_dicom and xyzdel at same time");
634 if( new_xyzorient && new_ijk_to_dicom )
635 EDERR("can't set ijk_to_dicom and xyzorient at same time");
636
637 if( redo_bricks && THD_count_databricks(dset->dblk) > 0 )
638 EDERR("cannot reconfigure bricks that already are full") ;
639
640 if( errnum > 0 ) RETURN(errnum) ;
641
642 /* set new data grid size now */
643
644 if( new_nxyz ){
645 THD_dataxes *daxes = dset->daxes ;
646 THD_diskptr *dkptr = dset->dblk->diskptr ;
647
648 daxes->nxx = dkptr->dimsizes[0] = nxyz.ijk[0] ;
649 daxes->nyy = dkptr->dimsizes[1] = nxyz.ijk[1] ;
650 daxes->nzz = dkptr->dimsizes[2] = nxyz.ijk[2] ;
651
652 if( !redo_daxes && !new_ijk_to_dicom ){
653 THD_set_daxes_bbox(daxes) ;
654 THD_daxes_to_mat44(daxes) ;
655 dset->daxes->ijk_to_dicom_real = dset->daxes->ijk_to_dicom ;
656 THD_set_dicom_box (daxes) ;
657 }
658 }
659
660 /* set the new matrix transform between index and space */
661
662 if( new_ijk_to_dicom ){
663 THD_dataxes *daxes = dset->daxes ;
664
665 daxes->ijk_to_dicom = ijk_to_dicom ;
666 daxes->dicom_to_ijk = nifti_mat44_inverse( ijk_to_dicom ) ;
667 THD_set_dicom_box( daxes ) ;
668 (void)THD_daxes_from_mat44( daxes ) ; /* set the old stuff */
669 }
670
671 /*------ ye olde waye for ye axes change -----*/
672
673 if( redo_daxes ){
674 THD_dataxes *daxes = dset->daxes ;
675 #if 0
676 INFO_message("old geometry string = %s",EDIT_get_geometry_string(dset)) ;
677 #endif
678
679 /** copy new stuff into the daxes structure **/
680
681 if( new_xyzorg ){
682 #if 0
683 INFO_message("old daxes org = %g %g %g",daxes->xxorg,daxes->yyorg,daxes->zzorg) ;
684 #endif
685 daxes->xxorg = xyzorg.xyz[0] ;
686 daxes->yyorg = xyzorg.xyz[1] ;
687 daxes->zzorg = xyzorg.xyz[2] ;
688 #if 0
689 INFO_message("new daxes org = %g %g %g",daxes->xxorg,daxes->yyorg,daxes->zzorg) ;
690 #endif
691 }
692
693 if( new_xyzdel ){
694 #if 0
695 INFO_message("old daxes del = %g %g %g",daxes->xxdel,daxes->yydel,daxes->zzdel) ;
696 #endif
697 daxes->xxdel = xyzdel.xyz[0] ;
698 daxes->yydel = xyzdel.xyz[1] ;
699 daxes->zzdel = xyzdel.xyz[2] ;
700 #if 0
701 INFO_message("new daxes del = %g %g %g",daxes->xxdel,daxes->yydel,daxes->zzdel) ;
702 #endif
703 }
704
705 if( new_xyzorient ){
706 #if 0
707 INFO_message("old daxes orient = %d %d %d",daxes->xxorient,daxes->yyorient,daxes->zzorient) ;
708 #endif
709 daxes->xxorient = xyzorient.ijk[0] ;
710 daxes->yyorient = xyzorient.ijk[1] ;
711 daxes->zzorient = xyzorient.ijk[2] ;
712 #if 0
713 INFO_message("new daxes orient = %d %d %d",daxes->xxorient,daxes->yyorient,daxes->zzorient) ;
714 #endif
715 }
716
717 /*-- set bounding box and to_dicomm matrix for this dataset --*/
718
719 THD_set_daxes_bbox ( daxes ) ; /* 20 Dec 2005 */
720 THD_daxes_to_mat44 ( daxes ) ; /* 19 Dec 2005 */
721 dset->daxes->ijk_to_dicom_real = dset->daxes->ijk_to_dicom ;
722 THD_set_dicom_box ( daxes ) ;
723 THD_set_daxes_to_dicomm( daxes ) ; /* 20 Dec 2005 */
724
725 #if 0
726 INFO_message("new geometry string = %s",EDIT_get_geometry_string(dset)) ;
727 #endif
728 }
729
730 /**---------- Need to reconfigure the sub-bricks? ----------**/
731
732 if( new_datum_all && new_datum_array ){
733 EDERR("datum_all and datum_array can't be used together") ;
734 RETURN(errnum) ;
735 }
736
737 if( redo_bricks ){
738 int old_nvals = dset->dblk->nvals ;
739 #if 0
740 fprintf(stderr,"EDIT_dset_items: about to redo_bricks\n") ;
741 #endif
742 if( ! new_nvals ) nvals = old_nvals ;
743
744 /** make an array of data types, if one not provided **/
745
746 if( ! new_datum_array ){
747 datum_array = (int *) RwcMalloc( sizeof(int) * nvals ) ;
748
749 #if 0
750 fprintf(stderr,"EDIT_dset_items: about to make datum_array\n") ;
751 #endif
752 for( ii=0 ; ii < nvals ; ii++ )
753 datum_array[ii] = (new_datum_all) ? datum_all
754 : (ii < old_nvals) ? DSET_BRICK_TYPE(dset,ii)
755 : DSET_BRICK_TYPE(dset,0) ;
756 } /* 06 Apr 2005 [rickr] */
757
758 if( new_nvals ){
759 if( dset->dblk->nvals != nvals )
760 THD_copy_datablock_auxdata( NULL , dset->dblk ) ; /* 30 Nov 1997 */
761
762 myRwcFree( dset->dblk->brick_bytes ) ;
763 myRwcFree( dset->dblk->brick_fac ) ;
764
765 dset->dblk->nvals = dset->dblk->diskptr->nvals = nvals ;
766 }
767
768 THD_init_datablock_brick( dset->dblk , nvals , datum_array ) ;
769
770 if( ! new_datum_array ) myRwcFree(datum_array) ;
771 }
772
773 /**---------- Need to add new brick_fac values? ----------**/
774
775 if( new_brick_fac ){
776 if( brick_fac != NULL ){
777 for( ii=0 ; ii < dset->dblk->nvals ; ii++ )
778 dset->dblk->brick_fac[ii] = brick_fac[ii] ;
779 } else {
780 for( ii=0 ; ii < dset->dblk->nvals ; ii++ )
781 dset->dblk->brick_fac[ii] = 0.0 ;
782 }
783 }
784
785 /** 30 Nov 1997: do just one brick_fac value **/
786
787 if( new_brick_fac_one ){
788 if( brick_fac_one_iv < 0 || brick_fac_one_iv >= dset->dblk->nvals ){
789 EDERR_int("illegal index for ADN_brick_fac_one",brick_fac_one_iv) ;
790 RETURN(errnum) ;
791 }
792 dset->dblk->brick_fac[ brick_fac_one_iv ] = brick_fac_one ;
793 }
794
795 /**--------- 30 Nov 1997: add a single brick label value --------**/
796
797 if( new_brick_label_one ){
798 if( brick_label_one_iv < 0 || brick_label_one_iv >= dset->dblk->nvals ){
799 EDERR_int("illegal index for ADN_brick_label_one",brick_label_one_iv) ;
800 RETURN(errnum) ;
801 }
802
803 THD_store_datablock_label( dset->dblk, brick_label_one_iv, brick_label_one ) ;
804 }
805
806 /*---- add a single brick keywords value ----*/
807
808 if( new_brick_keywords_one ){
809 if( brick_keywords_one_iv < 0 || brick_keywords_one_iv >= dset->dblk->nvals ){
810 EDERR_int("illegal index for ADN_brick_keywords_one",brick_keywords_one_iv) ;
811 RETURN(errnum) ;
812 }
813
814 if( new_brick_keywords_one == 1 )
815 THD_store_datablock_keywords( dset->dblk, brick_keywords_one_iv,
816 brick_keywords_one );
817 else if( new_brick_keywords_one == 2 )
818 THD_append_datablock_keywords( dset->dblk, brick_keywords_one_iv,
819 brick_keywords_one );
820 }
821
822 /*---- Add a single brick stataux value.
823 The input is a float array formatted like so:
824 <statcode> <npar> <value> ... <value>
825 where <statcode> is a FUNC_*_TYPE code
826 <npar> is the number of values to follow (may be 0);
827 normally is FUNC_need_stat_aux[<statcode>]
828 <value> is an auxiliary statistical parameter needed
829 for data of type <statcode> ----*/
830
831 if( new_brick_stataux_one ){
832 int jv , npar , kv , iv ;
833
834 iv = brick_stataux_one_iv ;
835
836 #if 0
837 fprintf(stderr,"stataux_one: iv=%d bso[0]=%g bso[1]=%g bso[2]=%g\n",
838 iv, brick_stataux_one[0], brick_stataux_one[1], brick_stataux_one[2] ) ;
839 #endif
840
841 if( iv < 0 || iv >= dset->dblk->nvals ){
842 EDERR("illegal index for ADN_brick_stataux_one") ;
843 RETURN(errnum) ;
844 }
845
846 jv = brick_stataux_one[0] ; /* statcode */
847
848 npar = brick_stataux_one[1] ; /* # of values present */
849 if( npar < 0 ){
850 EDERR("illegal npar for ADN_brick_stataux_one") ;
851 RETURN(errnum) ;
852 }
853
854 kv = FUNC_need_stat_aux[jv] ; /* # of values needed */
855 if( npar > kv ) npar = kv ;
856
857 THD_store_datablock_stataux( dset->dblk ,
858 iv , jv , npar , brick_stataux_one + 2 ) ;
859 }
860
861 /**---------- Need to reconfigure the time axis? ----------**/
862
863 redo_taxis = ( new_ntt || new_nsl || new_ttorg || new_ttdel ||
864 new_ttdur || new_zorg_sl || new_dz_sl || new_toff_sl ) ;
865
866 if( ! new_ntt ) ntt = ISVALID_TIMEAXIS(dset->taxis) ? dset->taxis->ntt : 0 ;
867
868 if( ntt == 0 && dset->taxis != NULL ){
869 myRwcFree( dset->taxis->toff_sl ) ;
870 myRwcFree( dset->taxis ) ;
871 dset->taxis = NULL ;
872 }
873
874 redo_taxis = ( redo_taxis && ntt > 0 ) ;
875
876 if( (new_nsl && nsl > 0) && !new_toff_sl ){ /* if we have new slice count */
877 EDERR("have new_nsl but not new_toff_sl") ; /* but no new slice offsets */
878 RETURN(errnum) ;
879 }
880
881 if( redo_taxis ){
882 THD_timeaxis *taxis = dset->taxis ;
883
884 if( taxis == NULL ){
885 taxis = dset->taxis = myRwcNew( THD_timeaxis ) ;
886 taxis->type = TIMEAXIS_TYPE ;
887 taxis->toff_sl = NULL ;
888 taxis->nsl = 0 ;
889 taxis->ttorg = taxis->ttdel = taxis->ttdur = 0.0 ;
890 taxis->ntt = ntt ;
891 }
892
893 if( new_ntt ) taxis->ntt = ntt ;
894 if( new_ttorg ) taxis->ttorg = ttorg ;
895 if( new_ttdel ) taxis->ttdel = ttdel ;
896 if( new_ttdur ) taxis->ttdur = ttdur ;
897 if( new_zorg_sl ) taxis->zorg_sl = zorg_sl ;
898 if( new_dz_sl ) taxis->dz_sl = dz_sl ;
899
900 if( new_nsl ){
901 taxis->nsl = nsl ;
902 if( nsl > 0 )
903 taxis->toff_sl = (float *) RwcRealloc( (char *) taxis->toff_sl ,
904 sizeof(float) * nsl ) ;
905 else
906 myRwcFree(taxis->toff_sl) ;
907 }
908
909 if( new_toff_sl )
910 for( ii=0 ; ii < taxis->nsl ; ii++ ) taxis->toff_sl[ii] = toff_sl[ii] ;
911 }
912
913 if( new_tunits ){
914 THD_timeaxis * taxis = dset->taxis ;
915
916 if( taxis == NULL) {
917 if (DSET_NVALS(dset) > 1) {
918 EDERR("have new_tunits but have no time axis") ;
919 RETURN(errnum) ;
920 }
921 } else {
922 taxis->units_type = tunits ;
923 }
924 }
925
926 /**--------------- Need to redo dataset type codes? ------------**/
927 /** Note that changing the type codes by themselves won't fix **/
928 /** nvals or other such stuff -- that must be done separately. **/
929
930 if( new_type ) dset->type = type ;
931 if( new_view_type ) dset->view_type = view_type ;
932
933 if( new_func_type ){
934 if( (ISANAT(dset) && func_type <= LAST_ANAT_TYPE) ||
935 (ISFUNC(dset) && func_type <= LAST_FUNC_TYPE) ){
936
937 dset->func_type = func_type ;
938
939 } else{
940 EDERR("illegal new_func type combination") ; RETURN(errnum) ;
941 }
942 }
943
944 /****--------------- hopefully, we are done! ---------------****/
945
946 RETURN(errnum) ;
947 }
948
949 /*!
950 Scale dataset's dxyz, same as 3drefit's -xyzscale
951 */
THD_volDXYZscale(THD_dataxes * daxes,float xyzscale,int reuse_shift)952 int THD_volDXYZscale( THD_dataxes * daxes, float xyzscale, int reuse_shift)
953 {
954 static char FuncName[]={"THD_volDXYZscale"};
955 float dxp, dyp, dzp;
956 int rl, ap , is;
957 float xop , yop , zop ;
958 static float shift[3] ;
959
960 ENTRY("THD_volDXYZscale");
961
962 if (!daxes) RETURN(0);
963
964 if( xyzscale > 0.0f ){ /* 18 Jul 2006 */
965 dxp = daxes->xxdel * xyzscale ; /* new grid */
966 dyp = daxes->yydel * xyzscale ; /* spacings */
967 dzp = daxes->zzdel * xyzscale ;
968 rl = abs(THD_get_axis_direction(daxes,ORI_R2L_TYPE)) ;
969 ap = abs(THD_get_axis_direction(daxes,ORI_A2P_TYPE)) ;
970 is = abs(THD_get_axis_direction(daxes,ORI_I2S_TYPE)) ;
971
972 if( rl == 0 || ap == 0 || is == 0 )
973 ERROR_exit("-xyzscale: Indeterminate axis directions!") ;
974
975 if( !reuse_shift ){ /* to calculate shift */
976 float op[3] , oo[3] ;
977 op[0] = xop = daxes->xxorg +
978 (daxes->xxdel-dxp)*0.5f*(daxes->nxx-1) ;
979 op[1] = yop = daxes->yyorg +
980 (daxes->yydel-dyp)*0.5f*(daxes->nyy-1) ;
981 op[2] = zop = daxes->zzorg +
982 (daxes->zzdel-dzp)*0.5f*(daxes->nzz-1) ;
983 oo[0] = daxes->xxorg ;
984 oo[1] = daxes->yyorg ;
985 oo[2] = daxes->zzorg ;
986 shift[0] = op[rl-1] - xyzscale * oo[rl-1] ; /* RL shift */
987 shift[1] = op[ap-1] - xyzscale * oo[ap-1] ; /* AP shift */
988 shift[2] = op[is-1] - xyzscale * oo[is-1] ; /* IS shift */
989
990 } else { /* to apply pre calculated shift */
991
992 xop = xyzscale * daxes->xxorg + shift[daxes->xxorient/2] ;
993 yop = xyzscale * daxes->yyorg + shift[daxes->yyorient/2] ;
994 zop = xyzscale * daxes->zzorg + shift[daxes->zzorient/2] ;
995 }
996
997 daxes->xxdel = dxp ; daxes->yydel = dyp ; daxes->zzdel = dzp ;
998 daxes->xxorg = xop ; daxes->yyorg = yop ; daxes->zzorg = zop ;
999 }
1000 RETURN(1);
1001 }
1002
1003 /*-------------------------------------------------------------------*/
1004 #undef DPOLD /* 22 Sep 2014 == Bilbo's birthday */
1005
1006 /*-------------------------------------------------------------------*/
1007 /*! Remove any +???? suffix from a prefix, returning a new one.
1008 -- 22 Nov 2002 - RWCox
1009 ---------------------------------------------------------------------*/
1010
THD_deplus_prefix(char * prefix)1011 char * THD_deplus_prefix( char *prefix )
1012 {
1013 #ifdef DPOLD
1014 static char *plussers[] = {
1015 "+orig", "+orig.", "+orig.HEAD", "+orig.BRIK", "+orig.BRIK.gz",
1016 "+acpc", "+acpc.", "+acpc.HEAD", "+acpc.BRIK", "+acpc.BRIK.gz",
1017 "+tlrc", "+tlrc.", "+tlrc.HEAD", "+tlrc.BRIK", "+tlrc.BRIK.gz"
1018 };
1019 #else
1020 static char *plussers[] = { "+orig" , "+acpc" , "+tlrc" } ;
1021 #endif
1022 char *newprefix , *cpt ;
1023 int nn, N_nn;
1024
1025 if( prefix == NULL ) return NULL ;
1026
1027 newprefix = strdup(prefix);
1028
1029 N_nn = sizeof(plussers)/sizeof(char *);
1030 for (nn=0; nn<N_nn; ++nn) {
1031 #ifdef DPOLD
1032 if( STRING_HAS_SUFFIX(newprefix, plussers[nn]) ) {
1033 newprefix[strlen(newprefix)-strlen(plussers[nn])] = '\0';
1034 return newprefix ;
1035 }
1036 #else
1037 cpt = strstr(newprefix,plussers[nn]) ;
1038 if( cpt != NULL ) *cpt = '\0' ;
1039 #endif
1040 }
1041
1042 return newprefix ;
1043 }
1044