pyfemtet 0.8.4__py3-none-any.whl → 0.8.7__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of pyfemtet might be problematic. Click here for more details.

@@ -2,6 +2,7 @@
2
2
  from dash.development.base_component import Component
3
3
 
4
4
  # application
5
+ from flask import Flask
5
6
  from dash import Dash
6
7
  import webbrowser
7
8
 
@@ -20,6 +21,7 @@ from pyfemtet.opt.visualization._wrapped_components import html, dcc, dbc
20
21
  from abc import ABC, abstractmethod
21
22
  import logging
22
23
  import psutil
24
+ import json
23
25
  from pyfemtet.logger import get_module_logger, get_dash_logger
24
26
 
25
27
  logger = get_module_logger('opt.monitor', __name__)
@@ -132,15 +134,19 @@ class SidebarApplicationBase:
132
134
  # define app
133
135
  self.title = title if title is not None else 'App'
134
136
  self.subtitle = subtitle if title is not None else ''
137
+ self.server = Flask(__name__)
135
138
  self.app = Dash(
136
139
  __name__,
137
140
  external_stylesheets=[dash_bootstrap_components.themes.BOOTSTRAP],
138
141
  title=title,
139
142
  update_title=None,
143
+ server=self.server,
140
144
  )
141
145
  self.pages = dict()
142
146
  self.nav_links = dict()
143
147
  self.page_objects = []
148
+ self.host = None
149
+ self.port = None
144
150
 
145
151
  def add_page(self, page: AbstractPage, order: int = None):
146
152
  page.set_application(self)
@@ -191,7 +197,7 @@ class SidebarApplicationBase:
191
197
  className="p-3 bg-light rounded-3",
192
198
  )
193
199
 
194
- def run(self, host='localhost', port=None, debug=False):
200
+ def run(self, host='localhost', port=None, debug=False, host_record=None):
195
201
  self._setup_layout()
196
202
  port = port or self.DEFAULT_PORT
197
203
  # port を検証
@@ -201,6 +207,11 @@ class SidebarApplicationBase:
201
207
  webbrowser.open(f'http://localhost:{str(port)}')
202
208
  else:
203
209
  webbrowser.open(f'http://{host}:{str(port)}')
210
+ self.host = host
211
+ self.port = port
212
+ if host_record is not None:
213
+ host_record.set(self.host, self.port)
214
+
204
215
  self.app.run(debug=debug, host=host, port=port)
205
216
 
206
217
 
@@ -138,18 +138,18 @@ class FemtetControl(AbstractPage):
138
138
 
139
139
  # check holding history
140
140
  if self.application.history is None:
141
- return kwargs, Msg.ERR_HISTORY_CSV_NOT_READ
141
+ return kwargs, Msg.WARN_HISTORY_CSV_NOT_READ
142
142
 
143
- # get metadata
144
- additional_metadata = self.application.history.metadata[0]
143
+ # get extra_data
144
+ extra_data = self.application.history.meta_columns[0]
145
145
 
146
- # check metadata exists
147
- if additional_metadata == '':
146
+ # check extra_data exists
147
+ if extra_data == '':
148
148
  return kwargs, Msg.WARN_INVALID_METADATA
149
149
 
150
- # check the metadata is valid json
150
+ # check the extra_data is valid json
151
151
  try:
152
- d = json.loads(additional_metadata)
152
+ d = json.loads(extra_data)
153
153
  femprj_path = os.path.abspath(d['femprj_path'])
154
154
  except (TypeError, json.decoder.JSONDecodeError, KeyError):
155
155
  return kwargs, Msg.WARN_INVALID_METADATA
@@ -447,17 +447,50 @@ class MainGraph(AbstractPage):
447
447
  Output(self.tooltip.id, "show"),
448
448
  Output(self.tooltip.id, "bbox"),
449
449
  Output(self.tooltip.id, "children"),
450
- Input(self.graph.id, "hoverData"),)
451
- def show_hover(hoverData):
450
+ Output(self.tooltip.id, "direction"),
451
+ Input(self.graph.id, "hoverData"),
452
+ State(self.graph.id, "figure"),
453
+ )
454
+ def show_hover(hoverData, figure):
452
455
  if hoverData is None:
453
- return False, no_update, no_update
456
+ return False, no_update, no_update, no_update
454
457
 
455
458
  if self.application.history is None:
456
459
  raise PreventUpdate
457
460
 
