def compute(self, fractions_dict, concentration_dict, start_date, end_date): """Compute and return the concentration time series. Parameters: * fractions_list -- dict of fractions timeseries in [0.0, 1.0] * concentration_list -- dict of label keys with concentration values in [mg/l] Computation is based on constant concentration of the fractions """ timeseries = SparseTimeseriesStub() for events in enumerate_dict_events(fractions_dict): date = events['date'] del(events['date']) concentration = 0 for key, value in events.items(): if key in ['intakes', 'defined_input']: for key_intake, value_intake in value.items(): if key_intake == 'intake_wl_control': concentration += value_intake[1] * concentration_dict[key_intake] else: concentration += value_intake[1] * concentration_dict[key_intake.label.program_name] else: concentration += value[1] * concentration_dict[key] timeseries.add_value(date, concentration) return timeseries
def compute(self, open_water, buckets_summary, precipitation, evaporation, seepage, infiltration, minimum_level_timeseries, maximum_level_timeseries, intakes_timeseries, pumps_timeseries, max_intake = None, max_outtake = None): """Compute and return the pair of intake and pump time series. This function returns the pair of SparseTimeseriesStub(s) that consists of the intake time series and pump time series for the given open water. Parameters: * open_water -- OpenWater for which to compute the level control * buckets_summary -- BucketsSummary with the summed buckets outcome * precipitation, * evaporation, * seepage, * infiltration * intakes_timeseries -- dict of intake timeseries in [m3/day] * pumps_timeseries -- dict of pump timeseries in [m3/day] """ storage = SparseTimeseriesStub() result = SparseTimeseriesStub() water_level_timeseries = SparseTimeseriesStub() pump_time_series = SparseTimeseriesStub() intake_time_series = SparseTimeseriesStub() total_incoming = SparseTimeseriesStub() total_outgoing = SparseTimeseriesStub() surface = 1.0 * open_water.surface water_level = open_water.init_water_level ts = {} ts['bucket_total_incoming'] = buckets_summary.total_incoming ts['bucket_total_outgoing'] = buckets_summary.total_outgoing ts['precipitation'] = precipitation ts['evaporation'] = evaporation ts['seepage'] = seepage ts['infiltration'] = infiltration ts['min_level'] = minimum_level_timeseries ts['max_level'] = maximum_level_timeseries ts['intakes'] = {} for intake, timeseries in intakes_timeseries.iteritems(): if not intake.computed_level_control: ts['intakes'][intake] = timeseries ts['pumps'] = {} for pump, timeseries in pumps_timeseries.iteritems(): if not pump.computed_level_control: ts['pumps'][pump] = timeseries for events in enumerate_dict_events(ts): date = events['date'] if self.inside_range(date) < 0: continue elif self.inside_range(date) > 0: break if not events.has_key('intakes'): events['intakes'] = {} incoming_value = [ events['bucket_total_outgoing'][1], events['precipitation'][1], events['seepage'][1]] + \ [event[1] for event in events['intakes'].values()] incoming_value = sum(incoming_value) if not events.has_key('pumps'): events['pumps'] = {} outgoing_value = [ events['bucket_total_incoming'][1], events['infiltration'][1], events['evaporation'][1]] + \ [event[1] for event in events['pumps'].values()] outgoing_value = sum(outgoing_value) water_level += (incoming_value + outgoing_value) / surface level_control = self._compute_level_control(surface, water_level, events['min_level'][1], events['max_level'][1]) if level_control < 0: if max_outtake is not None: pump = max(level_control, -1*max_outtake) else: pump = level_control intake = 0 else: pump = 0 if max_intake is not None: intake = min(level_control, max_intake) else: intake = level_control water_level += (pump + intake) / surface pump_time_series.add_value(date, pump) intake_time_series.add_value(date, intake) water_level_timeseries.add_value(date, water_level) storage_value = (water_level - open_water.bottom_height) * surface storage.add_value(date, storage_value) result.add_value(date, level_control) total_incoming.add_value(date, sum([incoming_value, intake])) total_outgoing.add_value(date, sum([outgoing_value, pump])) date += timedelta(1) return {'intake_wl_control':intake_time_series, 'outtake_wl_control':pump_time_series, 'storage':storage, 'water_level':water_level_timeseries, 'total_incoming':total_incoming, 'total_outgoing':total_outgoing}
def compute(self, inflow_dict, outflow_dict, storage, concentration_dict, start_date, end_date): """Compute and return the concentration time series. Parameters: * fractions_list -- dict of fractions timeseries in [0.0, 1.0] * concentration_list -- dict of label keys with concentration values in [mg/l] Computation is based on constant concentration of the fractions """ total_outflow = SparseTimeseriesStub() for events in enumerate_dict_events(outflow_dict): date = events['date'] del(events['evaporation']) del(events['date']) total= 0.0 for key, event in events.items(): if key in ['outtakes', 'defined_output']: for key_outtake, event_outtake in event.items(): total += event_outtake[1] else: total += event[1] total_outflow.add_value(date, total) start_storage = next(storage.events(start_date, end_date))[1] storage_chloride = start_storage * concentration_dict['initial'] delta = SparseTimeseriesStub() timeseries = SparseTimeseriesStub() for events in enumerate_dict_events(dict(tuple(inflow_dict.items()) + (('total_outflow', total_outflow), ('storage', storage)))): date = events['date'] if date < start_date: continue if date >= end_date: break total_outflow = -events['total_outflow'][1] storage = events['storage'][1] del(events['date']) del(events['total_outflow']) del(events['storage']) out = (storage_chloride/storage) * total_outflow plus = 0.0 for key, value in events.items(): if key in ['intakes', 'defined_input']: for key_intake, value_intake in value.items(): if key_intake == 'intake_wl_control': plus += value_intake[1] * concentration_dict[key_intake] else: plus += value_intake[1] * concentration_dict[key_intake.label.program_name] else: plus += value[1] * concentration_dict[key] storage_chloride = storage_chloride + plus - out timeseries.add_value(date, storage_chloride/storage) delta.add_value(date, plus - out) return timeseries, delta
def compute(self, flow_dict, concentration_dict, start_date, end_date, nutricalc_timeseries=None): """Compute and return the concentration time series. Parameters: *flow_list* dictionary of incoming waterflows *concentration_list* dict of label keys with concentration values in [mg/l] This method returns a dictionary of flow to time series. The flow can be (specified by) a string such as 'precipitation', 'seepage' or 'drained', or can be (specified by) a PumpingStation. In an earlier version of this method the keys of the returned dictionary where always a string but that has been changed to solve the problem reported in ticket:2542. Remarks: * flows_dict['defined_input'] is a dictionary from intake to time series * this method would benefit from additional documentation and a review """ loads = {} if nutricalc_timeseries: flow_dict['nutricalc'] = nutricalc_timeseries first_ts = True for events in enumerate_dict_events(flow_dict): date = events['date'] if date < start_date: continue if date >= end_date: break del(events['date']) if nutricalc_timeseries: del(events['drained']) del(events['undrained']) for key, value in events.items(): # key never seems to be equal to 'intakes' if key in ['intakes', 'defined_input']: for key_intake, value_intake in value.items(): if key_intake == 'intake_wl_control': # if key is indeed never equal to 'intakes', # key_intake will never be equal to # 'intake_wl_control' load = value_intake[1] * \ concentration_dict[key_intake] label = 'intake_wl_control' else: load = value_intake[1] * \ concentration_dict[key_intake.label.program_name] label = key_intake elif key == 'nutricalc': label = key load = value[1] else: label = key load = value[1] * concentration_dict[key] if first_ts: loads[label] = TimeseriesStub() loads[label].add_value(date, load) first_ts = False return loads
def export_excel_small(request, area_slug, scenario_slug): """ export van een configuratie naar Excel """ t1 = time.time() bucket_export = False configuration = WaterbalanceConf.objects.get( waterbalance_area__slug=area_slug, waterbalance_scenario__slug=scenario_slug) waterbalance_computer = \ CachedWaterbalanceComputer(CacheKeyName(configuration), configuration) logger.debug("%s seconds - got waterbalance computer", time.time() - t1) start_date = configuration.calculation_start_date end_date = datetime.now() end_date = datetime(end_date.year, end_date.month, end_date.day) excel_template = pkg_resources.resource_filename("lizard_waterbalance", "/templates/lizard_waterbalance/excel_export_template.xls") rb = xlrd.open_workbook(excel_template, on_demand=True) wb = copy(rb) logger.debug("%s seconds - opened excel template", time.time() - t1) input_ts = waterbalance_computer.get_input_timeseries(start_date, end_date) buckets_summary = waterbalance_computer.get_bucketflow_summary(start_date, end_date) #bakjes export if bucket_export: if u'bakjes' in rb.sheet_names(): sheet = wb.sheet_by_name(u'bakjes') else: sheet = wb.add_sheet('bakje') buckets = waterbalance_computer.get_buckets_timeseries(start_date, end_date) #TO DO: afmaken sheet = wb.get_sheet(0) #tests buckets_summary = waterbalance_computer.get_bucketflow_summary(start_date, end_date) vertical_openwater = waterbalance_computer.get_vertical_open_water_timeseries(start_date, end_date) level_control = waterbalance_computer.get_level_control_timeseries(start_date, end_date) fractions = waterbalance_computer.get_fraction_timeseries(start_date, end_date) sluice_error = waterbalance_computer.calc_sluice_error_timeseries(start_date, end_date) chloride_concentration, delta_concentration = waterbalance_computer.get_concentration_timeseries(start_date, end_date) impact_minimum, impact_incremental = waterbalance_computer.get_impact_timeseries(start_date, end_date) logger.debug("%s seconds - got all values", time.time() - t1) #combine cols of table header = ['year', 'month', 'day'] data_cols = {} data_cols[(2, 'neerslag', '[mm/dag]')] = input_ts['precipitation'] data_cols[(3, 'verdamping', '[mm/dag]')] = input_ts['evaporation'] data_cols[(5, 'min peil', '[mNAP]')] = configuration.open_water.minimum_level.get_timeseries() data_cols[(7, 'neerslag', '[mNAP]')] = configuration.open_water.maximum_level.get_timeseries() # try: # data_cols[(6, 'streefpeil', '[mNAP]')] = configuration.open_water.target_level.get_timeseries() # except: # pass #in data_cols[(9, 'neerslag', '[m3/dag]')] = vertical_openwater['precipitation'] data_cols[(10, 'verdamping', '[m3/dag]')] = vertical_openwater['seepage'] data_cols[(11, 'verhard', '[m3/dag]')] = buckets_summary.hardened data_cols[(12, 'riolering', '[m3/dag]')] = buckets_summary.sewer data_cols[(13, 'gedraineerd', '[m3/dag]')] = buckets_summary.drained data_cols[(14, 'uitspoelig', '[m3/dag]')] = buckets_summary.undrained data_cols[(15, 'afstroming', '[m3/dag]')] = buckets_summary.flow_off col = 16 for intake, timeserie in input_ts['incoming_timeseries'].items(): data_cols[(col, str(intake), '[m3/dag]')] = timeserie col = col + 1 data_cols[(20, 'inlaat peilhandhaving', '[m3/dag]')] = level_control["intake_wl_control"] #uit data_cols[(22, 'verdamping', '[m3/dag]')] = vertical_openwater['evaporation'] data_cols[(23, 'wegzijiging', '[m3/dag]')] = vertical_openwater['infiltration'] data_cols[(24, 'intrek', '[m3/dag]')] = buckets_summary.indraft data_cols[(29, 'uitlaat', '[m3/dag]')] = level_control["outtake_wl_control"] #totaal data_cols[(32, 'totaal in', '[m3/dag]')] = level_control['total_incoming'] data_cols[(33, 'totaal uit', '[m3/dag]')] = level_control['total_outgoing'] data_cols[(35, 'berekend waterpeil', '[mNAP]')] = level_control['water_level'] data_cols[(36, 'berekende berging', '[m3]')] = level_control['storage'] data_cols[(50, 'verschil chloride', '[g]')] = delta_concentration data_cols[(51, 'chloride concentratie', '[mg/l]')] = chloride_concentration #fracties data_cols[(68, 'fractie initieel', '[-]')] = fractions['initial'] data_cols[(69, 'fractie neerslag', '[-]')] = fractions['precipitation'] data_cols[(70, 'fractie kwel', '[-]')] = fractions['seepage'] data_cols[(71, 'fractie verhard', '[-]')] = fractions['hardened'] data_cols[(72, 'fractie riolering', '[-]')] = fractions['sewer'] data_cols[(73, 'fractie gedraineerd', '[-]')] = fractions['drained'] data_cols[(74, 'fractie uitspoeling', '[-]')] = fractions['undrained'] data_cols[(75, 'fractie uitstroom', '[-]')] = fractions['flow_off'] colnr = 76 for key, item in fractions['intakes'].items(): data_cols[(colnr, 'fractie %s'%str(key), '[-]')] = item colnr = colnr + 1 data_cols[(108, 'sluitfout', '[m3/dag]')] = sluice_error colnr = 135 for key, item in impact_minimum.items(): data_cols[(colnr, 'min fosfaatb %s'%str(key), '[mg/m2/dag]' )] = item colnr = colnr + 1 colnr = colnr + 1 for key, item in impact_incremental.items(): data_cols[(colnr, 'incr fosfaatb %s'%str(key), '[mg/m2/dag]')] = item colnr = colnr + 1 start_row = 13 row = start_row excel_date_fmt = 'D/M/YY' style = xlwt.XFStyle() style.num_format_str = excel_date_fmt logger.debug("%s seconds - referenced all values", time.time() - t1) sheet.write(10,0,'datum') for key in data_cols.keys(): sheet.write(10,key[0],key[1]) sheet.write(11,key[0],key[2]) for event_dict in enumerate_dict_events(data_cols): date = event_dict['date'] sheet.write(row,0,date, style) for key, event in event_dict.items(): if not key == 'date': sheet.write(row,key[0],event[1]) row = row + 1 if date > end_date: break #for max: Formula('MAX(A1:B1)') buffer = StringIO() wb.save(buffer) del wb logger.debug("%s seconds - saved excel file to memory", time.time() - t1) buffer.seek(0) response = HttpResponse(buffer.read(), mimetype='xls') today = datetime.now() response['Content-Disposition'] = \ 'attachment; filename=wb_export_%s_%s_%i-%i-%i.xls'% \ (configuration.waterbalance_area.slug[:25], configuration.waterbalance_scenario.slug[:20], today.day, today.month, today.year) return response
def compute(self, open_water, buckets_summary, precipitation_timeseries, seepage_timeseries, storage_timeseries, total_output_timeseries, intakes_timeseries, start_date, end_date): """Compute and return the fraction series. This function returns the pair of SparseTimeseriesStub(s) that consists of the intake time series and pump time series for the given open water. Parameters: * open_water -- OpenWater for which to compute the fractions * buckets_summary -- BucketsSummary with the summed buckets outcome * precipitation, * seepage, * storage_timeseries -- storage time series in [m3/day] * intakes_timeseries -- list of intake timeseries in [m3/day] """ fractions_initial = SparseTimeseriesStub() fractions_precipitation = SparseTimeseriesStub() fractions_seepage = SparseTimeseriesStub() fractions_hardened = SparseTimeseriesStub() fractions_sewer = SparseTimeseriesStub() fractions_drained = SparseTimeseriesStub() fractions_undrained = SparseTimeseriesStub() fractions_flow_off = SparseTimeseriesStub() fractions_intakes = {} for key in intakes_timeseries.keys(): fractions_intakes[key] = SparseTimeseriesStub() previous_initial = 100.0 previous_precipitation = 0.0 previous_seepage = 0.0 previous_hardened = 0.0 previous_sewer = 0.0 previous_drained = 0.0 previous_undrained = 0.0 previous_flow_off = 0.0 previous_intakes = {} for key in intakes_timeseries.keys(): previous_intakes[key] = 0.0 previous_storage = self.initial_storage(open_water) ts = {} ts['hardened'] = buckets_summary.hardened ts['drained'] = buckets_summary.drained ts['undrained'] = buckets_summary.undrained ts['flow_off'] = buckets_summary.flow_off ts['precipitation'] = precipitation_timeseries ts['seepage'] = seepage_timeseries ts['sewer'] = buckets_summary.sewer ts['storage'] = storage_timeseries ts['total_output'] = total_output_timeseries ts['intakes'] = intakes_timeseries first = True for events in enumerate_dict_events(ts): date = events['date'] if date < start_date: continue if date >= end_date: break if first: first = False previous_storage = (open_water.init_water_level - open_water.bottom_height) * open_water.surface total_output = -1 * events['total_output'][1] current_storage = events['storage'][1] initial = self.compute_fraction(0, total_output, current_storage, previous_initial, previous_storage) precipitation = self.compute_fraction(events['precipitation'][1], total_output, current_storage, previous_precipitation, previous_storage) seepage = self.compute_fraction(events['seepage'][1], total_output, current_storage, previous_seepage, previous_storage) hardened = self.compute_fraction(events['hardened'][1], total_output, current_storage, previous_hardened, previous_storage) sewer = self.compute_fraction(events['sewer'][1], total_output, current_storage, previous_sewer, previous_storage) drained = self.compute_fraction(events['drained'][1], total_output, current_storage, previous_drained, previous_storage) undrained = self.compute_fraction(events['undrained'][1], total_output, current_storage, previous_undrained, previous_storage) flow_off = self.compute_fraction(events['flow_off'][1], total_output, current_storage, previous_flow_off, previous_storage) intakes = {} for key, intake_timeserie in events['intakes'].items(): intakes[key] = self.compute_fraction(intake_timeserie[1], total_output, current_storage, previous_intakes[key], previous_storage) # Due to rounding errors, the sum of the fractions is seldom equal # to 1.0. As the fraction of the next day depends on the fraction # of the previous day, this effect gets worse over time. To avoid # this effect, we divide each fraction by the sum of fractions. total_fractions = initial + precipitation + seepage + sewer + hardened + \ drained + undrained + flow_off + sum(intakes.values()) #TO DO: dit is een correctie die niet mogelijk hoeft te zijn. graag een alert als dit niet klopt #initial /= total_fractions #precipitation /= total_fractions #seepage /= total_fractions #hardened /= total_fractions #drained /= total_fractions #undrained /= total_fractions #flow_off /= total_fractions #intakes = [intake / total_fractions for intake in intakes] fractions_initial.add_value(date, initial) previous_initial = initial fractions_precipitation.add_value(date, precipitation) previous_precipitation = precipitation fractions_seepage.add_value(date, seepage) previous_seepage = seepage fractions_hardened.add_value(date, hardened) previous_hardened = hardened fractions_sewer.add_value(date, sewer) previous_sewer = sewer fractions_drained.add_value(date, drained) previous_drained = drained fractions_undrained.add_value(date, undrained) previous_undrained = undrained fractions_flow_off.add_value(date, flow_off) previous_flow_off = flow_off previous_intakes = {} for key in intakes.keys(): fractions_intakes[key].add_value(date, intakes[key]) previous_intakes[key] = intakes[key] previous_storage = current_storage result = {'initial':fractions_initial, 'precipitation':fractions_precipitation, 'seepage':fractions_seepage, 'hardened':fractions_hardened, 'drained':fractions_drained, 'sewer':fractions_sewer, 'undrained':fractions_undrained, 'flow_off':fractions_flow_off, 'intakes': {} } for key in intakes_timeseries.keys(): result['intakes'][key] = fractions_intakes[key] return result