source: issm/trunk/src/m/consistency/checkfield.py@ 21341

Last change on this file since 21341 was 21341, checked in by Mathieu Morlighem, 8 years ago

merged trunk-jpl and trunk for revision 21337

File size: 7.5 KB
Line 
1import numpy as np
2import os
3from pairoptions import pairoptions
4import MatlabFuncs as m
5
6def checkfield(md,*args):
7 """
8 CHECKFIELD - check field consistency
9
10 Used to check model consistency.,
11 Requires:
12 'field' or 'fieldname' option. If 'fieldname' is provided, it will retrieve it from the model md. (md.(fieldname))
13 If 'field' is provided, it will assume the argument following 'field' is a numeric array.
14
15 Available options:
16 - NaN: 1 if check that there is no NaN
17 - size: [lines cols], NaN for non checked dimensions
18 - >: greater than provided value
19 - >=: greater or equal to provided value
20 - <: smallerthan provided value
21 - <=: smaller or equal to provided value
22 - < vec: smallerthan provided values on each vertex
23 - timeseries: 1 if check time series consistency (size and time)
24 - values: cell of strings or vector of acceptable values
25 - numel: list of acceptable number of elements
26 - cell: 1 if check that is cell
27 - empty: 1 if check that non empty
28 - message: overloaded error message
29
30 Usage:
31 md = checkfield(md,fieldname,options);
32 """
33
34 #get options
35 options=pairoptions(*args)
36
37 #get field from model
38 if options.exist('field'):
39 field=options.getfieldvalue('field')
40 fieldname=options.getfieldvalue('fieldname','no fieldname')
41 else:
42 fieldname=options.getfieldvalue('fieldname')
43 exec("field=md.{}".format(fieldname))
44
45 if isinstance(field,(bool,int,long,float)):
46 field=np.array([field])
47
48 #check empty
49 if options.exist('empty'):
50 if not field:
51 md = md.checkmessage(options.getfieldvalue('message',\
52 "field '%s' is empty" % fieldname))
53
54 #Check size
55 if options.exist('size'):
56 fieldsize=options.getfieldvalue('size')
57 if len(fieldsize) == 1:
58 if np.isnan(fieldsize[0]):
59 pass
60 elif np.ndim(field)==1:
61 if not np.size(field)==fieldsize[0]:
62 md = md.checkmessage(options.getfieldvalue('message',"field {} size should be {}".format(fieldname,fieldsize[0])))
63 else:
64 try:
65 exec("md.{}=field[:,0]".format(fieldname))
66 print('{} had a bad dimension, we fixed it but you should check it'.format(fieldname))
67 except IndexError:
68 md = md.checkmessage(options.getfieldvalue('message',"field {} should have {} dimension".format(fieldname,len(fieldsize))))
69 elif len(fieldsize) == 2:
70 if np.isnan(fieldsize[0]):
71 if not np.size(field,1)==fieldsize[1]:
72 md = md.checkmessage(options.getfieldvalue('message',\
73 "field '%s' should have %d columns" % (fieldname,fieldsize[1])))
74 elif np.isnan(fieldsize[1]):
75 if not np.size(field,0)==fieldsize[0]:
76 md = md.checkmessage(options.getfieldvalue('message',\
77 "field '%s' should have %d lines" % (fieldname,fieldsize[0])))
78 else:
79 if (not np.size(field,0)==fieldsize[0]) or (not np.size(field,1)==fieldsize[1]):
80 md = md.checkmessage(options.getfieldvalue('message',\
81 "field '%s' size should be %d x %d" % (fieldname,fieldsize[0],fieldsize[1])))
82
83 #Check numel
84 if options.exist('numel'):
85 fieldnumel=options.getfieldvalue('numel')
86 if np.size(field) not in fieldnumel:
87 if len(fieldnumel)==1:
88 md = md.checkmessage(options.getfieldvalue('message',\
89 "field '%s' size should be %d" % (fieldname,fieldnumel)))
90 elif len(fieldnumel)==2:
91 md = md.checkmessage(options.getfieldvalue('message',\
92 "field '%s' size should be %d or %d" % (fieldname,fieldnumel[0],fieldnumel[1])))
93 else:
94 md = md.checkmessage(options.getfieldvalue('message',\
95 "field '%s' size should be %s" % (fieldname,fieldnumel)))
96
97 #check NaN
98 if options.getfieldvalue('NaN',0):
99 if np.any(np.isnan(field)):
100 md = md.checkmessage(options.getfieldvalue('message',\
101 "NaN values found in field '%s'" % fieldname))
102
103 #check Inf
104 if options.getfieldvalue('Inf',0):
105 if np.any(np.isinf(field)):
106 md = md.checkmessage(options.getfieldvalue('message',\
107 "Inf values found in field '%s'" % fieldname))
108
109 #check cell
110 if options.getfieldvalue('cell',0):
111 if not isinstance(field,(tuple,list,dict)):
112 md = md.checkmessage(options.getfieldvalue('message',\
113 "field '%s' should be a cell" % fieldname))
114
115 #check values
116 if options.exist('values'):
117 fieldvalues=options.getfieldvalue('values')
118 if False in m.ismember(field,fieldvalues):
119 if len(fieldvalues)==1:
120 md = md.checkmessage(options.getfieldvalue('message',\
121 "field '%s' value should be '%s'" % (fieldname,fieldvalues[0])))
122 elif len(fieldvalues)==2:
123 md = md.checkmessage(options.getfieldvalue('message',\
124 "field '%s' values should be '%s' or '%s'" % (fieldname,fieldvalues[0],fieldvalues[1])))
125 else:
126 md = md.checkmessage(options.getfieldvalue('message',\
127 "field '%s' should have values in %s" % (fieldname,fieldvalues)))
128
129 #check greater
130 if options.exist('>='):
131 lowerbound=options.getfieldvalue('>=')
132 if np.any(field<lowerbound):
133 md = md.checkmessage(options.getfieldvalue('message',\
134 "field '%s' should have values above %d" % (fieldname,lowerbound)))
135 if options.exist('>'):
136 lowerbound=options.getfieldvalue('>')
137 if np.any(field<=lowerbound):
138 md = md.checkmessage(options.getfieldvalue('message',\
139 "field '%s' should have values above %d" % (fieldname,lowerbound)))
140
141 #check smaller
142 if options.exist('<='):
143 upperbound=options.getfieldvalue('<=')
144 if np.any(field>upperbound):
145 md = md.checkmessage(options.getfieldvalue('message',\
146 "field '%s' should have values below %d" % (fieldname,upperbound)))
147 if options.exist('<'):
148 upperbound=options.getfieldvalue('<')
149 if np.any(field>=upperbound):
150 md = md.checkmessage(options.getfieldvalue('message',\
151 "field '%s' should have values below %d" % (fieldname,upperbound)))
152
153 #check file
154 if options.getfieldvalue('file',0):
155 if not os.path.exists(field):
156 md = md.checkmessage("file provided in '%s': '%s' does not exist" % (fieldname,field))
157
158 #Check row of strings
159 if options.exist('stringrow'):
160 if not isinstance(field,list):
161 md = md.checkmessage(options.getfieldvalue('message',\
162 "field '%s' should be a list" %fieldname))
163
164 #Check forcings (size and times)
165 if options.getfieldvalue('timeseries',0):
166 if np.size(field,0)==md.mesh.numberofvertices:
167 if np.ndim(field)>1 and not np.size(field,1)==1:
168 md = md.checkmessage(options.getfieldvalue('message',\
169 "field '%s' should have only one column as there are md.mesh.numberofvertices lines" % fieldname))
170 elif np.size(field,0)==md.mesh.numberofvertices+1 or np.size(field,0)==2:
171 if not all(field[-1,:]==np.sort(field[-1,:])):
172 md = md.checkmessage(options.getfieldvalue('message',\
173 "field '%s' columns should be sorted chronologically" % fieldname))
174 if any(field[-1,0:-1]==field[-1,1:]):
175 md = md.checkmessage(options.getfieldvalue('message',\
176 "field '%s' columns must not contain duplicate timesteps" % fieldname))
177 else:
178 md = md.checkmessage(options.getfieldvalue('message',\
179 "field '%s' should have md.mesh.numberofvertices or md.mesh.numberofvertices+1 lines" % fieldname))
180
181 #Check single value forcings (size and times)
182 if options.getfieldvalue('singletimeseries',0):
183 if np.size(field,0)==2:
184 if not all(field[-1,:]==np.sort(field[-1,:])):
185 md = md.checkmessage(options.getfieldvalue('message',\
186 "field '%s' columns should be sorted chronologically" % fieldname))
187 if any(field[-1,0:-1]==field[-1,1:]):
188 md = md.checkmessage(options.getfieldvalue('message',\
189 "field '%s' columns must not contain duplicate timesteps" % fieldname))
190 else:
191 md = md.checkmessage(options.getfieldvalue('message',\
192 "field '%s' should have 2 lines" % fieldname))
193
194 return md
195
Note: See TracBrowser for help on using the repository browser.