Doxygen Source Code Documentation
plug_reorder.c File Reference
#include "afni.h"#include <unistd.h>#include "plug_reorder_parseMap.c"Go to the source code of this file.
Data Structures | |
| struct | ClassInfo |
Defines | |
| #define | MAIN_PLUGIN_REORDER |
| #define | NUM_DUPACTION_STRINGS (sizeof(dupaction_strings)/sizeof(char *)) |
| #define | FREEUP(thing) if((thing) != NULL) {free((thing)); (thing) = NULL;} |
| #define | FREE_WORKSPACE |
Functions | |
| char * | REORDER_main (PLUGIN_interface *) |
| int | compare_class (const void *i, const void *j) |
| DEFINE_PLUGIN_PROTOTYPE PLUGIN_interface * | PLUGIN_init (int ncall) |
Variables | |
| char | helpstring [] |
| char * | dupaction_strings [] |
Define Documentation
|
|
Value: Definition at line 242 of file plug_reorder.c. Referenced by REORDER_main(). |
|
|
Definition at line 240 of file plug_reorder.c. |
|
|
Definition at line 28 of file plug_reorder.c. |
|
|
Definition at line 104 of file plug_reorder.c. Referenced by PLUGIN_init(), and REORDER_main(). |
Function Documentation
|
||||||||||||
|
Definition at line 125 of file plug_reorder.c. References ClassInfo::classKRH, and i. Referenced by REORDER_main().
|
|
|
Definition at line 160 of file plug_reorder.c. References ANAT_ALL_MASK, dupaction_strings, helpstring, NUM_DUPACTION_STRINGS, PLUTO_set_sequence(), and REORDER_main().
00161 {
00162 PLUGIN_interface *plint; /* will be the output of this routine */
00163
00164 if(ncall >= 1) { /* only one interface */
00165 return NULL;
00166 }
00167
00168 /*---------------- set titles and call point ----------------*/
00169
00170 plint = PLUTO_new_interface("Reorder",
00171 "Reorders voxel time-courses within a 3D+Time BRIK",
00172 helpstring,
00173 PLUGIN_CALL_VIA_MENU,
00174 REORDER_main);
00175
00176 PLUTO_set_sequence( plint , "z:Kummer" ) ;
00177
00178 /*--------- 1st line: Input dataset ---------*/
00179
00180 PLUTO_add_option(plint,
00181 "Input",/* label at left of input line */
00182 "Input",/* tag to return to plugin */
00183 TRUE /* is this mandatory? */
00184 );
00185
00186 PLUTO_add_dataset(plint,
00187 "---->>", /* label next to button */
00188 ANAT_ALL_MASK, /* take any anat datasets */
00189 0, /* don't allow fim funcs*/
00190 DIMEN_4D_MASK | /* need 3D+time datasets*/
00191 BRICK_ALLTYPE_MASK /* handle any type */
00192 );
00193
00194 /*---------- 2nd line: Output dataset prefix ----------*/
00195
00196 PLUTO_add_option(plint,
00197 "Output", /* label at left of input line */
00198 "Output", /* tag to return to plugin */
00199 TRUE /* is this mandatory? */
00200 );
00201
00202 PLUTO_add_string(plint,
00203 "Prefix", /* label next to textfield */
00204 0,NULL, /* no fixed strings to choose among */
00205 19 /* 19 spaces for typing in value */
00206 );
00207
00208 /*---------- 3rd line: Map file name ----------*/
00209
00210 PLUTO_add_option(plint,
00211 "Map file", /* label at left of input line */
00212 "MapFile", /* tag to return to plugin */
00213 TRUE /* is this mandatory? */
00214 );
00215
00216 PLUTO_add_string(plint,
00217 "FileName", /* label next to textfield */
00218 0,NULL, /* no fixed strings to choose among */
00219 19 /* 19 spaces for typing in value */
00220 );
00221
00222 PLUTO_add_string(plint,
00223 "Duplicates", /* label next to textfield */
00224 NUM_DUPACTION_STRINGS, /* number of strings to choose among */
00225 dupaction_strings, /* fixed strings to choose among */
00226 0 /* index of default (collate) */
00227 );
00228
00229 /*--------- done with interface setup ---------*/
00230
00231 return plint;
00232 }
|
|
|
Definition at line 251 of file plug_reorder.c. References ADN_malloc_type, ADN_none, ADN_ntt, ADN_nvals, ADN_prefix, Bool, calloc, ClassInfo::classKRH, compare_class(), DATABLOCK_MEM_MALLOC, THD_3dim_dataset::daxes, DSET_ARRAY, DSET_BRICK_TYPE, DSET_load, DSET_NUM_TIMES, DSET_unload, dupaction_strings, EDIT_dset_items(), EDIT_empty_copy(), EDIT_substitute_brick(), free, FREE_WORKSPACE, FREEUP, ClassInfo::length, NUM_DUPACTION_STRINGS, THD_dataxes::nxx, THD_dataxes::nyy, THD_dataxes::nzz, PLUTO_add_dset(), PLUTO_commandstring(), PLUTO_find_dset(), PLUTO_popup_meter(), PLUTO_prefix_ok(), PLUTO_set_meter(), PLUTO_string_index(), realloc, REORDER_parseMap(), THD_delete_3dim_dataset(), tross_Append_History(), and tross_Copy_History(). Referenced by PLUGIN_init().
00252 {
00253 MCW_idcode *idc; /* input dataset idcode */
00254 THD_3dim_dataset *old_dset; /* input dataset */
00255 THD_3dim_dataset *new_dset; /* output dataset */
00256
00257 ClassInfo *classKRH; /* array of ClassInfo structures, returned by reference from 'parseMap' */
00258
00259 char *new_prefix; /* pointer to the output dataset prefix */
00260 char *mapFile; /* pointer to the name of map file to open */
00261 char *dupstr; /* pointer to duplicate action label string */
00262 char currentClass; /* character sentinel */
00263
00264 register int ii; /* register counter variables */
00265 register int jj;
00266 register int kk;
00267 register int mm;
00268
00269 int perc; /* percentage value for progress meter */
00270 int ninp; /* number of time points */
00271 int nvox; /* number of voxels */
00272 int old_datum; /* data type of input dataset */
00273 int error; /* general status variable */
00274 int startIndex; /* index sentinel */
00275 int currentLength; /* length of the current epoch */
00276 int newLength; /* length of the time-course after averaging duplicates */
00277 int instances; /* number of instances of the current epoch class */
00278 int timePoint; /* current time point being processed */
00279 int *map; /* array of indices for remapping time points, returned from 'parseMap' */
00280 int mapLength; /* length of 'map' array, returned by reference from 'parseMap' */
00281 int dupaction; /* 0: collate duplicate epochs, !0: average duplicate epochs */
00282 int classCount; /* length of 'ClassInfo' array, returned by reference from 'parseMap' */
00283
00284 double sum; /* sum variable for averaging */
00285 double divisor; /* divisor for calculating the mean, this will equal 'instances' */
00286
00287 byte **bPtr = NULL; /* for byte data, will point to the 3D+time data to be reordered */
00288 short **sPtr = NULL; /* for short data, will point to the 3D+time data to be reordered */
00289 float **fPtr = NULL; /* for float data, will point to the 3D+time data to be reordered */
00290
00291 byte **bData = NULL; /* for byte data, will point to the reordered 3D+time data */
00292 short **sData = NULL; /* for short data, will point to the reordered 3D+time data */
00293 float **fData = NULL; /* for float data, will point to the reordered 3D+time data */
00294
00295 Bool dupsToAverage = False; /* flag to indicate whether there are segments to average */
00296
00297 /**********************************************************************/
00298 /****** Check inputs from AFNI to see if they are reasonable-ish ******/
00299
00300 /*--------- go to first input line ---------*/
00301
00302 PLUTO_next_option(plint);
00303
00304 idc = PLUTO_get_idcode(plint); /* get dataset item */
00305
00306 old_dset = PLUTO_find_dset(idc); /* get Ptr to dataset */
00307 if(NULL == old_dset) {
00308 return "*************************\n"
00309 "Cannot find Input Dataset\n"
00310 "*************************";
00311 }
00312
00313 /*--------- go to second input line ---------*/
00314
00315 PLUTO_next_option(plint);
00316
00317 new_prefix = PLUTO_get_string(plint); /* get string item (the output prefix) */
00318 if(! PLUTO_prefix_ok(new_prefix)) { /* check if it is OK */
00319 return "************************\n"
00320 "Output Prefix is illegal\n"
00321 "************************";
00322 }
00323
00324 /*--------- go to next input lines ---------*/
00325
00326 PLUTO_next_option(plint); /* skip to next line */
00327
00328 mapFile = PLUTO_get_string(plint); /* get the map filename */
00329 if(NULL == mapFile || access(mapFile, R_OK) < 0) { /* check if it is OK and readable */
00330 return "****************************\n"
00331 "Epoch map file is unreadable\n"
00332 "****************************";
00333 }
00334
00335 dupstr = PLUTO_get_string(plint); /* get the string item */
00336 dupaction = PLUTO_string_index(dupstr, /* find it in the list it came from */
00337 NUM_DUPACTION_STRINGS,
00338 dupaction_strings);
00339
00340 /********************************************************/
00341 /*********** At this point, the inputs are OK ***********/
00342
00343 PLUTO_popup_meter(plint); /* popup a progress meter */
00344
00345 /*--------- set up pointers to each sub-brick in the input dataset ---------*/
00346
00347 #ifdef DEBUG_PLUGIN_REORDER
00348 printf("[Reorder] Loading dataset into memory...\n");
00349 #endif
00350 DSET_load(old_dset); /* must be in memory before we get pointers to it */
00351
00352 nvox = /* number of voxels per sub-brick */
00353 old_dset->daxes->nxx * old_dset->daxes->nyy * old_dset->daxes->nzz;
00354
00355 #ifdef DEBUG_PLUGIN_REORDER
00356 printf("[Reorder] %d voxels per subBRIK [%dx%dx%d].\n"
00357 , nvox, old_dset->daxes->nxx, old_dset->daxes->nyy, old_dset->daxes->nzz);
00358 #endif
00359
00360 ninp = DSET_NUM_TIMES(old_dset); /* get number of time points in old dataset */
00361 #ifdef DEBUG_PLUGIN_REORDER
00362 printf("[Reorder] %d time points [subBRIK].\n", ninp);
00363 #endif
00364
00365 /********************************************************/
00366 /*************** Parse the epoch map file ***************/
00367
00368 mapLength = ninp; /* initialize with the expected length for mapFile entries */
00369 if(NULL == (map = REORDER_parseMap(mapFile
00370 , &mapLength
00371 , &classKRH
00372 , &classCount))) {
00373 return "*******************************\n"
00374 "Critical error parsing map file\n"
00375 "*******************************";
00376 }
00377
00378 #ifdef DEBUG_PLUGIN_REORDER0
00379 printf("\n[Reorder] Indices for epoch remapping:\n");
00380 for(ii = 0; ii < mapLength; ii++) {
00381 printf("%d\n", map[ii]);
00382 }
00383
00384 printf("\n[Reorder] Meta-sequence of epoch classes is:\n");
00385 for(ii = 0; ii < classCount; ii++) {
00386 printf("[%d] Class %c [Width %d TRs]\n", ii, classKRH[ii].classKRH, classKRH[ii].length);
00387 }
00388 #endif
00389
00390 /* Sort 'class' to reflect the final order
00391 to aid in any epoch averaging required */
00392 qsort((void *)classKRH, classCount, sizeof(ClassInfo), compare_class);
00393
00394 #ifdef DEBUG_PLUGIN_REORDER
00395 printf("\n[Reorder] Sorted meta-sequence of epoch classes is:\n");
00396 for(ii = 0; ii < classCount; ii++) {
00397 printf("[%d] Class %c [Width %d TRs]\n", ii, classKRH[ii].classKRH, classKRH[ii].length);
00398 }
00399 #endif
00400
00401 old_datum /* get old dataset datum type */
00402 = DSET_BRICK_TYPE(old_dset, 0);
00403
00404 switch(old_datum) { /* pointer type depends on input datum type */
00405
00406 default:
00407 return "*******************************\n"
00408 "Illegal datum in Input Dataset\n"
00409 "******************************";
00410
00411 /**create array of pointers into old dataset sub-bricks **/
00412 /**Note that we skip the first 'ignore' sub-bricks here **/
00413
00414 /*---------- input is bytes -----------*/
00415 /* voxel #i at time #k is bPtr[k][i] */
00416 /* for i = 0..nvox-1 and k = 0..ninp-1.*/
00417
00418 case MRI_byte:
00419 /* Workspace for 3D+time data */
00420 bPtr = (byte **)calloc(sizeof(byte *), ninp);
00421 if(NULL == bPtr) {
00422 return "************************\n"
00423 "!! Allocation Failure !!\n"
00424 "************************";
00425 }
00426
00427 for(kk = 0; kk < ninp; kk++) {
00428 bPtr[kk] = (byte *)DSET_ARRAY(old_dset,kk);
00429 }
00430
00431 /* Array of pointers for reordering subBRIKS */
00432 bData = (byte **)calloc(sizeof(byte *), mapLength);
00433 if(NULL == bData) {
00434 FREEUP(bPtr);
00435 return "************************\n"
00436 "!! Allocation Failure !!\n"
00437 "************************";
00438 }
00439 /* Allocate memory for subBRIKS */
00440 for(kk = 0; kk < mapLength; kk++) {
00441 bData[kk] = (byte *)calloc(sizeof(byte), nvox);
00442 if(NULL == bData[kk]) {
00443 FREEUP(bPtr);
00444 FREEUP(bData);
00445 return "************************\n"
00446 "!! Allocation Failure !!\n"
00447 "************************";
00448 }
00449 }
00450 break;
00451
00452 /*---------- input is shorts ----------*/
00453 /* voxel #i at time #k is sPtr[k][i] */
00454 /* for i = 0..nvox-1 and k = 0..ninp-1.*/
00455
00456 case MRI_short:
00457 /* Workspace for 3D+time data */
00458 sPtr = (short **)calloc(sizeof(short *), ninp);
00459 if(NULL == sPtr) {
00460 return "************************\n"
00461 "!! Allocation Failure !!\n"
00462 "************************";
00463 }
00464
00465 for(kk = 0; kk < ninp; kk++) {
00466 sPtr[kk] = (short *)DSET_ARRAY(old_dset,kk);
00467 }
00468
00469 /* Array of pointers for reordering subBRIKS */
00470 sData = (short **)calloc(sizeof(short *), mapLength);
00471 if(NULL == sData) {
00472 FREEUP(sPtr);
00473 return "************************\n"
00474 "!! Allocation Failure !!\n"
00475 "************************";
00476 }
00477 /* Allocate memory for subBRIKS */
00478 for(kk = 0; kk < mapLength; kk++) {
00479 sData[kk] = (short *)calloc(sizeof(short), nvox);
00480 if(NULL == sData[kk]) {
00481 FREEUP(sPtr);
00482 FREEUP(sData);
00483 return "************************\n"
00484 "!! Allocation Failure !!\n"
00485 "************************";
00486 }
00487 }
00488 break;
00489
00490 /*---------- input is floats ----------*/
00491 /* voxel #i at time #k is fPtr[k][i] */
00492 /* for i = 0..nvox-1 and k = 0..ninp-1.*/
00493
00494 case MRI_float:
00495 /* Workspace for 3D+time data */
00496 fPtr = (float **)calloc(sizeof(float *), ninp);
00497 if(NULL == fPtr) {
00498 return "************************\n"
00499 "!! Allocation Failure !!\n"
00500 "************************";
00501 }
00502
00503 for(kk = 0; kk < ninp; kk++) {
00504 fPtr[kk] = (float *)DSET_ARRAY(old_dset,kk);
00505 }
00506
00507 /* Array of pointers for reordering subBRIKS */
00508 fData = (float **)calloc(sizeof(float *), mapLength);
00509 if(NULL == fData) {
00510 FREEUP(fPtr);
00511 return "************************\n"
00512 "!! Allocation Failure !!\n"
00513 "************************";
00514 }
00515 /* Allocate memory for subBRIKS */
00516 for(kk = 0; kk < mapLength; kk++) {
00517 fData[kk] = (float *)calloc(sizeof(float), nvox);
00518 if(NULL == fData[kk]) {
00519 FREEUP(fPtr);
00520 FREEUP(fData);
00521 return "************************\n"
00522 "!! Allocation Failure !!\n"
00523 "************************";
00524 }
00525 }
00526 break;
00527
00528 } /* end of switch on input type */
00529
00530 /*********************** Make a new dataset ***********************/
00531
00532 new_dset /* start with copy of old one */
00533 = EDIT_empty_copy(old_dset);
00534
00535 { char * his = PLUTO_commandstring(plint) ;
00536 tross_Copy_History(old_dset,new_dset) ;
00537 tross_Append_History(new_dset,his) ; free(his);
00538 }
00539
00540 /*-- edit some of its internal parameters --*/
00541
00542 ii = EDIT_dset_items(
00543 new_dset,
00544 ADN_prefix , new_prefix, /* filename prefix */
00545 ADN_malloc_type, DATABLOCK_MEM_MALLOC, /* store in memory */
00546 ADN_nvals , mapLength, /* # time points */
00547 ADN_ntt , mapLength, /* # time points */
00548 ADN_none);
00549 if(0 != ii) {
00550 THD_delete_3dim_dataset(new_dset, False);
00551 switch(old_datum) {
00552 case MRI_byte:
00553 FREEUP(bPtr);
00554 FREEUP(bData);
00555 break;
00556 case MRI_short:
00557 FREEUP(sPtr);
00558 FREEUP(sData);
00559 break;
00560 case MRI_float:
00561 FREEUP(fPtr);
00562 FREEUP(fData);
00563 break;
00564 }
00565 FREE_WORKSPACE;
00566 return "***********************************\n"
00567 "Error while creating output dataset\n"
00568 "***********************************";
00569 }
00570
00571 /*****************************************************/
00572 /****** Setup has ended. Now do some real work. ******/
00573
00574 switch(old_datum) {
00575
00576 /*****************************************/
00577 /* voxel #i at time #k is array[kk][ii] */
00578 /* for ii = 0..nvox-1 and kk = 0..ninp-1.*/
00579
00580 case MRI_byte:
00581 #ifdef DEBUG_PLUGIN_REORDER
00582 printf("\n[Reorder] Collating/byte data...\n");
00583 #endif
00584
00585 /* Reorder the time-course of each voxel */
00586 for(kk = 0; kk < mapLength; kk++) {
00587 if(NULL == memcpy((void *)bData[kk]
00588 , (void *)bPtr[map[kk]]
00589 , sizeof(byte)*nvox)) {
00590 THD_delete_3dim_dataset(new_dset, False);
00591 FREEUP(bPtr);
00592 FREEUP(bData);
00593 FREE_WORKSPACE;
00594 return "***********************************\n"
00595 "!! Error performing memory copy !!\n"
00596 "**********************************";
00597 }
00598 perc = (100 * kk) / mapLength; /* display percentage done */
00599 PLUTO_set_meter(plint, perc); /* on the progress meter */
00600 }
00601
00602 PLUTO_set_meter(plint, 100); /* set progress meter to 100% */
00603
00604 if(dupaction) { /* new_dset may change in length again */
00605 /* Verify that averaging is possible:
00606 All duplicates must have the same length.
00607 */
00608 error = 0; /* start with no error */
00609 for(ii = 0; ii < classCount; ii++) {
00610 for(kk = 1; kk < (classCount-1); kk++) {
00611 if(classKRH[ii].classKRH == classKRH[kk].classKRH) {
00612 if(classKRH[ii].length != classKRH[kk].length) {
00613 error = 1; /* lengths differ! */
00614 break;
00615 }
00616 dupsToAverage = True; /* there is at least one duplicate to average */
00617 }
00618 }
00619 if(error) {
00620 PLUTO_popup_message(plint
00621 ,"*********************************************************\n"
00622 "* Duplicate stimulus regions in map file must have the *\n"
00623 "* same length for averaging. Returning collated regions.*\n"
00624 "*********************************************************");
00625 break;
00626 }
00627 }
00628
00629 if(!error) { /* average the crap */
00630 #ifdef DEBUG_PLUGIN_REORDER
00631 printf("[Reorder] All duplicate epochs have the same length...\n");
00632 #endif
00633
00634 if(dupsToAverage) {
00635 #ifdef DEBUG_PLUGIN_REORDER
00636 printf("[Reorder] Averaging duplicate epochs...\n");
00637 printf("[Reorder] Initial time-length is %d...\n", mapLength);
00638 #endif
00639
00640 newLength = mapLength; /* length may change after averaging, track new length */
00641
00642 /* Perform averaging */
00643 /* For each class, do: */
00644 for(ii = 0, startIndex = 0, timePoint = 0; ii < classCount;) {
00645 #ifdef DEBUG_PLUGIN_REORDER
00646 printf("[Reorder] Processing instances of class %c...\n"
00647 , classKRH[ii].classKRH);
00648 #endif
00649
00650 /* Get the number of duplicates of the current class */
00651 for(jj = ii + 1, instances = 1; jj < classCount; jj++, instances++) {
00652 if(classKRH[ii].classKRH != classKRH[jj].classKRH) {
00653 break;
00654 }
00655 }
00656
00657 #ifdef DEBUG_PLUGIN_REORDER
00658 printf(" %d instances of class %c...\n", instances, classKRH[ii].classKRH);
00659 #endif
00660
00661 if(instances > 1) {
00662 #ifdef DEBUG_PLUGIN_REORDER
00663 printf(" Averaging %d contiguous epochs...\n", instances);
00664 #endif
00665
00666 divisor = (double)instances;
00667
00668 /* For each time point in the duplicated classes: */
00669 for(jj = startIndex; jj < (classKRH[ii].length+startIndex); jj++, timePoint++) {
00670 /* For each voxel: */
00671 for(kk = 0; kk < nvox; kk++) {
00672 /* Average the duplicate time-points for the current voxel */
00673 for(mm = 0, sum = 0.0; mm < instances; mm++) {
00674 sum = sum + (double)bData[jj+(mm*classKRH[ii].length)][kk];
00675 }
00676 bData[timePoint][kk] = (byte)((sum / divisor) + 0.5);
00677 }
00678 }
00679
00680 /* Update final length of time-course */
00681 newLength = newLength - (classKRH[ii].length * (instances - 1));
00682
00683 /* Jump over the indices of all instances of the current class */
00684 startIndex = startIndex + (instances *classKRH[ii].length);
00685
00686 /* Go to the next class to process */
00687 ii += instances;
00688 }
00689 else { /* just copy the data points */
00690 #ifdef DEBUG_PLUGIN_REORDER
00691 printf(" Copying single epoch...\n");
00692 #endif
00693
00694 for(jj = startIndex; jj < (classKRH[ii].length+startIndex); jj++, timePoint++) {
00695 for(kk = 0; kk < nvox; kk++) {
00696 bData[timePoint][kk] = bData[jj][kk];
00697 }
00698 }
00699
00700 /* Jump to the index of the next class in the time-course */
00701 startIndex = startIndex + classKRH[ii].length;
00702
00703 /* eat up another class */
00704 ++ii;
00705 }
00706
00707 /* Update progress meter with the percentage done */
00708 perc = (100 * timePoint) / mapLength;
00709 PLUTO_set_meter(plint, perc);
00710 }
00711
00712 /* Set progress meter to 100% */
00713 PLUTO_set_meter(plint, 100);
00714
00715 #ifdef DEBUG_PLUGIN_REORDER
00716 printf("[Reorder] Final time-length is %d...\n", newLength);
00717 #endif
00718 ii = EDIT_dset_items(
00719 new_dset,
00720 ADN_nvals, newLength, /* # time points */
00721 ADN_ntt, newLength, /* # time points */
00722 ADN_none);
00723 if(0 != ii) {
00724 THD_delete_3dim_dataset(new_dset, False);
00725 FREEUP(bPtr);
00726 FREEUP(bData);
00727 FREE_WORKSPACE;
00728 return "******************************************\n"
00729 "!! Error while creating output dataset !!\n"
00730 "*****************************************";
00731 }
00732
00733 /* Free unused subBRIKS */
00734 if(newLength < mapLength) {
00735 #ifdef DEBUG_PLUGIN_REORDER
00736 printf("[Reorder] Freeing %d unused subBRIKs...\n", mapLength-newLength);
00737 #endif
00738 for(ii = newLength; ii < mapLength; ii++) {
00739 FREEUP(bData[ii]);
00740 }
00741 bData = (byte **)realloc((void *)bData, sizeof(byte *)*newLength);
00742 if(NULL == bData) {
00743 THD_delete_3dim_dataset(new_dset, False);
00744 FREEUP(bPtr);
00745 FREE_WORKSPACE;
00746 return "************************\n"
00747 "!! Reallocation error !!\n"
00748 "************************";
00749 }
00750 }
00751 mapLength = newLength;
00752 }
00753 }
00754 }
00755
00756 /* Write results into new dataset */
00757 #ifdef DEBUG_PLUGIN_REORDER
00758 printf("[Reorder] Writing %d subBRIKS into new data set...\n", mapLength);
00759 #endif
00760 for(kk = 0; kk < mapLength; kk++) {
00761 EDIT_substitute_brick(new_dset, kk, MRI_byte, bData[kk]);
00762 }
00763 break;
00764
00765 case MRI_short:
00766 #ifdef DEBUG_PLUGIN_REORDER
00767 printf("\n[Reorder] Collating/short data...\n");
00768 #endif
00769
00770 /* Reorder the time-course of each voxel */
00771 for(kk = 0; kk < mapLength; kk++) {
00772 if(NULL == memcpy((void *)sData[kk]
00773 , (void *)sPtr[map[kk]]
00774 , sizeof(short)*nvox)) {
00775 THD_delete_3dim_dataset(new_dset, False);
00776 FREEUP(sPtr);
00777 FREEUP(sData);
00778 FREE_WORKSPACE;
00779 return "***********************************\n"
00780 "!! Error performing memory copy !!\n"
00781 "**********************************";
00782 }
00783 perc = (100 * kk) / mapLength; /* display percentage done */
00784 PLUTO_set_meter(plint, perc); /* on the progress meter */
00785 }
00786
00787 PLUTO_set_meter(plint, 100); /* set progress meter to 100% */
00788
00789 if(dupaction) { /* new_dset may change in length again */
00790 /* Verify that averaging is possible:
00791 All duplicates must have the same length.
00792 */
00793 error = 0; /* start with no error */
00794 for(ii = 0; ii < classCount; ii++) {
00795 for(kk = 1; kk < (classCount-1); kk++) {
00796 if(classKRH[ii].classKRH == classKRH[kk].classKRH) {
00797 if(classKRH[ii].length != classKRH[kk].length) {
00798 error = 1; /* lengths differ! */
00799 break;
00800 }
00801 dupsToAverage = True; /* there is at least one duplicate to average */
00802 }
00803 }
00804 if(error) {
00805 PLUTO_popup_message(plint
00806 ,"*********************************************************\n"
00807 "* Duplicate stimulus regions in map file must have the *\n"
00808 "* same length for averaging. Returning collated regions.*\n"
00809 "*********************************************************");
00810 break;
00811 }
00812 }
00813
00814 if(!error) { /* average the crap */
00815 #ifdef DEBUG_PLUGIN_REORDER
00816 printf("[Reorder] All duplicate epochs have the same length...\n");
00817 #endif
00818
00819 if(dupsToAverage) {
00820 #ifdef DEBUG_PLUGIN_REORDER
00821 printf("[Reorder] Averaging duplicate epochs...\n");
00822 printf("[Reorder] Initial time-length is %d...\n", mapLength);
00823 #endif
00824
00825 newLength = mapLength; /* length may change after averaging, track new length */
00826
00827 /* Perform averaging */
00828 /* For each class, do: */
00829 for(ii = 0, startIndex = 0, timePoint = 0; ii < classCount;) {
00830 #ifdef DEBUG_PLUGIN_REORDER
00831 printf("[Reorder] Processing instances of class %c...\n"
00832 , classKRH[ii].classKRH);
00833 #endif
00834
00835 /* Get the number of duplicates of the current class */
00836 for(jj = ii + 1, instances = 1; jj < classCount; jj++, instances++) {
00837 if(classKRH[ii].classKRH != classKRH[jj].classKRH) {
00838 break;
00839 }
00840 }
00841
00842 #ifdef DEBUG_PLUGIN_REORDER
00843 printf(" %d instances of class %c...\n", instances, classKRH[ii].classKRH);
00844 #endif
00845
00846 if(instances > 1) {
00847 #ifdef DEBUG_PLUGIN_REORDER
00848 printf(" Averaging %d contiguous epochs...\n", instances);
00849 #endif
00850
00851 divisor = (double)instances;
00852
00853 /* For each time point in the duplicated classes: */
00854 for(jj = startIndex; jj < (classKRH[ii].length+startIndex); jj++, timePoint++) {
00855 /* For each voxel: */
00856 for(kk = 0; kk < nvox; kk++) {
00857 /* Average the duplicate time-points for the current voxel */
00858 for(mm = 0, sum = 0.0; mm < instances; mm++) {
00859 sum = sum + (double)sData[jj+(mm*classKRH[ii].length)][kk];
00860 }
00861 sData[timePoint][kk] = (short)((sum / divisor) + 0.5);
00862 }
00863 }
00864
00865 /* Update final length of time-course */
00866 newLength = newLength - (classKRH[ii].length * (instances - 1));
00867
00868 /* Jump over the indices of all instances of the current class */
00869 startIndex = startIndex + (instances *classKRH[ii].length);
00870
00871 /* Go to the next class to process */
00872 ii += instances;
00873 }
00874 else { /* just copy the data points */
00875 #ifdef DEBUG_PLUGIN_REORDER
00876 printf(" Copying single epoch...\n");
00877 #endif
00878
00879 for(jj = startIndex; jj < (classKRH[ii].length+startIndex); jj++, timePoint++) {
00880 for(kk = 0; kk < nvox; kk++) {
00881 sData[timePoint][kk] = sData[jj][kk];
00882 }
00883 }
00884
00885 /* Jump to the index of the next class in the time-course */
00886 startIndex = startIndex + classKRH[ii].length;
00887
00888 /* eat up another class */
00889 ++ii;
00890 }
00891
00892 /* Update progress meter with the percentage done */
00893 perc = (100 * timePoint) / mapLength;
00894 PLUTO_set_meter(plint, perc);
00895 }
00896
00897 /* Set progress meter to 100% */
00898 PLUTO_set_meter(plint, 100);
00899
00900 #ifdef DEBUG_PLUGIN_REORDER
00901 printf("[Reorder] Final time-length is %d...\n", newLength);
00902 #endif
00903 ii = EDIT_dset_items(
00904 new_dset,
00905 ADN_nvals, newLength, /* # time points */
00906 ADN_ntt, newLength, /* # time points */
00907 ADN_none);
00908 if(0 != ii) {
00909 THD_delete_3dim_dataset(new_dset, False);
00910 FREEUP(sPtr);
00911 FREEUP(sData);
00912 FREE_WORKSPACE;
00913 return "******************************************\n"
00914 "!! Error while creating output dataset !!\n"
00915 "*****************************************";
00916 }
00917
00918 /* Free unused subBRIKS */
00919 if(newLength < mapLength) {
00920 #ifdef DEBUG_PLUGIN_REORDER
00921 printf("[Reorder] Freeing %d unused subBRIKs...\n", mapLength-newLength);
00922 #endif
00923 for(ii = newLength; ii < mapLength; ii++) {
00924 FREEUP(sData[ii]);
00925 }
00926 sData = (short **)realloc((void *)sData, sizeof(short *)*newLength);
00927 if(NULL == sData) {
00928 THD_delete_3dim_dataset(new_dset, False);
00929 FREEUP(sPtr);
00930 FREE_WORKSPACE;
00931 return "*************************\n"
00932 "!! Reallocation error !!\n"
00933 "************************";
00934 }
00935 }
00936 mapLength = newLength;
00937 }
00938 }
00939 }
00940
00941 /* Write results into new dataset */
00942 #ifdef DEBUG_PLUGIN_REORDER
00943 printf("[Reorder] Writing %d subBRIKS into new data set...\n", mapLength);
00944 #endif
00945 for(kk = 0; kk < mapLength; kk++) {
00946 EDIT_substitute_brick(new_dset, kk, MRI_short, sData[kk]);
00947 }
00948 break;
00949
00950 case MRI_float:
00951 #ifdef DEBUG_PLUGIN_REORDER
00952 printf("\n[Reorder] Collating/float data...\n");
00953 #endif
00954
00955 /* Reorder the time-course of each voxel */
00956 for(kk = 0; kk < mapLength; kk++) {
00957 if(NULL == memcpy((void *)fData[kk]
00958 , (void *)fPtr[map[kk]]
00959 , sizeof(float)*nvox)) {
00960 THD_delete_3dim_dataset(new_dset, False);
00961 FREEUP(fPtr);
00962 FREEUP(fData);
00963 FREE_WORKSPACE;
00964 return "***********************************\n"
00965 "!! Error performing memory copy !!\n"
00966 "**********************************";
00967 }
00968 perc = (100 * kk) / mapLength; /* display percentage done */
00969 PLUTO_set_meter(plint, perc); /* on the progress meter */
00970 }
00971
00972 PLUTO_set_meter(plint, 100); /* set progress meter to 100% */
00973
00974 if(dupaction) { /* new_dset may change in length again */
00975 /* Verify that averaging is possible:
00976 All duplicates must have the same length.
00977 */
00978 error = 0; /* start with no error */
00979 for(ii = 0; ii < classCount; ii++) {
00980 for(kk = 1; kk < (classCount-1); kk++) {
00981 if(classKRH[ii].classKRH == classKRH[kk].classKRH) {
00982 if(classKRH[ii].length != classKRH[kk].length) {
00983 error = 1; /* lengths differ! */
00984 break;
00985 }
00986 dupsToAverage = True; /* there is at least one duplicate to average */
00987 }
00988 }
00989 if(error) {
00990 PLUTO_popup_message(plint
00991 ,"*********************************************************\n"
00992 "* Duplicate stimulus regions in map file must have the *\n"
00993 "* same length for averaging. Returning collated regions.*\n"
00994 "*********************************************************");
00995 break;
00996 }
00997 }
00998
00999 if(!error) { /* average the crap */
01000 #ifdef DEBUG_PLUGIN_REORDER
01001 printf("[Reorder] All duplicate epochs have the same length...\n");
01002 #endif
01003
01004 if(dupsToAverage) {
01005 #ifdef DEBUG_PLUGIN_REORDER
01006 printf("[Reorder] Averaging duplicate epochs...\n");
01007 printf("[Reorder] Initial time-length is %d...\n", mapLength);
01008 #endif
01009
01010 newLength = mapLength; /* length may change after averaging, track new length */
01011
01012 /* Perform averaging */
01013 /* For each class, do: */
01014 for(ii = 0, startIndex = 0, timePoint = 0; ii < classCount;) {
01015 #ifdef DEBUG_PLUGIN_REORDER
01016 printf("[Reorder] Processing instances of class %c...\n"
01017 , classKRH[ii].classKRH);
01018 #endif
01019
01020 /* Get the number of duplicates of the current class */
01021 for(jj = ii + 1, instances = 1; jj < classCount; jj++, instances++) {
01022 if(classKRH[ii].classKRH != classKRH[jj].classKRH) {
01023 break;
01024 }
01025 }
01026
01027 #ifdef DEBUG_PLUGIN_REORDER
01028 printf(" %d instances of class %c...\n", instances, classKRH[ii].classKRH);
01029 #endif
01030
01031 if(instances > 1) {
01032 #ifdef DEBUG_PLUGIN_REORDER
01033 printf(" Averaging %d contiguous epochs...\n", instances);
01034 #endif
01035
01036 divisor = (double)instances;
01037
01038 /* For each time point in the duplicated classes: */
01039 for(jj = startIndex; jj < (classKRH[ii].length+startIndex); jj++, timePoint++) {
01040 /* For each voxel: */
01041 for(kk = 0; kk < nvox; kk++) {
01042 /* Average the duplicate time-points for the current voxel */
01043 for(mm = 0, sum = 0.0; mm < instances; mm++) {
01044 sum = sum + (double)fData[jj+(mm*classKRH[ii].length)][kk];
01045 }
01046 fData[timePoint][kk] = (float)((sum / divisor) + 0.5);
01047 }
01048 }
01049
01050 /* Update final length of time-course */
01051 newLength = newLength - (classKRH[ii].length * (instances - 1));
01052
01053 /* Jump over the indices of all instances of the current class */
01054 startIndex = startIndex + (instances *classKRH[ii].length);
01055
01056 /* Go to the next class to process */
01057 ii += instances;
01058 }
01059 else { /* just copy the data points */
01060 #ifdef DEBUG_PLUGIN_REORDER
01061 printf(" Copying single epoch...\n");
01062 #endif
01063
01064 for(jj = startIndex; jj < (classKRH[ii].length+startIndex); jj++, timePoint++) {
01065 for(kk = 0; kk < nvox; kk++) {
01066 fData[timePoint][kk] = fData[jj][kk];
01067 }
01068 }
01069
01070 /* Jump to the index of the next class in the time-course */
01071 startIndex = startIndex + classKRH[ii].length;
01072
01073 /* eat up another class */
01074 ++ii;
01075 }
01076
01077 /* Update progress meter with the percentage done */
01078 perc = (100 * timePoint) / mapLength;
01079 PLUTO_set_meter(plint, perc);
01080 }
01081
01082 /* Set progress meter to 100% */
01083 PLUTO_set_meter(plint, 100);
01084
01085 #ifdef DEBUG_PLUGIN_REORDER
01086 printf("[Reorder] Final time-length is %d...\n", newLength);
01087 #endif
01088 ii = EDIT_dset_items(
01089 new_dset,
01090 ADN_nvals, newLength, /* # time points */
01091 ADN_ntt, newLength, /* # time points */
01092 ADN_none);
01093 if(0 != ii) {
01094 THD_delete_3dim_dataset(new_dset, False);
01095 FREEUP(fPtr);
01096 FREEUP(fData);
01097 FREE_WORKSPACE;
01098 return "******************************************\n"
01099 "!! Error while creating output dataset !!\n"
01100 "*****************************************";
01101 }
01102
01103 /* Free unused subBRIKS */
01104 if(newLength < mapLength) {
01105 #ifdef DEBUG_PLUGIN_REORDER
01106 printf("[Reorder] Freeing %d unused subBRIKs...\n", mapLength-newLength);
01107 #endif
01108 for(ii = newLength; ii < mapLength; ii++) {
01109 FREEUP(fData[ii]);
01110 }
01111 fData = (float **)realloc((void *)fData, sizeof(float *)*newLength);
01112 if(NULL == fData) {
01113 THD_delete_3dim_dataset(new_dset, False);
01114 FREEUP(fPtr);
01115 FREE_WORKSPACE;
01116 return "*************************\n"
01117 "!! Reallocation error !!\n"
01118 "************************";
01119 }
01120 }
01121 mapLength = newLength;
01122 }
01123 }
01124 }
01125
01126 /* Write results into new dataset */
01127 #ifdef DEBUG_PLUGIN_REORDER
01128 printf("[Reorder] Writing %d subBRIKS into new data set...\n", mapLength);
01129 #endif
01130 for(kk = 0; kk < mapLength; kk++) {
01131 EDIT_substitute_brick(new_dset, kk, MRI_float, fData[kk]);
01132 }
01133 break;
01134
01135 } /* end of switch over input type */
01136
01137 DSET_unload(old_dset);
01138
01139 /*************** Cleanup and go home *****************/
01140
01141 PLUTO_add_dset(plint, new_dset, DSET_ACTION_MAKE_CURRENT);
01142
01143 #ifdef DEBUG_PLUGIN_REORDER
01144 printf("[Reorder] Cleaning up workspace...\n");
01145 #endif
01146 FREE_WORKSPACE;
01147
01148 return NULL; /* NULL string returned means all was OK */
01149 }
|
Variable Documentation
|
|
Initial value:
{ "Collate", "Average" }Definition at line 101 of file plug_reorder.c. Referenced by PLUGIN_init(), and REORDER_main(). |
|
|
Definition at line 42 of file plug_reorder.c. Referenced by PLUGIN_init(). |