Skip to content

Commit fe05858

Browse files
authored
i.atcorr: major refactoring of create_iwave.py (OSGeo#3886)
* speed up (e.g., do not run loops if one run is sufficient) * lower the amount of code duplicity * remove lines that actually do not do anything (e.g., lines containing declaration `print` without brackets) * general beauty salon treatment
1 parent f4a83f4 commit fe05858

File tree

1 file changed

+42
-52
lines changed

1 file changed

+42
-52
lines changed

imagery/i.atcorr/create_iwave.py

Lines changed: 42 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -59,20 +59,15 @@ def read_input(csvfile):
5959
first column is wavelength
6060
values are those of the discrete band filter functions
6161
"""
62-
infile = open(csvfile)
62+
with open(csvfile) as infile:
63+
# get number of bands and band names
64+
bands = infile.readline().strip().split(",")[1:]
6365

64-
# get number of bands and band names
65-
bands = infile.readline().split(",")
66-
bands.remove(bands[0])
67-
bands[-1] = bands[-1].strip()
68-
print(" > Number of bands found: %d" % len(bands))
69-
infile.close()
66+
print(f" > Number of bands found: {len(bands)}")
7067

7168
# create converter dictionary for import
7269
# fix nodata or \n
73-
conv = {}
74-
for b in range(len(bands)):
75-
conv[b + 1] = lambda s: float(s or 0)
70+
conv = {b + 1: lambda s: float(s or 0) for b in range(len(bands))}
7671

7772
values = np.loadtxt(csvfile, delimiter=",", skiprows=1, converters=conv)
7873

@@ -87,10 +82,8 @@ def interpolate_band(values, step=2.5):
8782
and min, max wl values
8883
values must be numpy array with 2 columns
8984
"""
90-
9185
# removing nodata and invalid values
92-
w = values[:, 1] >= 0
93-
values_clean = values[w]
86+
values_clean = values[values[:, 1] >= 0]
9487

9588
wavelengths = values_clean[:, 0] # 1st column of input array
9689
responses = values_clean[:, 1] # 2nd column
@@ -184,25 +177,25 @@ def pretty_print(filter_f):
184177
Create pretty string out of filter function
185178
8 values per line, with spaces, commas and all the rest
186179
"""
187-
pstring = ""
180+
pstring = []
188181
for i in range(len(filter_f) + 1):
189182
if i % 8 == 0:
190183
if i != 0:
191184
value_wo_leading_zero = ("%.4f" % (filter_f[i - 1])).lstrip("0")
192-
pstring += value_wo_leading_zero
193-
if i > 1 and i < len(filter_f):
194-
pstring += ", "
195-
if i != 1:
185+
pstring.append(value_wo_leading_zero)
186+
if i > 1:
187+
if i < len(filter_f):
188+
pstring.append(", ")
196189
# trim the trailing whitespace at the end of line
197-
pstring = pstring.rstrip()
198-
pstring += "\n "
190+
pstring[-1] = pstring[-1].rstrip()
191+
pstring.append("\n ")
199192
else:
200193
value_wo_leading_zero = ("%.4f" % (filter_f[i - 1])).lstrip("0")
201-
pstring += value_wo_leading_zero
194+
pstring.append(value_wo_leading_zero)
202195
if i < len(filter_f):
203-
pstring += ", "
196+
pstring.append(", ")
204197
# trim starting \n and trailing ,
205-
return pstring.lstrip("\n").rstrip(", ")
198+
return "".join(pstring).lstrip("\n").rstrip(", ")
206199

207200

208201
def write_cpp(bands, values, sensor, folder):
@@ -212,6 +205,24 @@ def write_cpp(bands, values, sensor, folder):
212205
needs other functions: interpolate_bands, pretty_print
213206
"""
214207

208+
def get_min_wavelength(c, rthresh, fi):
209+
"""Get minimum wavelength rounded by threshold.
210+
211+
:param fi: filter function
212+
"""
213+
while c > 0 and fi[c - 1] > rthresh:
214+
c -= 1
215+
return np.ceil(li[0] * 1000 + (2.5 * c))
216+
217+
def get_max_wavelength(c, rthresh, fi):
218+
"""Get maximum wavelength rounded by threshold.
219+
220+
:param fi: filter function
221+
"""
222+
while c < len(fi) - 1 and fi[c + 1] > rthresh:
223+
c += 1
224+
return np.floor(li[0] * 1000 + (2.5 * c))
225+
215226
# keep in sync with IWave::parse()
216227
rthresh = 0.01
217228
print(" > Response peaks from interpolation to 2.5 nm steps:")
@@ -225,17 +236,8 @@ def write_cpp(bands, values, sensor, folder):
225236
li = limits
226237
# Get wavelength range for spectral response in band
227238
maxresponse_idx = np.argmax(fi)
228-
# Get minimum wavelength with spectral response
229-
c = maxresponse_idx
230-
while c > 0 and fi[c - 1] > rthresh:
231-
c -= 1
232-
min_wavelength = np.ceil(li[0] * 1000 + (2.5 * c))
233-
# Get maximum wavelength with spectral response
234-
c = maxresponse_idx
235-
while c < len(fi) - 1 and fi[c + 1] > rthresh:
236-
c += 1
237-
max_wavelength = np.floor(li[0] * 1000 + (2.5 * c))
238-
print(" %s (%inm - %inm)" % (bands[0], min_wavelength, max_wavelength))
239+
min_wavelength = get_min_wavelength(maxresponse_idx, rthresh, fi)
240+
max_wavelength = get_max_wavelength(maxresponse_idx, rthresh, fi)
239241

240242
else:
241243
filter_f = []
@@ -247,29 +249,17 @@ def write_cpp(bands, values, sensor, folder):
247249

248250
# Get wavelength range for spectral response in band
249251
maxresponse_idx = np.argmax(fi)
250-
# Get minimum wavelength with spectral response
251-
c = maxresponse_idx
252-
while c > 0 and fi[c - 1] > rthresh:
253-
c -= 1
254-
min_wavelength = np.ceil(li[0] * 1000 + (2.5 * c))
255-
# Get maximum wavelength with spectral response
256-
c = maxresponse_idx
257-
while c < len(fi) - 1 and fi[c + 1] > rthresh:
258-
c += 1
259-
max_wavelength = np.floor(li[0] * 1000 + (2.5 * c))
252+
min_wavelength = get_min_wavelength(maxresponse_idx, rthresh, fi)
253+
max_wavelength = get_max_wavelength(maxresponse_idx, rthresh, fi)
260254
print(" %s (%inm - %inm)" % (bands[b], min_wavelength, max_wavelength))
261255

262256
# writing...
263257
outfile = open(os.path.join(folder, sensor + "_cpp_template.txt"), "w")
264258
outfile.write("/* Following filter function created using create_iwave.py */\n\n")
265259

266-
if len(bands) == 1:
267-
outfile.write("void IWave::%s()\n{\n\n" % (sensor.lower()))
268-
else:
269-
outfile.write("void IWave::%s(int iwa)\n{\n\n" % (sensor.lower()))
270-
271260
# single band case
272261
if len(bands) == 1:
262+
outfile.write("void IWave::%s()\n{\n\n" % (sensor.lower()))
273263
outfile.write(" /* %s of %s */\n" % (bands[0], sensor))
274264
outfile.write(" static const float sr[%i] = {" % (len(filter_f)))
275265
filter_text = pretty_print(filter_f)
@@ -295,6 +285,7 @@ def write_cpp(bands, values, sensor, folder):
295285
outfile.write("}\n")
296286

297287
else: # more than 1 band
288+
outfile.write("void IWave::%s(int iwa)\n{\n\n" % (sensor.lower()))
298289
# writing bands
299290
for b in range(len(bands)):
300291
outfile.write(" /* %s of %s */\n" % (bands[b], sensor))
@@ -305,9 +296,8 @@ def write_cpp(bands, values, sensor, folder):
305296
outfile.write(filter_text + "\n };\n\t\n")
306297

307298
# writing band limits
308-
for b in range(len(bands)):
309-
inf = ", ".join(["%.4f" % i[0] for i in limits])
310-
sup = ", ".join(["%.4f" % i[1] for i in limits])
299+
inf = ", ".join(["%.4f" % i[0] for i in limits])
300+
sup = ", ".join(["%.4f" % i[1] for i in limits])
311301

312302
outfile.write(" static const float wli[%i] = {%s};\n" % (len(bands), inf))
313303
outfile.write(" static const float wls[%i] = {%s};\n" % (len(bands), sup))

0 commit comments

Comments
 (0)