|
@@ -29,6 +29,7 @@ import sys
|
|
|
import numpy as np
|
|
|
from scipy import interpolate
|
|
|
|
|
|
+
|
|
|
def usage():
|
|
|
"""How to use this..."""
|
|
|
print("create_iwave.py <csv file>")
|
|
@@ -47,6 +48,7 @@ def usage():
|
|
|
print("This script will interpolate the filter functions to 2.5 nm steps")
|
|
|
print("and output a cpp template file in the IWave format to be added to iwave.cpp")
|
|
|
|
|
|
+
|
|
|
def read_input(csvfile):
|
|
|
"""
|
|
|
Function to read input file
|
|
@@ -58,10 +60,10 @@ def read_input(csvfile):
|
|
|
first column is wavelength
|
|
|
values are those of the discrete band filter functions
|
|
|
"""
|
|
|
- infile = open(csvfile, 'r')
|
|
|
+ infile = open(csvfile, "r")
|
|
|
|
|
|
# get number of bands and band names
|
|
|
- bands = infile.readline().split(',')
|
|
|
+ bands = infile.readline().split(",")
|
|
|
bands.remove(bands[0])
|
|
|
bands[-1] = bands[-1].strip()
|
|
|
print(" > Number of bands found: %d" % len(bands))
|
|
@@ -71,13 +73,14 @@ def read_input(csvfile):
|
|
|
# fix nodata or \n
|
|
|
conv = {}
|
|
|
for b in range(len(bands)):
|
|
|
- conv[b+1] = lambda s: float(s or 0)
|
|
|
+ conv[b + 1] = lambda s: float(s or 0)
|
|
|
|
|
|
- values = np.loadtxt(csvfile, delimiter=',', skiprows=1, converters = conv)
|
|
|
+ values = np.loadtxt(csvfile, delimiter=",", skiprows=1, converters=conv)
|
|
|
|
|
|
return (bands, values)
|
|
|
|
|
|
-def interpolate_band(values, step = 2.5):
|
|
|
+
|
|
|
+def interpolate_band(values, step=2.5):
|
|
|
"""
|
|
|
Receive wavelength and response for one band
|
|
|
interpolate at 2.5 nm steps
|
|
@@ -87,12 +90,14 @@ def interpolate_band(values, step = 2.5):
|
|
|
"""
|
|
|
|
|
|
# removing nodata and invalid values
|
|
|
- w = values[:,1] >= 0
|
|
|
+ w = values[:, 1] >= 0
|
|
|
values_clean = values[w]
|
|
|
|
|
|
- wavelengths = values_clean[:,0] # 1st column of input array
|
|
|
- responses = values_clean[:,1] # 2nd column
|
|
|
- assert len(wavelengths) == len(responses), "Number of wavelength slots and spectral responses are not equal!"
|
|
|
+ wavelengths = values_clean[:, 0] # 1st column of input array
|
|
|
+ responses = values_clean[:, 1] # 2nd column
|
|
|
+ assert len(wavelengths) == len(
|
|
|
+ responses
|
|
|
+ ), "Number of wavelength slots and spectral responses are not equal!"
|
|
|
|
|
|
# spectral responses are written out with .4f in pretty_print()
|
|
|
# anything smaller than 0.0001 will become 0.0000 -> discard with ...
|
|
@@ -136,13 +141,16 @@ def interpolate_band(values, step = 2.5):
|
|
|
|
|
|
# how many spectral responses?
|
|
|
expected = np.ceil((stop - start) / step)
|
|
|
- assert len(filter_f) == expected, "Number of interpolated spectral responses not equal to expected number of interpolations"
|
|
|
+ assert (
|
|
|
+ len(filter_f) == expected
|
|
|
+ ), "Number of interpolated spectral responses not equal to expected number of interpolations"
|
|
|
|
|
|
# convert limits from nanometers to micrometers
|
|
|
- lowerlimit = start/1000
|
|
|
- upperlimit = stop/1000
|
|
|
+ lowerlimit = start / 1000
|
|
|
+ upperlimit = stop / 1000
|
|
|
+
|
|
|
+ return (filter_f, (lowerlimit, upperlimit))
|
|
|
|
|
|
- return(filter_f, (lowerlimit, upperlimit))
|
|
|
|
|
|
def plot_filter(values):
|
|
|
"""Plot wl response values and interpolated
|
|
@@ -153,40 +161,42 @@ def plot_filter(values):
|
|
|
filter_f, limits = interpolate_band(values)
|
|
|
|
|
|
# removing nodata
|
|
|
- w = values[:,1] >= 0
|
|
|
+ w = values[:, 1] >= 0
|
|
|
response = values[w]
|
|
|
|
|
|
- plot(response[:,0],response[:,1], 'ro')
|
|
|
+ plot(response[:, 0], response[:, 1], "ro")
|
|
|
plot(arange(limits[0], limits[1], 2.5), filter_f)
|
|
|
|
|
|
return
|
|
|
|
|
|
+
|
|
|
def pretty_print(filter_f):
|
|
|
"""
|
|
|
Create pretty string out of filter function
|
|
|
8 values per line, with spaces, commas and all the rest
|
|
|
"""
|
|
|
- pstring = ''
|
|
|
- for i in range(len(filter_f)+1):
|
|
|
- if i %8 is 0:
|
|
|
+ pstring = ""
|
|
|
+ for i in range(len(filter_f) + 1):
|
|
|
+ if i % 8 is 0:
|
|
|
if i is not 0:
|
|
|
- value_wo_leading_zero = ('%.4f' % (filter_f[i-1])).lstrip('0')
|
|
|
+ value_wo_leading_zero = ("%.4f" % (filter_f[i - 1])).lstrip("0")
|
|
|
pstring += value_wo_leading_zero
|
|
|
if i > 1 and i < len(filter_f):
|
|
|
- pstring += ', '
|
|
|
+ pstring += ", "
|
|
|
if i is not 1:
|
|
|
# trim the trailing whitespace at the end of line
|
|
|
pstring = pstring.rstrip()
|
|
|
pstring += "\n "
|
|
|
else:
|
|
|
- value_wo_leading_zero = ('%.4f' % (filter_f[i-1])).lstrip('0')
|
|
|
+ value_wo_leading_zero = ("%.4f" % (filter_f[i - 1])).lstrip("0")
|
|
|
pstring += value_wo_leading_zero
|
|
|
if i < len(filter_f):
|
|
|
- pstring += ', '
|
|
|
+ pstring += ", "
|
|
|
# trim starting \n and trailing ,
|
|
|
pstring = pstring.lstrip("\n").rstrip(", ")
|
|
|
return pstring
|
|
|
|
|
|
+
|
|
|
def write_cpp(bands, values, sensor, folder):
|
|
|
"""
|
|
|
from bands, values and sensor name
|
|
@@ -224,7 +234,7 @@ def write_cpp(bands, values, sensor, folder):
|
|
|
filter_f = []
|
|
|
limits = []
|
|
|
for b in range(len(bands)):
|
|
|
- fi, li = interpolate_band(values[:,[0,b+1]])
|
|
|
+ fi, li = interpolate_band(values[:, [0, b + 1]])
|
|
|
filter_f.append(fi)
|
|
|
limits.append(li)
|
|
|
|
|
@@ -243,68 +253,80 @@ def write_cpp(bands, values, sensor, folder):
|
|
|
print(" %s (%inm - %inm)" % (bands[b], min_wavelength, max_wavelength))
|
|
|
|
|
|
# writing...
|
|
|
- outfile = open(os.path.join(folder, sensor+"_cpp_template.txt"), 'w')
|
|
|
- outfile.write('/* Following filter function created using create_iwave.py */\n\n')
|
|
|
+ outfile = open(os.path.join(folder, sensor + "_cpp_template.txt"), "w")
|
|
|
+ outfile.write("/* Following filter function created using create_iwave.py */\n\n")
|
|
|
|
|
|
if len(bands) == 1:
|
|
|
- outfile.write('void IWave::%s()\n{\n\n' % (sensor.lower()))
|
|
|
+ outfile.write("void IWave::%s()\n{\n\n" % (sensor.lower()))
|
|
|
else:
|
|
|
- outfile.write('void IWave::%s(int iwa)\n{\n\n' % (sensor.lower()))
|
|
|
+ outfile.write("void IWave::%s(int iwa)\n{\n\n" % (sensor.lower()))
|
|
|
|
|
|
# single band case
|
|
|
if len(bands) == 1:
|
|
|
- outfile.write(' /* %s of %s */\n' % (bands[0], sensor))
|
|
|
- outfile.write(' static const float sr[%i] = {' % (len(filter_f)))
|
|
|
+ outfile.write(" /* %s of %s */\n" % (bands[0], sensor))
|
|
|
+ outfile.write(" static const float sr[%i] = {" % (len(filter_f)))
|
|
|
filter_text = pretty_print(filter_f)
|
|
|
outfile.write(filter_text)
|
|
|
|
|
|
# calculate wl slot for band start
|
|
|
# slots range from 250 to 4000 at 2.5 increments (total 1500)
|
|
|
- s_start = int((limits[0]*1000 - 250)/2.5)
|
|
|
-
|
|
|
- outfile.write('\n')
|
|
|
- outfile.write(' ffu.wlinf = %.4ff;\n' % (limits[0]))
|
|
|
- outfile.write(' ffu.wlsup = %.4ff;\n' % (limits[1]))
|
|
|
- outfile.write(' int i = 0;\n')
|
|
|
- outfile.write(' for(i = 0; i < %i; i++)\tffu.s[i] = 0;\n' % (s_start))
|
|
|
- outfile.write(' for(i = 0; i < %i; i++)\tffu.s[%i+i] = sr[i];\n' % (len(filter_f), s_start))
|
|
|
- outfile.write(' for(i = %i; i < 1501; i++)\tffu.s[i] = 0;\n' % (s_start + len(filter_f)))
|
|
|
- outfile.write('}\n')
|
|
|
-
|
|
|
- else: # more than 1 band
|
|
|
+ s_start = int((limits[0] * 1000 - 250) / 2.5)
|
|
|
+
|
|
|
+ outfile.write("\n")
|
|
|
+ outfile.write(" ffu.wlinf = %.4ff;\n" % (limits[0]))
|
|
|
+ outfile.write(" ffu.wlsup = %.4ff;\n" % (limits[1]))
|
|
|
+ outfile.write(" int i = 0;\n")
|
|
|
+ outfile.write(" for(i = 0; i < %i; i++)\tffu.s[i] = 0;\n" % (s_start))
|
|
|
+ outfile.write(
|
|
|
+ " for(i = 0; i < %i; i++)\tffu.s[%i+i] = sr[i];\n"
|
|
|
+ % (len(filter_f), s_start)
|
|
|
+ )
|
|
|
+ outfile.write(
|
|
|
+ " for(i = %i; i < 1501; i++)\tffu.s[i] = 0;\n"
|
|
|
+ % (s_start + len(filter_f))
|
|
|
+ )
|
|
|
+ outfile.write("}\n")
|
|
|
+
|
|
|
+ else: # more than 1 band
|
|
|
# writing bands
|
|
|
for b in range(len(bands)):
|
|
|
- outfile.write(' /* %s of %s */\n' % (bands[b], sensor))
|
|
|
- outfile.write(' static const float sr%i[%i] = {\n' % (b+1,len(filter_f[b])))
|
|
|
+ outfile.write(" /* %s of %s */\n" % (bands[b], sensor))
|
|
|
+ outfile.write(
|
|
|
+ " static const float sr%i[%i] = {\n" % (b + 1, len(filter_f[b]))
|
|
|
+ )
|
|
|
filter_text = pretty_print(filter_f[b])
|
|
|
- outfile.write(filter_text+'\n };\n\t\n')
|
|
|
+ outfile.write(filter_text + "\n };\n\t\n")
|
|
|
|
|
|
# writing band limits
|
|
|
for b in range(len(bands)):
|
|
|
inf = ", ".join(["%.4f" % i[0] for i in limits])
|
|
|
sup = ", ".join(["%.4f" % i[1] for i in limits])
|
|
|
|
|
|
- outfile.write(' static const float wli[%i] = {%s};\n' % (len(bands), inf))
|
|
|
- outfile.write(' static const float wls[%i] = {%s};\n' % (len(bands), sup))
|
|
|
+ outfile.write(" static const float wli[%i] = {%s};\n" % (len(bands), inf))
|
|
|
+ outfile.write(" static const float wls[%i] = {%s};\n" % (len(bands), sup))
|
|
|
|
|
|
- outfile.write('\n')
|
|
|
- outfile.write(' ffu.wlinf = (float)wli[iwa-1];\n')
|
|
|
- outfile.write(' ffu.wlsup = (float)wls[iwa-1];\n\n')
|
|
|
+ outfile.write("\n")
|
|
|
+ outfile.write(" ffu.wlinf = (float)wli[iwa-1];\n")
|
|
|
+ outfile.write(" ffu.wlsup = (float)wls[iwa-1];\n\n")
|
|
|
|
|
|
- outfile.write(' int i;\n')
|
|
|
- outfile.write(' for(i = 0; i < 1501; i++) ffu.s[i] = 0;\n\n')
|
|
|
+ outfile.write(" int i;\n")
|
|
|
+ outfile.write(" for(i = 0; i < 1501; i++) ffu.s[i] = 0;\n\n")
|
|
|
|
|
|
- outfile.write(' switch(iwa)\n {\n')
|
|
|
+ outfile.write(" switch(iwa)\n {\n")
|
|
|
|
|
|
# now start of case part...
|
|
|
for b in range(len(bands)):
|
|
|
- s_start = int((limits[b][0]*1000 - 250)/2.5)
|
|
|
- outfile.write(' case %i: for(i = 0; i < %i; i++) ffu.s[%i+i] = sr%i[i];\n' % ((b+1), len(filter_f[b]), s_start, (b+1)))
|
|
|
- outfile.write(' break;\n')
|
|
|
- outfile.write(' }\n}\n')
|
|
|
+ s_start = int((limits[b][0] * 1000 - 250) / 2.5)
|
|
|
+ outfile.write(
|
|
|
+ " case %i: for(i = 0; i < %i; i++) ffu.s[%i+i] = sr%i[i];\n"
|
|
|
+ % ((b + 1), len(filter_f[b]), s_start, (b + 1))
|
|
|
+ )
|
|
|
+ outfile.write(" break;\n")
|
|
|
+ outfile.write(" }\n}\n")
|
|
|
|
|
|
return
|
|
|
|
|
|
+
|
|
|
def main():
|
|
|
""" control function """
|
|
|
|
|
@@ -330,20 +352,20 @@ def main():
|
|
|
hiwl = 0
|
|
|
maxr = 0
|
|
|
maxi = 0
|
|
|
- for i in range(len(values[:,0])):
|
|
|
- if maxr < values[i,b]:
|
|
|
- maxr = values[i,b]
|
|
|
+ for i in range(len(values[:, 0])):
|
|
|
+ if maxr < values[i, b]:
|
|
|
+ maxr = values[i, b]
|
|
|
maxi = i
|
|
|
|
|
|
i = maxi
|
|
|
- while i >= 0 and values[i,b] > rthresh:
|
|
|
- lowl = values[i,0]
|
|
|
+ while i >= 0 and values[i, b] > rthresh:
|
|
|
+ lowl = values[i, 0]
|
|
|
i -= 1
|
|
|
|
|
|
i = maxi
|
|
|
- nvalues = len(values[:,0])
|
|
|
- while i < nvalues and values[i,b] > rthresh:
|
|
|
- hiwl = values[i,0]
|
|
|
+ nvalues = len(values[:, 0])
|
|
|
+ while i < nvalues and values[i, b] > rthresh:
|
|
|
+ hiwl = values[i, 0]
|
|
|
i += 1
|
|
|
|
|
|
print(" %s (%inm - %inm)" % (bands[b - 1], lowl, hiwl))
|
|
@@ -352,14 +374,24 @@ def main():
|
|
|
write_cpp(bands, values, sensor, os.path.dirname(inputfile))
|
|
|
|
|
|
print
|
|
|
- print(" > Filter functions exported to %s" % ("sensors_csv/"+sensor+"_cpp_template.txt"))
|
|
|
- print(" > Please check this file for possible errors before inserting the code into file iwave.cpp")
|
|
|
- print(" > Don't forget to add the necessary data to the files iwave.h, geomcond.h, geomcond.cpp, and to i.atcorr.html")
|
|
|
+ print(
|
|
|
+ " > Filter functions exported to %s"
|
|
|
+ % ("sensors_csv/" + sensor + "_cpp_template.txt")
|
|
|
+ )
|
|
|
+ print(
|
|
|
+ " > Please check this file for possible errors before inserting"
|
|
|
+ " the code into file iwave.cpp"
|
|
|
+ )
|
|
|
+ print(
|
|
|
+ " > Don't forget to add the necessary data to the files"
|
|
|
+ " iwave.h, geomcond.h, geomcond.cpp, and to i.atcorr.html"
|
|
|
+ )
|
|
|
print
|
|
|
|
|
|
return
|
|
|
|
|
|
-if __name__ == '__main__':
|
|
|
+
|
|
|
+if __name__ == "__main__":
|
|
|
if len(sys.argv) == 1:
|
|
|
usage()
|
|
|
sys.exit()
|