source: 1dwg/branches/v1.1/python/cansas1d_example.py @ 300

Last change on this file since 300 was 300, checked in by prjemian, 7 years ago

refs #23

  • Property svn:eol-style set to native
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision URL Header
File size: 5.9 KB
Line 
1#!/usr/bin/env python
2'''
3Example use of Gnosis_utils to read both cansas1d:1.1
4and cansas1d/1.0 files
5
6This demonstrates full access to the contents of
7the XML file using a single line to open the file::
8
9    sasxml = readCanSasFile(xmlFile)
10
11.. note:: Since :meth:`readCanSasFile` raises exceptions
12   if the namespace or version does not match, it is best
13   to wrap this call in ``try ... except``` block,
14   as shown in :meth:`demo`.
15
16'''
17
18
19########### SVN repository information ###################
20# $Date$
21# $Author$
22# $Revision$
23# $URL$
24# $Id$
25########### SVN repository information ###################
26
27
28import os
29import sys
30import gnosis.xml.objectify     # easy_install -U gnosis
31
32
33    # support reading v1.0 and v1.1 data files
34    # v1.1 schema is backwards compatible, mostly
35CANSAS_NAMESPACES = {
36    '1.0': 'cansas1d/1.0',
37    '1.1': 'urn:cansas1d:1.1',
38}
39
40
41def readCanSasFile(xmlFile):
42    '''
43    open a canSAS XML data file as a gnosis file object
44   
45    usage::
46   
47        try:
48            sasxml = readCanSasFile(xmlFile)
49        except (Exception_canSAS_namespace, Exception_canSAS_version), answer:
50            print answer
51            return
52        print 'namespace:', sasxml.xmlns
53        print 'version:', sasxml.version
54        SASentry = sasxml.SASentry                  # just the first one
55        # ...
56   
57    '''
58    # read in the XML file
59    sasxml = gnosis.xml.objectify.XML_Objectify(xmlFile).make_instance()
60    # namespace check to accept file as canSAS XML
61    if sasxml.xmlns not in CANSAS_NAMESPACES.values():
62        msg = "Not a canSAS data file (namespace found: %s)" % sasxml.xmlns
63        raise Exception_canSAS_namespace, msg
64    if sasxml.version not in CANSAS_NAMESPACES.keys():
65        msg = "Not v1.1 file (found: %s)" % msg
66        raise Exception_canSAS_version, msg
67    return sasxml
68
69
70class Exception_canSAS_namespace(Exception):
71    '''canSAS XML file namespace'''
72    pass
73
74class Exception_canSAS_version(Exception):
75    '''version string of the canSAS standard'''
76    pass
77
78
79def indra_metadata(SASentry):
80    '''print metadata from APS/USAXS Indra package'''
81    if 'metadata' in SASentry.__dict__:
82        for metadata in SASentry.metadata:
83            '''loop through the USAXS metadata'''
84            print metadata.xmlns
85            for index in metadata.usaxs:
86                '''multiple invocations of the usaxs element'''
87                for item in dir(index):
88                    '''discover the element names'''
89                    if item[0] == '_':    # sift out data structure management terms
90                        continue
91                    if item in ('PCDATA', 'name', 'xmlns'):  # sift this out
92                        continue
93                    s = ''
94                    s += '('+index.xmlns+') '
95                    s += '('+index.name+') '
96                    s += item + ': '
97                    s += index.__dict__[item].PCDATA
98                    print s
99
100
101def print_SASdata(sd):
102    '''print the contents of the SASdata element'''
103    numPts = len(sd.Idata)
104    if 'name' in sd.__dict__:
105        print 'SASdata name:', sd.name
106    print '# points:', numPts
107    columns = [
108        ['Q ('+sd.Idata[0].Q.unit+')'],
109        ['I ('+sd.Idata[0].I.unit+')'],
110        ['Idev ('+sd.Idata[0].Idev.unit+')'],
111    ]
112    for Idata in sd.Idata:
113        values = (Idata.Q.PCDATA, Idata.I.PCDATA, Idata.Idev.PCDATA)
114        for item, value in enumerate(values):
115            columns[item].append(str(value))
116    print columnsToText(columns)
117
118
119def print_optional_item(title, parent, item):
120    ''' this item is optional and may not be present'''
121    if item in parent.__dict__:
122        #print item, item in parent.__dict__
123        obj = parent.__dict__[item]
124        s = title+':\t'
125        s += obj.PCDATA
126        if 'unit' in obj.__dict__:
127            s += ' (' + obj.unit + ')'
128        print s
129
130
131def columnsToText(columns):
132    '''
133    convert a list of column lists into rows of text
134   
135    column widths will be chosen from the maximum character width of each column
136   
137    :param [[str]] columns: list of column lists (all same length)
138    :returns str: text block, with line separators
139   
140    Example::
141   
142        >>> columns = [ ['1A', '2A'], ['1B is long', '2B'], ['1C', '2C'] ]
143        >>> print columnsToText( columns )
144        1A  1B is long  1C
145        2A  2B          2C
146   
147    '''
148    # get the largest width for each column
149    widths = [max(map(len, item)) for item in columns]
150    # left-align each column
151    sep = ' '*2
152    fmt = sep.join(['%%-%ds' % item for item in widths])
153    # rows = zip(*columns) : matrix transpose
154    result = [fmt % tuple(row) for row in zip(*columns)]
155    return '\n'.join(result)
156
157
158def demo(xmlFile):
159    print '#---------------------------------------------------'
160    print 'XML:', xmlFile
161    # read in the XML file
162    try:
163        sasxml = readCanSasFile(xmlFile)
164    except (Exception_canSAS_namespace, Exception_canSAS_version), answer:
165        print answer
166        return
167    print 'namespace:', sasxml.xmlns
168    print 'version:', sasxml.version
169    SASentry = sasxml.SASentry                  # just the first one
170    print 'title:', SASentry.Title.PCDATA
171    print 'run:', SASentry.Run.PCDATA
172    print_optional_item('instrument', SASentry.SASinstrument, 'name')
173    indra_metadata(SASentry)        # foreign XML elements from APS/USAXS
174    print_optional_item('sample ID', SASentry.SASsample, 'ID')
175    print_optional_item('sample thickness', SASentry.SASsample, 'thickness')
176    print_optional_item('sample transmission', SASentry.SASsample, 'transmission')
177    if 'position' in SASentry.SASsample.__dict__:
178        print_optional_item('sample X', SASentry.SASsample.position, 'x')
179        print_optional_item('sample Y', SASentry.SASsample.position, 'y')
180    print_SASdata(SASentry.SASdata)
181
182
183if __name__ == "__main__":
184    if len(sys.argv) == 2:
185        demo(sys.argv[1])
186    else:
187        demo(os.path.join('..', 'examples', 'bimodal-test1.xml'))
188        demo(os.path.join('..', 'examples', 's81-polyurea.xml'))
Note: See TracBrowser for help on using the repository browser.