| 1 | \documentclass[12pt,a4paper]{article} |
|---|
| 2 | %%\usepackage[dvips]{graphics} |
|---|
| 3 | %%\usepackage{epsf} |
|---|
| 4 | \setlength{\textheight}{24cm} |
|---|
| 5 | \setlength{\textwidth}{16cm} |
|---|
| 6 | \setlength{\headheight}{0cm} |
|---|
| 7 | \setlength{\headsep}{0cm} |
|---|
| 8 | \setlength{\topmargin}{0cm} |
|---|
| 9 | \setlength{\oddsidemargin}{0cm} |
|---|
| 10 | \setlength{\evensidemargin}{0cm} |
|---|
| 11 | \setlength{\hoffset}{0cm} |
|---|
| 12 | \setlength{\marginparwidth}{0cm} |
|---|
| 13 | |
|---|
| 14 | \begin{document} |
|---|
| 15 | |
|---|
| 16 | \begin{center} |
|---|
| 17 | {\large NeXus--SWIG Interface}\\ |
|---|
| 18 | Mark Koennecke\\ |
|---|
| 19 | Laboratory for Neutron Scattering\\ |
|---|
| 20 | Paul Scherrer Institute\\ |
|---|
| 21 | CH--5232 Villigen--PSI\\ |
|---|
| 22 | Switzerland\\ |
|---|
| 23 | Mark.Koennecke@psi.ch\\ |
|---|
| 24 | November 2002\\ |
|---|
| 25 | \end{center} |
|---|
| 26 | |
|---|
| 27 | |
|---|
| 28 | \section{Introduction} |
|---|
| 29 | This is a description of the SWIG interface to the NeXus--API. NeXus |
|---|
| 30 | is a proposal for a common data format for synchrotron and neutron |
|---|
| 31 | diffraction data. NeXus uses HDF, the Hierachical Data Format, from |
|---|
| 32 | the National Center for Super Computing Applications (NCSA) as its |
|---|
| 33 | physical file format. NeXus files are accessed through a NeXus--API |
|---|
| 34 | which sits between application programs and the HDF--libraries and |
|---|
| 35 | then the files themselves. For more information on NeXus see:\\ |
|---|
| 36 | \centerline{http://lns00.psi.ch/NeXus} |
|---|
| 37 | |
|---|
| 38 | SWIG is the Simplified Wrapper and Interface Generator. This is a |
|---|
| 39 | software tool which creates the necessary wrapper code needed to access a |
|---|
| 40 | given ANSI--C or C++ library from a variety of scripting languages |
|---|
| 41 | including: Tcl, Java, Perl, Phyton, scheme etc. For more information |
|---|
| 42 | about SWIG see:\\ |
|---|
| 43 | \centerline{http://www.swig.org} |
|---|
| 44 | |
|---|
| 45 | This now is the description of the SWIG interface to the |
|---|
| 46 | NeXus--API. This document is intended for users who are familiar with |
|---|
| 47 | the NeXus--API. The meaning of the functions is the same as for the |
|---|
| 48 | ANSI--C NeXus--API, only function signatures may have changed. Please |
|---|
| 49 | refer to the NeXus--API documentation for further reference. |
|---|
| 50 | |
|---|
| 51 | |
|---|
| 52 | \section{General Remarks} |
|---|
| 53 | When interfacing an API like NeXus to a scripting language |
|---|
| 54 | a couple of issues have to be handled: |
|---|
| 55 | \begin{description} |
|---|
| 56 | \item[pointers] The NeXus--API uses pointers extensively. Fortunately |
|---|
| 57 | SWIG provides a means for encapsulating pointers in a script language. |
|---|
| 58 | \item[memory management] Most scripting language have some kind of |
|---|
| 59 | automatic variable management or garbage collection. Interfaces |
|---|
| 60 | generated with SWIG however still use the C memory management. This |
|---|
| 61 | imples that if you call C--routines which allocate memory you should |
|---|
| 62 | not forget to free the memory again after you are done. Otherwise you |
|---|
| 63 | may end up with a system out of memory due to memory leakage. |
|---|
| 64 | \item[datasets] NeXus works on possibly large datasets which may have |
|---|
| 65 | different number types. Support for handling large arrays misses in |
|---|
| 66 | many scripting languages. Therefore this interface system provides its |
|---|
| 67 | own implementation of datasets. |
|---|
| 68 | \item[return values] Some functions of the NeXus--API return more then |
|---|
| 69 | one value through the call by reference mechanism. These functions had |
|---|
| 70 | to be wrapped such that all necessary return values are passed back |
|---|
| 71 | into the scripting language. |
|---|
| 72 | \end{description} |
|---|
| 73 | |
|---|
| 74 | Necessarily the generated interface will look slightly different in |
|---|
| 75 | each target scripting language. For instance the constant NXACC\_READ |
|---|
| 76 | is referred to as: |
|---|
| 77 | \begin{verbatim} |
|---|
| 78 | $NXACC_READ |
|---|
| 79 | \end{verbatim} in Tcl. In scheme this looks like: |
|---|
| 80 | \begin{verbatim} |
|---|
| 81 | (nxacc-read) |
|---|
| 82 | \end{verbatim} |
|---|
| 83 | Functions also follow the calling conventions of the target |
|---|
| 84 | language. An example in Tcl and scheme: |
|---|
| 85 | \begin{description} |
|---|
| 86 | \item[Tcl] \verb+ set fd [nx_open ``nxinter.hdf'' $NXACC\_READ] + |
|---|
| 87 | \item[mzScheme] (define fd (nx-open ``nxinter.hdf'' (nxacc-read))) |
|---|
| 88 | \end{description} |
|---|
| 89 | The actual mapping generated for a target scripting language by SWIG |
|---|
| 90 | can be found by studying SWIG's documentation or through browsing the |
|---|
| 91 | generated wrapper file for your interface. All examples in the |
|---|
| 92 | reference below are given in Tcl syntax. |
|---|
| 93 | |
|---|
| 94 | SWIG goes a long way to help in the creation of scripting language |
|---|
| 95 | interfaces. The user still has to master the process of compiling and |
|---|
| 96 | linking a scripting language extension and loading it into the target |
|---|
| 97 | interpreter. Examples for this are provided in the SWIG package. |
|---|
| 98 | |
|---|
| 99 | |
|---|
| 100 | \section{The Dataset Interface} |
|---|
| 101 | The dataset interface brings multidimensional datasets to the |
|---|
| 102 | scripting language. This is necessary because many scripting languages |
|---|
| 103 | do not have a good support for multi dimensional arrays of numbers. |
|---|
| 104 | If a scripting language supports |
|---|
| 105 | multidimensional arrays, another extension could be written which |
|---|
| 106 | transfers such data efficiently, either directly from the NeXus file |
|---|
| 107 | or using the NeXus dataset as an intermediary. |
|---|
| 108 | Currently no such optimisations are provided. |
|---|
| 109 | |
|---|
| 110 | There usually is a number type associated with a NeXus dataset. In |
|---|
| 111 | order to save effort and for simplification the NeXus number types |
|---|
| 112 | were used. The names are self explaining, if more information about |
|---|
| 113 | the meaning of these types is required, please consult the NeXus |
|---|
| 114 | documentation. The types provided are (in Tcl syntax): |
|---|
| 115 | \begin{verbatim} |
|---|
| 116 | $NX_FLOAT32 |
|---|
| 117 | $NX_FLOAT64 |
|---|
| 118 | $NX_INT8 |
|---|
| 119 | $NX_UINT8 |
|---|
| 120 | $NX_INT16 |
|---|
| 121 | $NX_UINT16 |
|---|
| 122 | $NX_INT32 |
|---|
| 123 | $NX_UINT32 |
|---|
| 124 | $NX_CHAR |
|---|
| 125 | \end{verbatim} |
|---|
| 126 | |
|---|
| 127 | For notational convenience a symbol {\bf nxdsPtr} is now |
|---|
| 128 | introduced. This symbol stands for a pointer to a NeXus dataset |
|---|
| 129 | wrapped according to the scripting languages conventions. |
|---|
| 130 | |
|---|
| 131 | |
|---|
| 132 | The dataset interface consists of the following functions. Tcl syntax |
|---|
| 133 | is assumed for this description. |
|---|
| 134 | |
|---|
| 135 | {\bf nxdsPtr create\_nxds rank type dim0 dim1 dim2 dim3 dim4 dim5 dim6} |
|---|
| 136 | creates a NeXus dataset with the specified rank and type and the |
|---|
| 137 | dimensions given as dim0 - dim6. If you do not need so many |
|---|
| 138 | dimensions, leave the surplus ones out, this sytem will replace the |
|---|
| 139 | values with zeros. The interface can be easily extended to support |
|---|
| 140 | more then 7 dimensions if required. |
|---|
| 141 | |
|---|
| 142 | {\bf nxdsPtr create\_text\_nxds textdata} convenience function which |
|---|
| 143 | wraps textdata into a NeXus dataset. |
|---|
| 144 | |
|---|
| 145 | {\bf drop\_nxds nxdsPtr} use this function to dispose of datasets which |
|---|
| 146 | are no longer needed. Do this, otherwise memory leaks occur! |
|---|
| 147 | |
|---|
| 148 | |
|---|
| 149 | {\bf get\_nxds\_rank nxdsPtr} returns the rank of the dataset. |
|---|
| 150 | |
|---|
| 151 | {\bf get\_nxds\_type nxdsPtr} returns the data type of the datset as an |
|---|
| 152 | integer. |
|---|
| 153 | |
|---|
| 154 | {\bf get\_nxds\_dim nxdsPtr which} returns the dimension of the dataset |
|---|
| 155 | in dimension which. |
|---|
| 156 | |
|---|
| 157 | {\bf get\_nxds\_value nxdsPtr dim0 dim1 dim2 dim3 dim4 dim5 dim6} |
|---|
| 158 | returns the value of the dataset at the index specified by dim0 - |
|---|
| 159 | dim6. Again, leave out unneccessary indexes. |
|---|
| 160 | |
|---|
| 161 | {\bf get\_nxds\_text nxdsPtr} convenience function which returns the |
|---|
| 162 | content of the dataset as a text string. his works only if the dataset |
|---|
| 163 | has rank 1 and is of type NX\_CHAR, NX\_INT8 or NX\_UINT8. |
|---|
| 164 | |
|---|
| 165 | {\bf put\_nxds\_value nxdsPtr val dim0 dim1 dim2 dim3 dim4 dim5 dim6} |
|---|
| 166 | sets the value of the dataset at the cell denoted by dim0 -dim6 to the |
|---|
| 167 | value val. Again, you may omit surplu indexes. |
|---|
| 168 | |
|---|
| 169 | |
|---|
| 170 | \section{The NeXus--API Interface} |
|---|
| 171 | |
|---|
| 172 | \subsection{Notation} |
|---|
| 173 | After opening them, NeXus files are referred to through a |
|---|
| 174 | handle. This handle is denoted through the symbol {nxFil} in the next |
|---|
| 175 | sections. |
|---|
| 176 | |
|---|
| 177 | There is another symbol {\bf nxSuccess} which stands for an |
|---|
| 178 | integer. This is 1 if the function returned with success and 0 in case |
|---|
| 179 | of a failure. If a function returns a pointer, failure is indicated |
|---|
| 180 | through the NULL pointer. The encoding of the NULL pointer varies |
|---|
| 181 | between scripting languages. |
|---|
| 182 | |
|---|
| 183 | |
|---|
| 184 | \subsection{Error Handling} |
|---|
| 185 | Most NeXus-API functions return 1 on success and 0 in case of an |
|---|
| 186 | error. The exception are those functions which return a pointer. These |
|---|
| 187 | return a NULL pointer in case of an error. In each case more |
|---|
| 188 | information about the problem can be obtained by calling: |
|---|
| 189 | {\bf nx\_getlasterror} This call returns a string describing the last |
|---|
| 190 | NeXus error found. |
|---|
| 191 | |
|---|
| 192 | \subsection{File Creation accessCode Constants} |
|---|
| 193 | The meanings of the constants are as described in the NeXus--API |
|---|
| 194 | documentation. |
|---|
| 195 | \begin{verbatim} |
|---|
| 196 | $NXACC_READ |
|---|
| 197 | $NXACC_RDWR |
|---|
| 198 | $NXACC_CREATE |
|---|
| 199 | $NXACC_CREATE4 |
|---|
| 200 | $NXACC_CREATE5 |
|---|
| 201 | \end{verbatim} |
|---|
| 202 | |
|---|
| 203 | |
|---|
| 204 | |
|---|
| 205 | \subsection{Opening and Closing of Files} |
|---|
| 206 | {nxFil nx\_open filename accessCode} opens the NeXus file filename. The |
|---|
| 207 | accessCodes must be one of the constants given above. Returns a new |
|---|
| 208 | handle in the case of a success, NULL in case of failure. |
|---|
| 209 | |
|---|
| 210 | {\bf nxFil nx\_flush nxFil} flushes a NeXus file. |
|---|
| 211 | |
|---|
| 212 | {\bf nx\_close nxFil} closes a NeXus file, The handle nxFil is useless |
|---|
| 213 | after this. his call is necessary, especially when writing files. |
|---|
| 214 | |
|---|
| 215 | |
|---|
| 216 | \subsection{Group Operations} |
|---|
| 217 | {\bf nxSuccess nx\_makegroup nxFil name nxclass} |
|---|
| 218 | |
|---|
| 219 | {\bf nxSuccess nx\_opengroup nxFil name nxclass} |
|---|
| 220 | |
|---|
| 221 | {\bf nxSuccess nx\_closegroup nxFil} |
|---|
| 222 | |
|---|
| 223 | {\bf nxMulti nx\_getnextentry nxFil separatorChar} performs group |
|---|
| 224 | directory searches. nxMulti is a string containing name and NeXus |
|---|
| 225 | class of the group item separated by the character given as |
|---|
| 226 | separatorChar. If the search ends, NULL is returned. |
|---|
| 227 | |
|---|
| 228 | {\bf nxSuccess nx\_initgroupdir nxFil} |
|---|
| 229 | |
|---|
| 230 | {nxPtr nx\_getgroupID nxFil} returns a pointer to a structure needed |
|---|
| 231 | for linking. |
|---|
| 232 | |
|---|
| 233 | |
|---|
| 234 | \subsection{Dataset Handling} |
|---|
| 235 | |
|---|
| 236 | {\bf nxSuccess nx\_makedata nxFil name rank type dimDs} |
|---|
| 237 | makes a new dataset. The dimensions are described through the NeXus |
|---|
| 238 | dataset dimDs. |
|---|
| 239 | |
|---|
| 240 | {\bf nxSuccess nx\_compmakedata nxFil name rank type dimDs bufds} |
|---|
| 241 | as above, but for compressed datasets. The HDF--5 buffering size is |
|---|
| 242 | specified through the NeXus dataset bufDs. |
|---|
| 243 | |
|---|
| 244 | {\bf nx\_opendata nxFil name} |
|---|
| 245 | |
|---|
| 246 | {\bf nx\_closedata nxFil} |
|---|
| 247 | |
|---|
| 248 | {\bf nx\_putslab nxFil nxdsPtr startDs} slabbed data writing. The |
|---|
| 249 | data comes from the NeXus dataset nxdsPtr. The start point from the |
|---|
| 250 | NeXus dataset startDS. The size of the dataset to write is the size of |
|---|
| 251 | nxdsPtr. |
|---|
| 252 | |
|---|
| 253 | {\bf nxdsPtr nx\_getslab nxFil startDs sizeDs} reads a slab. startDS |
|---|
| 254 | and sizeDs are two NeXus datasets describing the slab to read. The |
|---|
| 255 | data is returned as a NeXus dataset. Do not forget to drop this |
|---|
| 256 | dataset once you are done with the data! |
|---|
| 257 | |
|---|
| 258 | {\bf nxdsPtr nx\_getds nxFil} reads dataset name. This convenience |
|---|
| 259 | function opens the dataset, allocates a NeXus dataset of appropriate |
|---|
| 260 | type and size for you and closes the SDS again. |
|---|
| 261 | |
|---|
| 262 | {\bf nxSuccess nx\_putds nxFil name nxdsPtr} writes the dataset |
|---|
| 263 | nxdsPtr to the file as name at the current position in the |
|---|
| 264 | hierarchy. Same convenience fatures as above. |
|---|
| 265 | |
|---|
| 266 | {\bf nxdsPtr nx\_getdata nxFil} normal NeXus getdata but returns a |
|---|
| 267 | NeXus dataset. |
|---|
| 268 | |
|---|
| 269 | {\bf nxSuccess nx\_putdata nxFil nxdsPtr} normal NeXus putdata. Data is |
|---|
| 270 | taken from the NeXus dataset nxdsPtr. |
|---|
| 271 | |
|---|
| 272 | {\bf nxdsPtr nx\_getinfo nxFil} returns the current datasets type, rank |
|---|
| 273 | and dimensions in a one dimensional NeXus dataset. |
|---|
| 274 | |
|---|
| 275 | {\bf ptr nx\_getdataID nxFil} retrieves link pointer for linking. |
|---|
| 276 | |
|---|
| 277 | \subsection{Attributes} |
|---|
| 278 | {\bf nxText nx\_getnextattr nxFil separatorChar}reads the next entry |
|---|
| 279 | of attribute directory. nxText then contains then name, length and |
|---|
| 280 | type of the attribute formatted as a string and separated by the |
|---|
| 281 | character separatorChar. |
|---|
| 282 | |
|---|
| 283 | {\bf nxSuccess nx\_putattr nxFil name nxdsPtr} writes an attribute name |
|---|
| 284 | from the NeXus dataset nxdsPtr. |
|---|
| 285 | |
|---|
| 286 | {\bf nxdsPtr nx\_getattr nxFil name type length} reads an attribute |
|---|
| 287 | into a dataset. The data type and the length of the attribute have to |
|---|
| 288 | specified. |
|---|
| 289 | |
|---|
| 290 | \subsection{Making Links} |
|---|
| 291 | {bf nxSuccess nx\_makelink nxFil nxLink} makes a link. nxLink is one |
|---|
| 292 | of the pointers returned from the nx\_getgroupID or nx\_getdataID |
|---|
| 293 | functions. |
|---|
| 294 | |
|---|
| 295 | \section{Example} |
|---|
| 296 | As an example for the usage of the API see the API test program |
|---|
| 297 | documented below: |
|---|
| 298 | \begin{verbatim} |
|---|
| 299 | #------------------------------------------------------------------------- |
|---|
| 300 | # Test program for the nxinter interface. Also example usage. |
|---|
| 301 | # |
|---|
| 302 | # copyright: GPL |
|---|
| 303 | # |
|---|
| 304 | # Mark Koennecke, October 2002 |
|---|
| 305 | #------------------------------------------------------------------------ |
|---|
| 306 | |
|---|
| 307 | #load ./nxinter.so |
|---|
| 308 | |
|---|
| 309 | #------------- testing dataset interface |
|---|
| 310 | set ds [create_nxds 2 $NX_FLOAT32 3 3] |
|---|
| 311 | |
|---|
| 312 | put_nxds_value $ds 1 0 0 |
|---|
| 313 | put_nxds_value $ds 1 1 1 |
|---|
| 314 | put_nxds_value $ds 1 2 2 |
|---|
| 315 | |
|---|
| 316 | puts stdout "Testing dataset interface " |
|---|
| 317 | puts stdout [format "rank = %d" [get_nxds_rank $ds]] |
|---|
| 318 | puts stdout [format "type = %d" [get_nxds_type $ds]] |
|---|
| 319 | puts stdout [format "dim1 = %d" [get_nxds_dim $ds 1]] |
|---|
| 320 | |
|---|
| 321 | proc printDS {ds} { |
|---|
| 322 | for {set i 0} {$i < 3} {incr i} { |
|---|
| 323 | puts stdout " " |
|---|
| 324 | for {set j 0} {$j < 3} {incr j} { |
|---|
| 325 | puts -nonewline stdout [format " %f" [get_nxds_value $ds $i $j]] |
|---|
| 326 | } |
|---|
| 327 | } |
|---|
| 328 | puts stdout " " |
|---|
| 329 | } |
|---|
| 330 | |
|---|
| 331 | printDS $ds |
|---|
| 332 | puts stdout "Hmmmmmmmhhh....... seems OK" |
|---|
| 333 | |
|---|
| 334 | #-------------- prepare a dimension dataset |
|---|
| 335 | set dimds [create_nxds 1 $NX_INT32 2] |
|---|
| 336 | put_nxds_value $dimds 3 0 |
|---|
| 337 | put_nxds_value $dimds 3 1 |
|---|
| 338 | |
|---|
| 339 | #--------- prepare slabbing slabber dimensions |
|---|
| 340 | set start [create_nxds 1 $NX_INT32 2] |
|---|
| 341 | put_nxds_value $start 0 0 |
|---|
| 342 | put_nxds_value $start 0 1 |
|---|
| 343 | |
|---|
| 344 | |
|---|
| 345 | #----------------------------------- write tests |
|---|
| 346 | puts stdout "Testing writing ..........." |
|---|
| 347 | |
|---|
| 348 | set fd [nx_open "nxinter.hdf" $NXACC_CREATE5] |
|---|
| 349 | puts stdout [format "Opening file worked: %s" $fd] |
|---|
| 350 | |
|---|
| 351 | #---------- write an attribute..... |
|---|
| 352 | set tds [create_text_nxds "Rosa Waschmaschinen sind hip"] |
|---|
| 353 | puts stdout [format "Writing SuperDuper = %s" [get_nxds_text $tds]] |
|---|
| 354 | puts stdout [format "Writing attribute results in: %d " \ |
|---|
| 355 | [nx_putattr $fd "SuperDuper" $tds]] |
|---|
| 356 | drop_nxds $tds |
|---|
| 357 | |
|---|
| 358 | #----------- making groups.... |
|---|
| 359 | set status [nx_makegroup $fd fish NXentry] |
|---|
| 360 | if {$status == 1} { |
|---|
| 361 | puts stdout "Creating vGroup worked" |
|---|
| 362 | } |
|---|
| 363 | |
|---|
| 364 | set status [nx_opengroup $fd fish NXentry] |
|---|
| 365 | if {$status == 1} { |
|---|
| 366 | puts stdout "Opening vGroup worked" |
|---|
| 367 | } |
|---|
| 368 | |
|---|
| 369 | set lnk [nx_getgroupID $fd] |
|---|
| 370 | puts stdout [format "groupID determined to: %s" $lnk] |
|---|
| 371 | |
|---|
| 372 | #------------ writing tata |
|---|
| 373 | puts stdout "Test Writing data....." |
|---|
| 374 | puts stdout [nx_makedata $fd "fish" 2 $NX_FLOAT32 $dimds] |
|---|
| 375 | puts stdout [nx_opendata $fd "fish"] |
|---|
| 376 | puts stdout [nx_putdata $fd $ds] |
|---|
| 377 | set lnk [nx_getdataID $fd] |
|---|
| 378 | puts stdout $lnk |
|---|
| 379 | puts stdout [nx_closedata $fd] |
|---|
| 380 | |
|---|
| 381 | #--------------- testing slabbed tata writing |
|---|
| 382 | puts stdout "Testing writing in slabs" |
|---|
| 383 | put_nxds_value $dimds 6 0 |
|---|
| 384 | puts stdout [format "Dimensions for slab test: %f, %f" \ |
|---|
| 385 | [get_nxds_value $dimds 0] [get_nxds_value $dimds 1]] |
|---|
| 386 | |
|---|
| 387 | puts stdout [nx_makedata $fd "fish2" 2 $NX_FLOAT32 $dimds] |
|---|
| 388 | puts stdout [nx_opendata $fd "fish2"] |
|---|
| 389 | puts stdout [nx_putslab $fd $ds $start] |
|---|
| 390 | put_nxds_value $start 3 0 |
|---|
| 391 | puts stdout [nx_putslab $fd $ds $start] |
|---|
| 392 | puts stdout [nx_closedata $fd] |
|---|
| 393 | puts stdout "Finished Writing Slabs........." |
|---|
| 394 | |
|---|
| 395 | puts stdout [format "Linking = %d" [nx_makelink $fd $lnk]] |
|---|
| 396 | |
|---|
| 397 | set status [nx_closegroup $fd] |
|---|
| 398 | if {$status == 1} { |
|---|
| 399 | puts stdout "Closing vGroup worked" |
|---|
| 400 | } |
|---|
| 401 | |
|---|
| 402 | |
|---|
| 403 | nx_close $fd |
|---|
| 404 | puts stdout "Closed file" |
|---|
| 405 | #---------------- finished writing tests |
|---|
| 406 | |
|---|
| 407 | |
|---|
| 408 | #---------------- trying to read |
|---|
| 409 | puts stdout "Testing Reading files" |
|---|
| 410 | |
|---|
| 411 | set fd [nx_open "nxinter.hdf" $NXACC_READ] |
|---|
| 412 | puts stdout "Opening file for reading worked" |
|---|
| 413 | |
|---|
| 414 | set run 1 |
|---|
| 415 | |
|---|
| 416 | #----------------- printing group content |
|---|
| 417 | puts stdout "Group directory listing" |
|---|
| 418 | while {$run == 1} { |
|---|
| 419 | set entry [nx_getnextentry $fd / ] |
|---|
| 420 | if { [string length $entry] < 2 } { |
|---|
| 421 | set run 0 |
|---|
| 422 | } else { |
|---|
| 423 | puts stdout $entry |
|---|
| 424 | } |
|---|
| 425 | } |
|---|
| 426 | #--------- printing attributes |
|---|
| 427 | puts stdout "Attributes" |
|---|
| 428 | set run 1 |
|---|
| 429 | while {$run == 1} { |
|---|
| 430 | set entry [nx_getnextattr $fd / ] |
|---|
| 431 | puts stdout $entry |
|---|
| 432 | if { [string length $entry] < 2 } { |
|---|
| 433 | set run 0 |
|---|
| 434 | } |
|---|
| 435 | } |
|---|
| 436 | |
|---|
| 437 | set rds [nx_getattr $fd "SuperDuper" $NX_CHAR 30] |
|---|
| 438 | puts stdout $rds |
|---|
| 439 | if {[string compare $rds NULL] != 0} { |
|---|
| 440 | puts stdout [format "SuperDuper = %s" [get_nxds_text $rds]] |
|---|
| 441 | } |
|---|
| 442 | drop_nxds $rds |
|---|
| 443 | |
|---|
| 444 | #---------------- reading tata |
|---|
| 445 | puts stdout [nx_opengroup $fd fish NXentry] |
|---|
| 446 | puts stdout [nx_opendata $fd "fish"] |
|---|
| 447 | set rds [nx_getdata $fd] |
|---|
| 448 | puts stdout $rds |
|---|
| 449 | |
|---|
| 450 | puts stdout "Read data should be a 3x3 unity matrix" |
|---|
| 451 | printDS $rds |
|---|
| 452 | |
|---|
| 453 | puts stdout [nx_closedata $fd] |
|---|
| 454 | |
|---|
| 455 | #----------- reading slabbed data |
|---|
| 456 | puts stdout "Testing slabbed reading......" |
|---|
| 457 | puts stdout [nx_opendata $fd "fish2"] |
|---|
| 458 | set ids [nx_getinfo $fd] |
|---|
| 459 | puts stdout [format "fish2: type %f, rank %f, d1 %f, d2 %f" \ |
|---|
| 460 | [get_nxds_value $ids 0] [get_nxds_value $ids 1] \ |
|---|
| 461 | [get_nxds_value $ids 2] [get_nxds_value $ids 3]] |
|---|
| 462 | drop_nxds $ids |
|---|
| 463 | |
|---|
| 464 | put_nxds_value $dimds 3 0 |
|---|
| 465 | set r1 [nx_getslab $fd $start $dimds] |
|---|
| 466 | printDS $r1 |
|---|
| 467 | put_nxds_value $start 0 0 |
|---|
| 468 | set r2 [nx_getslab $fd $start $dimds] |
|---|
| 469 | printDS $r2 |
|---|
| 470 | puts stdout [nx_closedata $fd] |
|---|
| 471 | |
|---|
| 472 | puts stdout [nx_closegroup $fd] |
|---|
| 473 | puts stdout [nx_close $fd] |
|---|
| 474 | |
|---|
| 475 | #--------------- dropping datasets: do not forget!!! |
|---|
| 476 | drop_nxds $ds |
|---|
| 477 | drop_nxds $rds |
|---|
| 478 | drop_nxds $dimds |
|---|
| 479 | \end{verbatim} |
|---|
| 480 | \end{document} |
|---|