コード例 #1
0
    def _parse_tree_dict(self,
                         tree_dict: StrDict,
                         ncalls: int = 0) -> UniqueMolecule:
        product_node = UniqueMolecule(smiles=tree_dict["smiles"])
        self._add_node(
            product_node,
            depth=2 * ncalls,
            transform=ncalls,
            hide=tree_dict.get("hide", False),
            in_stock=tree_dict["in_stock"],
        )

        rxn_tree_dict = tree_dict.get("children", [])
        if not rxn_tree_dict:
            return product_node

        rxn_tree_dict = rxn_tree_dict[0]
        reaction_node = FixedRetroReaction(
            product_node,
            smiles=rxn_tree_dict["smiles"],
            metadata=rxn_tree_dict.get("metadata", {}),
        )
        self._add_node(reaction_node,
                       depth=2 * ncalls + 1,
                       hide=rxn_tree_dict.get("hide", False))
        self.tree.graph.add_edge(product_node, reaction_node)

        reactant_nodes = []
        for reactant_tree in rxn_tree_dict.get("children", []):
            reactant_node = self._parse_tree_dict(reactant_tree, ncalls + 1)
            self.tree.graph.add_edge(reaction_node, reactant_node)
            reactant_nodes.append(reactant_node)
        reaction_node.reactants = (tuple(reactant_nodes), )

        return product_node
コード例 #2
0
ファイル: config.py プロジェクト: wangxr0526/aizynthfinder
 def _update_from_config(self, config: StrDict) -> None:
     #  The first 3 places for properties are kept for historical reasons, but they are not recommended usage
     dict_ = config.get("finder", {}).pop("properties", {})
     dict_.update(config.get("policy", {}).pop("properties", {}))
     dict_.update(config.get("filter", {}).pop("properties", {}))
     dict_.update(config.pop("properties", {}))
     self.properties = dict_
コード例 #3
0
 def _update_dict(original: StrDict, other: StrDict) -> StrDict:
     # Used to complement the update method of the built-in dict type
     # it works for recursive dicts (to 1 level)
     for key, val in original.items():
         if key not in other or not isinstance(other[key], type(val)):
             continue
         if isinstance(val, Mapping):
             original[key] = Config._update_dict(original[key], other[key])
         else:
             original[key] = other[key]
     for key, val in other.items():
         if key not in original:
             original[key] = val
     return original
コード例 #4
0
def deserialize_action(
    dict_: StrDict, molecule_store: MoleculeDeserializer
) -> RetroReaction:
    """
    Deserialize a retrosynthesis action

    :param dict_: the (re)action as a dictionary
    :param molecule_store: the molecule deserialization object
    :return: the created action object
    """
    mol_spec = dict_.pop("mol")
    mol = molecule_store.get_tree_molecules([mol_spec])[0]
    try:
        class_spec = dict_.pop("class")
    except KeyError:
        class_spec = "aizynthfinder.chem.TemplatedRetroReaction"
    cls = load_dynamic_class(class_spec)
    return cls(mol, **dict_)
コード例 #5
0
ファイル: aizynthfinder.py プロジェクト: naisuu/aizynthfinder
    def run_from_json(self, params: StrDict) -> StrDict:
        """
        Run a search tree by reading settings from a JSON

        :param params: the parameters of the tree search
        :return: dictionary with all settings and top scored routes
        """
        self.stock.select(params["stocks"])
        self.expansion_policy.select(
            params.get("policy", params.get("policies", "")))
        if "filter" in params:
            self.filter_policy.select(params["filter"])
        else:
            self.filter_policy.deselect()
        self.config.C = params["C"]
        self.config.max_transforms = params["max_transforms"]
        self.config.cutoff_cumulative = params["cutoff_cumulative"]
        self.config.cutoff_number = params["cutoff_number"]
        self.target_smiles = params["smiles"]
        self.config.return_first = params["return_first"]
        self.config.time_limit = params["time_limit"]
        self.config.iteration_limit = params["iteration_limit"]
        self.config.exclude_target_from_stock = params[
            "exclude_target_from_stock"]
        self.config.filter_cutoff = params["filter_cutoff"]

        self.prepare_tree()
        self.tree_search()
        self.build_routes()
        if not params.get("score_trees", False):
            return {
                "request": self._get_settings(),
                "trees": self.routes.dicts,
            }

        self.routes.compute_scores(*self.scorers.objects())
        return {
            "request": self._get_settings(),
            "trees": self.routes.dict_with_scores(),
        }
コード例 #6
0
    def from_dict(cls, source: StrDict) -> "Configuration":
        """
        Loads a configuration from a dictionary structure.
        The parameters not set in the dictionary are taken from the default values.
        The policies and stocks specified are directly loaded.

        :param source: the dictionary source
        :return: a Configuration object with settings from the source
        """
        config_obj = Configuration()
        config_obj._update_from_config(source)

        config_obj.expansion_policy.load_from_config(
            **source.get("policy", {}).get("files", {})
        )
        config_obj.filter_policy.load_from_config(
            **source.get("filter", {}).get("files", {})
        )
        config_obj.stock.load_from_config(**source.get("stock", {}))
        config_obj.scorers.load_from_config(**source.get("scorer", {}))

        return config_obj
コード例 #7
0
 def _update_from_config(self, config: StrDict) -> None:
     self._properties.update(config.get("finder", {}).get("properties", {}))
     self._properties.update(config.get("policy", {}).get("properties", {}))
     self._properties.update(config.get("filter", {}).get("properties", {}))
     self._properties.update(config.get("properties", {}))
     self.__dict__.update(self._properties)