Changeset 996
- Timestamp:
- 02/11/11 20:33:45 (7 months ago)
- Location:
- trunk
- Files:
-
- 5 added
- 17 edited
-
manual/NAPI.xml (modified) (1 diff)
-
manual/applying-nexus.xml (modified) (1 diff)
-
manual/design.xml (modified) (1 diff)
-
manual/ex_code_napi.xml (added)
-
manual/ex_code_native.xml (added)
-
manual/examples.xml (modified) (3 diffs)
-
manual/examples/h5py/BasicReader.py (modified) (1 diff)
-
manual/examples/h5py/BasicWriter.py (modified) (2 diffs)
-
manual/examples/h5py/my_lib.py (modified) (3 diffs)
-
manual/examples/h5py/prj_test.nexus.hdf5 (modified) (previous)
-
manual/examples/h5py/writer_1_3.hdf5 (modified) (previous)
-
manual/examples/h5py/writer_1_3.py (modified) (2 diffs)
-
manual/examples/h5py/writer_1_3_h5py.py (added)
-
manual/examples/h5py/writer_2_1.hdf5 (modified) (previous)
-
manual/h5py-example.xml (modified) (5 diffs)
-
manual/img/ex_writer_1_3.png (added)
-
manual/img/ex_writer_2_1.png (added)
-
manual/introduction.xml (modified) (1 diff)
-
manual/writer_1_3.xml (modified) (1 diff)
-
manual/writer_2_1.xml (modified) (1 diff)
-
xslt/nxdl_types2docbook.xsl (modified) (1 diff)
-
xslt/nxdl_units2docbook.xsl (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/manual/NAPI.xml
r974 r996 655 655 </para> 656 656 </section> 657 658 </section>659 660 <section xml:id="NAPI-Examples">661 <title>Example NeXus program using NAPI</title>662 <indexterm>663 <primary>NAPI</primary>664 <secondary>examples</secondary>665 </indexterm>666 <para>667 The following code reads a two-dimensional set <code>counts</code>668 with dimension scales of <code>t</code> and <code>phi</code> using669 local routines, and then writes a NeXus file containing a single670 <code>NXentry</code> group and a single <code>NXdata</code> group.671 This is the simplest data file that conforms to the NeXus standard.672 The same code is provided in C, F77, and F90 versions.673 </para>674 <example>675 <title>NAPI C Example: write simple NeXus file</title>676 <programlisting language="c" linenumbering="numbered"677 ><xi:include href="examples/napi-example.c" parse="text"678 /></programlisting>679 </example>680 <example>681 <title>NAPI F77 Example: write simple NeXus file</title>682 <programlisting linenumbering="numbered"683 ><xi:include href="examples/napi-example.f77" parse="text"684 /></programlisting>685 </example>686 <example>687 <title>NAPI F90 Example: write simple NeXus file</title>688 <programlisting linenumbering="numbered"689 ><xi:include href="examples/napi-example.f90" parse="text"690 /></programlisting>691 </example>692 </section>693 694 <section xml:id="native-HDF5-Examples">695 <title>Example NeXus programs using native HDF5 commands</title>696 <indexterm>697 <primary>HDF5</primary>698 <secondary>examples</secondary>699 </indexterm>700 <para>701 C-language code examples are provided for702 writing and reading NeXus-compliant files703 using the native HDF5 interfaces. These examples are derived from the simple704 NAPI examples for705 <link xlink:href="#ex.simple.write"><code>writing</code></link>706 and707 <link xlink:href="#ex.simple.read"><code>reading</code></link>708 given in the709 <link xlink:href="#Introduction"><code>Introduction</code></link> chapter.710 </para>711 712 <example xml:id="native.hdf5.simple.write" xreflabel="Writing a simple NeXus file using native HDF5 commands">713 <title>Writing a simple NeXus file using native HDF5 commands</title>714 <programlisting linenumbering="numbered" language="c"715 ><xi:include href="examples/nxh5write.c" parse="text"716 /></programlisting>717 </example>718 719 <example xml:id="native.hdf5.simple.read" xreflabel="Reading a simple NeXus file using native HDF5 commands">720 <title>Reading a simple NeXus file using native HDF5 commands</title>721 <programlisting linenumbering="numbered" language="c"722 ><xi:include href="examples/nxh5read.c" parse="text"723 /></programlisting>724 </example>725 657 </section> 726 658 -
trunk/manual/applying-nexus.xml
r971 r996 19 19 20 20 <note><para> 21 If you are looking for a tutorial on reading or writing NeXus data files22 using the NeXus API, consult the23 < link xlink:href="#NAPI">NAPI chapter of Volume II</link>.24 Alternatively, there25 are examples of writing and reading NeXus data files using the26 <link xlink:href="#native-HDF5-Examples">native HDF5 commands in C</link>27 and also using .28 <link xlink:href="#Example-H5py">the <code>h5py</code> package in Python</link>.29 </para></note> 21 If you are looking for a tutorial on reading or writing NeXus data files 22 using the NeXus API, consult the 23 <xref linkend="NAPI"/> chapter of Volume II. 24 For code examples, refer to <xref linkend="Examples.NAPI"/> chapter of Volume II. 25 Alternatively, there are examples in the <xref linkend="native-HDF5-Examples"/> 26 chapter of writing and reading NeXus data files using the native HDF5 interfaces in C. 27 Further, there are also some Python examples using the <code>h5py</code> package 28 in the <xref linkend="#Example-H5py"/> section.</para></note> 29 30 30 <!-- 31 31 ====================================================== -
trunk/manual/design.xml
r973 r996 406 406 a more descriptive representation of the concept of linking. 407 407 </para> 408 <figure xml:id="fig.data-linking" >408 <figure xml:id="fig.data-linking" xreflabel="simple example showing data linking"> 409 409 <title>Linking in a NeXus file</title> 410 410 <mediaobject> -
trunk/manual/examples.xml
r977 r996 3 3 <!-- # $Id$ --> 4 4 <chapter xml:id="Examples" 5 xreflabel="Examples of reading or writing NeXus data files" 5 6 xmlns="http://docbook.org/ns/docbook" 6 7 version="5.0" … … 13 14 </imageobject> 14 15 </mediaobject> 15 16 <!-- TODO: build example from LRMECS data.17 Obtained lrcs3701.nxs from http://trac.mcs.anl.gov/projects/nexpy/browser/data/18 and intend to use it to build a good example.19 -->20 <!-- TODO needs examples on using the NAPI -->21 16 22 17 <para> … … 26 21 showing how to write a NeXus data file without using the NAPI. 27 22 </para> 28 <xi:include href="h5py-example.xml"/> 29 <xi:include href="writer_1_3.xml"/> 30 <xi:include href="writer_2_1.xml"/> 23 24 <section xml:id="Examples.NAPI" xreflabel="Code Examples that use the NAPI"> 25 <title>Code Examples that use the NAPI</title> 26 <para> 27 Various examples are given that show how to read and write NeXus data files using the 28 <xref linkend="NAPI"/>. 29 </para> 30 <!-- TODO needs examples using the NAPI --> 31 32 <!-- TODO: build example from LRMECS data. 33 Obtained lrcs3701.nxs from http://trac.mcs.anl.gov/projects/nexpy/browser/data/ 34 and intend to use it to build a good example. 35 --> 36 </section> 37 38 <section xml:id="Examples.nonNAPI" xreflabel="Code Examples that do not use the NAPI"> 39 <title>Code Examples that do not use the NAPI</title> 40 <para> 41 Sometimes, for whatever reason, it is necessary to write or read 42 NeXus files without using the routines provided by the <xref linkend="NAPI"/>. 43 Each example is written to support just one of the low-level file formats 44 supported by NeXus (HDF4, HDF5, or XML). 45 </para> 46 47 <xi:include href="h5py-example.xml"/> 48 </section> 31 49 32 50 </chapter> -
trunk/manual/examples/h5py/BasicReader.py
r667 r996 1 1 #!/usr/bin/env python 2 2 '''Reads NeXus HDF5 files using h5py and prints the contents''' 3 3 -
trunk/manual/examples/h5py/BasicWriter.py
r993 r996 1 2 '''Writes a NeXus HDF5 file using h5py '''1 #!/usr/bin/env python 2 '''Writes a NeXus HDF5 file using h5py and numpy''' 3 3 4 4 import h5py # HDF5 support 5 5 import numpy 6 import my_lib # uses h5py 6 7 7 8 print "Write a NeXus HDF5 file" … … 11 12 # load data from two column format 12 13 data = numpy.loadtxt('input.dat').T 14 mr_arr = data[0] 15 i00_arr = numpy.asarray(data[1],'int32') 13 16 14 17 # create the HDF5 NeXus file 15 f = h5py.File(fileName, "w") 16 f.attrs['file_name'] = fileName 17 f.attrs['file_time'] = timestamp 18 f.attrs['instrument'] = "APS USAXS at 32ID-B" 19 f.attrs['creator'] = "$Id$" 20 f.attrs['NeXus_version'] = "4.3.0" 21 f.attrs['HDF5_Version'] = h5py.version.hdf5_version 22 f.attrs['h5py_version'] = h5py.version.version 18 f = my_lib.makeFile(fileName, { 19 'file_name': fileName, 20 'file_time': timestamp, 21 'instrument': "APS USAXS at 32ID-B", 22 'creator': "$Id$", 23 'NeXus_version': "4.3.0", 24 'HDF5_Version': h5py.version.hdf5_version, 25 'h5py_version': h5py.version.version, 26 }) 23 27 24 nxentry = f.create_group("entry")25 nxentry.attrs["NX_class"] = "NXentry" # identify NeXus base class 28 nxentry = my_lib.makeGroup(f, "entry", "NXentry") 29 my_lib.makeDataset(nxentry, 'title', data='1-D scan of I00 v. mr') 26 30 27 nxdata = nxentry.create_group("mr_scan") 28 nxdata.attrs["NX_class"] = "NXdata" # identify NeXus base class 31 nxdata = my_lib.makeGroup(nxentry, "mr_scan", "NXdata") 29 32 30 mr = nxdata.create_dataset("mr", data=data[0]) 31 mr.attrs['units'] = "degrees" 33 my_lib.makeDataset(nxdata, "mr", mr_arr, 34 { 35 'units': 'degrees', 36 'long_name': 'USAXS mr (degrees)',} 37 ) 32 38 33 i00 = nxdata.create_dataset("I00", data=numpy.asarray(data[1],'int32')) 34 i00.attrs['units'] = "counts" 35 36 # NeXus wants to provide a default plot 37 # this is the preferred method to describe the axes 38 i00.attrs['signal'] = "1" # indicates the Y axis 39 i00.attrs['axes'] = "mr" # name "mr" as X axis 40 mr.attrs['long_name'] = "USAXS mr (degrees)" 41 i00.attrs['long_name'] = "USAXS I00 (counts)" 39 my_lib.makeDataset(nxdata, "I00", i00_arr, 40 { 41 'units': 'counts', 42 'signal': '1', # Y axis of default plot 43 'axes': 'mr', # name "mr" as X axis 44 'long_name': 'USAXS I00 (counts)',} 45 ) 42 46 43 47 f.close() # be CERTAIN to close the file 48 44 49 print "wrote file:", fileName -
trunk/manual/examples/h5py/my_lib.py
r977 r996 5 5 6 6 import h5py # HDF5 support 7 import numpy # in this case, provides data structures 7 8 8 def makeFile(filename): 9 # TODO: refactor attr dictionaries into keyword arguments 10 11 def makeFile(filename, attr = None): 9 12 """ 10 13 create and open an empty NeXus HDF5 file using h5py 11 14 12 15 :param str filename: valid file name 16 :param dict attr: optional dictionary of attributes 13 17 :return: h5py file object 14 18 """ 15 return h5py.File(filename, "w") 19 f = h5py.File(filename, "w") 20 add_attributes(f, attr) 21 return f 16 22 17 23 def makeGroup(parent, name, nxclass): … … 35 41 :param str name: valid NeXus dataset name 36 42 :param obj data: the data to be saved 37 :param dict attr: dictionary of attributes43 :param dict attr: optional dictionary of attributes 38 44 ''' 39 45 if data == None: 40 46 obj = parent.create_dataset(name) 41 elif type(data) == type("a string"):42 # pad strings with an extra space43 obj = parent.create_dataset(name, data=[data + " "])44 47 else: 45 48 obj = parent.create_dataset(name, data=data) 46 if attr: 47 if type(attr) == type({}): 48 # attr is a dictionary of attributes 49 for k, v in attr.items(): 50 obj.attrs[k] = v 49 add_attributes(obj, attr) 51 50 return obj 52 51 … … 60 59 """ 61 60 if not 'target' in sourceObject.attrs: 62 # NeXus -style link identifies full sourceObject HDF5 path63 sourceObject.attrs["target"] = s tr(sourceObject.name) # no unicode61 # NeXus link, NOT an HDF5 link! 62 sourceObject.attrs["target"] = sourceObject.name 64 63 parent._id.link(sourceObject.name, targetName, h5py.h5g.LINK_HARD) 65 64 65 def add_attributes(parent, attr): 66 """ 67 add attributes to an h5py data item 68 69 :param obj parent: h5py parent object 70 :param dict attr: dictionary of attributes 71 """ 72 if attr and type(attr) == type({}): 73 # attr is a dictionary of attributes 74 for k, v in attr.items(): 75 parent.attrs[k] = v 66 76 67 77 def get_2column_data(fileName): 68 '''read two-column data from a file''' 69 f = open(fileName, 'r') 70 TWO_COLUMNS = f.read() 71 f.close() 72 73 xArr = [] 74 yArr = [] 75 buffer = TWO_COLUMNS.strip().split("\n") 76 for row in buffer: 77 (x, y) = row.split() 78 xArr.append(float(x)) 79 yArr.append(int(y)) 78 '''read two-column data from a file, first column is float, second column is integer''' 79 buffer = numpy.loadtxt(fileName).T 80 xArr = buffer[0] 81 yArr = numpy.asarray(buffer[1],'int32') 80 82 return xArr, yArr -
trunk/manual/examples/h5py/writer_1_3.py
r977 r996 1 1 #!/usr/bin/env python 2 2 ''' 3 Writes the simplest NeXus HDF5 file using h5py 3 Writes the simplest NeXus HDF5 file using 4 a simple helper library with h5py and numpy calls 4 5 according to the example from Figure 1.3 5 6 in the Introduction chapter … … 15 16 tthData, countsData = my_lib.get_2column_data(INPUT_FILE) 16 17 17 f = my_lib.makeFile(HDF5_FILE) # create the HDF5 NeXus file 18 f = my_lib.makeFile(HDF5_FILE) 19 # since this is a simple example, no attributes are used at this point 18 20 19 21 nxentry = my_lib.makeGroup(f, 'Scan', 'NXentry') 20 22 nxdata = my_lib.makeGroup(nxentry, 'data', 'NXdata') 21 23 22 # call h5py library routine directly rather than our my_lib support 23 tth = nxdata.create_dataset("two_theta", data=tthData) 24 tth.attrs['units'] = "degrees" 25 26 counts = nxdata.create_dataset("counts", data=countsData) 27 counts.attrs['units'] = "counts" 28 counts.attrs['signal'] = "1" 29 counts.attrs['axes'] = "two_theta" 24 my_lib.makeDataset(nxdata, "two_theta", tthData, {'units': 'degrees'}) 25 my_lib.makeDataset(nxdata, "counts", countsData, 26 { 27 'units': 'counts', 28 'signal': '1', 29 'axes': 'two_theta', 30 }) 30 31 31 32 f.close() # be CERTAIN to close the file -
trunk/manual/h5py-example.xml
r977 r996 8 8 xmlns:xlink="http://www.w3.org/1999/xlink" 9 9 xmlns:xi="http://www.w3.org/2001/XInclude"> 10 <title>A complete example of writing and reading a NeXus data file using <code>h5py</code></title> 11 12 <para> One way to gain a quick familiarity with NeXus is to start working with some data. In this 13 example, we have a simple two-column set of data, collected as part of a series of alignment 14 scans for the APS USAXS instrument. We will show how to write this data using the Python 15 language and the <code>h5py</code> package<footnote> 10 <title>Python Examples using <code>h5py</code></title> 11 12 <para>One way to gain a quick familiarity with NeXus is to start working with some data. For at least the 13 first few examples in this section, we have a simple two-column set of 1-D data, collected as part of a 14 series of alignment scans by the APS USAXS instrument during the time it was stationed at 15 beam line 32ID. We will show how to write this 16 data using the Python language and the <code>h5py</code> package<footnote> 16 17 <para><link xlink:href="http://code.google.com/p/h5py" 17 18 ><code>http://code.google.com/p/h5py</code></link></para> … … 23 24 <para><link xlink:href="http://certif.com/spec.html" 24 25 ><code>http://certif.com/spec.html</code></link></para> 25 </footnote> data file and read as a text block from a file by the Python source code. </para> 26 </footnote> data file and read as a text block from a file by the Python source code. 27 Our examples will start with the simplest case and add only mild complexity with each new case 28 since these examples are meant for those who are unfamiliar with NeXus.</para> 26 29 27 30 <para>The data shown in <xref linkend="Example-H5py-Data"/> will be written to the NeXus HDF5 file 28 using the only two required NeXus objects <code>NXentry</code> and <code>NXdata</code>. The 31 using the only two required NeXus objects <code>NXentry</code> and <code>NXdata</code> in the first example 32 and then minor variations on this structure in the next two examples. The 29 33 data model is identical to the one in the <link xlink:href="#fig.simple-example">Introduction to 30 34 Volume I</link>) except that the names will be different, as shown below: … … 44 48 <entry> 45 49 <programlisting linenumbering="numbered" 46 ><xi:include href="examples/h5py/data-model.txt" parse="text"47 /></programlisting>50 ><xi:include href="examples/h5py/data-model.txt" parse="text" 51 /></programlisting> 48 52 </entry> 49 53 <entry> … … 60 64 </para> 61 65 62 <figure xml:id="Example-H5py-Plot" >66 <figure xml:id="Example-H5py-Plot" xreflabel="standard plot of our mr_scan data"> 63 67 <title>plot of our <emphasis>mr_scan</emphasis></title> 64 68 <mediaobject> … … 71 75 <title>two-column data for our <emphasis>mr_scan</emphasis></title> 72 76 <programlisting linenumbering="numbered" 73 ><xi:include href="examples/h5py/input.dat" parse="text"74 /></programlisting>77 ><xi:include href="examples/h5py/input.dat" parse="text" 78 /></programlisting> 75 79 </example> 76 80 77 <section xml:id="Example-H5py-Writing"> 78 <title>Writing the HDF5 file</title> 79 <para> In the main code section of <link xlink:href="#Example-H5py-BasicWriter" 80 ><code>BasicWriter.py</code></link>, a current time stamp is written in the format of 81 <emphasis>ISO 8601</emphasis>. Then the data (<code>mr</code> is similar to "two_theta" and 82 <code>I00</code> is similar to "counts") is collated into Python lists. Note that we convert 83 string representations of the data to <code>float()</code> and <code>int()</code> since the 84 <code>h5py</code> package will automatically handle all the data type instructions. </para> 85 <para> Next, the data is read from the file. The code assumes two points per line, separated by 86 <emphasis>white space</emphasis>. </para> 87 <para> The new HDF5 file is opened (and created if not already existing) for writing with the 88 command <code>f = h5py.File(fileName, "w")</code>. The common NeXus attributes are set next. 89 Then, with calls to <code>create_dataset()</code>, <code>h5py</code> creates the 90 <code>NXentry</code> and <code>NXdata</code> groups. Since we are not using the NAPI, our 91 code must create and set the <code>NX_class</code> attribute on each group. <note> 92 <para> We want to create the desired structure of 93 <code>/entry:NXentry/mr_scan:NXdata/</code>. First we call <code>nxentry = 94 f.create_group("entry")</code> to create the <code>NXentry</code> group called 95 <code>entry</code> at the root level. Then, we call <code>nxdata = 96 nxentry.create_group("mr_scan")</code> to create the <code>NXentry</code> group called 97 <code>entry</code> as a child of the <code>NXentry</code> group. </para> 81 <xi:include href="writer_1_3.xml"/> 82 <xi:include href="writer_2_1.xml"/> 83 84 <section xml:id="Example-H5py-complete" xreflabel="Complete h5py Example"> 85 <title>A complete example of writing and reading a NeXus data file using <code>h5py</code></title> 86 87 <section xml:id="Example-H5py-Writing"> 88 <title>Writing the HDF5 file</title> 89 <para>In the main code section of <link xlink:href="#Example-H5py-BasicWriter" 90 ><code>BasicWriter.py</code></link>, a current time stamp 91 is written in the format of <emphasis>ISO 8601</emphasis>. 92 For simplicity of this code example, we use a text string for the time, rather than 93 computing it directly from Python support library calls. It is easier this way to 94 see the exact type of string formatting for the time. When using the Python 95 <code>datatime</code> package, one way to write the time stamp is: 96 <programlisting language="python" linenumbering="numbered" 97 >timestamp = "T".join( str( datetime.datetime.now() ).split() )</programlisting> 98 </para> 99 <para>The data (<code>mr</code> is similar to "two_theta" and 100 <code>I00</code> is similar to "counts") is collated into two Python lists. We use our <code>my_lib</code> 101 support to read the file and parse the two-column format. </para> 102 <para>The new HDF5 file is opened (and created if not already existing) for writing, 103 setting common NeXus attributes in the same command from our support library. 104 Proper HDF5+NeXus groups are created for <code>/entry:NXentry/mr_scan:NXdata</code>. 105 Since we are not using the NAPI, our 106 support library must create and set the <code>NX_class</code> attribute on each group. <note> 107 <para> We want to create the desired structure of 108 <code>/entry:NXentry/mr_scan:NXdata/</code>. First, our support library calls <code>nxentry = 109 f.create_group("entry")</code> to create the <code>NXentry</code> group called 110 <code>entry</code> at the root level. Then, it calls <code>nxdata = 111 nxentry.create_group("mr_scan")</code> to create the <code>NXentry</code> group called 112 <code>entry</code> as a child of the <code>NXentry</code> group. </para> 113 </note> 114 </para> 115 <para>Next, we create a dataset called <code>title</code> to hold a title string that can 116 appear on the default plot.</para> 117 <para>Next, we create datasets for <code>mr</code> and <code>I00</code> using our support library. 118 The data type of each, as represented in <code>numpy</code>, will be recognized by 119 <code>h5py</code> and automatically converted to the proper HDF5 type in the file. 120 A Python dictionary of attributes is given, specifying the engineering units and other 121 values needed by NeXus to provide a default plot of this data. By setting <code>signal="1"</code> 122 as an attribute on <code>I00</code>, NeXus recognizes <code>I00</code> as the default 123 <emphasis>y</emphasis> axis for the plot. The <code>axes="mr"</code> connects the dataset 124 to be used as the <emphasis>x</emphasis> axis.</para> 125 <para> Finally, we <emphasis>must</emphasis> remember to call <code>f.close()</code> or we might 126 corrupt the file when the program quits. </para> 127 128 <example xml:id="Example-H5py-BasicWriter" xreflabel="Write a NeXus HDF5 file using Python with h5py"> 129 <title><citetitle>BasicWriter.py</citetitle>: Write a NeXus HDF5 file using Python with h5py</title> 130 <programlisting language="python" linenumbering="numbered" 131 ><xi:include href="examples/h5py/BasicWriter.py" parse="text" 132 /></programlisting> 133 </example> 134 </section> 135 136 <section xml:id="Example-H5py-Reading"> 137 <title>Reading the HDF5 file</title> 138 139 <para> The file reader, <link xlink:href="#Example-H5py-Reader" 140 ><code>BasicReader.py</code></link>, 141 is very simple since the bulk of the work is done by <code>h5py</code>. 142 Our code opens the HDF5 we wrote above, 143 prints the HDF5 attributes from the file, 144 reads the two datasets, 145 and then prints them out as columns. 146 As simple as that. 147 Of course, real code might add some error-handling and 148 extracting other useful stuff from the file. 149 </para> 150 <note> 151 <para> See that we identified each of the two datasets using HDF5 absolute path references 152 (just using the group and dataset names). Also, while coding this example, we were reminded 153 that HDF5 is sensitive to upper or lowercase. That is, <code>I00</code> is not the same is 154 <code>i00</code>. </para> 98 155 </note> 99 </para> 100 <para> Next, we call <code>create_dataset()</code> method from <code>h5py</code> to create 101 containers for each of our columns of data. The HDF5 data type will be set by 102 <code>h5py</code>.We define the engineering units as a standard NeXus attribute. Since a 103 default plot of our data would be <code>I00</code> vs. <code>mr</code>, we add NeXus 104 attributes to indicate either <code>primary</code> or <code>signal</code>. We also add a 105 <code>NAPItype</code> attribute but this may not be necessary. (For datasets with string 106 values, we would use a different command to construct the <code>NAPItype</code> 107 attribute.)</para> 108 <para> Finally, we <emphasis>must</emphasis> remember to call <code>f.close()</code> or we might 109 corrupt the file when the program quits. </para> 110 111 <example xml:id="Example-H5py-BasicWriter" xreflabel="Write a NeXus HDF5 file using Python with h5py"> 112 <title><citetitle>BasicWriter.py</citetitle>: Write a NeXus HDF5 file using Python with h5py</title> 113 <programlisting language="python" linenumbering="numbered" 114 ><xi:include href="examples/h5py/BasicWriter.py" parse="text" 115 /></programlisting> 116 </example> 156 157 <example xml:id="Example-H5py-Reader" xreflabel="Read a NeXus HDF5 file using Python with h5py"> 158 <title><citetitle>BasicReader.py</citetitle>: Read a NeXus HDF5 file using Python with h5py</title> 159 <programlisting language="python" linenumbering="numbered" 160 ><xi:include href="examples/h5py/BasicReader.py" parse="text" 161 /></programlisting> 162 </example> 163 <para>Output from <code>BasicReader.py</code> is shown in <xref 164 linkend="Example-H5py-Output"/>. </para> 165 166 <example xml:id="Example-H5py-Output"> 167 <title>Output from <code>BasicReader.py</code></title> 168 <programlisting linenumbering="numbered" 169 ><xi:include href="examples/h5py/output.txt" parse="text" 170 /></programlisting> 171 </example> 172 </section> 173 174 <section xml:id="Example-H5py-Validation"> 175 <title>Validating the HDF5 file</title> 176 <para> 177 Now we have an HDF5 file that contains our data. What makes 178 this different from a NeXus data file? A NeXus file 179 has a specific arrangement of groups and datasets 180 in an HDF5 file. 181 </para> 182 <para> 183 To test that our HDF5 file conforms to the NeXus standard, 184 we use the <code>NXvalidate</code><footnote><para>Need a 185 link/URL to <code>NXvalidate</code> here.</para></footnote> 186 program. Referring to the next figure, 187 we compare our HDF5 file with the rules for 188 generic<footnote><para>generic NeXus data files: NeXus data 189 files for which no application-specific NXDL 190 applies</para></footnote> data files 191 (<code>all.nxdl.xml</code>). The only items that have 192 been flagged are the "non-standard field names" 193 <emphasis>mr</emphasis> and 194 <emphasis>I00</emphasis>. Neither of these two names is 195 specifically named in the NeXus NXDL definition for 196 the <code>NXdata</code> base class. As we'll see shortly, 197 this is not a problem. 198 </para> 199 <figure xml:id="fig-Example-H5py-Validation"> 200 <title>NeXus validation of our HDF5 file</title> 201 <mediaobject> 202 <imageobject> 203 <imagedata fileref="examples/h5py/nxvalidate.png" width="300pt" scalefit="1"/> 204 </imageobject> 205 </mediaobject> 206 </figure> 207 <note><para>Note that <code>NXvalidate</code> shows 208 only the first data field for <emphasis>mr</emphasis> and 209 <emphasis>I00</emphasis>.</para></note> 210 </section> 211 212 <section xml:id="Example-H5py-Plotting"> 213 <title>Plotting the HDF5 file</title> 214 <para> 215 Now that we are certain our file conforms to the NeXus 216 standard, let's plot it using the <code>NeXpy</code><footnote><para><link 217 xlink:href="http://trac.mcs.anl.gov/projects/nexpy"><code 218 >http://trac.mcs.anl.gov/projects/nexpy</code ></link></para></footnote> 219 client tool. To help label the plot, we added the 220 <code>long_name</code> attributes to each of our datasets. 221 We also added metadata to the root level of our HDF5 file 222 similar to that written by the NAPI. It seemed to be a useful addition. 223 Compare this with 224 <xref linkend="Example-H5py-Plot"/> 225 and note that the horizontal axis of this plot is mirrored from that above. 226 This is because the data is stored in the file in descending 227 <code>mr</code> order and <code>NeXpy</code> has plotted 228 it that way by default. 229 </para> 230 <figure xml:id="fig-Example-H5py-nexpy-plot"> 231 <title>plot of our <emphasis>mr_scan</emphasis> using NeXpy</title> 232 <mediaobject> 233 <imageobject> 234 <imagedata fileref="examples/h5py/nexpy.png" width="300pt" scalefit="1"/> 235 </imageobject> 236 </mediaobject> 237 </figure> 238 </section> 117 239 </section> 118 240 119 <section xml:id="Example-H5py-Reading"> 120 <title>Reading the HDF5 file</title> 121 122 <para> The file reader, <link xlink:href="#Example-H5py-Reader" 123 ><code>BasicReader.py</code></link>, 124 is very simple since the bulk of the work is done by <code>h5py</code>. 125 Our code opens the HDF5 we wrote above, 126 prints the HDF5 attributes from the file, 127 reads the two datasets, 128 and then prints them out as columns. 129 As simple as that. 130 Of course, real code might add some error-handling and 131 extracting other useful stuff from the file. 132 </para> 133 <note> 134 <para> See that we identified each of the two datasets using HDF5 absolute path references 135 (just using the group and dataset names). Also, while coding this example, we were reminded 136 that HDF5 is sensitive to upper or lowercase. That is, <code>I00</code> is not the same is 137 <code>i00</code>. </para> 138 </note> 139 140 <example xml:id="Example-H5py-Reader" xreflabel="Read a NeXus HDF5 file using Python with h5py"> 141 <title><citetitle>BasicReader.py</citetitle>: Read a NeXus HDF5 file using Python with h5py</title> 142 <programlisting language="python" linenumbering="numbered" 143 ><xi:include href="examples/h5py/BasicReader.py" parse="text" 144 /></programlisting> 145 </example> 146 <para>Output from <code>BasicReader.py</code> is shown in <xref 147 linkend="Example-H5py-Output"/>. </para> 148 149 <example xml:id="Example-H5py-Output"> 150 <title>Output from <code>BasicReader.py</code></title> 241 <section xml:id="h5py-example-helpers" xreflabel="Python Helper Modules for h5py Examples"> 242 <title>Python Helper Modules for h5py Examples</title> 243 <para>Two additional Python modules were used to describe these <code>h5py</code> examples. 244 The source code for each is given here. The first is a library we wrote that helps us 245 create standard NeXus components using <code>h5py</code>. The second is a tool that helps 246 us inspect the content and structure of HDF5 files.</para> 247 248 <section xml:id="h5py-example-my_lib" xreflabel="mylib support module"> 249 <title>mylib support module</title> 250 <para>The examples in this section make use of 251 a small helper library that calls <code>h5py</code> to create the 252 various NeXus data components of 253 <xref linkend="Design-Groups"/>, 254 <xref linkend="Design-Fields"/>, 255 <xref linkend="Design-Attributes"/>, and 256 <xref linkend="Design-Links"/>. 257 In a smaller sense, this subroutine library (<code>my_lib</code>) fills the role of the NAPI for writing 258 the data using h5py.</para> 151 259 <programlisting linenumbering="numbered" 152 ><xi:include href="examples/h5py/output.txt" parse="text" 153 /></programlisting> 154 </example> 260 ><xi:include href="examples/h5py/my_lib.py" parse="text" 261 /></programlisting> 262 </section> 263 <section xml:id="h5py-example-h5toText" xreflabel="h5toText support module"> 264 <title>h5toText support module</title> 265 <para>The module <code>h5toText</code> reads an HDF5 data file and prints out the 266 structure of the groups, datasets, attributes, and links in that file. 267 There is a command-line option to print out more or less of the data 268 in the dataset arrays.</para> 269 <programlisting linenumbering="numbered" 270 ><xi:include href="examples/h5py/h5toText.py" parse="text" 271 /></programlisting> 272 </section> 155 273 </section> 156 274 157 <section xml:id="Example-H5py-Validation">158 <title>Validating the HDF5 file</title>159 <para>160 Now we have an HDF5 file that contains our data. What makes161 this different from a NeXus data file? A NeXus file162 has a specific arrangement of groups and datasets163 in an HDF5 file.164 </para>165 <para>166 To test that our HDF5 file conforms to the NeXus standard,167 we use the <code>NXvalidate</code><footnote><para>Need a168 link/URL to <code>NXvalidate</code> here.</para></footnote>169 program. Referring to the next figure,170 we compare our HDF5 file with the rules for171 generic<footnote><para>generic NeXus data files: NeXus data172 files for which no application-specific NXDL173 applies</para></footnote> data files174 (<code>all.nxdl.xml</code>). The only items that have175 been flagged are the "non-standard field names"176 <emphasis>mr</emphasis> and177 <emphasis>I00</emphasis>. Neither of these two names is178 specifically named in the NeXus NXDL definition for179 the <code>NXdata</code> base class. As we'll see shortly,180 this is not a problem.181 </para>182 <figure xml:id="fig-Example-H5py-Validation">183 <title>NeXus validation of our HDF5 file</title>184 <mediaobject>185 <imageobject>186 <imagedata fileref="examples/h5py/nxvalidate.png" width="300pt" scalefit="1"/>187 </imageobject>188 </mediaobject>189 </figure>190 <note><para>Note that <code>NXvalidate</code> shows191 only the first data field for <emphasis>mr</emphasis> and192 <emphasis>I00</emphasis>.</para></note>193 </section>194 195 <section xml:id="Example-H5py-Plotting">196 <title>Plotting the HDF5 file</title>197 <para>198 Now that we are certain our file conforms to the NeXus199 standard, let's plot it using the <code>NeXpy</code>200 client tool. To help label the plot, we added the201 <code>long_name</code> attributes to each of our datasets.202 Compare this with203 <xref linkend="Example-H5py-Plot"/>204 and note that this plot is mirrored from that above.205 This is because the data is stored in the file in descending206 <code>mr</code> order and <code>NeXpy</code> plots207 it that way.208 </para>209 <figure xml:id="fig-Example-H5py-nexpy-plot">210 <title>plot of our <emphasis>mr_scan</emphasis> using NeXpy</title>211 <mediaobject>212 <imageobject>213 <imagedata fileref="examples/h5py/nexpy.png" width="300pt" scalefit="1"/>214 </imageobject>215 </mediaobject>216 </figure>217 </section>218 275 219 276 </section> -
trunk/manual/introduction.xml
r977 r996 431 431 /></programlisting> 432 432 </example> 433 <!-- 434 (See <emphasis><link xlink:href="#Impatient">A complete example of writing and 435 reading a NeXus data file</link></emphasis> for an example to write and read data 436 using the structure of <xref linkend="ex.verysimple.nxdl.xml"/>.) 437 --> 433 For complete examples of reading and writing NeXus data files, refer to 434 the <xref linkend="Examples"/> chapter in Volume II. 438 435 This chapter has several examples of writing and reading NeXus data files. 439 436 If you want to define the format of a particular type of NeXus file -
trunk/manual/writer_1_3.xml
r977 r996 9 9 xmlns:xi="http://www.w3.org/2001/XInclude"> 10 10 <title><code>h5py</code> example writing the simplest NeXus data file</title> 11 12 <para>In the <xref linkend="Introduction"/> chapter, the 13 <xref linkend="Simple example"/> figure shows the simplest 14 possible NeXus data file. This <code>h5py</code> code 15 example will show how to build an HDF5 data file with that structure. 16 The numerical data will be taken from the writer in the 17 previous example, <xref linkend="Example-H5py"/>. 18 The structure of the file is almost identical with that example. 19 The only real difference is that, here, the only information 20 written to the file is the absolute minimum information NeXus requires. 21 </para> 22 <para>The source code that generates the file is shown. 23 Next is shown the results of <code>h5dump</code> on the data file. 24 Last, the structure of the data file is shown, as generated by <code>h5toText.py</code>. 25 This is easier to read, in general, than the <code>h5dump</code> output. 26 </para> 27 28 <!-- TODO: finish writing this section --> 29 <note><para>The text for this example is under construction.</para></note> 30 31 32 <programlisting linenumbering="numbered" 11 12 <para>In this example, the 1-D scan data will be written into the simplest 13 possible NeXus HDF5 data file, containing only the required NeXus components. 14 NeXus requires at least one <xref linkend="NXentry"/> group at the root level of 15 an HDF5 file. The <code>NXentry</code> group "all the data and associated 16 information that comprise a single measurement." 17 NeXus also requires that each <code>NXentry</code> group must contain at least 18 one <xref linkend="NXdata"/> group. <code>NXdata</code> is used to describe the 19 plottable data in the <code>NXentry</code> group. The simplest place to store 20 data in a NeXus file is directly in the <code>NXdata</code> group, 21 as shown in the next figure.</para> 22 23 <figure xml:id="fig.simple-example-h5py" xreflabel="Simplest NeXus data file"> 24 <!-- TODO: make new graphic and sync the names with THIS example! --> 25 <title>Simple Example</title> 26 <mediaobject> 27 <imageobject> 28 <imagedata fileref="img/ex_writer_1_3.png" width="250pt" scalefit="1"/> 29 </imageobject> 30 </mediaobject> 31 </figure> 32 33 <para>In the above figure, the data file (<code>writer_1_3_h5py.hdf5</code>) contains 34 a hierarchy of items, starting with an <code>NXentry</code> named <code>entry</code>. 35 (The full HDF5 path reference, <code>/entry</code> in this case, is shown to the right of each 36 component in the data structure.) The next <code>h5py</code> code 37 example will show how to build an HDF5 data file with this structure. 38 Starting with the numerical data described above, 39 the only information 40 written to the file is the <emphasis>absolute</emphasis> minimum information NeXus requires. 41 In this example, you can see how the HDF5 file is created, how 42 <xref linkend="Design-Groups"/> and datasets (<xref linkend="Design-Fields"/>) 43 are created, and how <xref linkend="Design-Attributes"/> are assigned. 44 Note particularly the <code>NX_class</code> attribute on each HDF5 group that 45 describes which of the NeXus <xref linkend="ClassDefinitions-Base"/> is being used. 46 When the next Python program (<code>writer_1_3_h5py.py</code>) is run from the 47 command line (and there are no problems), the <code>writer_1_3_h5py.hdf5</code> 48 file is generated. 49 </para> 50 51 <programlisting linenumbering="numbered" 52 ><xi:include href="examples/h5py/writer_1_3_h5py.py" parse="text" 53 /></programlisting> 54 55 <para>We wish to make things a bit simpler for ourselves when creating the common 56 structures we use in our data files. To help, we gather together some of the 57 common concepts such as <emphasis>create a file</emphasis>, 58 <emphasis>create a NeXus group</emphasis>, 59 <emphasis>create a dataset</emphasis> and start to build a helper library. 60 (See <xref linkend="h5py-example-my_lib" /> for more details.) 61 Here, we call it <code>my_lib</code>. Applying it to the simple example above, our 62 code only becomes a couple lines shorter! (Let's hope the library starts to help in larger or 63 more complicated projects.) Here's the revision that replaces direct calls to <code>numpy</code> 64 and <code>h5py</code> with calls to our library. It generates the file 65 <code>writer_1_3.hdf5</code>.</para> 66 <programlisting linenumbering="numbered" 33 67 ><xi:include href="examples/h5py/writer_1_3.py" parse="text" 34 68 /></programlisting> 35 36 <programlisting linenumbering="numbered" 37 ><xi:include href="examples/h5py/writer_1_3_h5dump.txt" parse="text" 38 /></programlisting> 39 40 <programlisting linenumbering="numbered" 69 70 <para>One of the tools provided with the HDF5 support libraries is 71 the <code>h5dump</code> command, a command-line tool to print out the 72 contents of an HDF5 data file. With no better tool in place (the 73 output is verbose), this is a good tool to investigate what has been 74 written to the HDF5 file. View this output from the command line 75 using <code>h5dump writer_1_3.hdf5</code>. Compare the data contents with 76 the numbers shown above. Note that the various HDF5 data types have all been 77 decided by the <code>h5py</code> support package.</para> 78 <note><para>The only difference between this file and one written using the NAPI 79 is that the NAPI file will have some additional, optional attributes set at the root 80 level of the file that tells the original file name, time it was written, and some version information 81 about the software involved.</para></note> 82 <programlisting linenumbering="numbered" 83 ><xi:include href="examples/h5py/writer_1_3_h5dump.txt" parse="text" 84 /></programlisting> 85 86 <para>Since the output of <code>h5dump</code> is verbose, a tool 87 (see <xref linkend="h5py-example-h5toText" />) 88 was created to 89 print out the structure of HDF5 data files. This tool provides a simplified view 90 of the NeXus file. It is run with a command like this: 91 <code>python h5toText.py h5dump writer_1_3.hdf5</code>. Here is the output:</para> 92 93 <programlisting linenumbering="numbered" 41 94 ><xi:include href="examples/h5py/writer_1_3_structure.txt" parse="text" 42 95 /></programlisting> 43 44 <para> 45 Both this example and the next will make use of 46 a small subroutine library that calls <code>h5py</code> to create the 47 various NeXus data components of 48 <xref linkend="Design-Groups"/>, 49 <xref linkend="Design-Fields"/>, 50 <xref linkend="Design-Attributes"/>, and 51 <xref linkend="Design-Links"/>. 52 In a smaller sense, this subroutine library fills the role of the NAPI for writing 53 the data using h5py. 54 </para> 55 56 <programlisting linenumbering="numbered" 57 ><xi:include href="examples/h5py/my_lib.py" parse="text" 58 /></programlisting> 59 60 <programlisting linenumbering="numbered" 61 ><xi:include href="examples/h5py/h5toText.py" parse="text" 62 /></programlisting> 96 97 <para>As the data files in these examples become more complex, you will appreciate 98 the information density provided by the <code>h5toText.py</code> tool.</para> 63 99 64 100 </section> -
trunk/manual/writer_2_1.xml
r977 r996 9 9 xmlns:xi="http://www.w3.org/2001/XInclude"> 10 10 <title><code>h5py</code> example writing a simple NeXus data file with links</title> 11 12 <para>In the <xref linkend="Design"/> chapter, the 13 <xref linkend="Simple example"/> figure shows a variation on 14 the simplest 15 possible NeXus data file, placing the measured data 16 in the <code>/entry/instrument/detector</code> group. 17 Links are made from that data to the <code>/entry/data</code> group. 18 This <code>h5py</code> code 19 example will show how to build an HDF5 data file with that structure. 20 The numerical data will be taken from the previous example. 21 </para> 22 23 <!-- TODO: finish writing this section --> 24 <note><para>The text for this example is under construction.</para></note> 25 26 27 <programlisting linenumbering="numbered" 11 12 <para>Building on the previous example, we wish to identify our measured data with 13 the detector on the instrument where it was generated. 14 In this hypothetical case, since the detector was positioned at some 15 angle <emphasis>two_theta</emphasis>, we choose to store both datasets, 16 <code>two_theta</code> and <code>counts</code>, in a NeXus group. 17 One appropriate NeXus group is <xref linkend="NXdetector"/>. 18 This group is placed in a <xref linkend="NXinstrument"/> group 19 which is placed in a <xref linkend="NXentry"/> group. 20 Still, NeXus requires a <xref linkend="NXdata"/> group. 21 Rather than duplicate the same data already placed in the detector group, 22 we choose to link to those datasets from the <code>NXdata</code> group. 23 (Compare the next figure with <xref linkend="fig.data-linking"/> in the 24 <xref linkend="Design"/> chapter of the NeXus User Manual.) 25 The <xref linkend="Design"/> chapter provides a figure 26 (<xref linkend="fig.data-linking"/>) with a small variation from our 27 previous example, placing the measured data 28 within the <code>/entry/instrument/detector</code> group. 29 Links are made from that data to the <code>/entry/data</code> group.</para> 30 <figure xml:id="fig.writer_2_1" xreflabel="h5py example showing data linking"> 31 <title>h5py example showing linking in a NeXus file</title> 32 <mediaobject> 33 <imageobject> 34 <imagedata fileref="img/ex_writer_2_1.png" width="400pt" 35 scalefit="1"/> 36 </imageobject> 37 </mediaobject> 38 </figure> 39 <para>The Python code to build an HDF5 data file with that structure (using 40 numerical data from the previous example) is shown below.</para> 41 <programlisting linenumbering="numbered" 28 42 ><xi:include href="examples/h5py/writer_2_1.py" parse="text" 29 43 /></programlisting> 30 31 <programlisting linenumbering="numbered" 44 <para>It is interesting to compare the output of the <code>h5dump</code> 45 of the data file <code>writer_2_1.hdf5</code> with our Python instructions.</para> 46 47 <programlisting linenumbering="numbered" 32 48 ><xi:include href="examples/h5py/writer_2_1_h5dump.txt" parse="text" 33 49 /></programlisting> 34 35 <programlisting linenumbering="numbered" 50 <para>Look carefully! It <emphasis>appears</emphasis> from the output of 51 <code>h5dump</code> that the actual data for <code>two_theta</code> 52 and <code>counts</code> has <emphasis>moved</emphasis> into 53 the group at HDF5 path <code>/entry/code</code>! But we stored 54 that data in <code>/entry/instrument/detector</code>. 55 This is normal for <code>h5dump</code> output.</para> 56 <para>A bit of explanation is necessary at this point. 57 The data is not stored in either group directly. Instead, HDF5 58 creates a <code>DATA</code> storage element in the file and posts a reference 59 to that <code>DATA</code> storage element as needed. 60 An HDF5 <emphasis>hard link</emphasis> 61 requests another reference to that same <code>DATA</code> storage element. 62 The <code>h5dump</code> tool describes in full that <code>DATA</code> storage element 63 the first time (alphabetically) it is called. In our case, that is within the 64 <code>NXdata</code> group. The next time it is called, within the 65 <code>NXdetector</code> group, <code>h5dump</code> reports that a hard link 66 has been made and shows the HDF5 path to the description.</para> 67 <para>NeXus recognizes this behavior of the HDF5 library and adds an additional structure 68 when building hard links, the <code>target</code> attribute, 69 to preserve the original location of the data. Not that it actually matters. 70 The <code>h5toText.py</code> tool knows about the additional NeXus 71 <code>target</code> attribute and shows the data to appear in its original 72 location, in the <code>NXdetector</code> group.</para> 73 <programlisting linenumbering="numbered" 36 74 ><xi:include href="examples/h5py/writer_2_1_structure.txt" parse="text" 37 75 /></programlisting> -
trunk/xslt/nxdl_types2docbook.xsl
r952 r996 41 41 <xslt:attribute name="xmlns">http://docbook.org/ns/docbook</xslt:attribute> 42 42 <xslt:attribute name="xml:id">nxdl-types</xslt:attribute> 43 <xslt:attribute name="xreflabel">NXDL: categories of data types</xslt:attribute> 43 44 <xslt:comment> auto-generated by a script </xslt:comment> 44 45 <xslt:element name="table"> -
trunk/xslt/nxdl_units2docbook.xsl
r952 r996 41 41 <xslt:attribute name="xmlns">http://docbook.org/ns/docbook</xslt:attribute> 42 42 <xslt:attribute name="xml:id">nxdl-units</xslt:attribute> 43 <xslt:attribute name="xreflabel">NXDL: categories of unit types</xslt:attribute> 43 44 <xslt:element name="table"> 44 45 <xslt:comment> xmlns="http://docbook.org/ns/docbook" </xslt:comment>
Note: See TracChangeset
for help on using the changeset viewer.
