Skip to content

M4L4 — Reaction Classification

Loads saved assembly and reaction data, then performs reaction classification. This can be run as a continuation of M4L4 — Enumeration, or independently if the output/ files already exist.

Loading

from nasap_net import load_assemblies, load_reactions

assemblies = load_assemblies('output/assemblies.yaml')
reactions = load_reactions(
    'output/reactions.csv',
    assemblies=assemblies,
    site_id_type='int',
)

Classifier

A classifier is a function that takes a Reaction and returns a string class label.

The following example classifies reactions into 6 classes based on the kinds of ligands exchanged and whether a ring is formed or broken.

from nasap_net import Reaction, IncompleteReactionClassifierError


def classify_reaction(reaction: Reaction) -> str:
    r = reaction.as_reaction_to_classify()

    if r.leaving_kind == 'X' and r.entering_kind == 'L':
        if r.forms_ring():
            return 'ring_close'
        return 'forward'

    elif r.leaving_kind == 'L' and r.entering_kind == 'X':
        if r.breaks_ring():
            return 'ring_open'
        return 'backward'

    elif r.leaving_kind == 'L' and r.entering_kind == 'L':
        return 'LL'

    elif r.leaving_kind == 'X' and r.entering_kind == 'X':
        return 'XX'

    raise IncompleteReactionClassifierError(r)

Note

Using IncompleteReactionClassifierError helps detect an incomplete classifier. Place raise IncompleteReactionClassifierError wherever the code should be unreachable. For example, if the last elif block were accidentally omitted, any X→X reaction would trigger the error, immediately revealing that the classifier needs to be updated.

Classification

Pass the list of reactions and the classifier to classify_reactions.

from nasap_net import classify_reactions

reaction_to_class = classify_reactions(reactions, classify_reaction)

reaction_to_class is a {Reaction: str} dictionary.

Results

Count the number of reactions per class.

from collections import Counter

counter = Counter(reaction_to_class.values())
for reaction_class, count in sorted(counter.items()):
    print(f'{reaction_class}: {count}')

Output:

LL: 148
XX: 8
backward: 28
forward: 28
ring_close: 2
ring_open: 2

Saving

import os
from nasap_net import save_classification_result

os.makedirs('output', exist_ok=True)
save_classification_result(
    reaction_to_class,
    'output/classification_result.csv',
    overwrite=True,
)