def options_layout(self):

        miller_index = get_matrix_input(self.id(), label="Miller index",
                                        default=((1, 0, 0), ),
                                        help="The surface plane defined by its Miller index (h, k, l)")

        min_slab_size = dcc.Input(id=self.id("min_slab_size"), value=6)
        min_vacuum_size = dcc.Input(id=self.id("min_vacuum_size"), value=10)
        #lll_reduce = dcc.Checklist()
        center_slab = dcc.Checklist(id=self.id("center_slab"), options=[{"label": " ", "value": "center_slab"}], values=[])
        #in_unit_planes = ...
        #primitive = ...
        #max_normal_search = ...
        #shift = ...
        #tol = ...

        # get_layout(name, display_name, type)
        # get_inputs(name, type)
        # get_value(type, inputs)

        options = html.Div([miller_index,
                            Label("Min slab size:"), min_slab_size,
                            Label("Min vacuum size:"), min_vacuum_size,
                            Label("Center slab:"), center_slab])

        return options
Exemple #2
0
        def add_initial_layout(data):

            algorithm_choices = html.Div([
                Label("Algorithm:"),
                dcc.RadioItems(
                    id=self.id("algorithm"),
                    options=[
                        {
                            "label": "ChemEnv Analysis",
                            "value": "chemenv"
                        },
                        {
                            "label": "LocalEnv Analysis",
                            "value": "localenv"
                        },
                        {
                            "label": "Bonding Graph",
                            "value": "bondinggraph"
                        },
                    ],
                    inputClassName="mpc-radio",
                    labelClassName="mpc-radio",
                    value="chemenv",
                ),
            ])

            analysis = html.Div(id=self.id("analysis"))

            return html.Div(
                [algorithm_choices,
                 html.Br(), analysis,
                 html.Br()])
        def _get_soap_graph(feature, label):

            spectrum = {
                "data": [{
                    "coloraxis": "coloraxis",
                    #'hovertemplate': 'x: %{x}<br>y: %{y}<br>color: %{z}<extra></extra>',
                    "type": "heatmap",
                    "z": feature.tolist(),
                }]
            }

            spectrum["layout"] = {
                "xaxis": {
                    "visible": False
                },
                "yaxis": {
                    "visible": False
                },
                "paper_bgcolor": "rgba(0,0,0,0)",
                "plot_bgcolor": "rgba(0,0,0,0)",
                "coloraxis": {
                    "colorscale": [
                        [0.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.0, "#f0f921"],
                    ],
                    "showscale":
                    False,
                },
                "margin": {
                    "l": 0,
                    "b": 0,
                    "t": 0,
                    "r": 0,
                    "pad": 0
                },
                # "height": 20*feature.shape[0],  # for fixed size plots
                # "width": 20*feature.shape[1]
            }

            return Columns([
                Column(Label(label), size="1"),
                Column(
                    dcc.Graph(
                        figure=spectrum,
                        config={"displayModeBar": False},
                        responsive=True,
                        style={"height": "60px"},
                    )),
            ])
        def _get_soap_graph(feature, label):

            spectrum = px.imshow(feature,
                                 aspect="equal",
                                 color_continuous_scale="plasma")

            coloraxis = spectrum.layout.coloraxis
            coloraxis["showscale"] = False

            layout = {
                "xaxis": {
                    "visible": False
                },
                "yaxis": {
                    "visible": False
                },
                "paper_bgcolor": "rgba(0,0,0,0)",
                "plot_bgcolor": "rgba(0,0,0,0)",
                "coloraxis": coloraxis,
                "margin": {
                    "l": 0,
                    "b": 0,
                    "t": 0,
                    "r": 0,
                    "pad": 0
                },
                # "height": 20*feature.shape[0],  # for fixed size plots
                # "width": 20*feature.shape[1]
            }

            spectrum.layout = layout

            return Columns([
                Column(Label(label), size="1"),
                Column(
                    dcc.Graph(
                        figure=spectrum,
                        config={"displayModeBar": False},
                        responsive=True,
                        style={"height": "60px"},
                    )),
            ])
