Example NeXus programs using NAPI

NAPI Simple 2-D Write Example (C, F77, F90)

Code examples are provided in this section that write 2-D data to a NeXus HDF5 file in C, F77, and F90 languages using the NAPI.

The following code reads a two-dimensional set counts with dimension scales of t and phi using local routines, and then writes a NeXus file containing a single NXentry group and a single NXdata group. This is the simplest data file that conforms to the NeXus standard. The same code is provided in C, F77, and F90 versions. Compare these code examples with Example NeXus C programs using native HDF5 commands.

NAPI C Example: write simple NeXus file

Note

This example uses the signal/axes attributes applied to the data field, as described in Associating plottable data by name using the axes attribute. New code should use the method described in Associating plottable data using attributes applied to the NXdata group.

 1#include "napi.h"
 2
 3int main()
 4{
 5    int counts[50][1000], n_t=1000, n_p=50, dims[2], i;
 6    float t[1000], phi[50];
 7    NXhandle file_id;
 8/* 
 9 * Read in data using local routines to populate phi and counts
10 *
11 * for example you may create a getdata() function and call
12 *
13 *      getdata (n_t, t, n_p, phi, counts);
14 */
15/* Open output file and output global attributes */
16    NXopen ("NXfile.nxs", NXACC_CREATE5, &file_id);
17      NXputattr (file_id, "user_name", "Joe Bloggs", 10, NX_CHAR);
18/* Open top-level NXentry group */
19      NXmakegroup (file_id, "Entry1", "NXentry");
20      NXopengroup (file_id, "Entry1", "NXentry");
21/* Open NXdata group within NXentry group */
22        NXmakegroup (file_id, "Data1", "NXdata");
23        NXopengroup (file_id, "Data1", "NXdata");
24/* Output time channels */
25          NXmakedata (file_id, "time_of_flight", NX_FLOAT32, 1, &n_t);
26          NXopendata (file_id, "time_of_flight");
27            NXputdata (file_id, t);
28            NXputattr (file_id, "units", "microseconds", 12, NX_CHAR);
29          NXclosedata (file_id);
30/* Output detector angles */
31          NXmakedata (file_id, "polar_angle", NX_FLOAT32, 1, &n_p);
32          NXopendata (file_id, "polar_angle");
33            NXputdata (file_id, phi);
34            NXputattr (file_id, "units", "degrees", 7, NX_CHAR);
35          NXclosedata (file_id);
36/* Output data */
37          dims[0] = n_t;
38          dims[1] = n_p;
39          NXmakedata (file_id, "counts", NX_INT32, 2, dims);
40          NXopendata (file_id, "counts");
41            NXputdata (file_id, counts);
42            i = 1;
43            NXputattr (file_id, "signal", &i, 1, NX_INT32);
44            NXputattr (file_id, "axes",  "polar_angle:time_of_flight", 26, NX_CHAR);
45          NXclosedata (file_id);
46/* Close NXentry and NXdata groups and close file */
47        NXclosegroup (file_id);
48      NXclosegroup (file_id);
49    NXclose (&file_id);
50    return;
51}

NAPI F77 Example: write simple NeXus file

Note

The F77 interface is no longer being developed.

 1      program WRITEDATA
 2      
 3      include 'NAPIF.INC'
 4      integer*4 status, file_id(NXHANDLESIZE), counts(1000,50), n_p, n_t, dims(2)
 5      real*4 t(1000), phi(50)
 6
 7!Read in data using local routines
 8      call getdata (n_t, t, n_p, phi, counts)
 9!Open output file
10      status = NXopen ('NXFILE.NXS', NXACC_CREATE, file_id)
11        status = NXputcharattr 
12     +         (file_id, 'user', 'Joe Bloggs', 10, NX_CHAR)
13!Open top-level NXentry group
14        status = NXmakegroup (file_id, 'Entry1', 'NXentry')
15        status = NXopengroup (file_id, 'Entry1', 'NXentry')
16!Open NXdata group within NXentry group
17          status = NXmakegroup (file_id, 'Data1', 'NXdata')
18          status = NXopengroup (file_id, 'Data1', 'NXdata')
19!Output time channels
20            status = NXmakedata 
21     +         (file_id, 'time_of_flight', NX_FLOAT32, 1, n_t)
22            status = NXopendata (file_id, 'time_of_flight')
23              status = NXputdata (file_id, t)
24              status = NXputcharattr 
25     +         (file_id, 'units', 'microseconds', 12, NX_CHAR)
26            status = NXclosedata (file_id)
27!Output detector angles
28            status = NXmakedata (file_id, 'polar_angle', NX_FLOAT32, 1, n_p)
29            status = NXopendata (file_id, 'polar_angle')
30              status = NXputdata (file_id, phi)
31              status = NXputcharattr (file_id, 'units', 'degrees', 7, NX_CHAR)
32            status = NXclosedata (file_id)
33!Output data
34            dims(1) = n_t
35            dims(2) = n_p
36            status = NXmakedata (file_id, 'counts', NX_INT32, 2, dims)
37            status = NXopendata (file_id, 'counts')
38              status = NXputdata (file_id, counts)
39              status = NXputattr (file_id, 'signal', 1, 1, NX_INT32)
40              status = NXputattr
41     +          (file_id, 'axes', 'polar_angle:time_of_flight', 26, NX_CHAR)
42            status = NXclosedata (file_id)
43!Close NXdata and NXentry groups and close file
44          status = NXclosegroup (file_id)
45        status = NXclosegroup (file_id)
46      status = NXclose (file_id)
47
48      stop
49      end

