0

我有以下代码,我似乎无法开始工作,我认为这与装饰器可能无法在循环中运行的事实有关?

如果我只在and函数中生成 1 个选项invoke_cell_geometry_options并在函数中指定一个唯一的 id (而不是在循环中),那么代码就可以工作。我可以发布工作修订版,尽管依赖关系会使它有点冗长,而且我似乎无法在不投入太多时间的情况下成功隔离感兴趣的代码。click_register_functionfill_region

我觉得我的逻辑是完全合理的,除非在循环或其他东西中当然不允许使用装饰器。请大家帮忙,不胜感激,谢谢!

app = dash.Dash()
app.config['suppress_callback_exceptions'] = True

app.layout = html.Div([
html.Button('Create Cell', id='cell-geometry-button', n_clicks=0),
html.Div(id='cell-geometry-config-container'),
html.A(id='click-register'),
])

num_clicks = 0


# Initiate cell geometry config with button
@app.callback(
    Output('cell-geometry-config-container', 'children'),
    [Input('cell-geometry-button', 'n_clicks')],)
def invoke_cell_geometry_options(n_clicks):
    geometry_ui_list = []
    global num_clicks
    num_clicks = n_clicks
    for i in range(n_clicks):
        graph_id = 'cell-graph-{}'.format(i)
        planes_list_id = 'planes-list-{}'.format(i)
        button_id = 'fill-region-button-{}'.format(i)
        click_register_id = 'click-register-{}'.format(i)

        geometry_ui_list.extend([dcc.Graph(id=graph_id),
                                 dcc.Input(id=planes_list_id, placeholder='Enter list of radial planes (comma separated)',
                                           type="text"),
                                 html.Button('Fill Region', id=button_id, n_clicks=0),
                                 html.A(id=click_register_id),
                                 html.Br(),
                        ])

    options = html.Div(geometry_ui_list)
    return options

for val in range(num_clicks):
    @app.callback(
        Output('click-register-{}'.format(val), 'children'),
        [Input('cell-graph-{}'.format(val), 'clickData')])
    def click_register_function(clickData):
        region = 0
        click_x = 0
        click_y = 0
        if clickData is not None:
            if 'points' in clickData:
                point = clickData['points'][0]
                if 'text' in point:
                    region = int(re.search(r'\d+', point['text']).group())
                if 'x' in point:
                    click_x = point['x']
                if 'y' in point:
                    click_y = point['y']
            return [region, click_x, click_y]


    # Fill Region
    @app.callback(
        Output('cell-graph-{}'.format(val), 'figure'),
        [Input('planes-list-{}'.format(val), 'value'),
         Input('fill-region-button-{}'.format(val), 'n_clicks')],
        [State('material-dropdown', 'value'),
         State('cell-graph-{}'.format(val), 'clickData')]
    )
    def fill_region(planes, n_clicks, selected_material, click_register):
        planes = [float(plane) for plane in planes.split(',')]
        planes.sort()

        edge = planes[-1]
        x = np.linspace(-edge, edge, 250)
        y = np.linspace(-edge, edge, 250)

        regions = []
        cell_hover = []
        # Normal Display
        for i in x:
            row = []
            text_row = []
            for j in y:

                if np.sqrt(i ** 2 + j ** 2) < planes[0]:
                    row.append(7)  # <- Arbitrary number to adjust color
                    text_row.append('Region 1')

                if np.sqrt(i ** 2 + j ** 2) > planes[-1]:
                    row.append(5)  # <- Arbitrary number to adjust color
                    text_row.append('Region {}'.format(len(planes) + 1))

                for k in range(len(planes) - 1):
                    if planes[k] < np.sqrt(i ** 2 + j ** 2) < planes[k + 1]:
                        row.append(k * 3)  # <- Arbitrary number to adjust color
                        text_row.append('Region {}'.format(k + 2))
            regions.append(row)
            cell_hover.append(text_row)

        ######################################################
        # Fill region in OpenMC
        outer_radii = []
        for plane in planes:
            outer_radii.append(openmc.ZCylinder(x0=0, y0=0, R=plane, name='{} Outer Radius'))

        cell_universe = openmc.Universe(name='{} Cell'.format(selected_material))
        cell_fillings = []

        # Initialize region
        if click_register is not None:
            region = click_register[0]
            click_x = click_register[1]
            click_y = click_register[2]

            if region == 1:  # For region 1
                cell_filling = openmc.Cell(name='', fill=model.materials[selected_material], region=-outer_radii[0])

            if region == (len(planes) + 1):  # For outer region
                cell_filling = openmc.Cell(name='', fill=model.materials[selected_material], region=+outer_radii[-1])

            for k in range(len(planes) - 1):
                if planes[k] < region < planes[k + 1]:  # For in-between regions
                    cell_filling = openmc.Cell(name='', fill=model.materials[selected_material],
                                               region=+outer_radii[k] & -outer_radii[k + 1])

            cell_fillings = []
            if n_clicks > 0:
                new_hover = []
                cell_fillings.append(cell_filling)

                # Change graph on Click # TODO: Figure out why new text wont show up
                if 0 < np.sqrt(click_x ** 2 + click_y ** 2) < planes[0]:
                    for row_ in cell_hover:
                        for text in row_:
                            new_hover.append(
                                text.replace('Region 1', '{} Region'.format(materials_list[selected_material])))

                if np.sqrt(click_x ** 2 + click_y ** 2) > planes[-1]:
                    for row_ in cell_hover:
                        for text in row_:
                            new_hover.append(text.replace('Region {}'.format(len(planes) + 1),
                                                          '{} Region'.format(materials_list[selected_material])))

                for k in range(len(planes) - 1):
                    if planes[k] < np.sqrt(click_x ** 2 + click_y ** 2) < planes[k + 1]:
                        for row_ in cell_hover:
                            for text in row_:
                                new_hover.append(text.replace('Region {}'.format(k + 2),
                                                              '{} Region'.format(materials_list[selected_material])))

                cell_hover = new_hover
                n_clicks = 0

        cell_universe.add_cells(cell_fillings)

        # Add completely filled cell universe to list of universes
        if len(cell_fillings) == len(planes) + 1:
            cell_universes.append(cell_universe)

        ######################################################

        heatmap = go.Heatmap(z=regions, x=x, y=y, hoverinfo='x+y+text', text=cell_hover, opacity=0.5, showscale=False)

        data = [heatmap]
        shapes = []

        for plane in planes:
            shape = {
                'type': 'circle',
                'x0': -plane,
                'y0': -plane,
                'x1': plane,
                'y1': plane,
                'line': {
                    'width': 4,
                },
                'opacity': 1
            }

            shapes.append(shape)

        layout = dict(title='Cell Region Depiction',
                      height=1000,
                      width=1000,
                      shapes=shapes)

        figure = dict(data=data, layout=layout)
        return figure

if __name__ == '__main__':
    app.run_server()
4

0 回答 0