base demand categories

calculates them using epanet demand categories + patterns.

Minor robustness modification to aggregatortimeseries::filteredpoints
to avoid dereferencing null pointer in case there are no points.