GreenScheduler / cats

CATS: the Climate-Aware Task Scheduler :cat2: :tiger2: :leopard:
https://greenscheduler.github.io/cats/
MIT License
52 stars 9 forks source link

Represent integrated forecast with an iterable class #36

Closed tlestang closed 1 year ago

tlestang commented 1 year ago

This defines a new class WindowedForecast representing the moving average (or sliding integration) of forecast data. The class constructor takes both a timeseries data (as a list of tuples) and a time averaging window size in units of time intervals between data points. So the time unit is 30min in the case of carbonintensity.org.uk.

Individual evaluations of the moving average can be accessed using indexed notation (__getitem__):

>>> wf = WindowedForecast(data, window)
>>> avg = wf[3] # average of intensities from 3rd timestamp 
                   # over integration window
>>> print(avg)
CarbonIntensityPointEstimate(datetime=datetime.datetime(2023, 5, 13, 16, 52, 26, 206318), value=0.587785)

Individual evaluations of Integrated forecast are returned as a CarbonIntensityPointEstimate instance. CarbonIntensityPointEstimate is defined as a dataclass next to WindowedForecast. Because it is possivle to compare two instances of CarbonIntensityPointEstimate, it is straightforward to retrieve the minimum of the integrated forecast

>>> best_estimate = min(WindowedForecast(data, window))
>>> msg = (
    f"The start time is {best_estimate.datetime} and the corresponding average "
    f "carbon intensity of the job runtime is {best_estimate.value}."
)
>>> print(msg)
The start time is 2023-05-13 16:53:26 and the corresponding average carbon intensity of the job runtime is 35.235

Finally, a WindowedForecast is iterable - that is it implements a __iter__ method returning an interator as a generator function.

for w in WindowedForecast(data, window=job_runtime):
    do_something(w.value)
tlestang commented 1 year ago

Note: I've avoided using NumPy (and potentially SciPy) on purpose. Bringing numpy alone means adding nearly 20MB of dependency to cats. However I couldn't resist the urge of using numpy.testing in the test - which brings numpy as a test dependency only. That I can live with since it will only be required in a dev environment.