1 #include "niml.h"
2 
3 /********************************************************************
4   Timing test for NIML element creation:
5     - load 1 row at a time:  NI_add_row()
6     - load all rows at once: NI_add_many_rows()
7     - load by columns:       NI_add_column()
8 *********************************************************************/
9 
10 typedef struct {      /* a location in space */
11   int id ;
12   float x,y,z ;
13 } AGNI_nod ;
14 
15 /* prototypes */
16 
17 NI_element * AGNI_nod_to_NIML_col ( int num_nod, AGNI_nod *nod ) ;
18 NI_element * AGNI_nod_to_NIML_row ( int num_nod, AGNI_nod *nod ) ;
19 NI_element * AGNI_nod_to_NIML_rows( int num_nod, AGNI_nod *nod ) ;
20 
21 /*------------------------------------------------------------------*/
22 
main(int argc,char * argv[])23 int main( int argc, char *argv[] )
24 {
25    int ii, nn, ct, nb ;
26    AGNI_nod *nod ;
27    NI_element *nel1, *nel2, *nel3 ;
28    NI_stream ns ;
29 
30    if( argc < 2 ){ printf("Usage: nisurf n\n"); exit(0); }
31 
32    nn = strtol(argv[1],NULL,10) ;
33    if( nn < 1 ) exit(1) ;
34 
35    /* make up some fake nodes */
36 
37    nod = NI_malloc(AGNI_nod, sizeof(AGNI_nod)*nn ) ;
38    for( ii=0 ; ii < nn ; ii++ ){
39       nod[ii].id = ii     ;
40       nod[ii].x  = 1.1*ii ;
41       nod[ii].y  = 2.2*ii ;
42       nod[ii].z  = 3.3*ii ;
43    }
44 
45    /* put nodes into a NIML data element: one row at a time */
46 
47    ct = NI_clock_time() ;                   /* start timer */
48    nel1 = AGNI_nod_to_NIML_row( nn , nod ) ; /* create element by row */
49    fprintf(stderr,"Clock time for %d nodes by row = %d ms\n",
50            nn,NI_clock_time()-ct) ;
51    if( nn < 10 ){                           /* print element */
52      ns = NI_stream_open( "fd:1" , "w" ) ;
53      if( ns == NULL ){ fprintf(stderr,"Can't open fd:1\n"); exit(1); }
54      nb = NI_write_element( ns , nel1 , NI_TEXT_MODE ) ;
55      fprintf(stderr,"num bytes=%d\n\n",nb) ;
56    }
57    /* NI_free_element(nel1) ; */                  /* free element */
58 
59    /* put nodes into a NIML data element: all rows at once */
60 
61    ct = NI_clock_time() ;
62    nel2 = AGNI_nod_to_NIML_rows( nn , nod ) ;
63    fprintf(stderr,"Clock time for %d nodes by rows = %d ms\n",
64            nn,NI_clock_time()-ct) ;
65    if( nn < 10 ){
66      nb = NI_write_element( ns , nel2 , NI_TEXT_MODE ) ;
67      fprintf(stderr,"num bytes=%d\n\n",nb) ;
68    }
69    /* NI_free_element(nel2) ; */
70 
71    /* put nodes into a NIML data element: by columns */
72 
73    ct = NI_clock_time() ;
74    nel3 = AGNI_nod_to_NIML_col( nn , nod ) ;
75    fprintf(stderr,"Clock time for %d nodes by col = %d ms\n",
76            nn,NI_clock_time()-ct) ;
77    if( nn < 10 ){
78      nb = NI_write_element( ns , nel3 , NI_TEXT_MODE ) ;
79      fprintf(stderr,"num bytes=%d\n\n",nb) ;
80    }
81    /* NI_free_element(nel3) ; */
82 
83    /* play with ni_group */
84 
85    if( nn < 5 ){
86       NI_group *ngr = NI_new_group_element() ;
87       NI_add_to_group( ngr , nel1 ) ;
88       NI_add_to_group( ngr , nel2 ) ;
89       NI_add_to_group( ngr , nel3 ) ;
90       nb = NI_write_element( ns , ngr , NI_BASE64_MODE ) ;
91       fprintf(stderr,"num bytes=%d\n\n",nb) ;
92       NI_free_element(ngr) ;
93    }
94 
95    fprintf(stderr,"\n*** That's all folks ***\n") ;
96    exit(0) ;
97 }
98 
99 /*------------------------------------------------------------------*/
100 /*! Make a NIML data element from an array of AGNI_nod structs.
101     Return value is NULL if you input stupid values.
102 --------------------------------------------------------------------*/
103 
AGNI_nod_to_NIML_row(int num_nod,AGNI_nod * nod)104 NI_element * AGNI_nod_to_NIML_row( int num_nod , AGNI_nod *nod )
105 {
106    NI_element *nel ;
107    int ii ;
108 
109    /* check inputs for sanity */
110 
111    if( num_nod < 1 || nod == NULL ) return NULL ;
112 
113    /* make a new data element, to be filled by rows */
114 
115    nel = NI_new_data_element( "surfixyz_row" , -1 ) ;
116 
117    /* define the mapping from struct components to element columns */
118 
119    NI_define_rowmap_VA( nel ,
120                           NI_INT   , offsetof(AGNI_nod,id) ,
121                           NI_FLOAT , offsetof(AGNI_nod,x)  ,
122                           NI_FLOAT , offsetof(AGNI_nod,y)  ,
123                           NI_FLOAT , offsetof(AGNI_nod,z)  ,
124                         -1 ) ;
125 
126    /* load the structs, one row at a time */
127 
128    for( ii=0 ; ii < num_nod ; ii++ )
129       NI_add_row( nel , nod+ii ) ;
130 
131    return nel ;
132 }
133 
134 /*------------------------------------------------------------------*/
135 /*! Make a NIML data element from an array of AGNI_nod structs.
136     Return value is NULL if you input stupid values.
137 --------------------------------------------------------------------*/
138 
AGNI_nod_to_NIML_rows(int num_nod,AGNI_nod * nod)139 NI_element * AGNI_nod_to_NIML_rows( int num_nod , AGNI_nod *nod )
140 {
141    NI_element *nel ;
142    int ii ;
143    int *ic ; float *xc,*yc,*zc ;
144 
145    /* check inputs for sanity */
146 
147    if( num_nod < 1 || nod == NULL ) return NULL ;
148 
149    /* make a new data element, to be filled by rows */
150 
151    nel = NI_new_data_element( "surfixyz_rows" , -1 ) ;
152 
153    /* define the mapping from struct components to element columns */
154 
155    NI_define_rowmap_VA( nel ,
156                           NI_INT   , offsetof(AGNI_nod,id) ,
157                           NI_FLOAT , offsetof(AGNI_nod,x)  ,
158                           NI_FLOAT , offsetof(AGNI_nod,y)  ,
159                           NI_FLOAT , offsetof(AGNI_nod,z)  , -1 ) ;
160 
161    /* load all the rows at once */
162 
163    NI_add_many_rows( nel , num_nod , sizeof(AGNI_nod) , nod ) ;
164 
165    return nel ;
166 }
167 
168 /*------------------------------------------------------------------*/
169 /*! Make a NIML data element from an array of AGNI_nod structs.
170     Return value is NULL if you input stupid values.
171 --------------------------------------------------------------------*/
172 
AGNI_nod_to_NIML_col(int num_nod,AGNI_nod * nod)173 NI_element * AGNI_nod_to_NIML_col( int num_nod , AGNI_nod *nod )
174 {
175    NI_element *nel ;
176    int ii ;
177    int *ic ; float *xc,*yc,*zc ;
178 
179    /* check inputs for sanity */
180 
181    if( num_nod < 1 || nod == NULL ) return NULL ;
182 
183    /* make a new data element, to be filled by columns */
184 
185    nel = NI_new_data_element( "surfixyz_col" , num_nod ) ;
186 
187    /* make the columns to be put in the element */
188 
189    ic = (int *)   malloc( sizeof(int)   * num_nod ) ;
190    xc = (float *) malloc( sizeof(float) * num_nod ) ;
191    yc = (float *) malloc( sizeof(float) * num_nod ) ;
192    zc = (float *) malloc( sizeof(float) * num_nod ) ;
193 
194    /* load the columns from the struct array */
195 
196    for( ii=0 ; ii < num_nod ; ii++ ){
197       ic[ii] = nod[ii].id ;
198       xc[ii] = nod[ii].x ;
199       yc[ii] = nod[ii].y ;
200       zc[ii] = nod[ii].z ;
201    }
202 
203    /* put columns into element */
204 
205    NI_add_column( nel , NI_INT   , ic ) ; free(ic) ;
206    NI_add_column( nel , NI_FLOAT , xc ) ; free(xc) ;
207    NI_add_column( nel , NI_FLOAT , yc ) ; free(yc) ;
208    NI_add_column( nel , NI_FLOAT , zc ) ; free(zc) ;
209 
210    return nel ;
211 }
212 
213 /*------------------------------------------------------------------*/
214 /*! Unload a <surfixyz> NI_element into an array of newly
215     malloc()-ed AGNI_nod.
216     Return value is number of nodes (will be 0 if an error occurs).
217     *nod will point to the output array if the number of nodes is
218     positive.
219 --------------------------------------------------------------------*/
220 
NIML_to_AGNI_nod(NI_element * nel,AGNI_nod ** nod)221 int NIML_to_AGNI_nod( NI_element *nel , AGNI_nod **nod )
222 {
223    int   num_nod , ii ;
224    AGNI_nod *mynod ;
225 
226    /* check element for correctness */
227 
228    if( nel             == 0        ||   /* no data element?          */
229        nel->vec_len    <  1        ||   /* empty element?             */
230        nel->vec_filled <  1        ||   /* no data was filled in?      */
231        nel->vec_num    <  4        ||   /* less than 4 columns?         */
232        nel->vec_typ[0] != NI_INT   ||   /* must be int,float,float,float */
233        nel->vec_typ[1] != NI_FLOAT ||
234        nel->vec_typ[2] != NI_FLOAT ||
235        nel->vec_typ[3] != NI_FLOAT   ) return 0 ;
236 
237    /* number of nodes is number of completely filled rows */
238 
239    num_nod = nel->vec_filled ;
240 
241    /* make space for the structs */
242 
243    mynod = (AGNI_nod *) malloc( sizeof(AGNI_nod) * num_nod ) ;
244 
245    /* define the mapping from struct components to element columns */
246 
247    NI_define_rowmap_VA( nel ,
248                           NI_INT   , offsetof(AGNI_nod,id) ,
249                           NI_FLOAT , offsetof(AGNI_nod,x)  ,
250                           NI_FLOAT , offsetof(AGNI_nod,y)  ,
251                           NI_FLOAT , offsetof(AGNI_nod,z)  ,
252                         -1 ) ;
253 
254    /* load data from NIML element to the structs */
255 
256    for( ii=0 ; ii < num_nod ; ii++ )
257       NI_get_row( nel , ii , mynod+ii ) ;
258 
259    /* we is done */
260 
261    *nod = mynod ; return num_nod ;
262 }
263