1 | import numpy as np
|
---|
2 | import os
|
---|
3 | from pairoptions import pairoptions
|
---|
4 | import MatlabFuncs as m
|
---|
5 |
|
---|
6 | def 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 |
|
---|