Git Product home page Git Product logo

pemfc-dash-app's Introduction

PEMFC-Dash-App

Web-interface for the PEMFC-Model core module (github.com/zbt-tools/pemfc-core)

127 0 0 1_8050_ (3)

Local installation using Anaconda

Prerequisites: git, Anaconda (anaconda.org)

  • Clone this repository
  • Navigate into your local directory of this repo with Anaconda prompt
  • Create new conda environment via:
    conda env create
  • Activate conda environment:
    conda activate dash_app
  • Run:
    python app.py
  • Open browser and paste specified local url

Local installation using pip

Prerequisites: git, Python (>=3.9.7), pip

  • Clone this repository
  • Navigate into your local directory of this repo with console
  • Install dependencies via pip:
    • Windows:
      pip install -r requirements\requirements.txt
    • Linux:
      pip install -r requirements/requirements.txt
  • Run:
    python app.py
  • Open browser and paste specified local url

Create web-host with gunicorn in docker container

Prerequisites: docker

  • Clone (git required) or download this repository
  • Navigate into your local directory of this repo with console
  • Create docker container:
    docker build --tag pemfc-dash-app .
  • Run docker container:
    docker run --rm -p 9090:8080 -e PORT=8080 pemfc-dash-app
  • Open browser and paste specified local url

Specific hosting on Ubuntu with uWSGI

Prerequisites: Ubuntu, git

  • follow instructions in ubuntu_specific/Manual.md

pemfc-dash-app's People

Contributors

lufire avatar fkuschel avatar kamalizzo avatar

Stargazers

Lars Prein avatar  avatar

Watchers

 avatar

pemfc-dash-app's Issues

Automatically maximize div height according to container height

style={
'text-align': 'center',
'height': 'auto', 'min-height': '100% !important',
}),# , 'overflow': 'hidden'}),
width={'size': 4}, align='center'),

I can't figure out the correct settings to maximize the div container (of "pretty_container" css class) containing the logo image to maximize it's height according to its containers and set it equal to the right column containing the title. Using an exact width property works, but it should be possible to automatically size the heights equally, i assume

Update user experience during initialization callback

The GUI is loaded.
After some seconds the initialization callback returns updated values for the input fields.
Quickfix could be: Loading spinner above Settings until updates are loaded.
Real fix: Use correct settings directly.

Relocate Spinner

Place Spinner Row in Settings Column between "UI-Curve" and "Sensitivity Study"

Call "results.apply(..)" throws error

Steps to reproduce:

  1. Start dash app
  2. Default settings
  3. Parameter Study:
  • Parameter: "anode-bpp-electrical_conductivity"
  • Variation Type: "Percent (+/-)"
  • Values: "1"

Error message:
"TypeError: float() argument must be a string or a real number, not 'list'"

Results itself seem to be converged when inspecting "results"-DataFrame in debug mode.

The following call produces the error:

results["set_name"] = \
results.apply(lambda row: ', '.join(f"{varpar}: " +
str(float(row[varpar])) for varpar in
row['variation_parameter']),
axis=1)

Optionally, to locate the call throwing the error remove the try-except-block from:

try:
# Calculation of polarization curve for each dataset
if isinstance(check_calc_ui, list):
if "calc_ui" in check_calc_ui:
ui_calculation = True
else:
ui_calculation = False
else:
ui_calculation = False
# Number of refinement steps for ui calculation
n_refinements = 10
mode = check_study_type
# Progress bar init
std_err_backup = sys.stderr
file_prog = open('progress.txt', 'w')
sys.stderr = file_prog
# Read pemfc settings.json from store
settings = dc.read_data(settings)
# Read data from input fields and save input in dict (legacy)
# / pd.DataDrame (one row with index "nominal")
df_input = dc.process_inputs(
inputs, inputs2, ids, ids2, returntype="DataFrame")
df_input_backup = df_input.copy()
# Create multiple parameter sets
if variation_mode == "dash_table":
data = sf.variation_parameter(
df_input, keep_nominal=False, mode=mode, table_input=tabledata)
else:
data = sf.variation_parameter(
df_input, keep_nominal=False, mode=mode, table_input=None)
if not ui_calculation:
# Create complete setting dict & append it in additional column
# "settings" to df_input
data = dc.create_settings(
data, settings, input_cols=df_input.columns)
# Run Simulation
results, success, err_modal, err_msg = sim.run_simulation(data)
# Add parameter set name(s)
results["set_name"] = \
results.apply(lambda row: ', '.join(f"{varpar}: " +
str(float(row[varpar])) for varpar in
row['variation_parameter']),
axis=1)
else: # ... calculate pol. curve for each parameter set
results = pd.DataFrame(columns=data.columns)
for i in range(0, len(data)):
try:
# Ensure DataFrame with double bracket
# https://stackoverflow.com/questions/20383647/pandas-selecting-by-label-sometimes-return-series-sometimes-returns-dataframe
# df_input_single = df_input.loc[[:], :]
max_i = sf.find_max_current_density(
data.iloc[[i]], df_input, settings)
# # Reset solver settings
# df_input = df_input_backup.copy()
success = False
# Prepare & calculate initial points
df_results = sf.uicalc_prepare_initcalc(
input_df=data.iloc[[i]], i_limits=[1, max_i],
settings=settings, input_cols=df_input.columns)
df_results, success, _, _ = sim.run_simulation(df_results)
if not success:
continue
# First refinement steps
for _ in range(n_refinements):
df_refine = sf.uicalc_prepare_refinement(
input_df=df_input, data_df=df_results,
settings=settings)
df_refine, success, _, _ = sim.run_simulation(
df_refine, return_unsuccessful=False)
df_results = pd.concat(
[df_results, df_refine], ignore_index=True)
results = pd.concat([results, df_results],
ignore_index=True)
except Exception as E:
err_modal = "generic-study-error"
pass
# Add parameter set name(s)
results["set_name"] = \
results.apply(lambda row: ', '.join(f"{varpar}: " +
str(float(row[varpar])) for
varpar in
row['variation_parameter']) +
", Current Density: " +
str(round(float(
row['simulation-current_density']),
1)) + " A/m²",
axis=1)
results = dc.store_data(results)
df_input_store = dc.store_data(df_input_backup)
file_prog.close()
sys.stderr = std_err_backup
except Exception as E:
modal_state = not modal_state
modal_title, modal_body = \
mf.modal_process("generic-study-error", error=repr(E))
# Save modal input in a dict
modal_input = {'modal_title': modal_title,
'modal_body': modal_body,
'modal_state': modal_state}
return None, None, "", modal_input