NAPI F90 Example: write simple NeXus file

Note

This example uses the signal/axes attributes applied to the data field, as described in Associating plottable data by name using the axes attribute. New code should use the method described in Associating plottable data using attributes applied to the NXdata group.

 1program WRITEDATA
 2      
 3   use NXUmodule
 4
 5   type(NXhandle) :: file_id
 6   integer, pointer :: counts(:,:)
 7   real, pointer :: t(:), phi(:)
 8
 9!Use local routines to allocate pointers and fill in data
10   call getlocaldata (t, phi, counts)
11!Open output file
12   if (NXopen ("NXfile.nxs", NXACC_CREATE, file_id) /= NX_OK) stop
13   if (NXUwriteglobals (file_id, user="Joe Bloggs") /= NX_OK) stop
14!Set compression parameters
15   if (NXUsetcompress (file_id, NX_COMP_LZW, 1000) /= NX_OK) stop
16!Open top-level NXentry group
17   if (NXUwritegroup (file_id, "Entry1", "NXentry") /= NX_OK) stop
18   !Open NXdata group within NXentry group
19      if (NXUwritegroup (file_id, "Data1", "NXdata") /= NX_OK) stop
20   !Output time channels
21         if (NXUwritedata (file_id, "time_of_flight", t, "microseconds") /= NX_OK) stop
22   !Output detector angles
23         if (NXUwritedata (file_id, "polar_angle", phi, "degrees") /= NX_OK) stop
24   !Output data
25         if (NXUwritedata (file_id, "counts", counts, "counts") /= NX_OK) stop
26            if (NXputattr (file_id, "signal", 1) /= NX_OK) stop
27            if (NXputattr (file_id, "axes", "polar_angle:time_of_flight") /= NX_OK) stop
28   !Close NXdata group
29      if (NXclosegroup (file_id) /= NX_OK) stop
30!Close NXentry group
31   if (NXclosegroup (file_id) /= NX_OK) stop
32!Close NeXus file
33   if (NXclose (file_id) /= NX_OK) stop
34
35end program WRITEDATA

NAPI Python Simple 3-D Write Example

A single code example is provided in this section that writes 3-D data to a NeXus HDF5 file in the Python language using the NAPI.

The data to be written to the file is a simple three-dimensional array (2 x 3 x 4) of integers. The single dataset is intended to demonstrate the order in which each value of the array is stored in a NeXus HDF5 data file.

NAPI Python Example: write simple NeXus file

 1#!/usr/bin/python
 2
 3import sys
 4import nxs
 5import numpy
 6
 7a = numpy.zeros((2,3,4),dtype=numpy.int)
 8val = 0
 9for i in range(2):
10    for j in range(3):
11        for k in range(4):
12            a[i,j,k] = val
13            val = val + 1
14
15nf = nxs.open("simple3D.h5", "w5")
16
17nf.makegroup("entry","NXentry")
18nf.opengroup("entry","NXentry")
19
20nf.makegroup("data","NXdata")
21nf.opengroup("data","NXdata")
22nf.putattr("signal","test")
23
24nf.makedata("test",'int32',[2,3,4])
25nf.opendata("test")
26nf.putdata(a)
27nf.closedata()
28
29nf.closegroup() # NXdata
30nf.closegroup() # NXentry
31
32nf.close()
33
34exit

View a NeXus HDF5 file using h5dump

For the purposes of an example, it is instructive to view the content of the NeXus HDF5 file produced by the above program. Since HDF5 is a binary file format, we cannot show the contents of the file directly in this manual. Instead, we first we view the content by showing the output from the h5dump tool provided as part of the HDF5 tool kit: h5dump simple3D.h5

