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))
Example #6
0
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)
Example #7
0
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)
Example #8
0
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')