00001 
00002 
00003 
00004 
00005 
00006 
00007 #ifndef __MAIN_PLUGIN_REORDER_C__
00008 #define __MAIN_PLUGIN_REORDER_C__
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 #define MAIN_PLUGIN_REORDER
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 typedef struct { 
00038         char classKRH;  
00039         int length;  
00040         } ClassInfo;
00041 
00042 static char helpstring[] = 
00043                 "Purpose: Reorders voxel time-courses within a 3D+time BRIK.\n"
00044                 "Input  : Name of the 3D+time dataset to reorder.\n"
00045                 "\n"
00046                 "Output : Prefix of filename for the new dataset.\n"
00047                 "\n"
00048                 "Map file : Text file with instructions a reordering the input dataset.\n"
00049                 "       Sample map file:\n"
00050                 "               # Experiment: Bogus\n"
00051                 "               # Date: April 1, 1997\n"
00052                 "               -\n"
00053                 "               -\n"
00054                 "               D1\n"
00055                 "               D2\n"
00056                 "               D3\n"
00057                 "               B1\n"
00058                 "               B2\n"
00059                 "               B3\n"
00060                 "               B4\n"
00061                 "               -\n"
00062                 "               a1\n"
00063                 "               a2\n"
00064                 "               a3\n"
00065                 "               A1\n"
00066                 "               A2\n"
00067                 "               A3\n"
00068                 "               A1\n"
00069                 "               A2\n"
00070                 "               A3\n"
00071                 "               -\n"
00072                 "\n"
00073                 "       # : Comment line (ignored)\n"
00074                 "       - : Point to be omitted from the output time-series. In the sample map,\n"
00075                 "               time points 1, 2, 10, and 20 will be omitted.\n"
00076                 "       Each non-comment line in a map file corresponds to a point in the time-series of\n"
00077                 "       an input 3D+time dataset. Codes for each time point define the plug-in action for\n"
00078                 "       those points. For example, the code in the fifth non-comment line of the sample\n"
00079                 "       above, 'D3', means that the fifth point in the time-series is the third point in\n"
00080                 "       the presentation of a stimulus named 'D'. \n"
00081                 "               Stimulus codes are single alphabetic characters and are case-sensitive, with\n"
00082                 "       uppercase preceding lowercase in the reordering (i.e., A-Z then a-z). Stimulus\n"
00083                 "       regions are numbered starting from 1 (i.e., [ X0 X1 X2 ] and [ X1 X3 X5 ] will\n"
00084                 "       cause the plug-in to abort), and, as shown in the sample with the code 'A', this\n"
00085                 "       delimits duplicate instances of the same stimulus code. For the sample map, images\n"
00086                 "       would be reordered so that the output time-series is:\n"
00087                 "                                       [ A1 A2 A3 A1 A2 A3 B1 B2 B3 B4 C1 C2 C3 a1 a2 a3 ]\n"
00088                 "\n"
00089                 "Duplicates : If there are duplicates of a stimulus presentation within a map (e.g.,\n"
00090                 "[ A1 A2 A3 ] in the sample), they can be:\n"
00091                 "       1) Collated: Duplicate instances of a stimulus will be placed in the order in\n"
00092                 "               which they occur in the map. In the case of the sample, this results in the\n"
00093                 "               ordering [ A1 A2 A3 A1 A2 A3 ... ].\n"
00094                 "       2) Averaged: Duplicate instances of a stimulus will be averaged. In the sample,\n"
00095                 "               this would result in the ordering [ A1' A2' A3' ... ], where Ai' is the mean\n"
00096                 "               of the i-th point of all of the stimulus A's present in the map file.\n"
00097                 "       **Duplicate stimulus regions must have the same length! For example,\n"
00098                 "       [ D1 D2 X1 D1 D2 D3 ] will cause the plug-in to abort.\n"
00099                 ;
00100 
00101 static char *dupaction_strings[] =  
00102                 { "Collate", "Average" };
00103 
00104 #define NUM_DUPACTION_STRINGS (sizeof(dupaction_strings)/sizeof(char *))
00105 
00106 
00107 
00108 
00109 
00110 #include "afni.h"
00111 
00112 #include <unistd.h>
00113 #include "plug_reorder_parseMap.c"
00114 
00115 
00116 
00117 
00118 
00119 char *REORDER_main(PLUGIN_interface *);
00120 
00121 
00122 
00123 
00124 
00125 int compare_class(const void *i, const void *j)
00126 
00127 
00128 
00129 {
00130 ClassInfo *iTmp = (ClassInfo *)i;
00131 ClassInfo *jTmp = (ClassInfo *)j;
00132 
00133 if(iTmp->classKRH == jTmp->classKRH) {
00134         return(0);
00135         }
00136 else if(iTmp->classKRH < jTmp->classKRH) {
00137         return(-1);
00138         }
00139 else {
00140         return(1);
00141         }
00142 }
00143 
00144 
00145 
00146 
00147 
00148 
00149 
00150 
00151 
00152 
00153 
00154 
00155 
00156 
00157 
00158 DEFINE_PLUGIN_PROTOTYPE
00159 
00160 PLUGIN_interface *PLUGIN_init(int ncall)
00161 {
00162 PLUGIN_interface *plint;  
00163 
00164 if(ncall >= 1) { 
00165         return NULL;
00166         }
00167 
00168 
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 
00179 
00180 PLUTO_add_option(plint,
00181                                 "Input",
00182                                 "Input",
00183                                  TRUE           
00184                                  );
00185 
00186 PLUTO_add_dataset(plint,
00187                                   "---->>",          
00188                                   ANAT_ALL_MASK,     
00189                                   0,                 
00190                                   DIMEN_4D_MASK |    
00191                                   BRICK_ALLTYPE_MASK 
00192                                   );
00193 
00194 
00195 
00196 PLUTO_add_option(plint,
00197                                  "Output",  
00198                                  "Output",  
00199                                  TRUE       
00200                                  );
00201 
00202 PLUTO_add_string(plint,
00203                                  "Prefix",  
00204                                  0,NULL,    
00205                                  19         
00206                                  );
00207 
00208 
00209 
00210 PLUTO_add_option(plint,
00211                                  "Map file",  
00212                                  "MapFile",   
00213                                  TRUE         
00214                                  );
00215 
00216 PLUTO_add_string(plint,
00217                                  "FileName",  
00218                                  0,NULL,      
00219                                  19           
00220                                  );
00221 
00222 PLUTO_add_string(plint,
00223                                  "Duplicates",          
00224                                  NUM_DUPACTION_STRINGS, 
00225                                  dupaction_strings,     
00226                                  0                      
00227                                  );
00228 
00229 
00230 
00231 return plint;
00232 }
00233 
00234 
00235 
00236 
00237 
00238 
00239 #undef  FREEUP
00240 #define FREEUP(thing) if((thing) != NULL) {free((thing)); (thing) = NULL;}
00241 
00242 #define FREE_WORKSPACE do{ FREEUP(bPtr); FREEUP(sPtr); FREEUP(fPtr); \
00243                                                    FREEUP(map); FREEUP(classKRH); } while(0)
00244 
00245 
00246 
00247 
00248 
00249 
00250 
00251 char *REORDER_main(PLUGIN_interface *plint)
00252 {
00253 MCW_idcode *idc;            
00254 THD_3dim_dataset *old_dset; 
00255 THD_3dim_dataset *new_dset; 
00256 
00257 ClassInfo *classKRH;           
00258 
00259 char *new_prefix;           
00260 char *mapFile;              
00261 char *dupstr;               
00262 char currentClass;          
00263 
00264 register int ii;            
00265 register int jj;
00266 register int kk;
00267 register int mm;
00268 
00269 int perc;                   
00270 int ninp;                   
00271 int nvox;                   
00272 int old_datum;              
00273 int error;                  
00274 int startIndex;             
00275 int currentLength;          
00276 int newLength;              
00277 int instances;              
00278 int timePoint;              
00279 int *map;                   
00280 int mapLength;              
00281 int dupaction;              
00282 int classCount;             
00283 
00284 double sum;                 
00285 double divisor;             
00286 
00287 byte  **bPtr = NULL;        
00288 short **sPtr = NULL;        
00289 float **fPtr = NULL;        
00290 
00291 byte  **bData = NULL;       
00292 short **sData = NULL;       
00293 float **fData = NULL;       
00294 
00295 Bool dupsToAverage = False; 
00296 
00297 
00298 
00299 
00300 
00301 
00302 PLUTO_next_option(plint);
00303 
00304 idc     = PLUTO_get_idcode(plint);    
00305 
00306 old_dset = PLUTO_find_dset(idc);  
00307 if(NULL == old_dset) {
00308         return "*************************\n"
00309                         "Cannot find Input Dataset\n"
00310                         "*************************";
00311         }
00312 
00313 
00314 
00315 PLUTO_next_option(plint);
00316 
00317 new_prefix = PLUTO_get_string(plint);   
00318 if(! PLUTO_prefix_ok(new_prefix)) {     
00319         return "************************\n"
00320                         "Output Prefix is illegal\n"
00321                         "************************";
00322         }
00323 
00324 
00325 
00326 PLUTO_next_option(plint); 
00327 
00328 mapFile = PLUTO_get_string(plint);                  
00329 if(NULL == mapFile || access(mapFile, R_OK) < 0) {  
00330         return "****************************\n"
00331                         "Epoch map file is unreadable\n"
00332                         "****************************";
00333         }
00334 
00335 dupstr = PLUTO_get_string(plint);         
00336 dupaction = PLUTO_string_index(dupstr,    
00337                                                            NUM_DUPACTION_STRINGS,
00338                                                            dupaction_strings);
00339 
00340 
00341 
00342 
00343 PLUTO_popup_meter(plint);  
00344 
00345 
00346 
00347 #ifdef DEBUG_PLUGIN_REORDER
00348 printf("[Reorder] Loading dataset into memory...\n");
00349 #endif
00350 DSET_load(old_dset);      
00351 
00352 nvox = 
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); 
00361 #ifdef DEBUG_PLUGIN_REORDER
00362 printf("[Reorder] %d time points [subBRIK].\n", ninp);
00363 #endif
00364 
00365 
00366 
00367 
00368 mapLength = ninp; 
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 
00391 
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 
00402         = DSET_BRICK_TYPE(old_dset, 0);
00403 
00404 switch(old_datum) { 
00405 
00406         default:
00407                 return "*******************************\n"
00408                                 "Illegal datum in Input Dataset\n"
00409                                 "******************************";
00410 
00411 
00412 
00413 
00414         
00415         
00416         
00417 
00418         case MRI_byte:
00419                 
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                 
00432                 bData = (byte **)calloc(sizeof(byte *), mapLength);
00433                 if(NULL == bData) {
00434                         FREEUP(bPtr);
00435                         return "************************\n"
00436                                    "!! Allocation Failure !!\n"
00437                                    "************************";
00438                         }
00439                 
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         
00453         
00454         
00455 
00456         case MRI_short:
00457                 
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                 
00470                 sData = (short **)calloc(sizeof(short *), mapLength);
00471                 if(NULL == sData) {
00472                         FREEUP(sPtr);
00473                         return "************************\n"
00474                                    "!! Allocation Failure !!\n"
00475                                    "************************";
00476                         }
00477                 
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         
00491         
00492         
00493 
00494         case MRI_float:
00495                 
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                 
00508                 fData = (float **)calloc(sizeof(float *), mapLength);
00509                 if(NULL == fData) {
00510                         FREEUP(fPtr);
00511                         return "************************\n"
00512                                    "!! Allocation Failure !!\n"
00513                                    "************************";
00514                         }
00515                 
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         } 
00529 
00530 
00531 
00532 new_dset 
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 
00541 
00542 ii = EDIT_dset_items(
00543                 new_dset,
00544                         ADN_prefix     , new_prefix,           
00545                         ADN_malloc_type, DATABLOCK_MEM_MALLOC, 
00546                         ADN_nvals      , mapLength,            
00547                         ADN_ntt        , mapLength,            
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 
00573 
00574 switch(old_datum) {
00575 
00576         
00577         
00578         
00579 
00580         case MRI_byte:
00581                 #ifdef DEBUG_PLUGIN_REORDER
00582                 printf("\n[Reorder] Collating/byte data...\n");
00583                 #endif
00584                 
00585                 
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; 
00599                         PLUTO_set_meter(plint, perc); 
00600                         }
00601                 
00602                 PLUTO_set_meter(plint, 100);      
00603                 
00604                 if(dupaction) { 
00605                         
00606 
00607 
00608                         error = 0; 
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; 
00614                                                         break;
00615                                                         }
00616                                                 dupsToAverage = True; 
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) { 
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; 
00641                 
00642                                         
00643                                         
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                                                 
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                                                         
00669                                                         for(jj = startIndex; jj < (classKRH[ii].length+startIndex); jj++, timePoint++) {
00670                                                                 
00671                                                                 for(kk = 0; kk < nvox; kk++) {
00672                                                                         
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                                                         
00681                                                         newLength = newLength - (classKRH[ii].length * (instances - 1));
00682                 
00683                                                         
00684                                                         startIndex = startIndex + (instances *classKRH[ii].length);
00685                 
00686                                                         
00687                                                         ii += instances;
00688                                                         }
00689                                                 else { 
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                                                         
00701                                                         startIndex = startIndex + classKRH[ii].length;
00702                 
00703                                                         
00704                                                         ++ii;
00705                                                         }
00706                 
00707                                                 
00708                                                 perc = (100 * timePoint) / mapLength;
00709                                                 PLUTO_set_meter(plint, perc);
00710                                                 }
00711                         
00712                                         
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,  
00721                                                                         ADN_ntt,   newLength,  
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                                         
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                 
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                 
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; 
00784                         PLUTO_set_meter(plint, perc); 
00785                         }
00786                 
00787                 PLUTO_set_meter(plint, 100);      
00788                 
00789                 if(dupaction) { 
00790                         
00791 
00792 
00793                         error = 0; 
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; 
00799                                                         break;
00800                                                         }
00801                                                 dupsToAverage = True; 
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) { 
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; 
00826                 
00827                                         
00828                                         
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                                                 
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                                                         
00854                                                         for(jj = startIndex; jj < (classKRH[ii].length+startIndex); jj++, timePoint++) {
00855                                                                 
00856                                                                 for(kk = 0; kk < nvox; kk++) {
00857                                                                         
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                                                         
00866                                                         newLength = newLength - (classKRH[ii].length * (instances - 1));
00867                 
00868                                                         
00869                                                         startIndex = startIndex + (instances *classKRH[ii].length);
00870                 
00871                                                         
00872                                                         ii += instances;
00873                                                         }
00874                                                 else { 
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                                                         
00886                                                         startIndex = startIndex + classKRH[ii].length;
00887                 
00888                                                         
00889                                                         ++ii;
00890                                                         }
00891                 
00892                                                 
00893                                                 perc = (100 * timePoint) / mapLength;
00894                                                 PLUTO_set_meter(plint, perc);
00895                                                 }
00896                         
00897                                         
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,  
00906                                                                         ADN_ntt,   newLength,  
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                                         
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                 
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                 
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; 
00969                         PLUTO_set_meter(plint, perc); 
00970                         }
00971                 
00972                 PLUTO_set_meter(plint, 100);      
00973                 
00974                 if(dupaction) { 
00975                         
00976 
00977 
00978                         error = 0; 
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; 
00984                                                         break;
00985                                                         }
00986                                                 dupsToAverage = True; 
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) { 
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; 
01011                 
01012                                         
01013                                         
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                                                 
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                                                         
01039                                                         for(jj = startIndex; jj < (classKRH[ii].length+startIndex); jj++, timePoint++) {
01040                                                                 
01041                                                                 for(kk = 0; kk < nvox; kk++) {
01042                                                                         
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                                                         
01051                                                         newLength = newLength - (classKRH[ii].length * (instances - 1));
01052                 
01053                                                         
01054                                                         startIndex = startIndex + (instances *classKRH[ii].length);
01055                 
01056                                                         
01057                                                         ii += instances;
01058                                                         }
01059                                                 else { 
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                                                         
01071                                                         startIndex = startIndex + classKRH[ii].length;
01072                 
01073                                                         
01074                                                         ++ii;
01075                                                         }
01076                 
01077                                                 
01078                                                 perc = (100 * timePoint) / mapLength;
01079                                                 PLUTO_set_meter(plint, perc);
01080                                                 }
01081                         
01082                                         
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,  
01091                                                                         ADN_ntt,   newLength,  
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                                         
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                 
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         } 
01136 
01137 DSET_unload(old_dset);
01138 
01139 
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;    
01149 }
01150 
01151 #endif
01152