NAPI Python Example: h5dump output of NeXus HDF5 file

 1HDF5 "simple3D.h5" {
 2GROUP "/" {
 3   ATTRIBUTE "NeXus_version" {
 4      DATATYPE  H5T_STRING {
 5            STRSIZE 5;
 6            STRPAD H5T_STR_NULLTERM;
 7            CSET H5T_CSET_ASCII;
 8            CTYPE H5T_C_S1;
 9         }
10      DATASPACE  SCALAR
11      DATA {
12      (0): "4.1.0"
13      }
14   }
15   ATTRIBUTE "file_name" {
16      DATATYPE  H5T_STRING {
17            STRSIZE 11;
18            STRPAD H5T_STR_NULLTERM;
19            CSET H5T_CSET_ASCII;
20            CTYPE H5T_C_S1;
21         }
22      DATASPACE  SCALAR
23      DATA {
24      (0): "simple3D.h5"
25      }
26   }
27   ATTRIBUTE "HDF5_Version" {
28      DATATYPE  H5T_STRING {
29            STRSIZE 5;
30            STRPAD H5T_STR_NULLTERM;
31            CSET H5T_CSET_ASCII;
32            CTYPE H5T_C_S1;
33         }
34      DATASPACE  SCALAR
35      DATA {
36      (0): "1.6.6"
37      }
38   }
39   ATTRIBUTE "file_time" {
40      DATATYPE  H5T_STRING {
41            STRSIZE 24;
42            STRPAD H5T_STR_NULLTERM;
43            CSET H5T_CSET_ASCII;
44            CTYPE H5T_C_S1;
45         }
46      DATASPACE  SCALAR
47      DATA {
48      (0): "2011-11-18 17:26:27+0100"
49      }
50   }
51   GROUP "entry" {
52      ATTRIBUTE "NX_class" {
53         DATATYPE  H5T_STRING {
54               STRSIZE 7;
55               STRPAD H5T_STR_NULLTERM;
56               CSET H5T_CSET_ASCII;
57               CTYPE H5T_C_S1;
58            }
59         DATASPACE  SCALAR
60         DATA {
61         (0): "NXentry"
62         }
63      }
64      GROUP "data" {
65         ATTRIBUTE "NX_class" {
66            DATATYPE  H5T_STRING {
67                  STRSIZE 6;
68                  STRPAD H5T_STR_NULLTERM;
69                  CSET H5T_CSET_ASCII;
70                  CTYPE H5T_C_S1;
71               }
72            DATASPACE  SCALAR
73            DATA {
74            (0): "NXdata"
75            }
76         }
77         DATASET "test" {
78            DATATYPE  H5T_STD_I32LE
79            DATASPACE  SIMPLE { ( 2, 3, 4 ) / ( 2, 3, 4 ) }
80            DATA {
81            (0,0,0): 0, 1, 2, 3,
82            (0,1,0): 4, 5, 6, 7,
83            (0,2,0): 8, 9, 10, 11,
84            (1,0,0): 12, 13, 14, 15,
85            (1,1,0): 16, 17, 18, 19,
86            (1,2,0): 20, 21, 22, 23
87            }
88            ATTRIBUTE "signal" {
89               DATATYPE  H5T_STD_I32LE
90               DATASPACE  SCALAR
91               DATA {
92               (0): 1
93               }
94            }
95         }
96      }
97   }
98}
99}

View a NeXus HDF5 file using punx tree

The output of h5dump contains a lot of structural information about the HDF5 file that can distract us from the actual content we added to the file. Next, we show the output from a custom Python tool (punx tree) built for NeXus data file validation and view. 1 The tree option of this tool 2 was developed to show the actual data content of an HDF5 file that we create.

1

punx : https://punx.readthedocs.io/

2

punx tree : https://punx.readthedocs.io/en/latest/source_code/h5tree.html#how-to-use-h5tree

NAPI Python Example: punx tree simple3D.h5 output of NeXus HDF5 file

 1simple3D.h5:NeXus data file
 2  @NeXus_version = 4.1.0
 3  @file_name = simple3D.h5
 4  @HDF5_Version = 1.6.6
 5  @file_time = 2011-11-18 17:26:27+0100
 6  entry:NXentry
 7    @NX_class = NXentry
 8    data:NXdata
 9      @NX_class = NXdata
10      test:NX_INT32[2,3,4] = __array
11        @signal = 1
12        __array = [
13            [
14              [0, 1, 2, 3]
15              [4, 5, 6, 7]
16              [8, 9, 10, 11]
17            ]
18            [
19              [12, 13, 14, 15]
20              [16, 17, 18, 19]
21              [20, 21, 22, 23]
22            ]
23          ]