df_result_data_store on server side

Right now df_result_data_store is cached in a normal dcc.Store element, meaning in the clients browser. To cache it on the server I introduced the ServersideOutput Store element for the previous result_data_store. Right now I think it makes sense to also save the df_result_data_store in a ServersideOutput class to allow for redis storage. What do you think?

try-except-block is too long. should be more fine-grained

try:
# Calculation of polarization curve for each dataset
if isinstance(check_calc_ui, list):
if "calc_ui" in check_calc_ui:
ui_calculation = True
else:
ui_calculation = False
else:
ui_calculation = False
# Number of refinement steps for ui calculation
n_refinements = 10
mode = check_study_type
# Progress bar init
std_err_backup = sys.stderr
file_prog = open('progress.txt', 'w')
sys.stderr = file_prog
# Read pemfc settings.json from store
settings = dc.read_data(settings)
# Read data from input fields and save input in dict (legacy)
# / pd.DataDrame (one row with index "nominal")
df_input = dc.process_inputs(
inputs, inputs2, ids, ids2, returntype="DataFrame")
df_input_backup = df_input.copy()
# Create multiple parameter sets
if variation_mode == "dash_table":
data = sf.variation_parameter(
df_input, keep_nominal=False, mode=mode, table_input=tabledata)
else:
data = sf.variation_parameter(
df_input, keep_nominal=False, mode=mode, table_input=None)
if not ui_calculation:
# Create complete setting dict & append it in additional column
# "settings" to df_input
data = dc.create_settings(
data, settings, input_cols=df_input.columns)
# Run Simulation
results, success, err_modal, err_msg = sim.run_simulation(data)
# Add parameter set name(s)
results["set_name"] = \
results.apply(lambda row: ', '.join(f"{varpar}: " +
str(float(row[varpar])) for varpar in
row['variation_parameter']),
axis=1)
else: # ... calculate pol. curve for each parameter set
results = pd.DataFrame(columns=data.columns)
for i in range(0, len(data)):
try:
# Ensure DataFrame with double bracket
# https://stackoverflow.com/questions/20383647/pandas-selecting-by-label-sometimes-return-series-sometimes-returns-dataframe
# df_input_single = df_input.loc[[:], :]
max_i = sf.find_max_current_density(
data.iloc[[i]], df_input, settings)
# # Reset solver settings
# df_input = df_input_backup.copy()
success = False
# Prepare & calculate initial points
df_results = sf.uicalc_prepare_initcalc(
input_df=data.iloc[[i]], i_limits=[1, max_i],
settings=settings, input_cols=df_input.columns)
df_results, success, _, _ = sim.run_simulation(df_results)
if not success:
continue
# First refinement steps
for _ in range(n_refinements):
df_refine = sf.uicalc_prepare_refinement(
input_df=df_input, data_df=df_results,
settings=settings)
df_refine, success, _, _ = sim.run_simulation(
df_refine, return_unsuccessful=False)
df_results = pd.concat(
[df_results, df_refine], ignore_index=True)
results = pd.concat([results, df_results],
ignore_index=True)
except Exception as E:
err_modal = "generic-study-error"
pass
# Add parameter set name(s)
results["set_name"] = \
results.apply(lambda row: ', '.join(f"{varpar}: " +
str(float(row[varpar])) for
varpar in
row['variation_parameter']) +
", Current Density: " +
str(round(float(
row['simulation-current_density']),
1)) + " A/m²",
axis=1)
results = dc.store_data(results)
df_input_store = dc.store_data(df_input_backup)
file_prog.close()
sys.stderr = std_err_backup
except Exception as E:
modal_state = not modal_state
modal_title, modal_body = \
mf.modal_process("generic-study-error", error=repr(E))
# Save modal input in a dict
modal_input = {'modal_title': modal_title,
'modal_body': modal_body,
'modal_state': modal_state}
return None, None, "", modal_input

Not all inputs are transferred to simulation

Example:
Multinputs under "Physical Properties"->

image

Debugging:

Inside first "Run Simulation" Button Callback:
dash_functions.process_inputs() collects values properly. Thats why also "save results" and "load results" works fine.
image

Inside next Callback "run_simulation()"
data_transfer.gui_to_sim_transfer(input_data, settings) creates settings-dict for calculation.
Default-values from local settings file are not overwritten.
image

I'm looking into it.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.