source: CMIP6dreqbuild/trunk/src/framework/titles.py @ 1305

Subversion URL: http://proj.badc.rl.ac.uk/svn/exarch/CMIP6dreqbuild/trunk/src/framework/titles.py
Revision 1305, 9.2 KB checked in by mjuckes, 12 months ago (diff)

misc ...

Line 
1
2import collections, autocorrect, shelve, xml
3from xml.dom import minidom
4import re
5from dreqPy import dreq
6
7re_nm = re.compile( '[0-9]+(nm|m|hPa)' )
8
9class BuildWl(object):
10  def __init__(self):
11    self.cc = collections.defaultdict( set )
12  def add(self,k,v):
13    self.cc[k].add(v)
14
15
16words = collections.defaultdict( set )
17wl = collections.defaultdict( set )
18def getstuff():
19  khyzz = collections.defaultdict( set )
20  for i in dq.coll['var'].items:
21    for w in i.title.split():
22      words[w].add( i.title )
23      wl[w.lower()].add( i.title )
24
25  bl = dict()
26  for x in range(1,8):
27    bl[x] = [w for w in words if len(w) == x]
28
29  khy = [k for k in words if k.find('-') != -1]
30  for k in khy:
31    this = k.replace('-',' ').lower()
32    for i in dq.coll['var'].items:
33      if i.title.lower().find( this ) != -1:
34        khyzz[k.lower()].add( i.title )
35  return words, wl, khy, khyzz, bl
36 
37
38special = dict()
39##Articles: a, an, the
40## Coordinating Conjunctions: and, but, or, for, nor, etc.
41## Prepositions (fewer than five letters): on, at, to, from, by, etc` ... per
42
43## that: possibly a conjunction, but not likely in this context
44
45lower = dict()
46
47lower[1] = ['a']
48lower[2] = ['as', 'at', 'by', 'in', 'nm', 'of', 'on', 'or', 'to']
49lower[3] = [ 'and', 'any', 'but', 'for',  'non', 'nor', 'not', 'out', 'per', 'the']
50lower[4] = ['into', 'onto', 'over', 'than', 'with', 'from']
51lower[5] = ['neither','either','degree']
52
53special[1] = ['X', 'Y', 'T', 'O', 'D']
54special[2] = ['10', '1H', '1m', '2H', '2m', '3D', '50', 'C3', 'C4', 'CO', 'H2', 'N2', 'NO', 'Ox', 'O2', 'O3', 'OD', 'OH', 'XY', 'pH']
55special[3] = ['100', '10m', '13C', '14C', '17O', '18O', '20C', '440', '443', '500', '550', '850', '865', '870', 'CH4', 'CO2', 'CWD', 'DMS', 'HCl', 'HO2', 'N2O', 'NH3', 'NH4', 'NHx', 'NO2', 'NO3', 'NOx', 'NOy', 'NPP', 'O1D',  'PAN', 'PBL', 'PO2', 'SF6', 'SO2', 'SO4', 'SWE', 'TEM', 'TOA', 'hPa']
56special[4] = ['1000', '100m', '300m', '700m', 'C2H2', 'C2H6', 'C3H6', 'C3H8', 'CFAD', 'HNO3', 'MISR', 'PCO2', 'PM10' ]
57special[5] = ['10hPa', '13CO2', '14CO2', '2000m', '4XCO2', '550nm', 'CFC11', 'CFC12', 'DI14C', 'ISCCP', 'MODIS', 'NMVOC', 'PM1.0', 'PM2.5', 'UGRID']
58special[6] = ['CFC113', 'HCFC22'] 
59special[7] = ['CALIPSO', 'PARASOL']
60special[8] = ['(=dp/dt)', '13Carbon', '14Carbon', 'CH3COCH3', 'CloudSat']
61
62people = set( ['Leovy', 'Hibler', 'Wesely', 'Eliassen', 'Vaisala', 'Redi', 'Boussinesq' ] )
63vocab = set( ['Dianeutral', 'Diazotrophs', 'Downwelling', 'Epineutral', 'Landuse', 'Longwave', 'Meltpond', 'Mesozooplankton', 'Methanogenesis', 'Methanotrophy', 'Microzooplankton', 'Needleleaf', 'Picophytoplankton', 'Streamfunction', 'Submesoscale', 'Thermosteric'] )
64
65class Specials(object):
66  def __init__(self):
67    self.ll = set()
68    self.uu = set()
69    for k,v in lower.items():
70      for x in v:
71         self.ll.add(x)
72
73    for k,v in special.items():
74      for x in v:
75         self.uu.add(x)
76
77    hyphen02 = set(['Run-off','Air-to-Sea','2D-Field','3D-Field'])
78    self.ehy = dict()
79    for k in hyphen02:
80      self.ehy[ k.lower() ] = k
81
82specials = Specials()
83
84re_x = re.compile( '([;:,\-\(\)"\'\_+*><=/.\[\]])' )
85re_n = re.compile( '[0-9]\.*[0-9]' )
86re_chem = re.compile( '^(((C|N|O|Br|F|Fe|H|Ca|Cl|Ch|S|Si)[0-9xy]{0,4}){1,6})$' )
87
88def cleantext(ss):
89  res = set( re_x.findall( ss ) )
90  for x in res:
91    ss = ss.replace( x, ' ' )
92  ss = ' '.join( [x.strip() for x in ss.split() ] )
93  return ss
94 
95
96def mycap(s):
97  if s in specials.ll:
98    return s.lower()
99  elif s in specials.uu:
100    return s
101  elif re_nm.match(s):
102    return s
103  else:
104    return s.capitalize()
105
106def getFrag(name):
107 """Returns a Frag class object, with name specified by argument."""
108 class Frag(object):
109  """Dynamically generated class object. On intiation, it represents a string object with added methods."""
110  words = collections.defaultdict( set )
111  wl = collections.defaultdict( set )
112  wl2 = BuildWl()
113  def __init__(self,s,ttl):
114    self.prf = ''
115    self.sfx = ''
116    if s[0] in ['(',',','.','"']:
117      self.prf = s[0]
118    if s[-1] in [')',',','.','"',';']:
119      self.sfx = s[-1]
120    self.word = s[len(self.prf):len(s)-len(self.sfx)]
121    self.words[self.word].add( ttl )
122    self.ttl = ttl
123 
124  def cap(self):
125    if self.word.find( '-' ) != -1:
126      if self.word.lower() in specials.ehy:
127        this = specials.ehy[self.word.lower()]
128      else:
129        this = '-'.join( [mycap(x) for x in self.word.split('-')] )
130    else:
131      this = mycap( self.word )
132     
133    if len(this) == 1:
134      print 'L1: ',self.word, this
135
136    self.wl[this].add( self.ttl )
137    self.wl2.add(this, self.ttl )
138    self.styled = this
139
140    return ''.join( [self.prf,this,self.sfx] )
141
142  def low(self):
143    self.wl[self.word.lower()].add( self.ttl )
144    self.wl2.add(self.word.lower(), self.ttl )
145    self.styled = self.word.lower()
146    return ''.join( [self.prf,self.word.lower(),self.sfx] )
147
148  def full(self,save=True):
149    if save:
150      self.wl[self.word].add( self.ttl )
151      self.wl2.add(self.word, self.ttl )
152      self.styled = self.word
153    return ''.join( [self.prf,self.word,self.sfx] )
154
155 Frag.__name__ = name
156 return Frag
157
158class TitleCase(object):
159  def __init__(self):
160    self.frag = getFrag( 'FragVar' )
161    self.fragd = getFrag( 'FragDesc' )
162    self.sh = shelve.open( 'inSh/titleCase' )
163    self.desc = set()
164    self.chem = set()
165    specials = set()
166    lowers = set()
167    for k in special:
168      for x in special[k]:
169        specials.add(x)
170    for k in lower:
171      for x in lower[k]:
172        lowers.add(x)
173
174    ee = dict()
175    for i in dq.coll['var'].items:
176      parts = [self.frag(x,i.title) for x in i.title.split() ]
177      for x in cleantext( i.description ).split():
178        if len( re_n.findall(x) ) == 0:
179          if re_chem.match(x) == None:
180            y = self.fragd(x,i.description)
181            y.low()
182            self.desc.add( y.word.lower() )
183          else:
184            self.chem.add( x )
185
186      pold = [x.full(save=False) for x in parts]
187      pnew = []
188      if parts[0].word in specials:
189        pnew.append( parts[0].full() )
190      else:
191        pnew.append( parts[0].cap() )
192
193      for p in parts[1:]:
194        if p.word in specials:
195          pnew.append( p.full() )
196        elif p.word.lower() in lowers:
197          pnew.append( p.low() )
198        else:
199          pnew.append( p.cap() )
200        if p.styled == 'ice':
201          print 'ICE:: ',parts
202        elif p.word.lower() == 'ice':
203          print 'ice: ',p.word,p.styled, parts
204
205      if pold != pnew:
206         ee[tuple(pnew)] = pold
207
208
209   
210    for l in sorted( ee.keys() ):
211         print '----------------'
212         old = ' '.join(ee[l])
213         print old
214         new = ' '.join(l)
215         print new
216         self.sh[old] = new
217
218    print 'NUMBER OF CHANGES: ', len(ee)
219
220  def list(self):
221    for k in sorted(special.keys()):
222      print k, ':: ',' '.join( sorted( special[k] ) )
223    for k in sorted(lower.keys()):
224      print k, ':: ',' '.join( sorted( lower[k] ) )
225     
226
227class MyChecker(object):
228  """Compare a set of words against a list of known words and generate an error report for unknown words.
229     Input:
230       tag: an string identifier copied into output records;
231       frag: a class object generated by getFrag. -- used to manage tokens generated by splitting title;
232  """
233  def __init__(self,tag,frag,full=True):
234    self.full = full
235    self.tag = tag
236    self.frag = frag
237    self.ns = self.nc = self.ne = 0
238    self.known = autocorrect.word.KNOWN_WORDS.union( [x.lower() for x in vocab] ).union( (x.lower() for x in people) )
239
240
241  def check(self,k,key=None):
242    if key == None:
243      key = k
244    if k in specials.uu:
245      self.ns += 1
246    elif k.lower() in self.known:
247      self.nc += 1
248    else:
249      if self.full:
250        print '%sUNKNOWN: ' % self.tag, k, self.frag.wl[key]
251      else:
252        print k
253        ##print '%sUNKNOWN: ' % self.tag, k, list( self.frag.wl[key] )[0][:80]
254      self.ne += 1
255
256
257class CFdesc(object):
258  def __init__(self):
259    self.fragd = getFrag( 'FragDesc' )
260    self.chem = set()
261    self.desc = set()
262    self.contentDoc = minidom.parse( 'ing02/inputs/cf-standard-name-table_v60.xml' )
263    vl = self.contentDoc.getElementsByTagName( 'description' )
264    for v in vl:
265      if v.firstChild != None:
266        this = v.firstChild.data
267        for x in cleantext( this ).split():
268          if len( re_n.findall(x) ) == 0:
269            if re_chem.match(x) == None:
270              y = self.fragd(x,this)
271              y.low()
272              self.desc.add( y.word.lower() )
273   
274
275def run():
276  tc = TitleCase()
277  tc.list()
278
279  myCheck = MyChecker('v::', tc.frag)
280
281  for k in sorted( tc.frag.wl.keys() ):
282    if k.find('-') != -1:
283      for x in k.split( '-'):
284        myCheck.check(x,key=k)
285    else:
286      myCheck.check(k)
287
288  myCheck = MyChecker( 'd::', tc.fragd, full=False)
289  for k in sorted( tc.fragd.wl.keys() ):
290    if k.find('-') != -1:
291      for x in k.split( '-'):
292        myCheck.check(x,key=k)
293    else:
294      myCheck.check(k)
295
296  print myCheck.ns, myCheck.nc, myCheck.ne
297  tc.sh.close()
298  return tc
299
300def run2():
301  cf = CFdesc()
302
303
304  myCheck = MyChecker( 'd::', cf.fragd, full=False)
305  for k in sorted( cf.fragd.wl.keys() ):
306    if k.find('-') != -1:
307      for x in k.split( '-'):
308        myCheck.check(x,key=k)
309    else:
310      myCheck.check(k)
311
312  print myCheck.ns, myCheck.nc, myCheck.ne
313  cf.sh.close()
314  return cf
315
316if __name__ == "__main__":
317  import sys
318  dq = dreq.loadDreq()
319  tc = run()
320  ##cf = run2()
321
Note: See TracBrowser for help on using the repository browser.