Skip to content

AFNI/NIfTI Server

Sections
Personal tools
You are here: Home » AFNI » Documentation

Doxygen Source Code Documentation


Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals   Search  

SUMA_SurfClust.c File Reference

#include "SUMA_suma.h"

Go to the source code of this file.


Defines

#define SUMA_ADD_NODE_TO_CLUST(dothisnode, Clust, NodeArea, ToBeAssigned)

Enumerations

enum  SUMA_CLUST_BUILD_METHODS { SUMA_NO_BUILD_METHOD, SUMA_OFFSETS2, SUMA_OFFSETS_LL, SUMA_OFFSETS2_NO_REC }

Functions

void SUMA_FreeClustDatum (void *data)
float * SUMA_CalculateNodeAreas (SUMA_SurfaceObject *SO)
 Calculate area of each node as one third of the sum of the areas of incident triangles. If you change this function make sure changes are also done on RickR's compute_node_areas since the two functions use the same principle.

SUMA_CLUST_DATUMSUMA_Build_Cluster_From_Node (int dothisnode, SUMA_CLUST_DATUM *AddToThisClust, float *ToBeAssigned, int *N_TobeAssigned, float *NodeArea, SUMA_SurfaceObject *SO, SUMA_SURFCLUST_OPTIONS *Opt)
 builds a cluster starting from some node

SUMA_CLUST_DATUMSUMA_Build_Cluster_From_Node_NoRec (int dothisnode, float *ToBeAssigned, int *N_TobeAssigned, float *NodeArea, SUMA_SurfaceObject *SO, SUMA_SURFCLUST_OPTIONS *Opt)
 builds a cluster starting from some node

DListSUMA_FindClusters (SUMA_SurfaceObject *SO, int *ni, float *nv, int N_ni, int dothisnode, SUMA_SURFCLUST_OPTIONS *Opt, float *NodeArea)
 Finds clusters of data on the surface.

SUMA_Boolean SUMA_Show_SurfClust_list (DList *list, FILE *Out, int detail, char *params)
char * SUMA_Show_SurfClust_list_Info (DList *list, int detail, char *params)
SUMA_DSETSUMA_MaskDsetByClustList (SUMA_DSET *idset, SUMA_SurfaceObject *SO, DList *list, SUMA_Boolean FullList, char *leName)
SUMA_DSETSUMA_SurfClust_list_2_DsetMask (SUMA_SurfaceObject *SO, DList *list, SUMA_Boolean FullList, char *leName)
int SUMA_ClusterCenterofMass (SUMA_SurfaceObject *SO, SUMA_CLUST_DATUM *cd, int UseSurfDist)
 Finds a node that best approximates the property of the center of mass on the surface. Note that the real center of mass of a curved surface is rarely on the surface, so this is an attempt at localizing a node that is central to an ROI and that can reflect the weight, or activity, distribution in that ROI.

SUMA_Boolean SUMA_Sort_ClustersList (DList *list, SUMA_SURF_CLUST_SORT_MODES SortMode)

Variables

SUMA_CommonFieldsSUMAg_CF
SUMA_DOSUMAg_DOv
SUMA_SurfaceViewerSUMAg_SVv
int SUMAg_N_SVv
int SUMAg_N_DOv
int BuildMethod

Define Documentation

#define SUMA_ADD_NODE_TO_CLUST dothisnode,
Clust,
NodeArea,
ToBeAssigned   
 

Value:

{   \
   if (LocalHead) fprintf(SUMA_STDERR,"%s: Adding node %d to cluster %p of %d nodes\n", FuncName, dothisnode, Clust, Clust->N_Node);   \
   Clust->NodeList[Clust->N_Node] = dothisnode; \
   Clust->totalarea += NodeArea[dothisnode]; \
   Clust->totalvalue += ToBeAssigned[dothisnode];  \
   Clust->totalabsvalue += (float)fabs((float)ToBeAssigned[dothisnode]);   \
   if (ToBeAssigned[dothisnode] < Clust->minvalue) { Clust->minvalue = ToBeAssigned[dothisnode]; Clust->minnode = dothisnode; }  \
   if (ToBeAssigned[dothisnode] > Clust->maxvalue) { Clust->maxvalue = ToBeAssigned[dothisnode]; Clust->maxnode = dothisnode; }  \
   Clust->ValueList[Clust->N_Node] = ToBeAssigned[dothisnode]; \
   ++Clust->N_Node;  \
}
A macro for SUMA_Build_Cluster_From_Node_NoRec

Definition at line 246 of file SUMA_SurfClust.c.

Referenced by SUMA_Build_Cluster_From_Node_NoRec().


Enumeration Type Documentation

enum SUMA_CLUST_BUILD_METHODS
 

Enumeration values:
SUMA_NO_BUILD_METHOD 
SUMA_OFFSETS2 
SUMA_OFFSETS_LL 
SUMA_OFFSETS2_NO_REC 

Definition at line 27 of file SUMA_SurfClust.c.


Function Documentation

SUMA_CLUST_DATUM* SUMA_Build_Cluster_From_Node int    dothisnode,
SUMA_CLUST_DATUM   AddToThisClust,
float *    ToBeAssigned,
int *    N_TobeAssigned,
float *    NodeArea,
SUMA_SurfaceObject   SO,
SUMA_SURFCLUST_OPTIONS   Opt
 

builds a cluster starting from some node