458
- # get hover location
461
+ # pt = {'curveNumber': 1, 'pointNumber': 0, 'pointIndex': 0, 'x': 1, 'y': 2369132.929996869, 'bbox': {'x0': 341.5, 'x1': 350.5, 'y0': 235, 'y1': 244}, 'customdata': [1]}
462
+ # bbox = {'x0': 341.5, 'x1': 350.5, 'y0': 235, 'y1': 244} # point の大きさ?
463
+ # figure = {'data': [{'customdata': [[1], [2], [3], [4], [5]], 'marker': {'color': '#6c757d', 'size': 6}, 'mode': 'markers', 'name': 'すべての解', 'x': [1, 2, 3, 4, 5], 'y': [2369132.929996866, 5797829.746579617, 1977631.590419346, 2083867.2403273676, 1539203.6452652698], 'type': 'scatter', 'hoverinfo': 'none'}, {'customdata': [[1], [3], [5]], 'legendgroup': 'optimal', 'line': {'color': '#6c757d', 'width': 1}, 'marker': {'color': '#007bff', 'size': 9}, 'mode': 'markers+lines', 'name': '最適解の推移', 'x': [1, 3, 5], 'y': [2369132.929996866, 1977631.590419346, 1539203.6452652698], 'type': 'scatter', 'hoverinfo': 'none'}, {'legendgroup': 'optimal', 'line': {'color': '#6c757d', 'dash': 'dash', 'width': 0.5}, 'mode': 'lines', 'showlegend': False, 'x': [5, 5], 'y': [1539203.6452652698, 1539203.6452652698], 'type': 'scatter', 'hoverinfo': 'none'}], 'layout': {'template': {'data': {'histogram2dcontour': [{'type': 'histogram2dcontour', 'colorbar': {'outlinewidth': 0, 'ticks': ''}, 'colorscale': [[0, '#0d0887'], [0.1111111111111111, '#46039f'], [0.2222222222222222, '#7201a8'], [0.3333333333333333, '#9c179e'], [0.4444444444444444, '#bd3786'], [0.5555555555555556, '#d8576b'], [0.6666666666666666, '#ed7953'], [0.7777777777777778, '#fb9f3a'], [0.8888888888888888, '#fdca26'], [1, '#f0f921']]}], 'choropleth': [{'type': 'choropleth', 'colorbar': {'outlinewidth': 0, 'ticks': ''}}], 'histogram2d': [{'type': 'histogram2d', 'colorbar': {'outlinewidth': 0, 'ticks': ''}, 'colorscale': [[0, '#0d0887'], [0.1111111111111111, '#46039f'], [0.2222222222222222, '#7201a8'], [0.3333333333333333, '#9c179e'], [0.4444444444444444, '#bd3786'], [0.5555555555555556, '#d8576b'], [0.6666666666666666, '#ed7953'], [0.7777777777777778, '#fb9f3a'], [0.8888888888888888, '#fdca26'], [1, '#f0f921']]}], 'heatmap': [{'type': 'heatmap', 'colorbar': {'outlinewidth': 0, 'ticks': ''}, 'colorscale': [[0, '#0d0887'], [0.1111111111111111, '#46039f'], [0.2222222222222222, '#7201a8'], [0.3333333333333333, '#9c179e'], [0.4444444444444444, '#bd3786'], [0.5555555555555556, '#d8576b'], [0.6666666666666666, '#ed7953'], [0.7777777777777778, '#fb9f3a'], [0.8888888888888888, '#fdca26'], [1, '#f0f921']]}], 'heatmapgl': [{'type': 'heatmapgl', 'colorbar': {'outlinewidth': 0, 'ticks': ''}, 'colorscale': [[0, '#0d0887'], [0.1111111111111111, '#46039f'], [0.2222222222222222, '#7201a8'], [0.3333333333333333, '#9c179e'], [0.4444444444444444, '#bd3786'], [0.5555555555555556, '#d8576b'], [0.6666666666666666, '#ed7953'], [0.7777777777777778, '#fb9f3a'], [0.8888888888888888, '#fdca26'], [1, '#f0f921']]}], 'contourcarpet': [{'type': 'contourcarpet', 'colorbar': {'outlinewidth': 0, 'ticks': ''}}], 'contour': [{'type': 'contour', 'colorbar': {'outlinewidth': 0, 'ticks': ''}, 'colorscale': [[0, '#0d0887'], [0.1111111111111111, '#46039f'], [0.2222222222222222, '#7201a8'], [0.3333333333333333, '#9c179e'], [0.4444444444444444, '#bd3786'], [0.5555555555555556, '#d8576b'], [0.6666666666666666, '#ed7953'], [0.7777777777777778, '#fb9f3a'], [0.8888888888888888, '#fdca26'], [1, '#f0f921']]}], 'surface': [{'type': 'surface', 'colorbar': {'outlinewidth': 0, 'ticks': ''}, 'colorscale': [[0, '#0d0887'], [0.1111111111111111, '#46039f'], [0.2222222222222222, '#7201a8'], [0.3333333333333333, '#9c179e'], [0.4444444444444444, '#bd3786'], [0.5555555555555556, '#d8576b'], [0.6666666666666666, '#ed7953'], [0.7777777777777778, '#fb9f3a'], [0.8888888888888888, '#fdca26'], [1, '#f0f921']]}], 'mesh3d': [{'type': 'mesh3d', 'colorbar': {'outlinewidth': 0, 'ticks': ''}}], 'scatter': [{'fillpattern': {'fillmode': 'overlay', 'size': 10, 'solidity': 0.2}, 'type': 'scatter'}], 'parcoords': [{'type': 'parcoords', 'line': {'colorbar': {'outlinewidth': 0, 'ticks': ''}}}], 'scatterpolargl': [{'type': 'scatterpolargl', 'marker': {'colorbar': {'outlinewidth': 0, 'ticks': ''}}}], 'bar': [{'error_x': {'color': '#2a3f5f'}, 'error_y': {'color': '#2a3f5f'}, 'marker': {'line': {'color': '#E5ECF6', 'width': 0.5}, 'pattern': {'fillmode': 'overlay', 'size': 10, 'solidity': 0.2}}, 'type': 'bar'}], 'scattergeo': [{'type': 'scattergeo', 'marker': {'colorbar': {'outlinewidth': 0, 'ticks': ''}}}], 'scatterpolar': [{'type': 'scatterpolar', 'marker': {'colorbar': {'outlinewidth': 0, 'ticks': ''}}}], 'histogram': [{'marker': {'pattern': {'fillmode': 'overlay', 'size': 10, 'solidity': 0.2}}, 'type': 'histogram'}], 'scattergl': [{'type': 'scattergl', 'marker': {'colorbar': {'outlinewidth': 0, 'ticks': ''}}}], 'scatter3d': [{'type': 'scatter3d', 'line': {'colorbar': {'outlinewidth': 0, 'ticks': ''}}, 'marker': {'colorbar': {'outlinewidth': 0, 'ticks': ''}}}], 'scattermapbox': [{'type': 'scattermapbox', 'marker': {'colorbar': {'outlinewidth': 0, 'ticks': ''}}}], 'scatterternary': [{'type': 'scatterternary', 'marker': {'colorbar': {'outlinewidth': 0, 'ticks': ''}}}], 'scattercarpet': [{'type': 'scattercarpet', 'marker': {'colorbar': {'outlinewidth': 0, 'ticks': ''}}}], 'carpet': [{'aaxis': {'endlinecolor': '#2a3f5f', 'gridcolor': 'white', 'linecolor': 'white', 'minorgridcolor': 'white', 'startlinecolor': '#2a3f5f'}, 'baxis': {'endlinecolor': '#2a3f5f', 'gridcolor': 'white', 'linecolor': 'white', 'minorgridcolor': 'white', 'startlinecolor': '#2a3f5f'}, 'type': 'carpet'}], 'table': [{'cells': {'fill': {'color': '#EBF0F8'}, 'line': {'color': 'white'}}, 'header': {'fill': {'color': '#C8D4E3'}, 'line': {'color': 'white'}}, 'type': 'table'}], 'barpolar': [{'marker': {'line': {'color': '#E5ECF6', 'width': 0.5}, 'pattern': {'fillmode': 'overlay', 'size': 10, 'solidity': 0.2}}, 'type': 'barpolar'}], 'pie': [{'automargin': True, 'type': 'pie'}]}, 'layout': {'autotypenumbers': 'strict', 'colorway': ['#636efa', '#EF553B', '#00cc96', '#ab63fa', '#FFA15A', '#19d3f3', '#FF6692', '#B6E880', '#FF97FF', '#FECB52'], 'font': {'color': '#2a3f5f'}, 'hovermode': 'closest', 'hoverlabel': {'align': 'left'}, 'paper_bgcolor': 'white', 'plot_bgcolor': '#E5ECF6', 'polar': {'bgcolor': '#E5ECF6', 'angularaxis': {'gridcolor': 'white', 'linecolor': 'white', 'ticks': ''}, 'radialaxis': {'gridcolor': 'white', 'linecolor': 'white', 'ticks': ''}}, 'ternary': {'bgcolor': '#E5ECF6', 'aaxis': {'gridcolor': 'white', 'linecolor': 'white', 'ticks': ''}, 'baxis': {'gridcolor': 'white', 'linecolor': 'white', 'ticks': ''}, 'caxis': {'gridcolor': 'white', 'linecolor': 'white', 'ticks': ''}}, 'coloraxis': {'colorbar': {'outlinewidth': 0, 'ticks': ''}}, 'colorscale': {'sequential': [[0, '#0d0887'], [0.1111111111111111, '#46039f'], [0.2222222222222222, '#7201a8'], [0.3333333333333333, '#9c179e'], [0.4444444444444444, '#bd3786'], [0.5555555555555556, '#d8576b'], [0.6666666666666666, '#ed7953'], [0.7777777777777778, '#fb9f3a'], [0.8888888888888888, '#fdca26'], [1, '#f0f921']], 'sequentialminus': [[0, '#0d0887'], [0.1111111111111111, '#46039f'], [0.2222222222222222, '#7201a8'], [0.3333333333333333, '#9c179e'], [0.4444444444444444, '#bd3786'], [0.5555555555555556, '#d8576b'], [0.6666666666666666, '#ed7953'], [0.7777777777777778, '#fb9f3a'], [0.8888888888888888, '#fdca26'], [1, '#f0f921']], 'diverging': [[0, '#8e0152'], [0.1, '#c51b7d'], [0.2, '#de77ae'], [0.3, '#f1b6da'], [0.4, '#fde0ef'], [0.5, '#f7f7f7'], [0.6, '#e6f5d0'], [0.7, '#b8e186'], [0.8, '#7fbc41'], [0.9, '#4d9221'], [1, '#276419']]}, 'xaxis': {'gridcolor': 'white', 'linecolor': 'white', 'ticks': '', 'title': {'standoff': 15}, 'zerolinecolor': 'white', 'automargin': True, 'zerolinewidth': 2}, 'yaxis': {'gridcolor': 'white', 'linecolor': 'white', 'ticks': '', 'title': {'standoff': 15}, 'zerolinecolor': 'white', 'automargin': True, 'zerolinewidth': 2}, 'scene': {'xaxis': {'backgroundcolor': '#E5ECF6', 'gridcolor': 'white', 'linecolor': 'white', 'showbackground': True, 'ticks': '', 'zerolinecolor': 'white', 'gridwidth': 2}, 'yaxis': {'backgroundcolor': '#E5ECF6', 'gridcolor': 'white', 'linecolor': 'white', 'showbackground': True, 'ticks': '', 'zerolinecolor': 'white', 'gridwidth': 2}, 'zaxis': {'backgroundcolor': '#E5ECF6', 'gridcolor': 'white', 'linecolor': 'white', 'showbackground': True, 'ticks': '', 'zerolinecolor': 'white', 'gridwidth': 2}}, 'shapedefaults': {'line': {'color': '#2a3f5f'}}, 'annotationdefaults': {'arrowcolor': '#2a3f5f', 'arrowhead': 0, 'arrowwidth': 1}, 'geo': {'bgcolor': 'white', 'landcolor': '#E5ECF6', 'subunitcolor': 'white', 'showland': True, 'showlakes': True, 'lakecolor': 'white'}, 'title': {'x': 0.05}, 'mapbox': {'style': 'light'}}}, 'title': {'text': '目的関数プロット'}, 'xaxis': {'title': {'text': '成功した解析数'}, 'type': 'linear', 'range': [0.7173255954539959, 5.282674404546004], 'autorange': False}, 'yaxis': {'title': {'text': 'Mises Stress'}, 'type': 'linear', 'range': [1194338.1744483153, 6109662.126322151], 'autorange': False}, 'transition': {'duration': 1000}, 'clickmode': 'event+select'}}
464
+
465
+ # get point location
459
466
  pt = hoverData["points"][0]
