diff --git a/solarcalc/cli.py b/solarcalc/cli.py new file mode 100644 index 0000000..f83e297 --- /dev/null +++ b/solarcalc/cli.py @@ -0,0 +1,36 @@ +import argparse as ap + +from solarcalc.spectopt import Light, Spectrum, BandCost, SimpleCost + +def parse_theory(tfile): + with open(tfile) as fh: + header = list(map(lambda x: x.strip(), fh.readline().split(","))) + domain = [int(x.rstrip("nm")) for x in header[5:]] + for line in fh: + cells = list(map(lambda x: x.strip(), line.split(","))) + date, mdate, temp, hum, tot, *wls = cells + wls = list(map(float, wls)) + yield (date, mdate, temp, hum, tot, Spectrum(domain, wls)) + + +def optimise_for_light(): + p = ap.ArgumentParser() + p.add_argument("-l", "--light", type=str, required=True, + help="Light definition file") + p.add_argument("theoretical", type=str, + help="Theoretical model output as a CSV") + args = p.parse_args() + + light = Light(args.light, interpolation='linear') + + cf = BandCost(bands=[(400, 500), (500, 600), (600, 700)], weights=[1, 0.1, 1]) + light = Light("./data/spectra/growtainer-actual.csv", interpolation='linear') + print("datetime", "model_datetime", "temp", "humidity", "total_solar", *light.channels, sep="\t") + for line in parse_theory("./data/output.csv"): + want = line[5][min(light.wavelengths):max(light.wavelengths)] + opt = light.optimise_settings(want, cost_function=cf) + print(*line[0:5], *opt, sep="\t") + + +if __name__ == "__main__": + optimise_for_light() diff --git a/solarcalc/spectopt.py b/solarcalc/spectopt.py index 6d1deae..6355154 100644 --- a/solarcalc/spectopt.py +++ b/solarcalc/spectopt.py @@ -15,8 +15,8 @@ class Spectrum(object): """Holds a spectral density curve, also integrate and interpolate""" def __init__(self, wavelengths, values): - self.wavelengths = wavelengths - self.values = values + self.wavelengths = np.array(wavelengths).astype(float) + self.values = np.array(values).astype(float) def interpolated(self, method='linear'): '''Create a function to interpolate spectrum to new wavelengths''' @@ -39,13 +39,18 @@ def banded_integral(self, bands): integr.append(s.integral(*band)) return integr + def __getitem__(self, item): + if isinstance(item, slice): + keep = np.logical_and(self.wavelengths >= item.start, self.wavelengths <= item.stop) + return Spectrum(self.wavelengths[keep], self.values[keep]) + + class CostFunc(object): '''Base class of cost functions, designed to be used with Light.optimise_settings''' def __call__(self, weights, light, desired): got = light.light_output(weights, wavelengths=desired.wavelengths) cost = self._cost(got, desired) - print(type(self).__name__, weights, cost) return cost class SimpleCost(CostFunc):