Exemple #5
0
    def update_contents(self, new_store_contents):
        """
        Structure -> mpid -> BibTeX references from MP -> (optional doi lookup
        via Crossref) -> formatting.
        Formatting is very messy right now.
        DOI lookup and (possibly) formatting should be cached in a builder.
        """

        struct = self.from_data(new_store_contents)

        if not isinstance(struct, Structure):
            raise PreventUpdate(
                "Literature mentions can only be retrieved for crystallographic "
                "structures at present and not molecules. Please make a feature "
                "request if this would be useful for you, and it will be "
                "prioritized."
            )

        with MPRester() as mpr:
            mpids = mpr.find_structure(struct)

            if len(mpids) == 0:
                raise PreventUpdate(
                    "No structures in the Materials Project database match this "
                    "crystal structure, so literature mentions cannot be retrieved. "
                    "Please submit this structure to Materials Project if you'd "
                    "like it to be added to the Materials Project database."
                )

            all_references = []
            for mpid in mpids:
                all_references.append(mpr.get_materials_id_references(mpid))
                self.logger.debug(f"Retrieved references for {mpid}.")

        if self.use_crossref:

            cr = Crossref(mailto=CROSSREF_MAILTO)
            individual_references = set()
            for references in all_references:
                individual_references.update(set(references.split("\n\n")))

            # exclude Materials Proect references (these are intended to be
            # references for the structure specifically)
            refs_to_remove = set()
            for ref in individual_references:
                if "Jain2013" in ref:
                    refs_to_remove.add(ref)
            individual_references -= refs_to_remove

            works = [cr.works(query=ref, limit=1) for ref in individual_references]
            self.logger.debug(f"Retrieved {len(works)} works from Crossref.")

            items = [
                work["message"]["items"][0]
                for work in works
                if len(work["message"]["items"]) > 0
            ]

            dois_to_item = {
                item["DOI"]: {
                    "cited-by": item.get("is-referenced-by-count", 0),
                    "score": item["score"],
                    "title": item.get("title", None),
                    "authors": item.get("author", []),
                    "journal": item.get("container-title", [None])[0],
                    "issue": item.get("issue", None),
                    "volume": item.get("volume", None),
                    "pages": item.get("page", None),
                    "date-parts": item.get("issued", {}).get("date-parts", [[None]]),
                }
                for item in items
                if item["score"] > 40
            }

            num_refs = len(dois_to_item)
            sorted_dois = sorted(
                list(dois_to_item.keys()),
                key=lambda doi: -dois_to_item[doi]["cited-by"],
            )

            if self.use_crossref_formatting:
                # use Crossref to retrieve pre-formatted text

                # remove leading "1. " from Science CSL style
                refs = {
                    doi: content_negotiation(ids=doi, format="text", style="science")[
                        3:
                    ]
                    for doi in dois_to_item.keys()
                }
                self.logger.debug(
                    f"Retrieved {len(refs)} formatted references from Crossref."
                )
                md = "  \n\n".join(
                    f"> [{refs[doi]}](https://dx.doi.org/{doi}) "
                    f"Cited by {dois_to_item[doi]['cited-by']}."
                    for doi in sorted_dois
                )
                formatted_references = dcc.Markdown(
                    md, className="mpc-markdown"
                )

            else:
                # else retrieve BibTeX entries to extract a nice author list
                # and perform our own formatting

                entries = {
                    doi: content_negotiation(ids=doi, format="bibtex")
                    for doi in sorted_dois
                }

                formatted_entries = []
                for doi, entry in entries.items():
                    author_string = self._bibtex_entry_to_author_text(entry)
                    journal_div = self._item_to_journal_div(dois_to_item[doi])

                    formatted_entries.append(
                        html.Blockquote(
                            [
                                html.A(
                                    [
                                        html.Div(
                                            [
                                                html.I(
                                                    # necessary since titles can contain HTML for superscripts etc.
                                                    dcc.Markdown(
                                                        dois_to_item[doi]["title"],
                                                        dangerously_allow_html=True
                                                    )
                                                )
                                            ]
                                        ),
                                        html.Div([author_string]),
                                        html.Div(
                                            [
                                                journal_div,
                                                html.Span(
                                                    f" Cited by {dois_to_item[doi]['cited-by']}."
                                                ),
                                            ]
                                        ),
                                    ],
                                    href=f"https://dx.doi.org/{doi}",
                                )
                            ],
                            className="mpc",
                            style={"padding-left": "1rem", "margin-bottom": "1rem"}
                        )
                    )

                formatted_references = html.Div(formatted_entries)
        else:
            # this uses pybtex directly on stored BibTeX entries from MP
            # most-accurate references and faster since no Crossref lookup
            # is required but no dois/hyperlinks available
            all_entries = {}
            for references in all_references:
                all_entries.update(Parser().parse_string(references).entries)
            md = self._pybtex_entries_to_markdown(all_entries)
            formatted_references = dcc.Markdown(md, className="mpc-markdown")
            num_refs = len(all_entries)

        return html.Div(
            [
                Label(f"{num_refs} references found{':' if num_refs>0 else '.'}"),
                formatted_references,
            ],
            style={"max-height": "20rem", "overflow-y": "scroll"},
        )
Exemple #6
0
    def options_layout(self):

        options = html.Div([
            html.Div([
                Label("Rotation axis"),
                dcc.Input(
                    value="[1, 0, 0]",
                    id=self.id("gb_rotation_axis"),
                    type="text",
                    className="input",
                ),
            ]),
            html.Br(),
            html.Div([
                Label("Choose Σ"),
                dcc.Dropdown(
                    id=self.id("gb_sigma_options"),
                    options=[],
                    placeholder="...",
                ),
            ]),
            html.Br(),
            html.Div([
                Label("Choose rotation angle"),
                dcc.Dropdown(
                    id=self.id("gb_rotation_options"),
                    options=[],
                    placeholder="...",
                ),
            ]),
            html.Br(),
            html.Div([
                Label("Grain width"),
                dcc.Slider(
                    id=self.id("gb_expand_times"),
                    min=1,
                    max=6,
                    step=1,
                    value=2,
                    marks={
                        2: "2",
                        4: "4",
                        6: "6"
                    },
                ),
            ]),
            html.Br(),
            html.Div([
                Label("Distance between grains in Å"),
                dcc.Input(
                    value="0.0",
                    id=self.id("gb_vacuum_thickness"),
                    type="text",
                    className="input",
                ),
            ]),
            html.Br(),
            html.Div([
                Label("Plane"),
                dcc.Input(
                    value="None",
                    id=self.id("gb_plane"),
                    type="text",
                    className="input",
                ),
            ]),
        ])

        return options