460
- bbox = pt["bbox"]
467
+
468
+ # get the bounding box of target
469
+ bbox = pt['bbox']
470
+
471
+ # get relative location of point
472
+ xrange = figure['layout']['xaxis']['range']
473
+ # yrange = figure['layout']['yaxis']['range']
474
+
475
+ is_left = pt['x'] < np.mean(xrange)
476
+
477
+ # デフォルトでは Hover が Point に重なり、
478
+ # Hover した瞬間に Un-hover する場合があるので
479
+ # offset を追加
480
+ if is_left:
481
+ direction = 'right'
482
+ bbox['x0'] = bbox['x0'] + 40
483
+ bbox['x1'] = bbox['x1'] + 40
484
+
485
+ else:
486
+ direction = 'left'
487
+ bbox['x0'] = bbox['x0'] + 15
488
+ bbox['x1'] = bbox['x1'] + 15
489
+
490
+ # ついでに縦方向も適当に調整
491
+ bbox['y0'] = bbox['y0'] + 80
492
+ bbox['y1'] = bbox['y1'] + 80
493
+
461
494
 
462
495
  # get row of the history from customdata defined in main_figure
463
496
  if 'customdata' not in pt.keys():
@@ -482,18 +515,20 @@ class MainGraph(AbstractPage):
482
515
  title_component,
483
516
  tbl_component_prm,
484
517
  ])
485
- tooltip_layout = html.Div([
486
- html.Div(img_component, style={'display': 'inline-block', 'margin-right': '10px', 'vertical-align': 'top'}),
487
- html.Div(description, style={'display': 'inline-block', 'margin-right': '10px'}),
488
- html.Div(tbl_component_obj, style={'display': 'inline-block', 'margin-right': '10px'}),
489
- ])
518
+ tooltip_layout = html.Div(
519
+ children=[
520
+ html.Div(img_component, style={'display': 'inline-block', 'margin-right': '10px'}),
521
+ html.Div(description, style={'display': 'inline-block', 'margin-right': '10px'}),
522
+ html.Div(tbl_component_obj, style={'display': 'inline-block', 'margin-right': '10px'}),
523
+ ],
524
+ )
490
525
 
