source: tags/libIGCM_v3.0_beta1/libIGCM_post/xios_parser.py

Last change on this file was 1352, checked in by sdipsl, 8 years ago
  • clearer message
  • Property svn:executable set to *
  • Property svn:keywords set to Revision Date Author
File size: 8.8 KB
Line 
1#! /usr/bin/env python
2# coding: utf-8
3
4#**************************************************************
5# Author: Sebastien Denvil
6# Contact: Sebastien.Denvil__at__ipsl.jussieu.fr
7# $Revision::                                         $ Revision of last commit
8# $Author::                                           $ Author of last commit
9# $Date::                                             $ Date of last commit
10# IPSL (2006)
11#  This software is governed by the CeCILL licence see libIGCM/libIGCM_CeCILL.LIC
12#
13#**************************************************************
14
15import os, pwd, sys, traceback, argparse
16import xml.etree.ElementTree as ET
17#import readline, rlcompleter
18#readline.parse_and_bind("tab: complete")
19
20indent = 0
21currentDepth = 0
22ignoreElems = []
23fromField=[]
24fromFile=[]
25
26def dump(args):
27    """Dump XIOS xmls files."""
28    # Read and dump xios_def_xml
29    for inputFile in args.file:       
30        # Read the file_def_xml
31        print '\nReading %s \n|' % (inputFile)
32        try:
33            tree = ET.parse(inputFile)
34        except:
35            print "Parse error. Please fix so that it can be parsed."
36            traceback.print_exc(file=sys.stdout)
37            return
38        root=tree.getroot()
39        # Call the recursive print
40        printRecur(root)
41
42def tsquery(args):
43    """query timeseries related parameters from an XIOS xml file."""
44    if args.verbosity >= 1: print 'Reading timeseries_def_xml=',args.file[0]
45    try:
46        tree = ET.parse(args.file[0])
47    except:
48        print "Parse error. Please fix so that it can be parsed."
49        traceback.print_exc(file=sys.stdout)
50        return
51    root=tree.getroot()
52    if args.verbosity >= 3: print root.tag, root.attrib
53    findTimeSeries(root)
54       
55def printRecur(root):
56    """Recursively prints the tree."""
57    global indent
58    global currentDepth
59    if root.tag in ignoreElems:
60        return
61    print ' '*indent + '|--> %s: %s' % (root.tag, root.attrib)
62    currentDepth += 1
63    indent += 4
64    if currentDepth <= args.depth or args.depth == None:
65        for elem in list(root):
66            printRecur(elem)
67    currentDepth -= 1
68    indent -= 4
69
70def findTimeSeries(root):
71    """Recursively find and list field tag with "timeseries", "id", "output_freq" and enable=.TRUE. attribute."""
72    if root.tag == 'file' and root.attrib.get('timeseries'):
73        if root.attrib.get('enabled') == '.TRUE.':
74            print 'id=%s,output_freq=%s' % (root.attrib.get('id'), root.attrib.get('output_freq'))
75    else:
76        for elem in list(root):
77            findTimeSeries(elem)
78   
79def findField(root):
80    """Recursively find and list field tag with "id" or "field_ref" attribute."""
81    global fromField
82    global fromFile
83    if root.tag in ignoreElems:
84        return   
85    if root.tag == 'field' and root.attrib.get('id'):
86        fromField.append(root.attrib.get('id'))
87    elif root.tag == 'field' and root.attrib.get('field_ref'):
88        fromFile.append(root.attrib.get('field_ref'))
89    else:
90        for elem in list(root):
91            findField(elem)
92
93def findFieldToRemove(root, fieldToRemove):
94    """Recursively find tag having a field_ref in fieldToRemove."""
95    if args.verbosity >= 3 and root.tag == 'file' and root.attrib.get('id'):
96        print '\nFIELDS FROM FILE_DEF with id', root.attrib.get('id')
97    for field in root.findall('field'):
98        if args.verbosity >= 3: print 'field_ref=', field.attrib.get('field_ref')
99        if field.attrib.get('field_ref') in fieldToRemove:
100            if args.correction:
101                if args.verbosity >= 2: print 'removing ', field.attrib.get('field_ref')
102                root.remove(field)
103            else:
104                if args.verbosity >= 2: print 'To be removed ', field.attrib.get('field_ref')
105    for elem in list(root):
106        findFieldToRemove(elem, fieldToRemove)
107       
108def check(args):
109    global fromFile
110    exitCode=0
111    # Read the field_def_xml
112    if args.verbosity >= 1: print '\nReading field_def_xml=',args.field[0]
113    try:
114        tree = ET.parse(args.field[0])
115    except:
116        print 'Parse error with %s. Please fix so that it can be parsed.' % (args.field[0])
117        traceback.print_exc(file=sys.stdout)
118        return
119    root=tree.getroot()
120    if args.verbosity >= 3: print root.tag, root.attrib, '\n'
121    # Build a list of field.id from field_def
122    findField(root)
123
124    # Loop over file_def files
125    for inputFile in args.file:       
126        # Read the file_def_xml
127        if args.verbosity >= 1: print '\nReading file_def_xml=',inputFile
128        try:
129            tree = ET.parse(inputFile)
130        except:
131            print "Parse error. Please fix so that it can be parsed."
132            traceback.print_exc(file=sys.stdout)
133            return
134        root=tree.getroot()
135        fromFile=[]
136        if args.verbosity >= 3: print root.tag, root.attrib, '\n'
137
138        # Build a list of field_ref from file_def
139        findField(root)
140        #print '4. fromFile=', fromFile
141       
142        # Compare the two lists. fromField must be a superset of fromFile.
143        if set(fromField).issuperset(set(fromFile)):
144            if args.verbosity >= 1: print '\nALL GOOD with %s' % (inputFile)
145            if args.verbosity >= 3: print 'fromField=', fromField
146            if args.verbosity >= 3: print 'fromFile=', fromFile
147        else:
148            if args.verbosity >= 1: print '\nTROUBLE AHEAD with %s' % (inputFile)
149            if args.verbosity >= 3: print ', '.join(sorted(list(set(fromFile)-set(fromField))))
150            # Identify fields in fromFile but not in fromField
151            fieldToRemove=list(set(fromFile)-set(fromField))
152            if args.verbosity >= 3: print 'fieldToRemove=', fieldToRemove
153            #
154            # And now locate and remove them if the modify command has been called
155            findFieldToRemove(root, fieldToRemove)
156            # Final steps
157            if args.correction: tree.write('modified.'+inputFile)
158            if not len(fieldToRemove) == 0 and not args.correction:
159                exitCode=1
160    # The end
161    sys.exit(exitCode)
162
163def showtime(args):
164    """
165    prints table of formatted text format options
166    """
167    for style in xrange(6):
168        for fg in xrange(30,36):
169            s1 = ''
170            for bg in xrange(40,46):
171                format = ';'.join([str(style), str(fg), str(bg)])
172                s1 += '\x1b[%sm %s \x1b[0m' % (format, pwd.getpwuid(os.getuid())[4]+' is on fire')
173            print s1
174        print '\n'
175   
176if __name__ == '__main__':
177
178    try:
179        # Create the top-level parser
180        parser = argparse.ArgumentParser(description='XIOS2 xml files tooling and ironsmith')
181        subparsers = parser.add_subparsers(description='Dump, check or modify xios xml files')
182
183        # create the parser for the "dump" command
184        parser_dump = subparsers.add_parser('dump',help='Dump the xml content without all the xml\'s ironsmith')
185        parser_dump.add_argument('-d', '--depth', type=int, default=None, help='How deep do we go. Full tree by default')
186        parser_dump.add_argument('file', nargs='+', help='XIOS xml file(s) to dump')
187        parser_dump.set_defaults(func=dump)
188
189        # create the parser for the "tsquery" command
190        parser_check = subparsers.add_parser('tsquery', help='query timeseries related parameters from an xml file')
191        parser_check.add_argument('--file', nargs=1, required=True, help='XIOS xml timeseries_def type')
192        parser_check.set_defaults(func=tsquery)
193       
194        # create the parser for the "check" command
195        parser_check = subparsers.add_parser('check', help='Check consistency between field_def and file_def files')
196        parser_check.add_argument('--field', nargs=1, required=True, help='XIOS xml field_def type')
197        parser_check.add_argument('--file', nargs='+', required=True, help='XIOS xml file_def type')
198        parser_check.set_defaults(func=check, correction=False)
199       
200        # create the parser for the "modify" command
201        parser_check = subparsers.add_parser('modify', help='Will make sure field_def is a superset of file_def')
202        parser_check.add_argument('--field', nargs=1, required=True, help='XIOS xml field_def type')
203        parser_check.add_argument('--file', nargs='+', required=True, help='XIOS xml file_def type')
204        parser_check.set_defaults(func=check, correction=True)
205
206        # create the parser for the "modify" command
207        parser_check = subparsers.add_parser('showtime', help='Just want to make sure you feel good today')
208        parser_check.set_defaults(func=showtime)
209       
210        # Each possible option
211        parser.add_argument('-v', '--verbosity', action='count', default=0)
212
213        # Parse the args.
214        args = parser.parse_args()
215
216        # And call whatever function was selected
217        args.func(args)
218    except KeyboardInterrupt:
219        print "Shutdown requested...exiting"
220    except Exception:
221        traceback.print_exc(file=sys.stdout)
222    sys.exit(0)
Note: See TracBrowser for help on using the repository browser.