1 /* ZSS: July 21/06 This file should be used with SUMA_COMPILED defined
2 suma_datasets.c is now in afni's directory and is in libmri.a
3 
4 */
5 #include <stdlib.h>
6 #include <stdio.h>
7 #include <assert.h>
8 #include <string.h>
9 #include <sys/time.h>
10 #include <math.h>
11 #include "mrilib.h"
12 #include "niml.h"
13 #include "../niml/niml_private.h"
14 #include "xutil.h"
15 
16 
17 #include "SUMA_suma.h"
18 
19 
20 #if defined SUMA_COMPILED
21    extern SUMA_CommonFields *SUMAg_CF;
22    extern int SUMAg_N_DOv;
23    extern SUMA_DO *SUMAg_DOv;
24 #endif
25 
SUMA_WriteDset_NameCheck_s(char * Name,SUMA_DSET * dset,SUMA_DSET_FORMAT form,int verb,char ** NameOutp)26 int SUMA_WriteDset_NameCheck_s (char *Name, SUMA_DSET *dset, SUMA_DSET_FORMAT form, int verb, char **NameOutp)
27 {
28    int exists = SUMA_WriteDset_NameCheck_eng(Name, dset, form, verb, NameOutp);
29    WorkErrLog_s();
30    return(exists);
31 }
32 
33 
34 /*!
35    \brief parse command line arguments for input/output debugging and
36    memory debugging. Use no fancies in this function!
37 
38    This function is to be called after SUMAg_CF has been created,
39    if #ifdef SUMA_COMPILED
40 
41    Default for iotrace = 0
42                memtrace = 1
43    Those defaults are common to all apps
44 
45 */
SUMA_ParseInput_basics_s(char * argv[],int argc)46 void SUMA_ParseInput_basics_s (char *argv[], int argc) /* for suma programs */
47 {
48 
49    static char FuncName[]={"SUMA_ParseInput_basics_s"};
50 
51    if (!SUMA_ParseInput_basics_eng (argv, argc)) return;
52 
53    if (get_Doiotrace()) { SUMA_INOUT_NOTIFY_ON; }
54    if (get_Domemtrace()) { SUMA_MEMTRACE_ON; }
55 
56    /* some more special ones */
57    #ifdef USE_TRACING
58       if (get_Doiotrace() == 2) { DBG_trace = 2; }
59    #endif
60 
61    return;
62 }
63 
64 /* A function to executes the proper macros for message generation. This one here is for suma programs */
WorkErrLog_s(void)65 void WorkErrLog_s(void)
66 {
67    static char FuncName[MAX_ERRLOG_FUNCNAME]={"WorkErrLog_s"};
68    SUMA_Boolean LocalHead = NOPE;
69    DListElmt *del=NULL;
70    SUMA_ERRLOG *el=NULL;
71    char mmm[256];
72    del = SUMA_PopErrLog(NULL);
73    while (del) {
74       el = (SUMA_ERRLOG *)del->data;
75       sprintf(FuncName, "%s", el->FuncName);
76            if (!strcmp(el->macroname,"L_Err")) { SUMA_L_Err("%s", el->msg); }
77       else if (!strcmp(el->macroname,"SL_Err")) { SUMA_SL_Err("%s", el->msg); }
78       else if (!strcmp(el->macroname,"SLP_Err")) { SUMA_SLP_Err("%s", el->msg); }
79       else if (!strcmp(el->macroname,"L_Warn")) { SUMA_L_Warn("%s", el->msg); }
80       else if (!strcmp(el->macroname,"SL_Warn")) { SUMA_SL_Warn("%s", el->msg); }
81       else if (!strcmp(el->macroname,"SLP_Warn")){SUMA_SLP_Warn("%s", el->msg); }
82       else if (!strcmp(el->macroname,"L_Note")) { SUMA_L_Note("%s", el->msg); }
83       else if (!strcmp(el->macroname,"SL_Note")) { SUMA_SL_Note("%s", el->msg); }
84       else if (!strcmp(el->macroname,"SLP_Note")){SUMA_SLP_Note("%s", el->msg); }
85       else if (!strcmp(el->macroname,"L_Crit")) { SUMA_L_Crit("%s", el->msg); }
86       else if (!strcmp(el->macroname,"SL_Crit")) { SUMA_SL_Crit("%s", el->msg); }
87       else if (!strcmp(el->macroname,"SLP_Crit")){SUMA_SLP_Crit("%s", el->msg); }
88       else {
89          snprintf(mmm, 255*sizeof(char), "Bad macroname %s", el->macroname);
90          sprintf(FuncName, "%s", "WorkErrLog_ns"); SUMA_S_Err("%s",mmm);
91       }
92       del = SUMA_PopErrLog(del);
93    }
94 }
95 
96 
97 /*!
98    \brief look for a dataset with a particular idcode
99 */
SUMA_FindDset_s(char * idcode,DList * DsetList)100 SUMA_DSET * SUMA_FindDset_s (char *idcode, DList *DsetList)
101 {
102    SUMA_DSET *dset = SUMA_FindDset_eng (idcode, DsetList, NULL, NULL);
103    WorkErrLog_s();
104    return(dset);
105 }
SUMA_FindDset2_s(char * idcode,DList * DsetList,char * itype)106 SUMA_DSET * SUMA_FindDset2_s (char *idcode, DList *DsetList, char *itype)
107 {
108    SUMA_DSET *dset = SUMA_FindDset_eng (idcode, DsetList, NULL, itype);
109    WorkErrLog_s();
110    return(dset);
111 }
112 
SUMA_FindDsetEl_s(char * idcode,DList * DsetList)113 DListElmt * SUMA_FindDsetEl_s (char *idcode, DList *DsetList)
114 {
115    DListElmt *el=NULL;
116    SUMA_DSET *dset = SUMA_FindDset_eng (idcode, DsetList, &el, NULL);
117    WorkErrLog_s();
118    return(el);
119 }
120 
SUMA_is_ID_4_DSET(char * idcode,SUMA_DSET ** dsetp)121 SUMA_Boolean  SUMA_is_ID_4_DSET(char *idcode, SUMA_DSET **dsetp)
122 {
123    static char FuncName[]={"SUMA_is_ID_4_DSET"};
124    SUMA_DSET *dset=NULL;
125 
126    SUMA_ENTRY;
127 
128    if (dsetp) *dsetp = NULL;
129    if (!idcode) SUMA_RETURN(NOPE);
130 
131    dset = SUMA_FindDset_s(idcode, SUMAg_CF->DsetList);
132 
133    if (dset) {
134       if (dsetp) *dsetp = dset;
135       SUMA_RETURN(YUP);
136    }
137 
138    SUMA_RETURN(NOPE);
139 }
140 
141 
142 /*!
143    \brief Returns the index of the node for which
144    data exists in row row of  Dset.
145    Set N_Node to SO->N_Node in the function call whenever
146    appropriate, it helps the function go faster
147    in certain instances. You can't get SO inside this
148    function from MeshParent_idcode of nel because this file
149    is not to know about surface objects.
150    Set N_Node to -1 if you don't want to use it
151 */
SUMA_GetNodeIndex_FromNodeRow_s(SUMA_DSET * dset,int row,int N_Node)152 int SUMA_GetNodeIndex_FromNodeRow_s(SUMA_DSET *dset, int row, int N_Node)
153 {
154    int i=SUMA_GetNodeIndex_FromNodeRow_eng(dset, row, N_Node);
155    WorkErrLog_s();
156    return(i);
157 }
158 
159 /*!
160    \brief j = SUMA_GetNodeRow_FromNodeIndex_s( dset, i);
161    Returns the row index of a node in the columns
162    of a data set. In other terms, node i's data are in
163    row j of the columns in nel
164    for N_Node, see comments in  SUMA_GetNodeIndex_FromNodeRow_s
165    \sa SUMA_GetNodeIndex_FromNodeRow_s
166 */
SUMA_GetNodeRow_FromNodeIndex_s(SUMA_DSET * dset,int node,int N_Node)167 int SUMA_GetNodeRow_FromNodeIndex_s(SUMA_DSET *dset, int node, int N_Node)
168 {
169    int i=SUMA_GetNodeRow_FromNodeIndex_eng(dset, node, N_Node);
170    WorkErrLog_s();
171    return(i);
172 }
173 
174 
175 /*!
176    \brief Load a surface-based dataset from disk
177 
178    \param Name (char *) THe name of the file
179    \param form (SUMA_DSET_FORMAT *) The format of the file
180                                   can choose SUMA_NO_DSET_FORMAT
181                                   and have the function attempt
182                                   to guess. In that case the function
183                                   will set the value of form
184    \return (SUMA_DSET *) dset
185    The datset does not get associated with a surface (owner_id[0] = '\0')
186    You'll have to do this manually later on if you wish
187    You typically want to insert that dataset into SUMA's DsetList list...
188 */
SUMA_LoadDset_s(char * Name,SUMA_DSET_FORMAT * form,int verb)189 SUMA_DSET *SUMA_LoadDset_s (char *Name, SUMA_DSET_FORMAT *form, int verb)
190 {
191    SUMA_DSET *dset = SUMA_LoadDset_eng (Name, form,  verb);
192    WorkErrLog_s();
193    return(dset);
194 }
195 
196 /*!
197    \brief writes a dataset to disk
198    \param Name (char *) Name of output file.
199    \param dset (SUMA_DSET *) Le dataset
200    \param form (SUMA_DSET_FORMAT ) Le format
201    \return OutName (char *)The name used for the output file
202                            (you have to free that one yourself)
203                            NULL if things went bad.
204    - Be careful, this function will not change the idcode of the
205    dataset being written. You'll have to do that manually.
206 */
SUMA_WriteDset_s(char * Name,SUMA_DSET * dset,SUMA_DSET_FORMAT form,int overwrite,int verb)207 char * SUMA_WriteDset_s (char *Name, SUMA_DSET *dset,
208                          SUMA_DSET_FORMAT form, int overwrite, int verb)
209 {
210    char *c=SUMA_WriteDset_eng (Name, dset, form, overwrite, verb, 1);
211    WorkErrLog_s();
212    return(c);
213 }
214 
SUMA_WriteDset_PreserveID(char * fn,SUMA_DSET * dset,SUMA_DSET_FORMAT oform,int overwrite,int verb)215 char *SUMA_WriteDset_PreserveID(char *fn, SUMA_DSET *dset,
216                                SUMA_DSET_FORMAT oform, int overwrite,
217                                int verb) {
218    static char FuncName[]={"SUMA_WriteDset_PreserveID"};
219    char *ofn=NULL, *oid=NULL, *fno=NULL;
220 
221    SUMA_ENTRY;
222    /* save old id and filename*/
223    ofn = SUMA_copy_string(SDSET_FILENAME(dset));
224    oid = SUMA_copy_string(SDSET_ID(dset));
225    /* change its ID before writing */
226    SUMA_NewDsetID2(dset,fn);
227    fno = SUMA_WriteDset_eng (fn, dset, oform, overwrite, verb, 1);
228    /* put old ID back */
229    NI_set_attribute (dset->ngr, "self_idcode", oid);
230    NI_set_attribute (dset->ngr, "filename", ofn);
231    SUMA_free(oid); oid=NULL;
232    SUMA_free(ofn); ofn=NULL;
233 
234    SUMA_RETURN(fno);
235 }
236 
237 /*!
238    \brief Removes the standard extension from a dataset filename
239    \param Name (char *) name
240    \param form SUMA_DSET_FORMAT
241    \return (char *) no_extension (you have to free that one with SUMA_free)
242 */
SUMA_RemoveDsetExtension_s(char * Name,SUMA_DSET_FORMAT form)243 char *SUMA_RemoveDsetExtension_s (char*Name, SUMA_DSET_FORMAT form)
244 {
245    char *c=SUMA_RemoveDsetExtension_eng (Name,  &form);
246    WorkErrLog_s();
247    return(c);
248 }
249 
250 /*!
251    \brief A function to create a dataset out of MRI_FLOAT_PTR(im)
252          that is typically used to read in a 1D file
253    \param FullName (char *) the filename
254    \param dset_id (char *) if null, SUMA_CreateDsetPointer will create one
255    \param dom_id (char *) domain idcode null if you have none
256    \param farp (float **) pointer to float vector. If far = MRI_FLOAT_PTR(im);
257                            then pass farp is &far . I want the pointer
258                            so that I can set it to NULL if the pointer
259                            is copied instead of the data (i.e. ptr_cpy ! = 0)
260    \param vec_len (int) That would be im->nx
261    \param vec_num (int) That would be im->ny
262    \param ptr_cpy (int) 0 if you want to copy the values in *farp,
263                         1 if you want to make a pointer copy. In that case
264                         (not supported yet, *farp is set to NULL)
265    \return dset (SUMA_DSET *) NULL if trouble, of course.
266 */
SUMA_far2dset_s(char * FullName,char * dset_id,char * dom_id,float ** farp,int vec_len,int vec_num,int ptr_cpy)267 SUMA_DSET *SUMA_far2dset_s( char *FullName, char *dset_id, char *dom_id,
268                                  float **farp, int vec_len, int vec_num,
269                                  int ptr_cpy)
270 {
271    SUMA_DSET *dset = SUMA_far2dset_eng( FullName, dset_id, dom_id,
272                                  farp, vec_len, vec_num,
273                                  ptr_cpy);
274    WorkErrLog_s();
275    return(dset);
276 }
277 
278 /*!
279 
280    \brief Load a surface-based data set of the DX format
281    \param Name (char *) name or prefix of dataset
282    \param verb (int) level of verbosity. 0 mute, 1 normal, 2 dramatic perhaps
283    \return dset (SUMA_DSET *)
284 
285 */
SUMA_LoadDXDset_s(char * Name,int verb)286 SUMA_DSET *SUMA_LoadDXDset_s (char *Name, int verb)
287 {
288    SUMA_DSET *dset=SUMA_LoadDXDset_eng (Name,  verb);
289    WorkErrLog_s();
290    return(dset);
291 }
292 
293 /*!
294 
295    \brief Load a surface-based data set of the 1D format
296    \param Name (char *) name or prefix of dataset
297    \param verb (int) level of verbosity. 0 mute, 1 normal, 2 dramatic perhaps
298    \return dset (SUMA_DSET *)
299 
300 */
SUMA_Load1DDset_s(char * oName,int verb)301 SUMA_DSET *SUMA_Load1DDset_s (char *oName, int verb)
302 {
303    SUMA_DSET *dset=SUMA_Load1DDset_eng (oName,  verb);
304    WorkErrLog_s();
305    return(dset);
306 }
307 
308 /*!
309    \brief a convenience function to return a 1D file in a float array
310    \param oName (char *) name of 1D file, can use '[]' if you like.
311    \param ncol (int *) to hold the number of columns in the file.
312    \param nrow (int *) to hold the number of rows in the file.
313    \param RowMajor (int) 0 keep result in column major   xxxxxx yyyyyy zzzzzz
314                         1 turn results to row major       xyz xyz xyz xyz
315    \return far(float *), the float array. Should be freed with free but SUMA_free
316    would work too.
317 */
SUMA_Load1D_s(char * oName,int * ncol,int * nrow,int RowMajor,int verb)318 float *SUMA_Load1D_s (char *oName, int *ncol, int *nrow, int RowMajor, int verb)
319 {
320    float *far=SUMA_Load1D_eng (oName, ncol, nrow,  RowMajor,  verb);
321    WorkErrLog_s();
322    return(far);
323 }
324 
325