491
- return True, bbox, tooltip_layout
526
+ return True, bbox, tooltip_layout, direction
492
527
 
493
528
  def create_formatted_parameter(self, row) -> Component:
494
- metadata = self.application.history.metadata
529
+ meta_columns = self.application.history.meta_columns
495
530
  pd.options.display.float_format = '{:.4e}'.format
496
- parameters = row.iloc[:, np.where(np.array(metadata) == 'prm')[0]]
531
+ parameters = row.iloc[:, np.where(np.array(meta_columns) == 'prm')[0]]
497
532
  names = parameters.columns
498
533
  values = [f'{value:.3e}' for value in parameters.values.ravel()]
499
534
  data = pd.DataFrame(dict(
@@ -506,9 +541,9 @@ class MainGraph(AbstractPage):
506
541
  return table
507
542
 
508
543
  def create_formatted_objective(self, row) -> Component:
509
- metadata = self.application.history.metadata
544
+ meta_columns = self.application.history.meta_columns
510
545
  pd.options.display.float_format = '{:.4e}'.format
511
- objectives = row.iloc[:, np.where(np.array(metadata) == 'obj')[0]]
546
+ objectives = row.iloc[:, np.where(np.array(meta_columns) == 'obj')[0]]
512
547
  names = objectives.columns
513
548
  values = [f'{value:.3e}' for value in objectives.values.ravel()]
514
549
  data = pd.DataFrame(dict(
@@ -522,20 +557,21 @@ class MainGraph(AbstractPage):
522
557
 
523
558
  def create_image_content_if_femtet(self, trial) -> Component:
524
559
  img_url = None
525
- metadata = self.application.history.metadata
526
- if metadata[0] != '':
527
- # get img path
528
- d = json.loads(metadata[0])
529
- femprj_path = d['femprj_path']
530
- model_name = d['model_name']
531
- femprj_result_dir = femprj_path.replace('.femprj', '.Results')
532
- img_path = os.path.join(femprj_result_dir, f'{model_name}_trial{trial}.jpg')
533
- if os.path.exists(img_path):
534
- # create encoded image
535
- with open(img_path, 'rb') as f:
536
- content = f.read()
537
- encoded_image = base64.b64encode(content).decode('utf-8')
538
- img_url = 'data:image/jpeg;base64, ' + encoded_image
560
+ meta_columns = self.application.history.meta_columns
561
+ if meta_columns[0] != '':
562
+ extra_data = json.loads(meta_columns[0])
563
+ if 'femprj_path' in extra_data.keys():
564
+ # get img path
565
+ femprj_path = extra_data['femprj_path']
566
+ model_name = extra_data['model_name']
567
+ femprj_result_dir = femprj_path.replace('.femprj', '.Results')
568
+ img_path = os.path.join(femprj_result_dir, f'{model_name}_trial{trial}.jpg')
569
+ if os.path.exists(img_path):
570
+ # create encoded image
571
+ with open(img_path, 'rb') as f:
572
+ content = f.read()
573
+ encoded_image = base64.b64encode(content).decode('utf-8')
574
+ img_url = 'data:image/jpeg;base64, ' + encoded_image
539
575
  return html.Img(src=img_url, style={"width": "200px"}) if img_url is not None else html.Div()
540
576
 
541
577
  def get_fig_by_tab_id(self, tab_id, with_length=False, kwargs: dict = None):
@@ -547,9 +547,9 @@ class PredictionModelGraph(AbstractPage):
547
547
  return tuple(ret.values())
548
548
 
549
549
  def create_formatted_parameter(self, row) -> Component:
550
- metadata = self.application.history.metadata
550
+ meta_columns = self.application.history.meta_columns
551
551
  pd.options.display.float_format = '{:.4e}'.format
552
- parameters = row.iloc[:, np.where(np.array(metadata) == 'prm')[0]]
552
+ parameters = row.iloc[:, np.where(np.array(meta_columns) == 'prm')[0]]
553
553
  names = parameters.columns
554
554
  values = [f'{value:.3e}' for value in parameters.values.ravel()]
555
555
  data = pd.DataFrame(dict(
@@ -563,20 +563,21 @@ class PredictionModelGraph(AbstractPage):
563
563
 
564
564
  def create_image_content_if_femtet(self, trial) -> Component:
565
565
  img_url = None
566
- metadata = self.application.history.metadata
567
- if metadata[0] != '':
568
- # get img path
569
- d = json.loads(metadata[0])
570
- femprj_path = d['femprj_path']
571
- model_name = d['model_name']
572
- femprj_result_dir = femprj_path.replace('.femprj', '.Results')
573
- img_path = os.path.join(femprj_result_dir, f'{model_name}_trial{trial}.jpg')
574
- if os.path.exists(img_path):
575
- # create encoded image
576
- with open(img_path, 'rb') as f:
577
- content = f.read()
578
- encoded_image = base64.b64encode(content).decode('utf-8')
579
- img_url = 'data:image/jpeg;base64, ' + encoded_image
566
+ meta_columns = self.application.history.meta_columns
567
+ if meta_columns[0] != '':
568
+ extra_data = json.loads(meta_columns[0])
569
+ if 'femprj_path' in extra_data:
570
+ # get img path
571
+ femprj_path = extra_data['femprj_path']
572
+ model_name = extra_data['model_name']
573
+ femprj_result_dir = femprj_path.replace('.femprj', '.Results')
574
+ img_path = os.path.join(femprj_result_dir, f'{model_name}_trial{trial}.jpg')
575
+ if os.path.exists(img_path):
576
+ # create encoded image
577
+ with open(img_path, 'rb') as f:
578
+ content = f.read()
579
+ encoded_image = base64.b64encode(content).decode('utf-8')
580
+ img_url = 'data:image/jpeg;base64, ' + encoded_image
580
581
  return html.Img(src=img_url, style={"width": "200px"}) if img_url is not None else html.Div()
581
582
 
582
583
  # def get_fig_by_tab_id(self, tab_id, with_length=False):
@@ -3,6 +3,7 @@ from time import sleep
3
3
  from threading import Thread
4
4
 
5
5
  import pandas as pd
6
+ from flask import jsonify
6
7
 
7
8
  from pyfemtet.opt.visualization._base import PyFemtetApplicationBase, logger
8
9
  from pyfemtet.opt.visualization._process_monitor.pages import HomePage, WorkerPage, PredictionModelPage, OptunaVisualizerPage
@@ -80,7 +81,22 @@ class ProcessMonitorApplication(PyFemtetApplicationBase):
80
81
  if not debug:
81
82
  super().setup_callback()
82
83
 
83
- def start_server(self, host=None, port=None):
84
+ from pyfemtet.opt._femopt_core import OptimizationStatus
85
+
86
+ @self.server.route('/interrupt')
87
+ def some_command():
88
+
89
+ # If the entire_state < INTERRUPTING, set INTERRUPTING
90
+ if self.local_entire_status_int < OptimizationStatus.INTERRUPTING:
91
+ self.local_entire_status_int = OptimizationStatus.INTERRUPTING
92
+ result = {"message": "Interrupting signal emitted successfully."}
93
+
94
+ else:
95
+ result = {"message": "Interrupting signal is already emitted."}
96
+
97
+ return jsonify(result)
98
+
99
+ def start_server(self, host=None, port=None, host_record=None):
84
100
  """Callback の中で使いたい Actor のデータを Application クラスのメンバーとやり取りしつつ、server を落とす関数"""
85
101
 
86
102
  self._should_get_actor_data = True
@@ -95,6 +111,7 @@ class ProcessMonitorApplication(PyFemtetApplicationBase):
95
111
  server_thread = Thread(
96
112
  target=self.run,
97
113
  args=(host, port,),
114
+ kwargs=dict(host_record=host_record),
98
115
  daemon=True,
99
116
  )
100
117
  server_thread.start()
@@ -188,7 +205,7 @@ def g_debug():
188
205
  g_application.run(debug=False)
189
206
 
190
207
 
191
- def main(history, status, worker_addresses, worker_status_list, host=None, port=None):
208
+ def main(history, status, worker_addresses, worker_status_list, host=None, port=None, host_record=None):
192
209
  g_application = ProcessMonitorApplication(history, status, worker_addresses, worker_status_list)
193
210
 
194
211
  g_home_page = HomePage(Msg.PAGE_TITLE_PROGRESS)
@@ -202,7 +219,7 @@ def main(history, status, worker_addresses, worker_status_list, host=None, port=
202
219
  g_application.add_page(g_worker_page, 3)
203
220
  g_application.setup_callback()
204
221
 
205
- g_application.start_server(host, port)
222
+ g_application.start_server(host, port, host_record)
206
223
 
207
224
 
208
225
  if __name__ == '__main__':
@@ -209,11 +209,11 @@ class HomePage(AbstractPage):
209
209
  Input('debug-button-2', 'n_clicks'),
210
210
  prevent_initial_call=True)
211
211
  def add_data(*_):
212
- metadata = self.application.history.metadata
212
+ meta_columns = self.application.history.meta_columns
213
213
  df = self.application.local_data
214
214
 
215
215
  new_row = df.iloc[-2:]
216
- obj_index = np.where(np.array(metadata) == 'obj')[0]
216
+ obj_index = np.where(np.array(meta_columns) == 'obj')[0]
217
217
  for idx in obj_index:
218
218
  new_row.iloc[:, idx] = np.random.rand(len(new_row))
219
219
 
@@ -183,11 +183,11 @@ class HomePage(AbstractPage):
183
183
  return alerts
184
184
 
185
185
  # get femprj in history csv
186
- kwargs = self.femtet_control.create_femtet_interface_args()[0] # read metadata from history.
186
+ kwargs = self.femtet_control.create_femtet_interface_args()[0] # read extra_data from history.
187
187
  femprj_path = kwargs['femprj_path']
188
188
  model_name = kwargs['model_name']
189
189
 
190
- # check metadata is valid
190
+ # check extra_data is valid
191
191
  if femprj_path is None:
192
192
  msg = Msg.ERR_FEMPRJ_IN_CSV_NOT_FOUND
193
193
  alerts = self.alert_region.create_alerts(msg, color='danger')
@@ -283,8 +283,8 @@ class HomePage(AbstractPage):
283
283
  # get parameter and update model
284
284
  df = self.application.history.get_df(valid_only=True)
285
285
  row = df[df['trial'] == trial]
286
- metadata = np.array(self.application.history.metadata)
287
- idx = np.where(metadata == 'prm')[0]
286
+ meta_columns = np.array(self.application.history.meta_columns)
287
+ idx = np.where(meta_columns == 'prm')[0]
288
288
 
289
289
  names = np.array(row.columns)[idx]
290
290
  values = np.array(row.iloc[:, idx]).ravel()
@@ -346,7 +346,7 @@ class HomePage(AbstractPage):
346
346
 
347
347
  # check the corresponding between history and Femtet
348
348
  # ├ history-side
349
- kwargs = self.femtet_control.create_femtet_interface_args()[0] # read metadata from history.
349
+ kwargs = self.femtet_control.create_femtet_interface_args()[0] # read extra_data from history.
350
350
  femprj_path_history_on_history: str or None = kwargs['femprj_path']
351
351
  model_name_on_history: str or None = kwargs['model_name']
352
352
  # ├ Femtet-side
@@ -673,7 +673,7 @@ class Tutorial(AbstractPage):
673
673
  destination_folder = source_folder.replace('wat_ex14_parametric', 'tutorial')
674
674
  shutil.copytree(source_folder, destination_folder, dirs_exist_ok=True)
675
675
 
676
- self.application.history.metadata[0] = json.dumps(
676
+ self.application.history.meta_columns[0] = json.dumps(
677
677
  dict(
678
678
  femprj_path=destination_file,
679
679
  model_name='Ex14',
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: pyfemtet
3
- Version: 0.8.4
3
+ Version: 0.8.7
4
4
  Summary: Design parameter optimization using Femtet.
5
5
  License: BSD-3-Clause
6
6
  Author: kazuma.naito
@@ -1,4 +1,4 @@
1
- pyfemtet/__init__.py,sha256=oR63M0ef9dMrWZnMjTb9xk69cW2iS6rluqpyJ5_0C84,21
1
+ pyfemtet/__init__.py,sha256=04WO81p8xrQAHiTKqHaDkKWih6M2Y3Hy-UCNVwih4Zc,21
2
2
  pyfemtet/_femtet_config_util/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
3
  pyfemtet/_femtet_config_util/autosave.py,sha256=dNirA9XGuFehas8_Jkj2BW9GOzMbPyhnt1WHcH_ObSU,2070
4
4
  pyfemtet/_femtet_config_util/exit.py,sha256=0BWID-tjOkmZwmgPFkcJMkWW39voccz5ARIBWvZbHaw,1877
@@ -6,10 +6,10 @@ pyfemtet/_message/1. make_pot.bat,sha256=wrTA0YaL7nUfNB0cS8zljOmwq2qgyG6RMwHQbrw
6
6
  pyfemtet/_message/2. make_mo.bat,sha256=6shJ3Yn4BXjDc0hhv_kiGUtVTq4oSRz8-iS4vW29rNE,155
7
7
  pyfemtet/_message/__init__.py,sha256=gE1-XX_PzHj9BbhqPaK5VcIHuv6_Tec5qlPMC3IRiBg,100
8
8
  pyfemtet/_message/babel.cfg,sha256=AQIFCQ7NlAA84PhV0gowHhbIXH41zA55mzhgyROniJk,73
9
- pyfemtet/_message/locales/ja/LC_MESSAGES/messages.mo,sha256=piTwHbUIWD_68JMMRvzRHD0IuIUdq0dJNYFy88ZjbQQ,18768
10
- pyfemtet/_message/locales/ja/LC_MESSAGES/messages.po,sha256=O5YDF47uPsLh4wXNgXz95p0U8895AbqLNJcLhRKIljE,25185
11
- pyfemtet/_message/locales/messages.pot,sha256=hHrjOC2W_ZOBaDedImBnLQpOeFYBF8K3G7165jYXTGo,14872
12
- pyfemtet/_message/messages.py,sha256=gvF6xwJHE2hlD3b4828Oqzv3jMO_OsZUYtQzRO6cXmk,13678
9
+ pyfemtet/_message/locales/ja/LC_MESSAGES/messages.mo,sha256=Af0m1bHsrMAjqyfLlDjW_OK09IXnuDvByaESf7BvuQU,18984
10
+ pyfemtet/_message/locales/ja/LC_MESSAGES/messages.po,sha256=CPVryK95GFl_GSSTz1uSvkKwXaYRvTboIr_aTgdfwbo,25441
11
+ pyfemtet/_message/locales/messages.pot,sha256=AxtocHuEX5VPgXgULpHBxU8swNLUzm9KEBbSP1Y6qP8,15017
12
+ pyfemtet/_message/messages.py,sha256=OsSXVLn9_YKwuHczW1A4CEnhZ0wrtHmOhxPA9OPOzHc,13856
13
13
  pyfemtet/_util/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
14
  pyfemtet/_util/dask_util.py,sha256=ufgr4m8slvyWP97lWBwolysQpJ1PmAO_-OI8IlEyvU8,233
15
15
  pyfemtet/_util/excel_macro_util.py,sha256=cF1Z3yl9FMM0J7dpMRTsle8uYxYcfHhQC0QffnVovdY,7944
@@ -24,12 +24,12 @@ pyfemtet/dispatch_extensions/_impl.py,sha256=yH_yeAnQ-Xi9GfjX-FQt9u3yHnrLYIteRb6
24
24
  pyfemtet/logger/__init__.py,sha256=UOJ9n_U2xwdTrp0Xgg-N6geySxNzKqTBQlXsaH0kW_w,420
25
25
  pyfemtet/logger/_impl.py,sha256=rsAd0HpmveOaLS39ucp3U2OcDhQMWjC5fnVGhbJtWVw,6375
26
26
  pyfemtet/opt/__init__.py,sha256=wRR8LbEhb5I6MUgmnCgjB6-tqHlOVxDIo7yPkq0QbBs,758
27
- pyfemtet/opt/_femopt.py,sha256=vqLUGMMHn0lp0bRE_FEV0sOoUcVAbohy9_8OLYw3ZrU,39217
28
- pyfemtet/opt/_femopt_core.py,sha256=mA2wQ5h_mmbTQ9ilhDHLUyN-jsWFDpJE2r5guUWlS10,38083
27
+ pyfemtet/opt/_femopt.py,sha256=ZhwOK1QYwo7Xk67qEOm4biKXzdIW2AUHYvgklBREDm8,40587
28
+ pyfemtet/opt/_femopt_core.py,sha256=kxKh4_TdXR4LBgv8WibPiZ5Pe9apJd5ArBCfnhBwcCQ,38969
29
29
  pyfemtet/opt/_test_utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
30
30
  pyfemtet/opt/_test_utils/control_femtet.py,sha256=8oAl9y5V2n8Nnsgx_ebcZVzwFt1eI3swkdiKg6pg3-M,1085
31
31
  pyfemtet/opt/_test_utils/hyper_sphere.py,sha256=nQhw8EIY0DwvcTqrbKhkxiITLZifr4-nG77E-_6ggmA,700
32
- pyfemtet/opt/_test_utils/record_history.py,sha256=JCNJLZMCNTpJ6VT7iwEt2DIbwmsuQmgC0ClQSfcatj4,3915
32
+ pyfemtet/opt/_test_utils/record_history.py,sha256=zsa1w73K7NLBqbj7yuv0fWVJvZtWdiI0eCaUoAn5Bjg,4239
33
33
  pyfemtet/opt/advanced_samples/excel_ui/(ref) original_project.femprj,sha256=5OqZfynTpVCrgEIOBOMYuDGaMvepi5lojVNFr1jAsEI,157489
34
34
  pyfemtet/opt/advanced_samples/excel_ui/femtet-macro.xlsm,sha256=ckF0SQ0f3IWSW6QoH1IPJdwUUlR7O_AiGC5fi8SI3jA,133137
35
35
  pyfemtet/opt/advanced_samples/excel_ui/pyfemtet-core.py,sha256=aF2TWXdbt7dnkeBqqVO6GvIExozjFp0mxx3BX8rpYNc,9879
@@ -39,19 +39,19 @@ pyfemtet/opt/advanced_samples/surrogate_model/gal_ex13_create_training_data_jp.p
39
39
  pyfemtet/opt/advanced_samples/surrogate_model/gal_ex13_optimize_with_surrogate.py,sha256=s0b31wuN3iXjb78dt0ro0ZjxHa8uLIH94jRfEuj1EVY,3090
40
40
  pyfemtet/opt/advanced_samples/surrogate_model/gal_ex13_optimize_with_surrogate_jp.py,sha256=OAOpHKyMMo1StSqNMqx4saYDn4hiGOKDypyK6uhTILQ,3215
41
41
  pyfemtet/opt/advanced_samples/surrogate_model/gal_ex13_parametric.femprj,sha256=iIHH1X-wWBqEYj4cFJXco73LCJXSrYBsSKOD0HxYu60,87599
42
- pyfemtet/opt/interface/__init__.py,sha256=dkQ8PoIzYJVRtckNN2VgL7FEwci9RbYM3owOvqnPm80,1219
42
+ pyfemtet/opt/interface/__init__.py,sha256=na6-elI9-karOqoSxT9LfLQpjBPm1lrUWjow0NYYRP4,1349
43
43
  pyfemtet/opt/interface/_base.py,sha256=y0uQ5jdsWbgt5odyqPin7NXcK_IbUwPDcrrkV_JhpRw,2722
44
44
  pyfemtet/opt/interface/_excel_interface.py,sha256=s103vePTPXXYiPwGdAEUFgtpvGXtu1nSljDtP4HsmcY,40355
45
- pyfemtet/opt/interface/_femtet.py,sha256=teALmp66aJ_rrmtEOjCGDG1jGLTZr2AmvMFmuuXRQkw,34634
46
- pyfemtet/opt/interface/_femtet_parametric.py,sha256=0pAEhHflp0wIxWBVMXI8nCC02oAyRKLinH3Y6O8bq3M,2224
45
+ pyfemtet/opt/interface/_femtet.py,sha256=Tn0qgVMJDv-6hBPDOWYBtlfvhsb4UH3MknX0PaXb8ro,35313
46
+ pyfemtet/opt/interface/_femtet_parametric.py,sha256=rhvnpHdbjNJAKxiCkgnExnZdV5qOB6pBv6AaLeTkeF8,10155
47
47
  pyfemtet/opt/interface/_femtet_with_nx/__init__.py,sha256=-6W2g2FDEcKzGHmI5KAKQe-4U5jDpMj0CXuma-GZca0,83
48
48
  pyfemtet/opt/interface/_femtet_with_nx/_interface.py,sha256=LkaODUSpBLq05uz5Jf-JKuH6Evq8ElZoItXxFZopWeM,5994
49
49
  pyfemtet/opt/interface/_femtet_with_nx/update_model.py,sha256=P7VH0i_o-X9OUe6AGaLF1fACPeHNrMjcrOBCA3MMrI4,3092
50
50
  pyfemtet/opt/interface/_femtet_with_sldworks.py,sha256=rjEgebuP1w1eAFVWw4eRJUq3lsyBcmXlkMjZKIpD0kw,11019
51
51
  pyfemtet/opt/interface/_surrogate/__init__.py,sha256=2UT5NuBylyWQJNjg1zsBRCV-MzNCUswTUt6ZuSrYFUM,120
52
- pyfemtet/opt/interface/_surrogate/_base.py,sha256=-k02jRywxaSKMDzGitPE_qBj5nUxC7OL6guF4y6F1Zw,2923
52
+ pyfemtet/opt/interface/_surrogate/_base.py,sha256=bQMoztVq1b-3BW5Z1V-dSROplMHutrblDI289j0cC-E,3001
53
53
  pyfemtet/opt/interface/_surrogate/_chaospy.py,sha256=gL72bCgs1AY_EZdJtcifSC-apwsZzp4zsWYxcpVKvtw,1969
54
- pyfemtet/opt/interface/_surrogate/_singletaskgp.py,sha256=YBRm-8MRwK26qg6T5LKaAhwPfF3jLcKQV-fycP6dnlA,2406
54
+ pyfemtet/opt/interface/_surrogate/_singletaskgp.py,sha256=ojZHsxGxSc8ZJqJQ_uMHvpK98TPUsHzXP0q4tmM0YPQ,2471
55
55
  pyfemtet/opt/optimizer/__init__.py,sha256=Ia6viowECkG0IFXtFef0tJ4jDKsoDzJLqMJ9xLFH2LQ,543
56
56
  pyfemtet/opt/optimizer/_base.py,sha256=j8aQc3fGehZTJT9ETf9cr3VWYs2FYk1F8fO3f7QyKAU,13099
57
57
  pyfemtet/opt/optimizer/_optuna/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -64,7 +64,7 @@ pyfemtet/opt/optimizer/_scipy_scalar.py,sha256=rGvrLjrgfYzxK9GA0-r2Hhoaqt6A0TQsT
64
64
  pyfemtet/opt/optimizer/parameter.py,sha256=YLE9lmYRaZA8isnTPJnbYXpUn6zsJFW4xg03QaSWey8,3950
65
65
  pyfemtet/opt/prediction/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
66
66
  pyfemtet/opt/prediction/_base.py,sha256=dEyEur3IntNokYK8NhPndHb2pWY_A4C1SjEejOTCUGw,2048
67
- pyfemtet/opt/prediction/single_task_gp.py,sha256=6NMSjTtzXJWaW7NEqfqOjz_37mbHpXh9Oo5_KjivRU0,3922
67
+ pyfemtet/opt/prediction/single_task_gp.py,sha256=t4Vby0Llh7ZcVQ6M5zYqwmmo-NwSXwWRExLtqzmPcu8,3929
68
68
  pyfemtet/opt/samples/femprj_sample/ParametricIF.femprj,sha256=9BtDHmc3cdom0Zq33DTdZ0mDAsIUY6i8SRkkg-n7GO0,442090
69
69
  pyfemtet/opt/samples/femprj_sample/ParametricIF.py,sha256=oXzchBZEbH69xacDht5HDnbZzKwapXsn6bp9qihY17Y,707
70
70
  pyfemtet/opt/samples/femprj_sample/ParametricIF_test_result.reccsv,sha256=TiOAqEDMub6SCGYClBv1JvQxphDOY3iIdr_pMmGgJ9M,2859
@@ -116,18 +116,18 @@ pyfemtet/opt/samples/femprj_sample_jp/wat_ex14_parametric_jp.femprj,sha256=dMwQM
116
116
  pyfemtet/opt/samples/femprj_sample_jp/wat_ex14_parametric_jp.py,sha256=vMy-KUP1wEMV9Rt6yXjkE40Fcs1t1cpQK-nQJK8hHao,2284
117
117
  pyfemtet/opt/samples/femprj_sample_jp/wat_ex14_parametric_parallel_jp.py,sha256=4X0cl3YWpYarcNBCH79mrlyFuKUYSqvnGzokEbv9ILk,2335
118
118
  pyfemtet/opt/visualization/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
119
- pyfemtet/opt/visualization/_base.py,sha256=xh6yIkoyBrV670JhAnR9rRewpH7P25wz0pnr0JH0pvc,7623
119
+ pyfemtet/opt/visualization/_base.py,sha256=b1oWPsCTFmoHRjFWhysmpE3VmaB7e-FNq6V9eMTZRz8,7934
120
120
  pyfemtet/opt/visualization/_complex_components/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
121
121
  pyfemtet/opt/visualization/_complex_components/alert_region.py,sha256=sX8xqT4NqhACagK4YgumF4ResrTqhOKQ8dN4q58shI8,2106
122
- pyfemtet/opt/visualization/_complex_components/control_femtet.py,sha256=LcMoh_MQQ1-hiz7nMGOmxSSoJLOX8viVxZB6uIggg_g,6243
122
+ pyfemtet/opt/visualization/_complex_components/control_femtet.py,sha256=sY0YH56MgDWtfFfEkFsfzpr0VbP8dRT0KrhhGzeRiRE,6227
123
123
  pyfemtet/opt/visualization/_complex_components/main_figure_creator.py,sha256=Wt_aL6srMNW-84LeZ86_OtljzmFoF9v0yklVpPAgNDE,9480
124
- pyfemtet/opt/visualization/_complex_components/main_graph.py,sha256=qcofnuWfItYQJWs16zY1p7L4vE_rr5mHEtj9poU0i5I,21711
125
- pyfemtet/opt/visualization/_complex_components/pm_graph.py,sha256=eh9rQYUcEefwN3eb7AnXXKFyknl_P_3xt4kl3Y4woI8,25010
124
+ pyfemtet/opt/visualization/_complex_components/main_graph.py,sha256=WbV0oW6nUS734688Zd4H1OpDrBBWJEu6u4u7lqoqnSQ,31975
125
+ pyfemtet/opt/visualization/_complex_components/pm_graph.py,sha256=FnxerXoddflukSj_BdhjK7jBl83qSDFsTUcQzs8Nij8,25153
126
126
  pyfemtet/opt/visualization/_complex_components/pm_graph_creator.py,sha256=f-ikYAPChazqyRQ0Y-tKrYrMBHzFHJJ4uV6QXBEBRKI,7304
127
127
  pyfemtet/opt/visualization/_create_wrapped_components.py,sha256=9AltJHr1DM6imZfpNp867rC-uAYqQ-emdgTLChKDrl8,2513
128
128
  pyfemtet/opt/visualization/_process_monitor/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
129
- pyfemtet/opt/visualization/_process_monitor/application.py,sha256=l9Z1SS4r1BXH6JlccjDyJNanG2JTu4OALbEdZje0XrY,7955
130
- pyfemtet/opt/visualization/_process_monitor/pages.py,sha256=VEyP7cRyVjLOgKD6KUHu3AivbwbmjTucQWv-obH-HY0,15135
129
+ pyfemtet/opt/visualization/_process_monitor/application.py,sha256=8ShNMPWrD_1IHyPz2a63tlzENQg7by3kg4pdXSuv0_4,8659
130
+ pyfemtet/opt/visualization/_process_monitor/pages.py,sha256=-G-zNvYS6HDXrwX0lQlInlJn3rZPr1-Rh4AAAOudmuY,15147
131
131
  pyfemtet/opt/visualization/_wrapped_components/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
132
132
  pyfemtet/opt/visualization/_wrapped_components/dbc.py,sha256=iSh4QRmLIQMfiAWowG1ThXLPhmKluRYOYPcdDFVI0t0,42162
133
133
  pyfemtet/opt/visualization/_wrapped_components/dcc.py,sha256=-Iw6MjFQmvJ__KcddPhFDqui6lk2ixB2U2tZH_Il5pA,17500
@@ -136,9 +136,9 @@ pyfemtet/opt/visualization/_wrapped_components/str_enum.py,sha256=NZqbh2jNEAckvJ
136
136
  pyfemtet/opt/visualization/result_viewer/.gitignore,sha256=ryvb4aqbbsHireHWlPQfxxqDHQJo6YkVYhE9imKt0b8,6
137
137
  pyfemtet/opt/visualization/result_viewer/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
138
138
  pyfemtet/opt/visualization/result_viewer/application.py,sha256=WcHBx_J5eNLKSaprpk9BGifwhO04oN8FiNGYTWorrXA,1691
139
- pyfemtet/opt/visualization/result_viewer/pages.py,sha256=zcsRmVpVK7xbmOpnKkSypNPsRyHcV3ingfNmuqln6nw,32171
140
- pyfemtet-0.8.4.dist-info/LICENSE,sha256=sVQBhyoglGJUu65-BP3iR6ujORI6YgEU2Qm-V4fGlOA,1485
141
- pyfemtet-0.8.4.dist-info/METADATA,sha256=gm8_jNbFddbgs4cCz1XchxJDMSfcTlBn-GHxCu0ikrE,3509
142
- pyfemtet-0.8.4.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
143
- pyfemtet-0.8.4.dist-info/entry_points.txt,sha256=ZfYqRaoiPtuWqFi2_msccyrVF0LurMn-IHlYamAegZo,104
144
- pyfemtet-0.8.4.dist-info/RECORD,,
139
+ pyfemtet/opt/visualization/result_viewer/pages.py,sha256=MZAjzbuq0toZrR-iJhElM3A12_jHVCTt65gz1kdNPbw,32193
140
+ pyfemtet-0.8.7.dist-info/LICENSE,sha256=sVQBhyoglGJUu65-BP3iR6ujORI6YgEU2Qm-V4fGlOA,1485
141
+ pyfemtet-0.8.7.dist-info/METADATA,sha256=uy1fm6IKQ5OXU8kZ7bowgMIyCbyaQ9NTgaxz0r1DoV0,3509
142
+ pyfemtet-0.8.7.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
143
+ pyfemtet-0.8.7.dist-info/entry_points.txt,sha256=ZfYqRaoiPtuWqFi2_msccyrVF0LurMn-IHlYamAegZo,104
144
+ pyfemtet-0.8.7.dist-info/RECORD,,