Parameters:
dothisnode  (int) start building from this node
AddToThisClust  (SUMA_CLUST_DATUM *)pointer to cluster to add to. Send NULL when function is first called. This is a non NULL when the function recurses.
ToBeAssigned  (float *) if ToBeAssigned[i] then node i (index into SO's nodelist) is considered in the clustering and the value at that node is ToBeAssigned[i]. Vector is SO->N_Node elements long. Gets modified during recursion.
N_ToBeAssigned  (int *) pointer to number of value values in ToBeAssigned. Changes with recursive calls.
NodeArea  (float *) Vector containing area of each node of surface
SO  (SUMA_SurfaceObject *) the usual deal
Opt  (SUMA_SURFCLUST_OPTIONS *) options for cluster building.
See also:
recursive calls SUCK a lot of memory and are a nightmare to track with function I/O. They are also slow and not necessary!
See also:
SUMA_Build_Cluster_From_Node_NoRec

Definition at line 105 of file SUMA_SurfClust.c.

References BuildMethod, SUMA_CLUST_DATUM::centralnode, DListElmt_::data, SUMA_SURFCLUST_OPTIONS::DistLim, dlist_destroy(), dlist_head, dlist_tail, SUMA_OFFSET_LL_DATUM::layer, SUMA_GET_OFFSET_STRUCT::layers, LocalHead, SUMA_CLUST_DATUM::maxnode, SUMA_CLUST_DATUM::maxvalue, SUMA_CLUST_DATUM::minnode, SUMA_CLUST_DATUM::minvalue, SUMA_GET_OFFSET_STRUCT::N_layers, SUMA_CLUST_DATUM::N_Node, SUMA_SurfaceObject::N_Node, SUMA_NODE_NEIGHB_LAYER::N_NodesInLayer, DListElmt_::next, SUMA_OFFSET_LL_DATUM::ni, SUMA_CLUST_DATUM::NodeList, SUMA_NODE_NEIGHB_LAYER::NodesInLayer, SUMA_OFFSET_LL_DATUM::off, SUMA_GET_OFFSET_STRUCT::OffVect, SUMA_Boolean, SUMA_ENTRY, SUMA_free, SUMA_Free_getoffsets(), SUMA_getoffsets2(), SUMA_getoffsets_ll(), SUMA_Initialize_getoffsets(), SUMA_malloc, SUMA_OFFSETS2, SUMA_OFFSETS_LL, SUMA_RETURN, SUMA_ShowOffset_Info(), SUMA_ShowOffset_ll_Info(), SUMA_SL_Crit, SUMA_SL_Err, SUMA_CLUST_DATUM::totalabsvalue, SUMA_CLUST_DATUM::totalarea, SUMA_CLUST_DATUM::totalvalue, SUMA_CLUST_DATUM::ValueList, SUMA_CLUST_DATUM::varvalue, and SUMA_CLUST_DATUM::weightedcentralnode.

Referenced by SUMA_FindClusters().

00108 {
00109    static char FuncName[]={"SUMA_Build_Cluster_From_Node"};
00110    SUMA_CLUST_DATUM *Clust = NULL;
00111    static int ncall;
00112    int il, jl, neighb;
00113    SUMA_GET_OFFSET_STRUCT *OffS = NULL;
00114    DList *offlist = NULL;
00115    DListElmt *elm = NULL;
00116    SUMA_OFFSET_LL_DATUM *dat=NULL;
00117    int NewClust = 0;
00118    SUMA_Boolean LocalHead = NOPE;
00119    
00120    SUMA_ENTRY;
00121    ++ncall;
00122    if (dothisnode < 0) {
00123       SUMA_SL_Err("Unexpected negative index.");
00124       SUMA_RETURN(NULL);
00125    }
00126    if (!AddToThisClust) {
00127       Clust = (SUMA_CLUST_DATUM *)SUMA_malloc(sizeof(SUMA_CLUST_DATUM));   
00128       Clust->N_Node = 0; Clust->totalarea = 0.0; /* Clust->rank = -1; */  
00129       Clust->totalvalue = 0.0; Clust->totalabsvalue = 0.0;  
00130       Clust->minvalue = ToBeAssigned[dothisnode]; Clust->minnode = dothisnode;
00131       Clust->maxvalue = ToBeAssigned[dothisnode]; Clust->maxnode = dothisnode; 
00132       Clust->varvalue = 0.0;  Clust->centralnode = 0; Clust->weightedcentralnode = 0; 
00133       Clust->NodeList = (int *)SUMA_malloc((*N_TobeAssigned) * sizeof(int)); 
00134       Clust->ValueList = (float *)SUMA_malloc((*N_TobeAssigned) * sizeof(float));  
00135       if (!Clust->NodeList || !Clust->ValueList) { 
00136          SUMA_SL_Crit("Failed to allocate for NodeList or ValueList");  
00137          SUMA_free(Clust); Clust = NULL;
00138          SUMA_RETURN(NULL);  
00139       }
00140       NewClust = 1;
00141       if (LocalHead) fprintf (SUMA_STDERR,"%s: New Cluster     %p, with node %d\n", FuncName, Clust, dothisnode);
00142    } else { 
00143       NewClust = 0;
00144       Clust = AddToThisClust; 
00145       if (LocalHead) fprintf (SUMA_STDERR,"%s: Reusing Cluster %p, with node %d\n", FuncName, Clust, dothisnode);
00146    }
00147    
00148    /* Add node to cluster */
00149    if (LocalHead) fprintf(SUMA_STDERR,"%s: Adding node %d to cluster %p of %d nodes\n", FuncName, dothisnode, Clust, Clust->N_Node);
00150    Clust->NodeList[Clust->N_Node] = dothisnode; 
00151    Clust->totalarea += NodeArea[dothisnode]; 
00152    Clust->totalvalue += ToBeAssigned[dothisnode];
00153    Clust->totalabsvalue += (float)fabs((float)ToBeAssigned[dothisnode]);
00154    if (ToBeAssigned[dothisnode] < Clust->minvalue) { Clust->minvalue = ToBeAssigned[dothisnode]; Clust->minnode = dothisnode; }
00155    if (ToBeAssigned[dothisnode] > Clust->maxvalue) { Clust->maxvalue = ToBeAssigned[dothisnode]; Clust->maxnode = dothisnode; }
00156    Clust->ValueList[Clust->N_Node] = ToBeAssigned[dothisnode];
00157    ++Clust->N_Node;
00158 
00159    /* mark it as assigned, an reduce the number of nodes left to assign*/
00160    ToBeAssigned[dothisnode] = 0; --(*N_TobeAssigned);
00161    
00162    if (BuildMethod == SUMA_OFFSETS2) {
00163       /* Tres bad memory utilization due to recursive calls */
00164       if (*N_TobeAssigned) {
00165          /* look in its vicinity - bad memory usage due to recursive calls*/
00166          OffS = SUMA_Initialize_getoffsets (SO->N_Node);
00167          SUMA_getoffsets2 (dothisnode, SO, Opt->DistLim, OffS, NULL, 0);
00168          #if 0
00169          if (NewClust) {
00170             FILE *fid=NULL;
00171             char *s=NULL, tmp[50];
00172             fid = fopen("offsets2.1D", "w"); 
00173             if (!fid) {
00174                SUMA_SL_Err("Could not open file for writing.\nCheck file permissions, disk space.\n");
00175             } else {
00176                s = SUMA_ShowOffset_Info(OffS, 0);
00177                if (s) { fprintf(fid,"%s\n", s);  SUMA_free(s); s = NULL;}
00178                fclose(fid);
00179             }      
00180          }
00181          #endif
00182          /* search to see if any are to be assigned */
00183          for (il=1; il<OffS->N_layers; ++il) { /* starting at layer 1, layer 0 is the node itself */
00184             for (jl=0; jl<OffS->layers[il].N_NodesInLayer; ++jl) {
00185                neighb = OffS->layers[il].NodesInLayer[jl];
00186                if (ToBeAssigned[neighb] && OffS->OffVect[neighb] <= Opt->DistLim) {
00187                      /* take that node into the cluster */
00188                      SUMA_Build_Cluster_From_Node( neighb, Clust, ToBeAssigned, N_TobeAssigned, NodeArea, SO, Opt); 
00189                }
00190             }
00191          }
00192          /* free this OffS structure (Note you can't recycle the same structure because you are using many
00193          OffS at one because of recursive calls */
00194          if (OffS) SUMA_Free_getoffsets(OffS); OffS = NULL;
00195       }
00196    } else if (BuildMethod == SUMA_OFFSETS_LL) { 
00197       if (*N_TobeAssigned) {
00198          /* look in its vicinity */
00199          if (!(offlist = SUMA_getoffsets_ll (dothisnode, SO, Opt->DistLim, NULL, 0))) {
00200             SUMA_SL_Err("Failed to get offsets.\nNo cleanup done.");
00201             SUMA_RETURN(NULL);
00202          }
00203          #if 0
00204          if (NewClust) {
00205             FILE *fid=NULL;
00206             char *s=NULL, tmp[50];
00207             fid = fopen("offsets_ll.1D", "w"); 
00208             if (!fid) {
00209                SUMA_SL_Err("Could not open file for writing.\nCheck file permissions, disk space.\n");
00210             } else {
00211                s = SUMA_ShowOffset_ll_Info(offlist, 0);
00212                if (s) { fprintf(fid,"%s\n", s);  SUMA_free(s); s = NULL;}
00213                fclose(fid);
00214             }      
00215          }
00216          #endif
00217 
00218          /* search to see if any are to be assigned, start at layer 1*/
00219          elm = dlist_head(offlist);
00220          dat = (SUMA_OFFSET_LL_DATUM *)elm->data;
00221          if (dat->layer != 0) {
00222             SUMA_SL_Err("Unexpected non zero layer for first element.");
00223             SUMA_RETURN(NULL);
00224          }
00225          do {
00226             elm = elm->next;
00227             dat = (SUMA_OFFSET_LL_DATUM *)elm->data;
00228             neighb = dat->ni;
00229             if (ToBeAssigned[neighb] && dat->off <= Opt->DistLim) {
00230                /* take that node into the cluster */
00231                SUMA_Build_Cluster_From_Node( neighb, Clust, ToBeAssigned, N_TobeAssigned, NodeArea, SO, Opt); 
00232             }      
00233          } while (elm != dlist_tail(offlist));
00234          dlist_destroy(offlist);  
00235       }      
00236    }
00237    
00238    /* If you ever use this function again, you should probably SUMA_free(offlist); dlist_destroy(candlist); SUMA_free(candlist); */
00239 
00240    SUMA_RETURN(Clust);
00241 }

SUMA_CLUST_DATUM* SUMA_Build_Cluster_From_Node_NoRec int    dothisnode,
float *    ToBeAssigned,
int *    N_TobeAssigned,
float *    NodeArea,
SUMA_SurfaceObject   SO,
SUMA_SURFCLUST_OPTIONS   Opt
 

builds a cluster starting from some node

Parameters:
dothisnode  (int) start building from this node
ToBeAssigned  (float *) if ToBeAssigned[i] then node i (index into SO's nodelist) is considered in the clustering and the value at that node is ToBeAssigned[i]. Vector is SO->N_Node elements long. Gets modified in function.
N_ToBeAssigned  (int *) pointer to number of value values in ToBeAssigned. Gets modified in function.
NodeArea  (float *) Vector containing area of each node of surface
SO  (SUMA_SurfaceObject *) the usual deal
Opt  (SUMA_SURFCLUST_OPTIONS *) options for cluster building.
See also:
Based on recursive SUMA_Build_Cluster_From_Node

Definition at line 273 of file SUMA_SurfClust.c.

References SUMA_CLUST_DATUM::centralnode, DListElmt_::data, SUMA_SURFCLUST_OPTIONS::DistLim, dlist_destroy(), dlist_head, dlist_init(), dlist_ins_next(), dlist_remove(), dlist_size, dlist_tail, itmp, SUMA_GET_OFFSET_STRUCT::layers, LocalHead, SUMA_CLUST_DATUM::maxnode, SUMA_CLUST_DATUM::maxvalue, SUMA_CLUST_DATUM::minnode, SUMA_CLUST_DATUM::minvalue, SUMA_GET_OFFSET_STRUCT::N_layers, SUMA_SurfaceObject::N_Node, SUMA_CLUST_DATUM::N_Node, SUMA_NODE_NEIGHB_LAYER::N_NodesInLayer, SUMA_CLUST_DATUM::NodeList, SUMA_NODE_NEIGHB_LAYER::NodesInLayer, SUMA_GET_OFFSET_STRUCT::OffVect, SUMA_ADD_NODE_TO_CLUST, SUMA_Boolean, SUMA_calloc, SUMA_ENTRY, SUMA_free, SUMA_Free_getoffsets(), SUMA_getoffsets2(), SUMA_Initialize_getoffsets(), SUMA_malloc, SUMA_Recycle_getoffsets(), SUMA_RETURN, SUMA_SL_Crit, SUMA_SL_Err, SUMA_CLUST_DATUM::totalabsvalue, SUMA_CLUST_DATUM::totalarea, SUMA_CLUST_DATUM::totalvalue, SUMA_SURFCLUST_OPTIONS::update, SUMA_CLUST_DATUM::ValueList, SUMA_CLUST_DATUM::varvalue, and SUMA_CLUST_DATUM::weightedcentralnode.

Referenced by SUMA_FindClusters().

00276 {
00277    static char FuncName[]={"SUMA_Build_Cluster_From_Node_NoRec"};
00278    SUMA_CLUST_DATUM *Clust = NULL;
00279    static int ncall;
00280    static int N_Orig = -1;
00281    int il, jl, neighb, itmp;
00282    SUMA_GET_OFFSET_STRUCT *OffS = NULL;
00283    DList *offlist = NULL, *candlist=NULL;
00284    DListElmt *elm = NULL, *dothiselm=NULL;
00285    SUMA_OFFSET_LL_DATUM *dat=NULL;
00286    int NewClust = 0;
00287    byte *visited=NULL;
00288    SUMA_Boolean LocalHead = NOPE;
00289    
00290    SUMA_ENTRY;
00291    ++ncall;
00292    /* a trick to know when to initialize */
00293    if (Opt->update < 0) { N_Orig = *N_TobeAssigned; Opt->update = -Opt->update; }
00294    
00295    if (dothisnode < 0) {
00296       SUMA_SL_Err("Unexpected negative index.");
00297       SUMA_RETURN(NULL);
00298    }
00299 
00300       OffS = SUMA_Initialize_getoffsets (SO->N_Node);
00301       Clust = (SUMA_CLUST_DATUM *)SUMA_malloc(sizeof(SUMA_CLUST_DATUM));   
00302       Clust->N_Node = 0; Clust->totalarea = 0.0; /* Clust->rank = -1; */  
00303       Clust->totalvalue = 0.0; Clust->totalabsvalue = 0.0;  
00304       Clust->minvalue = ToBeAssigned[dothisnode]; Clust->minnode = dothisnode;
00305       Clust->maxvalue = ToBeAssigned[dothisnode]; Clust->maxnode = dothisnode; 
00306       Clust->varvalue = 0.0;  Clust->centralnode = 0; Clust->weightedcentralnode = 0;
00307       Clust->NodeList = (int *)SUMA_malloc((*N_TobeAssigned) * sizeof(int)); 
00308       Clust->ValueList = (float *)SUMA_malloc((*N_TobeAssigned) * sizeof(float));  
00309       if (!Clust->NodeList || !Clust->ValueList || !OffS) { 
00310          SUMA_SL_Crit("Failed to allocate for NodeList or ValueList");  
00311          SUMA_free(Clust); Clust = NULL;
00312          SUMA_RETURN(NULL);  
00313       }
00314    candlist = (DList*)SUMA_malloc(sizeof(DList));
00315    visited = (byte *)SUMA_calloc(SO->N_Node, sizeof(byte));
00316    if (!visited || !candlist) {
00317       SUMA_SL_Crit("Failed to allocate for visited or candlist");  
00318       SUMA_free(Clust); Clust = NULL;
00319       SUMA_RETURN(NULL);  
00320    }
00321    dlist_init(candlist, NULL);
00322    /* Add node to cluster */
00323    SUMA_ADD_NODE_TO_CLUST(dothisnode, Clust, NodeArea, ToBeAssigned);
00324    /* mark it as assigned, an reduce the number of nodes left to assign*/
00325    ToBeAssigned[dothisnode] = 0; --(*N_TobeAssigned);
00326    visited[dothisnode] = YUP;
00327    dlist_ins_next(candlist, dlist_tail(candlist), (void *)dothisnode);
00328       while (*N_TobeAssigned && dlist_size(candlist)) {
00329          /* look in its vicinity */
00330          dothiselm = dlist_head(candlist); dothisnode = (int) dothiselm->data;
00331          SUMA_getoffsets2 (dothisnode, SO, Opt->DistLim, OffS, NULL, 0);
00332          /* remove node from candidate list */
00333          dlist_remove(candlist, dothiselm, (void*)&itmp);
00334          /* search to see if any are to be assigned */
00335          for (il=1; il<OffS->N_layers; ++il) { /* starting at layer 1, layer 0 is the node itself */
00336             for (jl=0; jl<OffS->layers[il].N_NodesInLayer; ++jl) {
00337                neighb = OffS->layers[il].NodesInLayer[jl];
00338                if (ToBeAssigned[neighb] && OffS->OffVect[neighb] <= Opt->DistLim) {
00339                      /* take that node into the cluster */
00340                      SUMA_ADD_NODE_TO_CLUST(neighb, Clust, NodeArea, ToBeAssigned);
00341                      /* mark it as assigned, an reduce the number of nodes left to assign*/
00342                      ToBeAssigned[neighb] = 0; --(*N_TobeAssigned);
00343                      if (Opt->update) {
00344                         if (N_Orig - *N_TobeAssigned >= Opt->update) {
00345                            if (LocalHead) fprintf(SUMA_STDERR,"%s: tick (%d nodes processed)\n", FuncName, N_Orig - *N_TobeAssigned); 
00346                            else fprintf(SUMA_STDERR,".");
00347                            
00348                            N_Orig = *N_TobeAssigned;
00349                         }
00350                      }
00351                      /* mark it as a candidate if it has not been visited as a candidate before */
00352                      if (!visited[neighb]) {
00353                         dlist_ins_next(candlist, dlist_tail(candlist), (void *)neighb);
00354                         visited[neighb] = YUP;   
00355                      }
00356                      
00357                }
00358             }
00359          }
00360          /* recycle */
00361          SUMA_Recycle_getoffsets (OffS);
00362       }
00363    /* free this OffS structure  */
00364    if (OffS) SUMA_Free_getoffsets(OffS); OffS = NULL;
00365    if (Opt->update) fprintf(SUMA_STDERR,"\n");
00366    /* destroy the list */
00367    if (candlist) { dlist_destroy(candlist); SUMA_free(candlist); candlist  = NULL; }
00368    SUMA_RETURN(Clust);
00369 }

float* SUMA_CalculateNodeAreas SUMA_SurfaceObject   SO
 

Calculate area of each node as one third of the sum of the areas of incident triangles. If you change this function make sure changes are also done on RickR's compute_node_areas since the two functions use the same principle.

Definition at line 51 of file SUMA_SurfClust.c.

References c, SUMA_CommonFields::DsetList, i, SUMA_SurfaceObject::MF, SUMA_MEMBER_FACE_SETS::N_Memb, SUMA_SurfaceObject::N_Node, SUMA_MEMBER_FACE_SETS::NodeMemberOfFaceSet, SUMA_SurfaceObject::PolyArea, SUMA_ENTRY, SUMA_malloc, SUMA_RETURN, SUMA_SL_Crit, and SUMA_SurfaceMetrics_eng().

00052 {
00053    static char FuncName[]={"SUMA_CalculateNodeAreas"};
00054    float *NodeAreas=NULL;
00055    int *flist = NULL, i, c;
00056    
00057    SUMA_ENTRY;
00058    
00059    if (!SO) { SUMA_RETURN(NodeAreas); }
00060    if (!SO->PolyArea) {
00061       if (!SUMA_SurfaceMetrics_eng(SO, "PolyArea", NULL, 0, SUMAg_CF->DsetList)) {
00062          fprintf (SUMA_STDERR,"Error %s: Failed in SUMA_SurfaceMetrics.\n", FuncName);
00063          SUMA_RETURN(NodeAreas);
00064       }
00065    }
00066    
00067    NodeAreas = (float *)SUMA_malloc(SO->N_Node*sizeof(float));
00068    if (!NodeAreas) { SUMA_SL_Crit ("Failed to allocate for NodeAreas"); SUMA_RETURN(NodeAreas); }
00069    
00070    for (i=0; i<SO->N_Node; ++i) {
00071       flist = SO->MF->NodeMemberOfFaceSet[i];
00072       NodeAreas[i] = 0.0;
00073       for (c = 0; c < SO->MF->N_Memb[i]; c++) {
00074          NodeAreas[i] += SO->PolyArea[flist[c]];
00075       }
00076       NodeAreas[i] /= 3.0;
00077    }
00078    
00079    SUMA_RETURN(NodeAreas);
00080 }

int SUMA_ClusterCenterofMass SUMA_SurfaceObject   SO,
SUMA_CLUST_DATUM   cd,
int    UseSurfDist
 

Finds a node that best approximates the property of the center of mass on the surface. Note that the real center of mass of a curved surface is rarely on the surface, so this is an attempt at localizing a node that is central to an ROI and that can reflect the weight, or activity, distribution in that ROI.

Parameters:
SO  (SUMA_SurfaceObject *)
cd  (SUMA_CLUST_DATUM *) basically the output of SUMA_SUMA_Build_Cluster_From_Node or an element of the list returned by SUMA_FindClusters Function will fill centralnode and weightedcentralnode
UseSurfDist  (int) 0: use distances along the surface (approximated by distances on the graph) 1: use Euclidian distances.
Returns:
ans (int) : NOPE failed, YUP succeeded.

Definition at line 789 of file SUMA_SurfClust.c.

References c, SUMA_CLUST_DATUM::centralnode, i, LocalHead, SUMA_OFFSET_STRUCT::N_Neighb, SUMA_CLUST_DATUM::N_Node, SUMA_SurfaceObject::N_Node, nc, SUMA_OFFSET_STRUCT::Neighb_dist, SUMA_OFFSET_STRUCT::Neighb_ind, SUMA_CLUST_DATUM::NodeList, SUMA_SurfaceObject::NodeList, SUMA_Boolean, SUMA_calloc, SUMA_ENTRY, SUMA_free, SUMA_Free_getoffsets(), SUMA_GetOffset2Offset(), SUMA_getoffsets2(), SUMA_Initialize_getoffsets(), SUMA_malloc, SUMA_NORM_VEC, SUMA_RETURN, SUMA_SL_Crit, SUMA_SL_Err, SUMA_SL_Note, SUMA_UNIT_VEC, SUMA_CLUST_DATUM::ValueList, and SUMA_CLUST_DATUM::weightedcentralnode.

Referenced by SUMA_FindClusters().

00790 {
00791    static char FuncName[]={"SUMA_ClusterCenterofMass"};
00792    SUMA_GET_OFFSET_STRUCT *OffS = NULL;
00793    SUMA_OFFSET_STRUCT OS;
00794    int *CoverThisNode = NULL, i, c, ni, nc, centralnode, weightedcentralnode, 
00795       nanch, k, WeightByValue = 1;
00796    float Uia[3], dia, Uca[3], dca,  s[3], s_w[3], *DistVec=NULL, 
00797          *weightedcentrality=NULL, minweightedcentrality = 0.0, *centrality=NULL, 
00798          mincentrality = 0.0, mtotal_w, mi_w, fac, mtotal, mi;   
00799    static int ncall;
00800    SUMA_Boolean LocalHead = NOPE;
00801    
00802    SUMA_ENTRY;
00803    
00804    centralnode = -1;
00805    weightedcentralnode = -1;
00806    if (!SO || !cd) { SUMA_RETURN(NOPE); }
00807    if (!cd->N_Node || !cd->NodeList) { SUMA_RETURN(NOPE); }
00808    OffS = SUMA_Initialize_getoffsets (SO->N_Node);
00809    if (!OffS) {
00810       SUMA_SL_Err("Failed to allocate for OffS");
00811       SUMA_RETURN(NOPE);
00812    }
00813 
00814    CoverThisNode = (int *)SUMA_calloc(SO->N_Node, sizeof(int));
00815    if (!CoverThisNode) {
00816       SUMA_SL_Crit("Failed to allocate for CoverThisNode");
00817       SUMA_RETURN(NOPE);
00818    }
00819    if (cd->N_Node == SO->N_Node) {
00820       /* not much to do, return 0 */
00821       SUMA_SL_Note("Cluster spans entire surface.\nNo central node.\n");
00822       cd->centralnode = 0;
00823       cd->weightedcentralnode = 0;
00824       SUMA_RETURN(YUP);
00825    }
00826    
00827    for (i=0; i<cd->N_Node; ++i) { CoverThisNode[cd->NodeList[i]] = 1; }
00828    nanch = cd->NodeList[0]; /* anchor node */
00829    SUMA_getoffsets2 (cd->NodeList[0], SO, 0, OffS, CoverThisNode, cd->N_Node);
00830    /* help me with a nicer structure (for sanity)*/
00831    if (!SUMA_GetOffset2Offset (OffS, &OS)) {
00832       SUMA_SL_Err("Failed in SUMA_GetOffset2Offset");
00833       SUMA_RETURN(NOPE);
00834    }
00835    if (OffS) SUMA_Free_getoffsets(OffS); OffS = NULL;
00836    /* put the distance in an easy to search array */
00837    DistVec = (float *) SUMA_calloc(SO->N_Node, sizeof(float));
00838    centrality = (float *)SUMA_malloc(OS.N_Neighb * sizeof(float));
00839    weightedcentrality = (float *)SUMA_malloc(OS.N_Neighb * sizeof(float));
00840    if (!DistVec || !centrality || !weightedcentrality) {
00841       SUMA_SL_Crit("Failed to allocate.");
00842       SUMA_RETURN(NOPE);
00843    }
00844    for (c=0; c < OS.N_Neighb; ++c) { DistVec[OS.Neighb_ind[c]] = OS.Neighb_dist[c]; }
00845    
00846    /* Now calculate the center of massity of each node 
00847    This is no center of mass in the proper definition of the term*/
00848    
00849    #if 1
00850    if (cd->N_Node == 1) {
00851       centralnode = cd->NodeList[0];
00852       weightedcentralnode = cd->NodeList[0];
00853    } else {
00854       for (c=0; c < OS.N_Neighb; ++c) {
00855          nc = OS.Neighb_ind[c]; /* Node index into SO of center node */
00856          s[0] = s[1] = s[2] = 0.0; s_w[0] = s_w[1] = s_w[2] = 0.0; 
00857          centrality[c] = 0.0; weightedcentrality[c] = 0.0; mtotal_w = 0.0; /* recalculated each time, not a big deal ... */
00858          for (i=0; i<cd->N_Node; ++i) {
00859             mi_w = cd->ValueList[i];
00860             mtotal_w += mi_w; 
00861             ni = cd->NodeList[i]; /* Node index into SO of other node in cluster */
00862             SUMA_UNIT_VEC((&(SO->NodeList[3*ni])), (&(SO->NodeList[3*nanch])), Uia, dia);
00863             if (UseSurfDist) { for (k=0; k<3;++k) { fac = Uia[k] * DistVec[ni]; s_w[k] += mi_w * fac; s[k] += fac;} }
00864             else { for (k=0; k<3;++k) { fac = Uia[k] * dia; s_w[k] += mi_w * fac; s[k] += fac; } }
00865          }
00866          SUMA_UNIT_VEC((&(SO->NodeList[3*nc])), (&(SO->NodeList[3*nanch])), Uca, dca);
00867          if (UseSurfDist) { for (k=0; k<3;++k) { fac = Uca[k] * DistVec[nc]; s_w[k] -= mtotal_w * fac; s[k] -= cd->N_Node * fac;  } }
00868          else { for (k=0; k<3;++k) { fac =  Uca[k] * dca; s_w[k] -= mtotal_w * fac; s[k] -= cd->N_Node * fac;} }
00869          
00870          SUMA_NORM_VEC(s, 3, centrality[c]); SUMA_NORM_VEC(s_w, 3, weightedcentrality[c]); 
00871          if (LocalHead) fprintf(SUMA_STDERR,"%s: call %d, Centrality of node %d / %d = %f , weighted %f\n", FuncName, ncall, nc, nanch, centrality[c], weightedcentrality[c]); 
00872          if (c == 0) { 
00873             mincentrality = centrality[c]; centralnode = nc; 
00874             minweightedcentrality = weightedcentrality[c]; weightedcentralnode = nc; 
00875          } else {
00876             if (centrality[c] < mincentrality) { mincentrality = centrality[c]; centralnode = nc; }
00877             if (weightedcentrality[c] < minweightedcentrality) { minweightedcentrality = weightedcentrality[c]; weightedcentralnode = nc; }
00878          }
00879          
00880       }
00881    }
00882    cd->centralnode = centralnode;
00883    cd->weightedcentralnode = weightedcentralnode;
00884    if (LocalHead) fprintf(SUMA_STDERR,"%s: Central node chosen %d, weighted %d\n", FuncName, cd->centralnode, cd->weightedcentralnode);
00885    #else
00886    if (cd->N_Node == 1) {
00887       centralnode = cd->NodeList[0];
00888    } else {
00889       for (c=0; c < OS.N_Neighb; ++c) {
00890          nc = OS.Neighb_ind[c]; /* Node index into SO of center node */
00891          s[0] = s[1] = s[2] = 0.0;
00892          centrality[c] = 0.0; mtotal = 0.0; /* recalculated each time, not a big deal ... */
00893          for (i=0; i<cd->N_Node; ++i) {
00894             if (WeightByValue) mi = cd->ValueList[i];
00895             else mi = 1.0;
00896             mtotal += mi;
00897             ni = cd->NodeList[i]; /* Node index into SO of other node in cluster */
00898             SUMA_UNIT_VEC((&(SO->NodeList[3*ni])), (&(SO->NodeList[3*nanch])), Uia, dia);
00899             if (UseSurfDist) { for (k=0; k<3;++k) s[k] += mi * Uia[k] * DistVec[ni]; }
00900             else { for (k=0; k<3;++k) s[k] += mi * Uia[k] * dia; }
00901          }
00902          SUMA_UNIT_VEC((&(SO->NodeList[3*nc])), (&(SO->NodeList[3*nanch])), Uca, dca);
00903          if (UseSurfDist) { for (k=0; k<3;++k) s[k] -= mtotal * Uca[k] * DistVec[nc]; }
00904          else { for (k=0; k<3;++k) s[k] -= mtotal * Uca[k] * dca; }
00905          
00906          SUMA_NORM_VEC(s, 3, centrality[c]);
00907          if (LocalHead) fprintf(SUMA_STDERR,"%s: call %d, Centrality of node %d / %d = %f\n", FuncName, ncall, nc, nanch, centrality[c]); 
00908          if (c == 0) { mincentrality = centrality[c]; centralnode = nc; }
00909          else if (centrality[c] < mincentrality) { mincentrality = centrality[c]; centralnode = nc; }
00910       }
00911    }
00912    cd->centralnode = centralnode;
00913    if (LocalHead) fprintf(SUMA_STDERR,"%s: Central node chosen %d\n", FuncName, cd->centralnode);
00914    cd->weightedcentralnode = -1;
00915    #endif   
00916    
00917    if (CoverThisNode) SUMA_free(CoverThisNode); CoverThisNode = NULL;
00918    if (OS.Neighb_dist) SUMA_free(OS.Neighb_dist); OS.Neighb_dist = NULL;
00919    if (OS.Neighb_ind) SUMA_free(OS.Neighb_ind); OS.Neighb_ind = NULL;
00920    if (DistVec) SUMA_free(DistVec); DistVec = NULL;
00921    if (centrality) SUMA_free(centrality); centrality = NULL;
00922    if (weightedcentrality) SUMA_free(weightedcentrality); weightedcentrality = NULL;
00923 
00924    ++ncall;
00925    SUMA_RETURN(YUP);  
00926 }  

DList* SUMA_FindClusters SUMA_SurfaceObject   SO,
int *    ni,
float *    nv,
int    N_ni,
int    dothisnode,
SUMA_SURFCLUST_OPTIONS   Opt,
float *    NodeArea
 

Finds clusters of data on the surface.

Parameters:
SO  (SUMA_SurfaceObject *) pointer to surface in question
ni  (int *) vector of N_Ni node indices that are to be considered for clustering
nv  (float *) vector of N_Ni node values (corresponding to ni) Only non 0 values are considered for clustering
N_ni  (int) number of values in ni and nv
dothisnode  (int) index of node (into SO's nodelist, not ni) to start/proceed from
Opt  (SUMA_SURFCLUST_OPTIONS *) structure containing clustering options
AddToThisClust  (SUMA_CLUST_DATUM *) add to this cluster
NodeArea  (float *) SO->N_Node vector of node areas.
Returns:
ClustList (DList *) list of clusters, in no particular order. Processing of the list is to be done later.
See also:
SUMA_Build_Cluster_From_Node

Definition at line 389 of file SUMA_SurfClust.c.

References SUMA_SURFCLUST_OPTIONS::AreaLim, BuildMethod, dlist_init(), dlist_ins_next(), dlist_tail, SUMA_SURFCLUST_OPTIONS::DoCentrality, i, LocalHead, SUMA_SurfaceObject::N_Node, SUMA_CLUST_DATUM::N_Node, nc, SUMA_CLUST_DATUM::NodeList, SUMA_Boolean, SUMA_Build_Cluster_From_Node(), SUMA_Build_Cluster_From_Node_NoRec(), SUMA_calloc, SUMA_ClusterCenterofMass(), SUMA_ENTRY, SUMA_free, SUMA_FreeClustDatum(), SUMA_LH, SUMA_malloc, SUMA_OFFSETS2, SUMA_OFFSETS2_NO_REC, SUMA_OFFSETS_LL, SUMA_realloc, SUMA_RETURN, SUMA_S_Err, SUMA_SL_Crit, SUMA_SL_Err, SUMA_SL_Note, SUMA_CLUST_DATUM::totalarea, SUMA_CLUST_DATUM::totalvalue, SUMA_SURFCLUST_OPTIONS::update, SUMA_CLUST_DATUM::ValueList, and SUMA_CLUST_DATUM::varvalue.

00392 {
00393    static char FuncName[]={"SUMA_FindClusters"};
00394    DList *list=NULL;
00395    DListElmt *elm=NULL;
00396    float *ToBeAssigned=NULL;
00397    float mean;
00398    int N_n, nc, i, kk, PureNothing=0;
00399    SUMA_CLUST_DATUM *Clust = NULL;
00400    SUMA_Boolean LocalHead = NOPE;
00401    
00402    SUMA_ENTRY;
00403    
00404    if (!SO || !nv || !ni) {
00405       SUMA_S_Err("Bad parameters");
00406    }
00407    if (dothisnode == -1) { /* initialize */
00408       SUMA_LH("Initializing");
00409       nc = 0;
00410       /* initialize the list */
00411       list = (DList *)SUMA_malloc(sizeof(DList));
00412       dlist_init(list, SUMA_FreeClustDatum); 
00413       ToBeAssigned = (float *)SUMA_calloc(SO->N_Node, sizeof(float));
00414       N_n = N_ni;
00415       for (i=0; i<N_n; ++i) {
00416          if (!nv[i]) {
00417             ++PureNothing;
00418          }
00419          ToBeAssigned[ni[i]] = nv[i];
00420       }
00421       if (Opt->update) {
00422          fprintf(SUMA_STDERR,"%s: Have %d nodes to work with. %d nodes have 0 value.\n", FuncName, N_n, PureNothing);
00423       }
00424    }
00425    
00426    while (N_n - PureNothing > 0) {
00427       dothisnode = -1;
00428       for (i=0;i<SO->N_Node; ++i) { 
00429          if (ToBeAssigned[i]) {  
00430             dothisnode = i; continue;  
00431          }  
00432       }
00433       if (dothisnode < 0) {
00434          SUMA_S_Err("Not expected here. dothisnode < 0"); 
00435          SUMA_RETURN(list);
00436       } 
00437 
00438       if (BuildMethod == SUMA_OFFSETS2_NO_REC) {
00439          Clust = SUMA_Build_Cluster_From_Node_NoRec(dothisnode, ToBeAssigned, &N_n, NodeArea, SO, Opt);
00440       } else if (BuildMethod == SUMA_OFFSETS2 || BuildMethod == SUMA_OFFSETS_LL) {
00441          Clust = SUMA_Build_Cluster_From_Node(dothisnode, NULL, ToBeAssigned, &N_n, NodeArea, SO, Opt);
00442       } else {
00443          SUMA_SL_Err("No Such Method!");
00444          SUMA_RETURN(list);
00445       }
00446       if (!Clust) {
00447          SUMA_SL_Err("Failed in SUMA_Build_Cluster_From_Node*");
00448          SUMA_RETURN(list);
00449       }   
00450       if (LocalHead) fprintf(SUMA_STDERR,"%s: Cluster %p is finished, %d nodes\n", FuncName, Clust, Clust->N_Node); 
00451       
00452       if (Opt->AreaLim > 0 && Clust->totalarea < Opt->AreaLim) {
00453          SUMA_LH("Cluster less than area limit");
00454          SUMA_FreeClustDatum((void *)Clust); Clust = NULL;
00455       } else {
00456          mean = Clust->totalvalue/((float)Clust->N_Node);
00457          for (kk=0; kk < Clust->N_Node; ++kk) {
00458             Clust->varvalue += (Clust->ValueList[kk] - mean) * (Clust->ValueList[kk] - mean);   
00459          }
00460          if (Clust->N_Node > 1) Clust->varvalue /= (Clust->N_Node - 1);
00461          else Clust->varvalue = 0.0;
00462          /* reallocate to save space */
00463          Clust->NodeList = (int *)SUMA_realloc(Clust->NodeList, sizeof(int)*Clust->N_Node);
00464          Clust->ValueList = (float *)SUMA_realloc(Clust->ValueList, sizeof(float)*Clust->N_Node);
00465          if (!Clust->NodeList || !Clust->ValueList) { 
00466             SUMA_SL_Crit("Failed to reallocate for NodeList or ValueList");  
00467             SUMA_RETURN(NULL);   
00468          }
00469          /* find the central node */
00470          if (Opt->DoCentrality) {
00471             if (Opt->update) {
00472                   SUMA_SL_Note("Looking for central nodes...(use -no_cent to skip this slow step)");
00473             } 
00474             if (!SUMA_ClusterCenterofMass  (SO, Clust, 1)) {
00475                SUMA_SL_Err("Failed to find central node");  
00476                SUMA_RETURN(list);   
00477             }
00478          }
00479 
00480          dlist_ins_next(list, dlist_tail(list), (void *)Clust); 
00481          ++nc;
00482       }
00483    }   
00484   
00485    if (N_n == 0) {
00486       if (LocalHead) fprintf(SUMA_STDERR,"%s: No more nodes to consider, cleaning up.\n", FuncName);
00487       if (ToBeAssigned) SUMA_free(ToBeAssigned); ToBeAssigned = NULL;   \
00488    }
00489    
00490    SUMA_RETURN(list);
00491 } 

void SUMA_FreeClustDatum void *    data
 

Definition at line 29 of file SUMA_SurfClust.c.

References SUMA_CLUST_DATUM::NodeList, SUMA_ENTRY, SUMA_free, SUMA_RETURNe, and SUMA_CLUST_DATUM::ValueList.

Referenced by SUMA_FindClusters().

00030 {
00031    static char FuncName[]={"SUMA_FreeClustDatum"};
00032    SUMA_CLUST_DATUM *Clust = NULL;
00033    SUMA_ENTRY;
00034    
00035    if (!data) SUMA_RETURNe;
00036    Clust = (SUMA_CLUST_DATUM *)data;
00037    if (Clust->NodeList) SUMA_free(Clust->NodeList); 
00038    if (Clust->ValueList) SUMA_free(Clust->ValueList);
00039    SUMA_free(Clust);
00040    
00041    SUMA_RETURNe;
00042 }

SUMA_DSET* SUMA_MaskDsetByClustList SUMA_DSET   idset,
SUMA_SurfaceObject   SO,
DList   list,
SUMA_Boolean    FullList,
char *    leName
 

Masks a data set by a clustering list

Definition at line 613 of file SUMA_SurfClust.c.

References DListElmt_::data, dlist_head, dlist_tail, SUMA_DSET::dnel, i, LocalHead, SUMA_SurfaceObject::N_Node, SUMA_CLUST_DATUM::N_Node, DListElmt_::next, SUMA_CLUST_DATUM::NodeList, SDEST_VECLEN, SUMA_Boolean, SUMA_calloc, SUMA_ENTRY, SUMA_free, SUMA_GetNodeDef(), SUMA_isDsetColumn_inferred(), SUMA_MaskedCopyofDset(), SUMA_RETURN, SUMA_SL_Err, NI_element::vec_len, and NI_element::vec_num.

00614 {
00615    static char FuncName[]={"SUMA_MaskDsetByClustList"};
00616    int i, j;
00617    DListElmt *elmt=NULL;
00618    SUMA_DSET *dset = NULL;
00619    int *ni=NULL, N_ni, cnt;
00620    SUMA_CLUST_DATUM *cd=NULL;
00621    byte *ismask=NULL, *rowmask=NULL, *colmask = NULL;
00622    SUMA_Boolean LocalHead = NOPE;
00623    
00624    SUMA_ENTRY;
00625 
00626    if (!list) {
00627       SUMA_SL_Err("NULL list");
00628       SUMA_RETURN(dset);  
00629    }
00630    /* which nodes in mask ? */
00631    ismask = (byte *)SUMA_calloc(SO->N_Node, sizeof(byte)); /* you need to allocate for SO->N_Node, to be safe, otherwise you will need
00632                                                             to search for the highest node index.. */
00633    elmt = NULL; cnt = 0;
00634    do {
00635       if (!elmt) elmt = dlist_head(list);
00636       else elmt = elmt->next;
00637       cd = (SUMA_CLUST_DATUM *)elmt->data; 
00638       for (j=0; j<cd->N_Node; ++j) {
00639             if(LocalHead) fprintf (SUMA_STDERR,"nic=%d\t", cd->NodeList[j]);
00640             ismask[cd->NodeList[j]] = 1;
00641             ++cnt;
00642       }
00643    } while (elmt != dlist_tail(list));
00644    if (LocalHead) fprintf(SUMA_STDERR,"%s:\n%d nodes in cluster list.\n", FuncName, cnt);
00645    
00646    /* now form a rowmask vector to parallel rows in idset */
00647    rowmask = (byte *)SUMA_calloc(idset->dnel->vec_len, sizeof(byte));
00648    colmask = (byte *)SUMA_calloc(idset->dnel->vec_num, sizeof(byte));
00649    
00650    /* get the node index column in idset */
00651    ni = SUMA_GetNodeDef(idset);
00652    N_ni = SDEST_VECLEN(idset);
00653    if (!ni) {
00654       SUMA_SL_Err("Failed to find node index column");
00655       SUMA_RETURN(NULL);
00656    }
00657    /* now, fill rowmask */
00658    for (i=0; i<idset->dnel->vec_len; ++i) { if (ismask[ni[i]]) { rowmask[i]=1; if(LocalHead) fprintf (SUMA_STDERR,"%d,%d\t", ni[i], i); } }
00659    /* fill colmask*/
00660    for (i=0; i<idset->dnel->vec_num; ++i) { 
00661       if (SUMA_isDsetColumn_inferred(idset, i)) {
00662          colmask[i]=0;
00663          if (LocalHead) fprintf(SUMA_STDERR,"%s: Column %d will not be written because it is inferred.\n", FuncName, i);
00664       } else colmask[i]=1;
00665    }
00666    
00667    dset = SUMA_MaskedCopyofDset(idset, rowmask, colmask, !FullList, 1);
00668    if (!dset) {
00669       SUMA_SL_Err("Failed to create masked copy of input");
00670       SUMA_RETURN(NULL);
00671    }
00672    
00673    if (rowmask) SUMA_free(rowmask); rowmask = NULL;
00674    if (colmask) SUMA_free(colmask); colmask = NULL;
00675    if (ismask) SUMA_free(ismask); ismask = NULL;
00676    
00677    SUMA_RETURN (dset);
00678 }

SUMA_Boolean SUMA_Show_SurfClust_list DList   list,
FILE *    Out,
int    detail,
char *    params
 

Show the ViewState structure

Definition at line 494 of file SUMA_SurfClust.c.

References SUMA_Boolean, SUMA_ENTRY, SUMA_free, SUMA_RETURN, SUMA_Show_SurfClust_list_Info(), and SUMA_SL_Err.

00495 {
00496    static char FuncName[]={"SUMA_Show_SurfClust_list"};
00497    char *s = NULL;
00498    
00499    SUMA_ENTRY;
00500 
00501    if (Out == NULL) Out = stdout;
00502 
00503    s = SUMA_Show_SurfClust_list_Info(list,  detail, params);
00504    if (!s) {
00505       SUMA_SL_Err("Failed in SUMA_Show_SurfClust_list_Info");
00506       SUMA_RETURN(NOPE);
00507    }  else {
00508       fprintf(Out, "%s", s);
00509       SUMA_free(s); s = NULL;
00510    }
00511    
00512    SUMA_RETURN(YUP);
00513 }

char* SUMA_Show_SurfClust_list_Info DList   list,
int    detail,
char *    params
 

Show the SurfClust list

Definition at line 516 of file SUMA_SurfClust.c.

References SUMA_CLUST_DATUM::centralnode, DListElmt_::data, dlist_head, dlist_tail, i, SUMA_CLUST_DATUM::maxnode, SUMA_CLUST_DATUM::maxvalue, SUMA_CLUST_DATUM::minnode, SUMA_CLUST_DATUM::minvalue, SUMA_CLUST_DATUM::N_Node, DListElmt_::next, SUMA_CLUST_DATUM::NodeList, DList_::size, SUMA_COUNTER_PLURAL, SUMA_COUNTER_SUFFIX, SUMA_ENTRY, SUMA_free, SUMA_pad_string(), SUMA_RETURN, SUMA_SS2S, SUMA_StringAppend(), SUMA_StringAppend_va(), SUMA_CLUST_DATUM::totalabsvalue, SUMA_CLUST_DATUM::totalarea, SUMA_CLUST_DATUM::totalvalue, SUMA_CLUST_DATUM::varvalue, and SUMA_CLUST_DATUM::weightedcentralnode.

Referenced by SUMA_Show_SurfClust_list().

00517 {
00518    static char FuncName[]={"SUMA_Show_SurfClust_list_Info"};
00519    int i, ic, max;
00520    SUMA_STRING *SS = NULL;
00521    DListElmt *elmt=NULL;
00522    SUMA_CLUST_DATUM *cd=NULL;
00523    char *s=NULL, *pad_str, str[20];   
00524    int lc[]= { 6, 6, 9, 9, 9, 6, 6, 9, 6, 9, 6, 9, 9 };
00525    char Col[][12] = { {"# Rank"}, {"num Nd"}, {"Area"}, {"Mean"}, {"|Mean|"},{"Cent"}, {"W Cent"},{"Min V"}, {"Min Nd"}, {"Max V"}, {"Max Nd"} , {"Var"}, {"SEM"} };
00526    SUMA_ENTRY;
00527 
00528    SS = SUMA_StringAppend (NULL, NULL);
00529    
00530    if (!list) {
00531       SS = SUMA_StringAppend (SS,"NULL list.\n");
00532       SUMA_SS2S(SS,s); 
00533       SUMA_RETURN(s);  
00534    }
00535 
00536    if (!list->size) {
00537       SS = SUMA_StringAppend (SS,"Empty list.\n");
00538       SUMA_SS2S(SS,s); 
00539       SUMA_RETURN(s);  
00540    }else{
00541       SS = SUMA_StringAppend_va (SS,"#Col. 0  = Rank \n"
00542                                     "#Col. 1  = Number of nodes\n"
00543                                     "#Col. 2  = Total area (units^2)\n"
00544                                     "#Col. 3  = Mean value\n"
00545                                     "#Col. 4  = Mean absolute value\n"
00546                                     "#Col. 5  = Central node\n"
00547                                     "#Col. 6  = Weighted central node\n"
00548                                     "#Col. 7  = Minimum value\n"
00549                                     "#Col. 8  = Minimum node\n"
00550                                     "#Col. 9  = Maximum value\n"
00551                                     "#Col. 10 = Maximum node\n"
00552                                     "#Col. 11 = Variance\n"
00553                                     "#Col. 12 = Standard error of the mean\n"
00554                                     "#Command history:\n"
00555                                     "#%s\n", params);
00556       
00557       for (ic=0; ic<13; ++ic) {
00558          if (ic == 0) sprintf(str,"%s", Col[ic]); 
00559          else sprintf(str,"%s", Col[ic]); 
00560          pad_str = SUMA_pad_string(str, ' ', lc[ic], 0);
00561          SS = SUMA_StringAppend_va (SS,"%s   ", pad_str);
00562          SUMA_free(pad_str);
00563       }
00564       SS = SUMA_StringAppend_va (SS,"\n");
00565       if (detail == 1) {
00566          SS = SUMA_StringAppend_va (SS,"#Other columns: list of 5 first nodes in ROI.\n");   
00567       }
00568       if (detail == 2) {
00569          SS = SUMA_StringAppend_va (SS,"#Other columns: list all  nodes in ROI.\n");   
00570       }
00571       if (detail > 0) {
00572          SS = SUMA_StringAppend_va (SS,"#A total of %d cluster%s were found.\n", list->size, SUMA_COUNTER_PLURAL(list->size));
00573       }
00574    }
00575    
00576    elmt = NULL; 
00577    ic = 1; 
00578    do {
00579       if (!elmt) elmt = dlist_head(list); else elmt = elmt->next;
00580       if (!elmt) SS = SUMA_StringAppend_va (SS,"#%d%s cluster element is NULL!\n", ic, SUMA_COUNTER_SUFFIX(ic));
00581       else {
00582          cd = (SUMA_CLUST_DATUM *)elmt->data;
00583          if (detail > 0) SS = SUMA_StringAppend_va (SS,"#%d%s cluster\n", ic, SUMA_COUNTER_SUFFIX(ic));
00584          SS = SUMA_StringAppend_va (SS,"%6d   %6d   %9.2f"
00585                                        "   %9.3f   %9.3f"
00586                                        "   %6d   %6d"
00587                                        "   %9.3f   %6d"
00588                                        "   %9.3f   %6d"
00589                                        "   %9.3f   %9.3f"
00590                                        , ic, cd->N_Node, cd->totalarea
00591                                        , cd->totalvalue/((float)cd->N_Node), cd->totalabsvalue/((float)cd->N_Node)
00592                                        , cd->centralnode, cd->weightedcentralnode 
00593                                        , cd->minvalue, cd->minnode
00594                                        , cd->maxvalue, cd->maxnode
00595                                        , cd->varvalue, sqrt(cd->varvalue/cd->N_Node));
00596          if (detail > 0) {
00597             if (detail == 1) {
00598                if (cd->N_Node < 5) max = cd->N_Node; else max = 5;
00599             } else max = cd->N_Node;
00600             for (i=0;i<max; ++i) SS = SUMA_StringAppend_va (SS,"%d\t", cd->NodeList[i]);
00601          }
00602          SS = SUMA_StringAppend(SS,"\n"); 
00603       }
00604       ++ic; 
00605    } while (elmt != dlist_tail(list));
00606    
00607    SUMA_SS2S(SS,s);
00608    
00609    SUMA_RETURN (s);
00610 }

SUMA_Boolean SUMA_Sort_ClustersList DList   list,
SUMA_SURF_CLUST_SORT_MODES    SortMode
 

Definition at line 928 of file SUMA_SurfClust.c.

References DListElmt_::data, dlist_head, dlist_ins_prev(), dlist_remove(), dlist_tail, LocalHead, SUMA_CLUST_DATUM::N_Node, DListElmt_::next, DListElmt_::prev, r, SUMA_Boolean, SUMA_ENTRY, SUMA_RETURN, SUMA_S_Err, SUMA_SORT_CLUST_BY_AREA, SUMA_SORT_CLUST_BY_NUMBER_NODES, SUMA_SORT_CLUST_NO_SORT, SUMA_SORT_CLUST_NOT_SET, SUMA_SURF_CLUST_SORT_MODES, and SUMA_CLUST_DATUM::totalarea.

00929 {
00930    static char FuncName[]={"SUMA_Sort_ClustersList"};
00931    DListElmt *elmt=NULL, *max_elmt=NULL, *elmt_comp=NULL;
00932    SUMA_CLUST_DATUM *cd=NULL, *cd_comp=NULL, *cd_max=NULL;
00933    int r = 0;
00934    SUMA_Boolean LocalHead = NOPE;
00935    
00936    SUMA_ENTRY;
00937    
00938    if (!list) { SUMA_RETURN(NOPE); }
00939    switch (SortMode) {
00940       case SUMA_SORT_CLUST_NOT_SET:
00941          SUMA_S_Err("Why are you calling me?");
00942          SUMA_RETURN(NOPE);
00943          break;
00944       case SUMA_SORT_CLUST_NO_SORT:
00945          SUMA_RETURN(YUP);
00946          break;
00947       case SUMA_SORT_CLUST_BY_NUMBER_NODES:
00948       case SUMA_SORT_CLUST_BY_AREA:
00949          elmt = NULL;
00950          do {
00951             if (!elmt) elmt = dlist_head(list);
00952             else elmt = elmt->next;
00953             cd = (SUMA_CLUST_DATUM *)elmt->data; 
00954             /* compare to all ahead of this element */
00955             if (elmt != dlist_tail(list)) {
00956                max_elmt = elmt; cd_max = (SUMA_CLUST_DATUM *)max_elmt->data; elmt_comp = NULL;
00957                do {
00958                   if (!elmt_comp) elmt_comp = elmt->next; 
00959                   else elmt_comp = elmt_comp->next; 
00960                   cd_comp = (SUMA_CLUST_DATUM *)elmt_comp->data; 
00961                   if (SortMode == SUMA_SORT_CLUST_BY_NUMBER_NODES) {
00962                      if (cd_comp->N_Node > cd_max->N_Node) { max_elmt = elmt_comp; cd_max = (SUMA_CLUST_DATUM *)max_elmt->data; }  
00963                   }else if (SortMode == SUMA_SORT_CLUST_BY_AREA) {
00964                      if (cd_comp->totalarea > cd_max->totalarea) { max_elmt = elmt_comp; cd_max = (SUMA_CLUST_DATUM *)max_elmt->data; }  
00965                   }
00966                } while (elmt_comp != dlist_tail(list));
00967                if (max_elmt != elmt) { /* max is the real deal */
00968                   dlist_remove(list, max_elmt, (void *)(&cd_max));
00969                   dlist_ins_prev(list, elmt, (void *)cd_max);
00970                   elmt = elmt->prev; /* continue from that one */
00971                }
00972             }
00973          } while (elmt != dlist_tail(list));
00974          SUMA_RETURN(YUP);
00975          break;
00976       default:
00977          break; 
00978    }
00979    
00980    
00981    
00982    SUMA_RETURN(YUP);
00983 }

SUMA_DSET* SUMA_SurfClust_list_2_DsetMask SUMA_SurfaceObject   SO,
DList   list,
SUMA_Boolean    FullList,
char *    leName
 

Turn the clusters to a cluster dataset mask

Definition at line 680 of file SUMA_SurfClust.c.

References DListElmt_::data, dlist_head, dlist_tail, i, LocalHead, SUMA_SurfaceObject::N_Node, SUMA_CLUST_DATUM::N_Node, DListElmt_::next, SUMA_CLUST_DATUM::NodeList, SUMA_AddDsetNelCol(), SUMA_Boolean, SUMA_CreateDsetPointer(), SUMA_ENTRY, SUMA_free, SUMA_LH, SUMA_malloc, SUMA_NODE_INDEX, SUMA_NODE_INT, SUMA_NODE_ROI, SUMA_RETURN, SUMA_SL_Crit, and SUMA_SL_Err.

00681 {
00682    static char FuncName[]={"SUMA_SurfClust_list_2_DsetMask"};
00683    int i, ic, max, j, rank;
00684    DListElmt *elmt=NULL;
00685    SUMA_DSET *dset = NULL;
00686    int *NodeIndex=NULL, N_Node, *Val = NULL;
00687    SUMA_CLUST_DATUM *cd=NULL;
00688    SUMA_Boolean LocalHead = NOPE;
00689    
00690    SUMA_ENTRY;
00691 
00692    if (!list) {
00693       SUMA_SL_Err("NULL list");
00694       SUMA_RETURN(dset);  
00695    }
00696    if (FullList) N_Node = SO->N_Node;
00697    else {
00698          elmt = NULL; N_Node = 0;
00699          do {
00700             if (!elmt) elmt = dlist_head(list);
00701             else elmt = elmt->next;
00702             cd = (SUMA_CLUST_DATUM *)elmt->data; 
00703             N_Node += cd->N_Node;
00704          } while (elmt != dlist_tail(list));
00705    }
00706    NodeIndex = (int *)SUMA_malloc(N_Node*sizeof(int));
00707    Val = (int *)SUMA_malloc(N_Node * sizeof(int));
00708    if (!NodeIndex || !Val){
00709       SUMA_SL_Crit("Failed to allocate NodeIndex and or Val");
00710       SUMA_RETURN(dset);
00711    }
00712    if (FullList) {
00713       for (i=0; i<N_Node; ++i) {
00714          NodeIndex[i] = i; Val[i] = 0;
00715       }
00716       elmt = NULL; rank = 1;
00717       do {
00718          if (!elmt) elmt = dlist_head(list);
00719          else elmt = elmt->next;
00720          cd = (SUMA_CLUST_DATUM *)elmt->data; 
00721          for (j=0; j<cd->N_Node; ++j) {
00722             Val[cd->NodeList[j]] = rank;
00723          }
00724          ++rank;
00725       } while (elmt != dlist_tail(list));
00726    } else {
00727       elmt = NULL; rank = 1; i = 0;
00728       do {
00729          if (!elmt) elmt = dlist_head(list);
00730          else elmt = elmt->next;
00731          cd = (SUMA_CLUST_DATUM *)elmt->data; 
00732          for (j=0; j<cd->N_Node; ++j) {
00733             Val[i] = rank;
00734             NodeIndex[i] = cd->NodeList[j];
00735             ++i;
00736          }
00737          ++rank;
00738       } while (elmt != dlist_tail(list)); 
00739    }
00740    
00741    SUMA_LH("Creating dset pointer");
00742    dset = SUMA_CreateDsetPointer(
00743                                  leName,         /* usually the filename */
00744                                  SUMA_NODE_ROI,                /* mix and match */
00745                                  NULL,    /* no idcode, let the function create one from the filename*/
00746                                  NULL,       /* no domain str specified */
00747                                  N_Node    /* Number of nodes allocated for */
00748                                  ); /* DO NOT free dset, it is store in DsetList */
00749                            
00750         /* form the dataset */
00751    SUMA_LH("Adding NodeDef column ...");
00752    if (!SUMA_AddDsetNelCol (   dset, /* the famed nel */ 
00753                            "le Node Def", 
00754                            SUMA_NODE_INDEX,
00755                            (void *)NodeIndex, 
00756                            NULL,  
00757                            1 
00758                            )) {
00759       fprintf (stderr,"Error  %s:\nFailed in SUMA_AddNelCol", FuncName);
00760       SUMA_RETURN(NULL);                    
00761    }
00762   
00763    if (!SUMA_AddDsetNelCol (dset, "Cluster Rank", SUMA_NODE_INT, (void *)Val, NULL ,1)) {
00764       fprintf (stderr,"Error  %s:\nFailed in SUMA_AddNelCol", FuncName);
00765       SUMA_RETURN (NULL);
00766    }
00767    
00768    if (NodeIndex) SUMA_free(NodeIndex); NodeIndex = NULL;
00769    if (Val) SUMA_free(Val); Val = NULL;
00770    
00771    SUMA_RETURN (dset);
00772 }

Variable Documentation

int BuildMethod [static]
 

Definition at line 26 of file SUMA_SurfClust.c.

Referenced by SUMA_Build_Cluster_From_Node(), and SUMA_FindClusters().

SUMA_CommonFields* SUMAg_CF  
 

Global pointer to structure containing info common to all viewers

Definition at line 19 of file SUMA_SurfClust.c.

SUMA_DO* SUMAg_DOv  
 

Global pointer to Displayable Object structure vector

Definition at line 20 of file SUMA_SurfClust.c.

int SUMAg_N_DOv  
 

Number of DOs stored in DOv

Definition at line 23 of file SUMA_SurfClust.c.

int SUMAg_N_SVv  
 

Number of SVs stored in SVv

Definition at line 22 of file SUMA_SurfClust.c.

SUMA_SurfaceViewer* SUMAg_SVv  
 

Global pointer to the vector containing the various Surface Viewer Structures

Definition at line 21 of file SUMA_SurfClust.c.

 

Powered by Plone

This site conforms to the following standards: