def __str__(self): """A human-readable representation of the context.""" s = "" if self.regions != regions.All: s += 'Regions: ' + str(self.regions) + '\n' if self.verbose: s += 'Generators:' + '\n' for g in self.generators: s += '\t' + str(g) summary = g.summary(self) if summary is not None: s += '\n\t ' + summary + '\n' else: s += '\n' s += 'Timesteps: %d h\n' % self.hours s += 'Demand energy: %s\n' % anyWh(self.total_demand()) s += 'Unused surplus energy: %s\n' % anyWh(self.surplus_energy()) if self.surplus_energy() > 0: spill_series = self.spill[self.spill.sum(axis=1) > 0] s += 'Timesteps with unused surplus energy: %d\n' % len( spill_series) if self.unserved.empty: s += 'No unserved energy' else: s += 'Unserved energy: %.3f%%' % self.unserved_percent() + '\n' if self.unserved_percent() > self.relstd * 1.001: s += 'WARNING: reliability standard exceeded\n' s += 'Unserved total hours: ' + str(len(self.unserved)) + '\n' # A subtle trick: generate a date range and then substract # it from the timestamps of unserved events. This will # produce a run of time detlas (for each consecutive hour, # the time delta between this timestamp and the # corresponding row from the range will be # constant). Group by the deltas. rng = pd.date_range(self.unserved.index[0], periods=len(self.unserved.index), freq='H') unserved_events = [ k for k, g in self.unserved.groupby(self.unserved.index - rng) ] s += 'Number of unserved energy events: ' + str( len(unserved_events)) + '\n' if not self.unserved.empty: s += 'Shortfalls (min, max): (%s, %s)' % (anyWh( self.unserved.min(), 'W'), anyWh(self.unserved.max(), 'W')) return s
def _legend(context): """Draw the legend.""" # ::-1 slicing reverses the list so that the legend appears in "merit order". gens = _generator_list(context)[::-1] labels = [] patches = [] if len(gens) > 20: unique = [] for g in gens: if type(g) not in unique: # pylint: disable=unidiomatic-typecheck unique.append(type(g)) # Replace the generator label with its class. genclass = str(type(g)).strip('<>').replace("'", "") labels.append(genclass.split()[1].split('.')[1]) patches.append(g.patch) else: for g in gens: labels.append(g.label + ' (%s)' % anyWh(g.capacity, 'W')) patches.append(g.patch) legend = plt.figlegend([Patch('black', 'red')] + patches, ['unserved'] + labels, 'upper right') plt.setp(legend.get_texts(), fontsize='small')
def summary(self, context): """Return a summary of the generator activity.""" costs = context.costs s = 'supplied %s' % anyWh(sum(self.series_power.values())) if self.capacity > 0: cf = self.capfactor() if cf > 0: s += ', CF %.1f%%' % cf if sum(self.series_spilled.values()) > 0: s += ', surplus %s' % anyWh(sum(self.series_spilled.values())) if self.capcost(costs) > 0: s += ', capcost $%s' % locale.format( '%d', self.capcost(costs), grouping=True) if self.opcost(costs) > 0: s += ', opcost $%s' % locale.format( '%d', self.opcost(costs), grouping=True) lcoe = self.lcoe(costs, context.years) if np.isfinite(lcoe) and lcoe > 0: s += ', LCOE $%d' % int(lcoe) return s
def summary(self, context): return Generator.summary(self, context) + \ ', ran %s hours' % locale.format('%d', self.runhours, grouping=True) + \ ', charged %s hours' % locale.format('%d', self.chargehours, grouping=True) + \ ', %s storage' % anyWh(self.maxstorage)
def __str__(self): """A short string representation of the generator.""" return '%s (%s:%s), %s' \ % (self.label, self.region(), self.polygon, anyWh(self.capacity, 'W'))