3 import xml.etree.ElementTree
as et
7 return prod_type ==
'float' or prod_type ==
'double'
10 if integer_type ==
'short':
12 elif integer_type ==
'int':
13 return -2147483648, 2147483647
14 elif integer_type ==
'byte':
19 parser = argparse.ArgumentParser()
20 parser.add_argument(
'filename')
21 parser.add_argument(
'-v',
'--verbose', action=
'store_true')
22 args = parser.parse_args()
24 product_string =
'{http://oceancolor.gsfc.nasa.gov}product'
25 type_string =
'{http://oceancolor.gsfc.nasa.gov}type'
26 range_string =
'{http://oceancolor.gsfc.nasa.gov}range'
27 validMax_string =
'{http://oceancolor.gsfc.nasa.gov}validMax'
28 validMin_string =
'{http://oceancolor.gsfc.nasa.gov}validMin'
29 displayMin_string =
'{http://oceancolor.gsfc.nasa.gov}displayMin'
30 displayMax_string =
'{http://oceancolor.gsfc.nasa.gov}displayMax'
31 addOffset_string =
'{http://oceancolor.gsfc.nasa.gov}addOffset'
32 scaleFactor_string =
'{http://oceancolor.gsfc.nasa.gov}scaleFactor'
33 algorithm_string =
'{http://oceancolor.gsfc.nasa.gov}algorithm'
35 xml_tree = et.parse(args.filename)
36 xml_tree_root = xml_tree.getroot()
37 for product
in xml_tree_root.findall(product_string):
38 product_name = product.attrib[
'name']
40 product_has_error =
False
41 product_invalid_validMin =
False
42 product_invalid_validMax =
False
43 product_missing_type =
False
44 product_missing_validMax_or_validMin =
False
45 product_missing_default_range =
False
46 product_validMax, product_validMin = 0xdeadbeef, 0xdeadbeef
47 product_addOffset, product_scaleFactor =
None,
None
52 (error_string := f
'{product_name}')
55 product_type = product.find(type_string).text
57 product_type =
'float'
67 (default_range := product.find(range_string))
68 _ = default_range.text
70 product_has_error =
True
71 product_missing_default_range =
True
73 print(
" Missing default range")
75 error_string +=
"\n Missing default range"
78 product_validMax = default_range.find(validMax_string).text
80 product_has_error =
True
81 product_missing_validMax_or_validMin =
True
82 if product_missing_type
is False and product_missing_default_range
is False:
84 print(
" Missing validMax")
86 error_string +=
"\n Missing validMax"
89 product_validMin = default_range.find(validMin_string).text
91 product_has_error =
True
92 product_missing_validMax_or_validMin =
True
93 if product_missing_type
is False and product_missing_default_range
is False:
95 print(
" Missing validMin")
97 error_string +=
"\n Missing validMin"
103 product_addOffset =
float(default_range.find(addOffset_string).text)
104 product_scaleFactor =
float(default_range.find(scaleFactor_string).text)
106 product_addOffset = 0
107 product_scaleFactor = 1
109 if ((product_addOffset
is not None and product_scaleFactor
is not None)
110 and (product_addOffset != 0
and product_scaleFactor != 1)
114 except AttributeError
as ae:
115 if str(ae) ==
"'NoneType' object has no attribute 'text'":
118 product_has_error =
True
119 if product_missing_default_range
is False and not float_or_double(product_type):
121 print(
" If scaleFactor/addOffset is defined, both must be")
123 error_string +=
"\n If scaleFactor/addOffset is defined, both must be"
124 product_addOffset = 0
125 product_scaleFactor = 1
126 except TypeError
as te:
127 product_has_error =
True
128 if (product_missing_default_range
is False and float_or_double(product_type)
and
129 product_addOffset
is not None and product_scaleFactor
is not None):
131 print(f
" {product_type} with a scaleFactor/addOffset")
133 error_string += f
"\n {product_type} with scaleFactor/addOffset"
134 product_addOffset = 0
135 product_scaleFactor = 1
138 _ = default_range.find(displayMin_string).text
139 _ = default_range.find(displayMax_string).text
141 product_has_error =
True
142 if product_missing_type
is False and product_missing_default_range
is False:
144 print(
" Missing displayMin/displayMax")
146 error_string +=
"\n Missing displayMin/displayMax"
150 min_possible = (int_min * product_scaleFactor) + product_addOffset
151 max_possible = (int_max * product_scaleFactor) + product_addOffset
154 min_is_valid =
float(product_validMin) >= min_possible
156 product_has_error =
True
158 print(f
" Issue parsing validMin, {product_validMin} cannot be parsed as a number")
160 error_string += f
"\n Issue parsing validMin of {product_validMin}"
162 max_is_valid =
float(product_validMax) <= max_possible
164 product_has_error =
True
166 print(f
" Issue parsing validMax, {product_validMax} cannot be parsed as a number")
168 error_string += f
"\n Issue parsing validMax of {product_validMax}"
175 if (
float(product_validMin) >
float(product_validMax)
and
176 product_missing_validMax_or_validMin
is False):
177 product_has_error =
True
179 print(f
" validMin of {product_validMin} is greater than validMax of {product_validMax}")
181 error_string += f
"\n validMin of {product_validMin} is greater than validMax of {product_validMax}"
185 if not min_is_valid
and product_missing_validMax_or_validMin
is False and product_missing_type
is False:
186 product_has_error =
True
187 product_invalid_validMin =
True
189 print(f
" Invalid validMin:", end=
' ')
190 print(f
"Minimum possible value is {min_possible} but validMin is {product_validMin}")
192 error_string += f
"\n Invalid validMin, Min possible value is {min_possible}"
194 if not max_is_valid
and product_missing_validMax_or_validMin
is False and product_missing_type
is False:
195 product_has_error =
True
196 product_invalid_validMax =
True
198 print(f
" Invalid validMax:", end=
' ')
199 print(f
"Max possible value is {max_possible} but validMax is {product_validMax}")
201 error_string += f
"\n Invalid validMax, Max possible value is {max_possible}"
205 for algo
in product.findall(algorithm_string):
206 algo_validMin = product_validMin
207 algo_validMax = product_validMax
208 algo_scaleFactor = product_scaleFactor
209 algo_addOffset = product_addOffset
210 algo_name = product_name
211 algo_error_string =
''
212 algo_has_error =
False
215 algo_name = algo.attrib[
'name']
217 algo_name = product_name
218 algo_error_string += f
"\n {algo_name}"
221 print(f
" {algo_name}")
224 (algo_range := algo.find(range_string))
226 (algo_range := default_range)
229 algo_validMax = algo_range.find(validMax_string).text
230 algo_validMin = algo_range.find(validMin_string).text
231 algo_addOffset =
float(algo_range.find(addOffset_string).text)
232 algo_scaleFactor =
float(algo_range.find(scaleFactor_string).text)
234 algo_validMax = product_validMax
235 algo_validMin = product_validMin
236 algo_addOffset = product_addOffset
237 algo_scaleFactor = product_scaleFactor
240 algo_min_possible = (int_min * product_scaleFactor) + product_addOffset
241 algo_max_possible = (int_max * product_scaleFactor) + product_addOffset
243 algo_invalid_validMin = (min_possible >
float(algo_validMin))
245 if product_has_error:
249 print(f
" Issue parsing validMin, {algo_validMin} cannot be parsed as a number")
251 error_string += f
"\n Issue parsing validMin {algo_validMin}"
254 algo_invalid_validMax = (
float(algo_validMax) > max_possible)
256 if product_has_error:
260 print(f
" Issue parsing validMax, {algo_validMin} cannot be parsed as a number")
262 error_string += f
"\n Issue parsing validMax: {algo_validMax}"
265 algo_invalid_validMin =
False
266 algo_invalid_validMax =
False
268 if algo_invalid_validMin
and not product_invalid_validMin:
269 if product_missing_type
is False and product_missing_validMax_or_validMin
is False:
270 product_has_error =
True
271 algo_has_error =
True
273 print(f
" Invalid validMin:", end=
' ')
274 print(f
"Minimum possible value is {min_possible} but validMin is {algo_validMin}")
276 algo_error_string += f
"\n Invalid validMin, Min possible value is {min_possible}"
280 if algo_invalid_validMax
and not product_invalid_validMax:
281 if product_missing_type
is False and product_missing_validMax_or_validMin
is False:
282 product_has_error =
True
283 algo_has_error =
True
285 print(f
" Invalid validMax:", end=
' ')
286 print(f
"Maximum possible value is {max_possible} but validMax is {algo_validMax}")
288 algo_error_string += f
"\n Invalid validMax, Max possible value is {max_possible}"
293 error_string += algo_error_string
294 product_type =
'none'
297 if not args.verbose
and product_has_error: