Création d'un éditeur / visualiseur moléculaire: programmation orientée objet, structures de données et molécules


12

Je suis nouveau dans la programmation et j'essaie de résoudre mon premier gros problème et d'écrire mon premier gros programme. J'ai cherché des exemples de code open source pour apprendre, mais jusqu'à présent, je n'ai trouvé que du code dans des langues que je ne comprends pas complètement ou qui font des choses liées mais encore trop éloignées pour que j'apprenne vraiment. J'ai du mal à prendre certaines mesures conceptuelles ici.

Je veux créer un simple logiciel pour construire, modifier et représenter plus tard de petites molécules organiques. Il s'agit principalement d'un exercice d'apprentissage. Un utilisateur donnerait une chaîne SMILES ou choisirait parmi un ensemble de base de molécules de démarrage, puis pourrait s'appuyer sur cette molécule soit graphiquement soit via une syntaxe de saisie de texte. Cependant, je ne suis même pas encore à ce point de complexité. Je n'arrive même pas à comprendre comment créer des classes / objets pour stocker les molécules. Donc, ma question succinctement: comment utiliser des classes / objets pour construire des molécules tout en conservant tous les niveaux d'informations, et quelles structures de données dois-je utiliser comme attributs pour quels objets? Et, les objets peuvent-ils être des attributs d'autres objets?

Voici ce que j'ai pensé jusqu'à présent: je pensais avoir une classe "Molécule", puis une classe / sous-classe "Atom" et une sous-classe "Bond", et peut-être aussi une sous-classe "FunctionalGroup". Cela semble être un bon point de départ, mais peut-être que je ne comprends pas bien la POO et c'est mauvais. Mais alors mon problème devient vraiment déroutant (pour moi). Même si j'ai tous ces concepts / idées / classes, je ne saisis pas complètement quelles infrastructures de données sont nécessaires pour représenter la molécule. Une liste d'atomes serait une bonne chose à avoir. Cette liste pourrait-elle être une liste d'objets Atom? J'aurais également besoin d'un moyen de stocker la connectivité. Une matrice 2D semble être une bonne idée, avec l'ordre des liaisons sous forme d'entiers dans les positions de la matrice.

À ce stade, je commence à être submergé par la tâche. Est-ce que tout ce que je fais jusqu'à présent a du sens? Ajouter un aspect d'affichage / de dessin en plus de cela peut signifier que je dois réécrire / retravailler un grand nombre de ces choses, mais j'essaie simplement d'arriver à un point où je peux au moins stocker des molécules avec les données pertinentes, puis accéder ces données à vérifier / modifier. Je pensais faire cela en Python, donc le code / les classes ressemblerait peut-être à ceci: http://pastebin.com/uUi1BMzr

C'est peut-être vraiment une question de programmation pour StackOverflow, mais je pensais que c'était assez spécifique pour aller ici. Toute aide serait grandement appréciée, même si vous précisez simplement où j'ai fait des bévues conceptuelles. Merci d'avance.


1
De plus, pour tous ceux qui tentent de faire quelque chose de similaire, je viens de trouver un joli package python open source qui m'a aidé avec quelques concepts appelés MMTK, pour la boîte à outils de mécanique moléculaire.
Nate

1
Avez-vous regardé OpenBabel? Cela devrait avoir tout ce dont vous avez besoin à portée de main.
Deathbreath

Réponses:


5

écrire un logiciel est un processus itératif - écrire du code -> voir jusqu'où vous pouvez aller, puis planifier les prochaines étapes -> écrire du code -> répéter. À ce stade de l'apprentissage de l'art, je vous suggère de vous lancer bientôt juste pour tester les eaux. Pas besoin de planifier tout le système à l'avance. Oui, le python serait une bonne première langue. Pour la visualisation, essayez MatPlotLib, NumPy et SciPy sont également pratiques. Les logiciels à l'échelle industrielle reposent toujours sur l'extraction de bibliothèques pré-construction, au lieu d'écrire tout vous-même, mais des solutions simples peuvent et doivent être écrites vous-même, en particulier lorsque vous apprenez à programmer. Votre disposition OO semble OK pour l'instant. Lorsque / si vos relations d'objet doivent changer plus tard, l'acte de refactorisation de votre code lui-même est une expérience digne à maîtriser. Bienvenue à bord !


Merci pour la contribution. Je vais juste continuer. J'apprends également un peu sur le passage et la mutation des attributs / variables d'un objet. C'est vraiment fascinant de prendre quelque chose du monde réel et d'essayer de le représenter dans le code informatique.
Nate

9

Votre objectif comporte de nombreux défis. Je vais les décomposer en plusieurs parties.

SMILES n'est pas un langage trivial à analyser, et les règles de perception de l'aromaticité ne sont pas bien définies. La définition de grammaire détaillée du projet OpenSMILES devrait aider certains.

SMILES définit la topologie, mais ne donne pas d'informations 2D ou 3D. Faire l'un ou l'autre est difficile. (Autrement dit, si vous voulez qu'il soit joli.)

Vraiment, vous devriez vous tourner vers la boîte à outils RDKit cheminformatics (ou OpenBabel, mais je préfère RDKit). Il a un analyseur SMILES intégré, ainsi qu'une disposition 2D, et je crois que la génération de conformation 3D. OpenBabel fait de même.

Ensuite, pour l'affichage, vous devrez comprendre le système GUI. En fait, ici, la boîte à outils CDK cheminformatics, en Java, est la plus avancée.

Mais vous êtes dans les bases de la façon de représenter une molécule. Il existe des différences entre les modèles de données à petites molécules et à grandes molécules (protéines, ADN), mais comme vous êtes intéressé par SMILES, cela signifie que vous êtes orienté vers les petites molécules.

Vous pouvez consulter les documents API pour RDKit, OpenBabel, CDK, OEChem et Indigo, entre autres. Cela vous donnera une idée des différentes façons dont les gens développent leur API de classe. Parmi ceux-ci, je préfère OEChem le plus, suivi de RDKit. Même si OEChem est open source, l'API est en ligne et librement lisible, avec des exemples d'utilisation.

En bref, ayez une classe Molecule, avec une liste d'instances Atom et Bond. "mol.AddAtom (numéro d'élément)" crée un nouvel atome, sans liaisons, "mol.AddBond (atom1, atom2, bond_type)" établit une connexion de liaison. Chaque liaison doit connaître les atomes auxquels elle est connectée, et chaque atome a besoin d'une liste de liaisons. Cela conduit à de nombreux cycles dans la structure des données, mais cela est nécessaire pour que divers algorithmes, comme la recherche de connectivité, puissent être effectués en temps linéaire.

N'utilisez pas de matrice 2D. Bien que cela soit faisable pour une petite molécule, elle n'évolue pas aussi bien et elle n'est pas nécessaire. Peu d'algorithmes ont besoin de la matrice de connectivité, et elle est facilement générée si / quand cela est nécessaire.

Ne pas avoir de "FunctionalGroup". C'est trop spécialisé. Utilisez quelque chose comme un "sous-ensemble" ou "fragment", qui contient la liste des atomes et des liaisons qui vous intéressent. De cette façon, vous pouvez également gérer des choses comme "les atomes sélectionnés" et "la sous-structure de l'anneau" et "l'échafaudage" en vous référant à le sous-ensemble spécifique.

J'ai regardé ta boîte à pâte. L'analyseur ne devrait pas fonctionner de cette façon. Vous devez séparer l'analyse de votre structure moléculaire réelle. Essayez quelque chose comme ceci:

class Molecule(object):
    def __init__(self):
        self.atoms = []
        self.bonds = []
        self._atom_id = 0
        self._bond_id = 0
    def _next_atom_id(self):
        atom_id = self._atom_id
        self.atom_id += 1
        return atom_id
    def AddAtom(self, eleno):
        self.atoms.append(Atom(self, self._next_atom_id(), eleno))
    def AddBond(self, atom1, atom2, bondtype):
        assert atom1.molecule is atom2.molecule
        self.bonds.append(Bond(self, self._next_bond_id(),
                               atom1, atom2, bondtype))

class Atom(object):
    def __init__(self, molecule, id, eleno):
        self.molecule = molecule
        self.id = id
        self.eleno = eleno
        self.charge = 0
        self.isotope = 0
   ..

puis l'analyseur pour une simple chaîne linéaire comme "CC O" est:

def parse_linear_chain(text):
   mol = Molecule()
   prev_atom = None
   for atom_symbol in text.split():
     eleno = lookup_symbol[atom_symbol]
     atom = mol.NewAtom(eleno)
     if pre_atom is not None:
       mol.AddBond(prev_atom, atom, 1)
     prev_atom = atom
   return mol

Bien sûr, un analyseur SMILES complet est beaucoup plus compliqué que cela, et le modèle de données complet doit gérer des choses comme les comptages d'hydrogène, qui sont souvent implicites.

Les listes de diffusion OpenBabel, RDKit et CDK sont également de bons endroits où aller, si vous décidez d'utiliser l'une de ces boîtes à outils. Il y a aussi le site de questions / réponses "Blue Obelisk", hébergé par Shapado.


1

Une autre approche pour commencer pourrait être de jeter un œil à du code qui fait déjà quelque chose en rapport avec votre problème. Dans ce cas, votre exercice pourrait même se retrouver dans un autre programme, et ce serait bien, non?

Les programmes qui pourraient vous intéresser sont

  • Le package de simulation MD et de modélisation moléculaire MMTK (comme déjà suggéré par Nate ci-dessus)

  • Le package de visualisation PyMol


1

Apprendre les détails d'un système d'objet moléculaire est une merveilleuse façon pour les chimistes d'apprendre la programmation orientée objet. Vous constaterez que la mise en œuvre d'un tel système affinera vos intuitions moléculaires. Vous devriez réfléchir sérieusement aux atomes, aux molécules et peut-être aux collections de molécules en termes d'attributs et de méthodes.

Voici quelques jolies diapositives en python (un peu plus anciennes) qui peuvent vous aider: http://www.wag.caltech.edu/home/rpm/python_course/Lecture_4.pdf

Pour vérifier votre travail: en plus de openbabel (qui a des liaisons python!) Et MMTK, il y a ELBOW dans phenix.

Pour le polyglotte en vous, il y a aussi PerlMol (Perlmol.org). PerlMol est écrit en Perl orienté objet et peut être téléchargé depuis CPAN.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.