def review(): """ review input data before running optimizer TODO: create links for editing data """ prev_page = 'parameter_input' username = auth.current_user.get_id() current_project = auth.current_user.get_project() if current_project is None: abort(400, 'No project selected') ### first pull data from db ### input_size = db.getInputSize(username, current_project) populations = db.getPopulations(username, current_project) plants = db.getPlants(username, current_project) tech_choices = db.getSelectedTechnologies(username, current_project) techs = db.getTechnologies(username, current_project) params = db.getParams(username, current_project) # create markers for the map population_markers = mapmaker.createPopulationsGeoJson(populations) plant_markers = mapmaker.createLocationsGeoJson(plants) if request.method == 'GET': return(render_template('review.html', nPop = input_size['numpops'], nPlant = input_size['numplants'], lifeSpan = input_size['durations'], populations = populations, plants = plants, techs = techs, params = params, tech_choices = tech_choices, population_markers = population_markers, plant_markers = plant_markers, MAPBOX_KEY = config['MAPBOX_KEY'], prev_page = prev_page, Identity = username, project_name = current_project))
def output(): username = auth.current_user.get_id() if request.args.get('project_name') is None: abort(400, 'project name not provided') current_project = request.args.get('project_name') # first pull output data values = output_scripts.output_values(username, project_name = None) solution_details = output_scripts.output_solutions(username, project_name = None) # map data of population clusters for all solutions populations = db.getPopulations(username, current_project) population_markers = mapmaker.createPopulationsGeoJson(populations) # population markers for MapBox # map data of locations for all solutions (markers) plants = db.getPlants(username, current_project) location_markers_allSols = mapmaker.createLocationsSolutionsGeoJson(plants, solution_details) # map data of LineString connecting locations and population clusters for all solutions plants_pop_linestring = mapmaker.createLocationClusterLinestringGeoJson(plants, populations, solution_details) return(render_template('output.html', valuesData = values, solutionDetails = solution_details, population_markers = population_markers, location_markers_allSols = location_markers_allSols, plants_pop_linestring = plants_pop_linestring, MAPBOX_KEY = config['MAPBOX_KEY'], Identity = username, project_name = current_project))
def output(): if 'projectID' not in request.args: abort(400, 'projectID not provided') projectID = request.args.get('projectID') # first pull output data solution_values, solution_details = output_scripts.get_output(projectID) # map data of population clusters for all solutions populations = db.getPopulations(projectID) population_markers = mapmaker.createPopulationsGeoJson( populations) # population markers for MapBox # map data of locations for all solutions (markers) plants = db.getPlants(projectID) location_markers_allSols = mapmaker.createLocationsSolutionsGeoJson( plants, solution_details) # map data of LineString connecting locations and population clusters for all solutions plants_pop_linestring = mapmaker.createLocationClusterLinestringGeoJson( plants, populations, solution_details) return (render_template('output.html', valuesData=solution_values, solutionDetails=solution_details, population_markers=population_markers, location_markers_allSols=location_markers_allSols, plants_pop_linestring=plants_pop_linestring, MAPBOX_KEY=config['MAPBOX_KEY'], projectID=projectID))
def population_input(): """ render webpage to ask for population input, save data to global populations (class PopulationsForm) then redirect to plant_input """ next_page = 'tech_input' prev_page = 'input_size' username = auth.current_user.get_id() current_project = auth.current_user.get_project() if current_project is None: abort(400, 'No project selected') populations = PopulationsForm() # process GET requests if request.method == 'GET': # If numpops exist, create the form with numpops rows existing_data = db.getInputSize(username, current_project) if existing_data['numpops'] is not None and existing_data['numpops'] > 0: numpops = existing_data['numpops'] for i in range(numpops): populations.rows.append_entry({'r': i+1}) else: # throw error abort(400, 'Number of populations not given') # Find existing data in the populations table existing_data = db.getPopulations(username, current_project) # give me all columns from populations table as list of tuples, remember to rename columns to match class OnePopulation. if data not exist, an empty list []} # fill in existing data to populations form if existing_data is not None: for i in range(min(len(existing_data), numpops)): populations.rows[i].Name.data = existing_data[i]['name'] populations.rows[i].Pr.data = existing_data[i]['pr'] populations.rows[i].GrowthRate.data = existing_data[i]['growthrate'] populations.rows[i].lat.data = existing_data[i]['lat'] populations.rows[i].lon.data = existing_data[i]['lon'] return(render_template('population_input.html', populations = populations, prev_page = prev_page, Identity = username)) # process POST requests if request.method == 'POST': if request.form['command'] == 'Next': # process saving data command if populations.validate(): # if validation pass, save data to DB and redirect to next page db.savePopulations(populations, username, current_project) APP.logger.info('populations validation passed! user %s, project %s', username, current_project) return(redirect(url_for(next_page))) else: # if validation fails, print out errors to web page APP.logger.info('validation for population_input failed! user %s, project %s. Errors: %s', username, current_project, str(populations.errors)) return(render_template('population_input.html', populations = populations, prev_page = prev_page, Identity = username)) elif request.form['command'] == 'Insert Data': # process parsing data command (lazy method for inputing data) numpops = db.getInputSize(username, current_project)['numpops'] for i in range(numpops): populations.rows.append_entry({'r': i+1}) populations = Parse.fill_populations(request.form['ExcelData'], populations) APP.logger.info('Lazy data parsed in populations form! user %s, project %s', username, current_project) return(render_template('population_input.html', populations = populations, prev_page = prev_page, Identity = username)) else: abort(400, 'Unknown request')
def review(): """ review input data before running optimizer TODO: create links for editing data """ prev_page = 'parameter_input' if 'projectID' not in request.args: abort(400, 'projectID not provided') projectID = request.args.get('projectID') ### step0: check if input is completed for this project, if not then abort ### project_status = db.getProject(projectID) print(project_status) if project_status['status'] == 'input uncompleted, not yet optimized': abort(400, 'input data not completed') ### first pull data from db ### input_size = db.getInputSize(projectID) populations = db.getPopulations(projectID) plants = db.getPlants(projectID) tech_choices = db.getSelectedTechnologies(projectID) techs = db.getTechnologies(projectID) params = db.getParams(projectID) # create markers for the map population_markers = mapmaker.createPopulationsGeoJson(populations) plant_markers = mapmaker.createLocationsGeoJson(plants) if request.method == 'GET': return (render_template('review.html', nPop=input_size['numpops'], nPlant=input_size['numplants'], lifeSpan=input_size['durations'], populations=populations, plants=plants, techs=techs, params=params, tech_choices=tech_choices, population_markers=population_markers, plant_markers=plant_markers, MAPBOX_KEY=config['MAPBOX_KEY'], prev_page=prev_page, projectID=projectID))
def get_output(projectID): """ read output values (ZE,ZC) from optimizer's output in the db""" output1_raw, output2_raw = db.get_optimizer_output(projectID) output1_return = [] for row in output2_raw: output1_return.append([row['solution_label'], row['zc'], row['ze']]) # get list of unique solutions solution_list = [] for row in output1_raw: if row['solution_label'] not in solution_list: solution_list.append(row['solution_label']) # get list of locations from db location_list = db.getPlants(projectID) # get list of techs from db tech_list = db.getTechnologies(projectID) # get population clusters and parameters from db populations = db.getPopulations(projectID) params = db.getParams(projectID) # we need to calculate populations at the end of project (for capacity calculation) lifespan = db.getInputSize(projectID)['durations'] for p in populations: p['end_pr'] = p['pr'] * (1 + p['growthrate'])**lifespan # format output2 output2_return = [] for SolutionID in solution_list: for location in location_list: # find tech index selected for this solution in output1_raw tech_index = [ r['t'] for r in output1_raw if r['var'] == 'w' and r['k'] == location['index'] and r['solution_label'] == SolutionID ] if len(tech_index) > 0: tech_index = tech_index[0] tech_name = [ r['technologyname'] for r in tech_list if r['index'] == tech_index ][0] tech_scale = [ r['scale'] for r in tech_list if r['index'] == tech_index ][0] else: tech_name = 'Not Installed' tech_scale = 'Not Installed' # find servicing clusters for this solution and location in output1_raw clus_index = [ str(r['r']) for r in output1_raw if r['var'] == 'q' and r['k'] == location['index'] and r['solution_label'] == SolutionID ] if len(clus_index) > 0: cluster_str = ', '.join(clus_index) else: cluster_str = '' # calculate capacities if len(clus_index) == 0: receiving_cap_m3y = 0 receiving_cap_mgd = 0 sending_cap_m3y = 0 sending_cap_mgd = 0 else: total_population = sum([ p['end_pr'] for p in populations if str(p['index']) in clus_index ]) mu = [p['value'] for p in params if p['label'] == 'mu'][0] alpha = [p['value'] for p in params if p['label'] == 'alpha'][0] receiving_cap_m3y = round(total_population * mu, 2) receiving_cap_mgd = round(receiving_cap_m3y / 365 / 3785.41178, 2) sending_cap_m3y = round(alpha * receiving_cap_m3y, 2) sending_cap_mgd = round(alpha * receiving_cap_mgd, 2) # append to output2_return output2_return.append([ str(SolutionID), str(location['index']), location['locationname'], tech_name, tech_scale, cluster_str, receiving_cap_m3y, sending_cap_m3y, receiving_cap_mgd, sending_cap_mgd ]) return (output1_return, output2_return)
def write_input_to_tsv(username, project_name, directory, filename): """ write input data to tab-separated file. this file will be read by the optimizer. data are previously saved under a username and project_name """ # make directory if not os.path.exists(directory): os.makedirs(directory) # delete file if exists filename = directory + '/' + filename if os.path.exists(filename): os.remove(filename) # pull data from db populations = db.getPopulations(username, project_name) plants = db.getPlants(username, project_name) techs = db.getTechnologies(username, project_name) params = db.getParams(username, project_name) duration = db.getInputSize(username, project_name)['durations'] # create file and start writing with open(filename, 'w') as file: # first line: file.write( str(len(populations)) + '\t' + # no. of pop clusters str(len(plants)) + '\t' + # no. of locations str(len(techs)) # no. of techs ) file.write('\n') # second line: parameters and duration value_array = [str(r['value']) for r in params] file.write('\t'.join(value_array)) file.write('\t' + str(duration)) file.write('\n') # third line: population number for all clusters, projected at the end of duration value_array = [ str(r['pr'] * (1 + r['growthrate'])**duration) for r in populations ] file.write('\t'.join(value_array)) file.write('\n') # -- line 4-8: tech table-- # line 4: Capkt of all techs value_array = [str(r['capkt']) for r in techs] file.write('\t'.join(value_array)) file.write('\n') # line 5: CCkt of all techs value_array = [str(r['cckt']) for r in techs] file.write('\t'.join(value_array)) file.write('\n') # line 6: OCt of all techs value_array = [str(r['oct']) for r in techs] file.write('\t'.join(value_array)) file.write('\n') # line 7: SRwt of all techs value_array = [str(r['srwt']) for r in techs] file.write('\t'.join(value_array)) file.write('\n') # line 8: GPt of all techs value_array = [str(r['gpt']) for r in techs] file.write('\t'.join(value_array)) file.write('\n') # line 9 and on: distance table distance_matrix = distance_pop_plant(populations, plants) value_array_each_row = [] for row in distance_matrix: value_array_each_row.append('\t'.join( [str(value) for value in row])) value_array = '\n'.join(value_array_each_row) file.write(value_array)
def write_input_to_tsv(projectID, directory, filename): """ write input data to tab-separated file. this file will be read by the optimizer. data are previously saved under a username and project_name """ # delete file if exists filename = directory + '/' + filename if os.path.exists(filename): os.remove(filename) # pull data from db populations = db.getPopulations(projectID) plants = db.getPlants(projectID) techs = db.getTechnologies(projectID) params = db.getParams(projectID) duration = db.getInputSize(projectID)['durations'] # determine the max number of column (later we will pad all rows with \t to reach this number of columns) n_col_tsv = max( 3, # number of cols in first row 8, # second row len(populations), len(techs), # row 4-8 len(plants) # row 9 and after ) # create file and start writing with open(filename, 'w') as file: # first line: file.write( str(len(populations)) + '\t' + # no. of pop clusters str(len(plants)) + '\t' + # no. of locations str(len(techs)) + # no. of techs (n_col_tsv - 3) * '\t' # padding with tabs ) file.write('\n') # second line: parameters and duration value_array = [str(r['value']) for r in params] value_array.append(str(duration)) file.write('\t'.join(value_array)) file.write((n_col_tsv - len(value_array)) * '\t') file.write('\n') # third line: population number for all clusters, projected at the end of duration value_array = [ str(r['pr'] * (1 + r['growthrate'])**duration) for r in populations ] file.write('\t'.join(value_array)) file.write((n_col_tsv - len(value_array)) * '\t') file.write('\n') # -- line 4-8: tech table-- # line 4: Capkt of all techs value_array = [str(r['capkt']) for r in techs] file.write('\t'.join(value_array)) file.write((n_col_tsv - len(value_array)) * '\t') file.write('\n') # line 5: CCkt of all techs value_array = [str(r['cckt']) for r in techs] file.write('\t'.join(value_array)) file.write((n_col_tsv - len(value_array)) * '\t') file.write('\n') # line 6: OCt of all techs value_array = [str(r['oct']) for r in techs] file.write('\t'.join(value_array)) file.write((n_col_tsv - len(value_array)) * '\t') file.write('\n') # line 7: SRwt of all techs value_array = [str(r['srwt']) for r in techs] file.write('\t'.join(value_array)) file.write((n_col_tsv - len(value_array)) * '\t') file.write('\n') # line 8: GPt of all techs value_array = [str(r['gpt']) for r in techs] file.write('\t'.join(value_array)) file.write((n_col_tsv - len(value_array)) * '\t') file.write('\n') # line 9 and on: distance table distance_matrix = distance_pop_plant(populations, plants) value_array_each_row = [] for row in distance_matrix: value_array = [str(value) for value in row] value_array_each_row.append('\t'.join(value_array) + (n_col_tsv - len(value_array)) * '\t') value_array_all = '\n'.join(value_array_each_row) file.write(value_array_all)
def population_input(): """ render webpage to ask for population input, save data to global populations (class PopulationsForm) then redirect to plant_input """ if 'projectID' not in request.args: abort(400, 'projectID not provided') projectID = request.args.get('projectID') next_page = 'tech_input' prev_page = 'input_size' populations = PopulationsForm() # process GET requests if request.method == 'GET': # If numpops exist, create the form with numpops rows existing_data = db.getInputSize(projectID) if existing_data[ 'numpops'] is not None and existing_data['numpops'] > 0: numpops = existing_data['numpops'] for i in range(numpops): populations.rows.append_entry({'r': i + 1}) else: # throw error abort(400, 'Number of populations not given') # Find existing data in the populations table existing_data = db.getPopulations(projectID) # fill in existing data to populations form if existing_data is not None: for i in range(min(len(existing_data), numpops)): populations.rows[i].Name.data = existing_data[i]['name'] populations.rows[i].Pr.data = existing_data[i]['pr'] populations.rows[ i].GrowthRate.data = existing_data[i]['growthrate'] * 100 populations.rows[i].lat.data = existing_data[i]['lat'] populations.rows[i].lon.data = existing_data[i]['lon'] return (render_template('population_input.html', populations=populations, prev_page=prev_page, projectID=projectID, MAPBOX_KEY=config['MAPBOX_KEY'])) # process POST requests if request.method == 'POST': if request.form['command'] == 'Save and Continue': # process saving data command if populations.validate(): # if validation pass, save data to DB and redirect to next page # first scale down growthrate by 100 for i in range(populations.rows.__len__()): populations.rows[i].GrowthRate.data = populations.rows[ i].GrowthRate.data / 100 db.savePopulations(populations, projectID) APP.logger.info('populations validation passed! project %s', projectID) return (redirect(url_for(next_page, projectID=projectID))) else: # if validation fails, print out errors to web page APP.logger.info( 'validation for population_input failed! project %s. Errors: %s', projectID, str(populations.errors)) return (render_template('population_input.html', populations=populations, prev_page=prev_page, projectID=projectID, MAPBOX_KEY=config['MAPBOX_KEY'])) elif request.form['command'] == 'Insert Data': # process parsing data command (lazy method for inputing data) numpops = db.getInputSize(projectID)['numpops'] for i in range(numpops): populations.rows.append_entry({'r': i + 1}) populations = Parse.fill_populations(request.form['ExcelData'], populations) APP.logger.info('Lazy data parsed in populations form! project %s', projectID) return (render_template('population_input.html', populations=populations, prev_page=prev_page, projectID=projectID, MAPBOX_KEY=config['MAPBOX_KEY'])) else: abort(400, 'Unknown request')