PDF file
Transcription
PDF file
2 Rapport de stage Master Recherche deuxième année Nanophysique, Nanocomposants, Nanomesures Université Paul Sabatier, Toulouse . Marie Brut . ———————————————————————– Flexibilité en biologie : Déformation des molécules par une approche de modes statiques ———————————————————————– . Responsables LAAS : Mehdi Djafari Rouhani Alain Estève Georges Landa . Laboratoire d’Architecture et d’Analyse des Systèmes CNRS 7, avenue du Colonel Roche 31077 Toulouse 3 1 Un immense merci à Mehdi, Alain et Georges pour m’avoir donné ce stage et permis de travailler ces derniers mois avec eux. Leur patience, leur pédagogie et leur bonne humeur permanente sont toujours venues à bout des difficultés et de mes incompréhensions . . . 2 Table des matières 1 Introduction au docking des macromolécules 1.1 Enjeu de la prédiction des interactions . . . . 1.2 Interactions entre macromolécules . . . . . . . 1.2.1 Mécanisme . . . . . . . . . . . . . . . . 1.2.2 Observations expérimentales . . . . . . 1.3 Avancées et difficultés rencontrées . . . . . . . 1.3.1 Les progrès du docking . . . . . . . . . 1.3.2 Les obstacles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 9 10 10 10 12 12 13 2 Une nouvelle approche pour déformer les molécules 2.1 Mise en œuvre de la théorie . . . . . . . . . . . . . . 2.2 Notre approche du problème de la flexibilité . . . . . 2.2.1 Cas simple d’un système à un degré de liberté 2.2.2 Cas d’un système à plusieurs degrés de liberté 2.3 Méthode et élaboration du logiciel . . . . . . . . . . . 2.3.1 Méthode générale . . . . . . . . . . . . . . . . 2.3.2 Explication de l’algorithme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 17 18 18 18 19 19 20 3 Validation de la méthode 3.1 Exemple d’un polymère ”intelligent” : le PNIPAM 3.2 Visualisation des modifications conformationnelles 3.3 Résultats . . . . . . . . . . . . . . . . . . . . . . . 3.3.1 L’eau . . . . . . . . . . . . . . . . . . . . . 3.3.2 Le PNIPAM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 22 23 24 24 24 . . . . . 28 28 28 29 29 30 4 Accrochage de deux molécules 4.1 Objectif . . . . . . . . . . . . 4.2 Méthode . . . . . . . . . . . . 4.3 Deux cas à traiter . . . . . . . 4.3.1 Cas où T12 6= 1 . . . . 4.3.2 Cas où T12 = 1 . . . . . . . . . . . . . . . . . . . 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 4.4 Application à la construction d’un C2 H6 avec deux CH4 . . . . . . . . . . 31 5 Conclusion A Rappel sur les protéines A.1 Les acides aminés . . . . . . . . . . . A.2 Structure et propriétés des protéines A.2.1 Les forces structurales . . . . A.2.2 Forme de la molécule . . . . . 33 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 36 37 37 38 B Décomposition d’un mouvement en modes normaux 40 B.1 Introduction aux modes normaux . . . . . . . . . . . . . . . . . . . . . . . 40 B.2 Principe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 B.3 Calcul des modes propres . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 C Résolution de systèmes linéaires : méthode de Gauss-Seidel C.1 Position du problème . . . . . . . . . . . . . . . . . . . . . . . C.2 Principe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . C.2.1 Ecriture du système . . . . . . . . . . . . . . . . . . . C.2.2 Décomposition de la matrice A . . . . . . . . . . . . . C.3 Méthode de Gauss-Seidel . . . . . . . . . . . . . . . . . . . . . C.3.1 Description de la méthode . . . . . . . . . . . . . . . . C.3.2 Condition d’arrêt . . . . . . . . . . . . . . . . . . . . . C.3.3 Algorithme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44 44 44 44 45 46 46 46 46 D Programmes 48 D.1 Flexibilité des macromolécules : calcul des déformations . . . . . . . . . . . 48 D.2 Visualisation de la déformation . . . . . . . . . . . . . . . . . . . . . . . . 69 D.3 Accrochage de deux molécules . . . . . . . . . . . . . . . . . . . . . . . . . 72 Table des figures 1.1 1.2 1.3 1.4 1.5 1.6 1.7 3.1 3.2 3.3 3.4 3.5 3.6 Organigramme expliquant la collaboration étroite qui existe entre la biologie et la bioinformatique. La création de nombreuses bases de données, les observations expérimentales ainsi que les prédictions par logiciel débouchent conjointement sur l’élaboration de nouveaux médicaments. . . . . . . . . . Sous contrainte de la protéine, l’évaluation de nombreux candidats mène finalement à considérer un complexe déterminé. . . . . . . . . . . . . . . . Exemple d’une protéine allostérique dont l’activité est modulée par la fixation non-covalente et réversible d’ une ou plusieurs molécules (ligand). La fixation de ces dernières induit un changement de la conformation des sousunités avec pour conséquence une modification de l’ activité biologique. . . Exemple de la détermination de la structure d’une protéine par RMN : les déplacements chimiques enregistrés révèlent qu’elle présente une structure secondaire. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Prédiction par RMN d’une interaction au niveau d’une membrane cellulaire. Réalisation du docking du promoteur N-Oct3 et du facteur de transcription HNF-3B. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Exemple du récepteur Glur2 : ce récepteur change de conformation selon le ligand avec lequel il doit interagir, d’où l’importance de prendre en compte le problème de la flexibilité lors du docking. . . . . . . . . . . . . . . . . . Structure en 3 dimensions de la molécule de PNIPAM, obtenue avec le logiciel de visualisation Molden. . . . . . . . . . . . . . . . . . . . . . . . . Exemple du fichier .xyz d’une molécule d’eau non déformée donné par le logiciel GAUSSIAN. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Molécule d’eau non déformée : la longueur des liaisons O − H est de 0.965 Angström, les trois atomes font un angle de 105.700 . . . . . . . . . . . . . . Premier mode de déformation obtenu : les liaisons O − H font 1.863 et 0.632 Angström, la valeur de l’angle a augmenté : 114.780 . . . . . . . . . . Second mode de déformation : la longueur des liaisons O − H est de 0.99 et 0.37 Angström, les trois atomes sont presque aligné : l’angle vaut 15.870 . Troisième mode de déformation : les longueurs des liaisons O − H sont voisines : 0.904 et 1.01 Angström, la valeur de l’angle est de 62.530 . . . . . 5 10 10 11 11 12 13 14 22 23 24 24 25 25 6 3.7 Indiqués par les flèches, les deux atomes O et H concernés par le greffage avec l’eau. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.8 A gauche, la molécule de PNIPAM non déformée. A droite, déformation de la molécule de PNIPAM obtenue en déplaçant l’oxygène dans la direction y. 3.9 A gauche, la molécule de PNIPAM non déformée. A droite, déformation dans la direction x : la distance N − N (azote en bleu) passe de 4.81 à 5.81 Angström et la distance C − C passe de 6.51 à 7.58 Angström. . . . . . . . 3.10 A gauche, la molécule de PNIPAM non déformée. A droite, déformation dans la direction z : la distance N − N (azote en bleu) passe de 4.81 à 5.05 Angström et la distance C − C passe de 6.51 à 6.61 Angström. . . . . . . . 4.1 4.2 25 26 27 27 Exemple de deux molécules de CH4 à assembler. Les deux hydrogènes fléchés vont être retirés et laisser place à une liaison entre les carbones. . . 31 Molécule de C2 H6 obtenue par greffage d’un CH4 sur un autre CH4 , on a pris une distance de 1.45 Angström. . . . . . . . . . . . . . . . . . . . . . . 32 A.1 Exemple de la structure très complexe d’une protéine, obtenue avec le logiciel de visualisation Molden. . . . . . . . . . . . . . . . . . . . . . . . . A.2 Représentation de la structure d’un acide aminé : le carbone est relié à un groupement amine, un groupement acide et un radical variant selon la molécule. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . A.3 Exemple de la représentation chimique de cinq acides aminés mettant en évidence les différents radicaux qui les caractérisent. . . . . . . . . . . . . A.4 Exemple de la détermination de la structure d’une protéine par RMN : les déplacements chimiques Cα et Cβ caractérisent la structure secondaire de cette molécule. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . A.5 Représentation de différentes structures d’une protéine : on distingue par exemple les formes secondaires (hélice alpha et feuillet bêta) et tertiaires. . 35 . 36 . 36 . 38 . 39 7 Introduction Selon un avis commun, les interactions en biologie reposent sur l’existence de structures complémentaires, de type clé-serrure, permettant une adaptation parfaite des biomolécules. A partir de cette réflexion, de nombreux modèles de docking ont été proposés, mais aucun ne semble satisfaisant. La raison invoquée est la flexibilité extrême des biomolécules. L’inadéquation des modèles semble donc inévitable, la structure clé-serrure étant en ellemême représentative d’un certaine rigidité. C’est pour palier à ce défaut que le traitement des déformations moléculaires à l’aide des ”modes statiques” a été envisagé au LAASCNRS. Les modes statiques n’ont rien de commun avec les modes normaux qui représentent quant à eux les vibrations propres de chaque molécule. Spécifiques à une molécule donnée, les modes normaux sont complètement modifiés lors de l’interaction avec une autre molécule. A l’inverse, les modes statiques sont conçus pour que la molécule puisse être soumise à une interaction ultérieure. Les déformations possibles sont calculées en fonction des paramètres représentant chacun un site particulier d’interaction. L’objectif est de réaliser le docking sur un site d’interaction, avec un temps minimum de calcul, celui-ci étant habituellement important en raison du nombre élevé d’atomes et des méthodes adoptées. Nous pourrons ainsi tester un grand nombre de cas avant d’établir une statistique sur les sites possibles et d’opter pour la structure la plus optimale. Le gain en temps de calcul est réalisé par un stockage préalable, dans une banque de données des modes statiques correspondant à chaque molécule. Ainsi, au moment de l’interaction, ces données seront utilisées pour minimiser l’énergie d’interaction. En fonction des sites d’interaction, toujours en nombre réduit, l’énergie d’interaction ne dépendra que de quelques paramètres. Non seulement la minimisation de cette énergie sera aisée, mais nous pourrons en plus envisager, moyennant une augmentation du temps de calcul, d’utiliser des potentiels anharmoniques dans l’expression de l’énergie. Il s’agit d’un autre avantage des modes statiques par rapport aux modes normaux qui sont fondamentalement des oscillateurs harmoniques. Dans ce rapport, nous commencerons par introduire le concept de docking des macromolécules, en particulier des molécules biologiques. Nous continuerons par la description du modèle des modes statiques et du logiciel Flexible que nous avons élaboré. Le chapitre 3 sera consacré à l’application du modèle au cas simple des polymères du type P-NIPAM. Nous expliquerons également la démarche adoptée pour élaborer un secong logiciel, Greffage, qui permet d’accrocher deux molécules. Enfin, nous évoquerons les conclusions principales de cette étude. Des annexes viennent compléter et éclaicir ce rapport afin d’aider 8 le lecteur à aborder ce travail multidisciplaire, couvrant la physique, la biologie et les méthodes numériques. Chapitre 1 Introduction au docking des macromolécules 1.1 Enjeu de la prédiction des interactions Connaı̂tre la structure en trois dimensions des macromolécules et comprendre leurs mécanismes de complexation est fondamental pour la compréhension des systèmes biologiques, et donc essentiel dans de nombreux domaines. Dans ce but, la physique apporte sa collaboration à la biologie structurale qui s’intéresse quant à elle au rapport qui existe entre la structure des molécules et leur fonction biologique (voir figure 1.1). Cette union débouche sur des avancées couvrant différentes applications, telles que : • La recherche pharmacologique (conception de médicaments en trouvant un ligand, c’est-à-dire une molécule médicamenteuse complémentaire, à assembler avec un récepteur membranaire connu) • La biologie cellulaire (interaction entre macromolécules, protéines ou acides nucléiques, intervenant dans les cycles cellulaires) • La recherche médicale (élaboration de nouveaux traitements visant les cellules une à une . . . ) • Les nanobiotechnologies (conception de puces à ADN, de biocapteurs . . . ) Cependant, le docking, phénomène par lequel deux molécules s’assemblent dans un espace à trois dimensions, demeure un problème aussi bien fondamental qu’irrésolu ; les tentatives échouent généralement lorsqu’elles sont appliquées à des molécules composées d’un grand nombre d’atomes, comme les protéines. En effet, lorsqu’on essaie de trouver la structure spatiale d’un complexe formé par deux molécules, une protéine et un ligand par exemple, il faut réaliser des essais avec de nombreux ligands et évaluer l’aptitude de chacun à produire l’effet recherché et ses performances en terme d’efficacité (voir figure 1.2). La question devient alors très complexe, 9 10 notamment en raison du nombre de conformations possibles, des contraintes, des interactions faibles . . . Ainsi, un des principaux objectifs de la bioinformatique est de parvenir à simuler et à prédire correctement les mécanismes et les interactions expliquant la formation et les propriétés des complexes protéine-protéine et protéine-ligand. Fig. 1.1 – Organigramme expliquant la collaboration étroite qui existe entre la biologie et la bioinformatique. La création de nombreuses bases de données, les observations expérimentales ainsi que les prédictions par logiciel débouchent conjointement sur l’élaboration de nouveaux médicaments. 11 Fig. 1.2 – Sous contrainte de la protéine, l’évaluation de nombreux candidats mène finalement à considérer un complexe déterminé. 1.2 1.2.1 Interactions entre macromolécules Mécanisme On pense généralement que la formation de ces complexes est fondée sur la reconnaissance de la structure tridimensionnelle d’un ligand par un site récepteur et contrôle l’activité de nombreuses molécules. Le plus souvent, le récepteur est une protéine qui possède un ou plusieurs sites actifs spécifiques, plus ou moins accessibles selon les cas. Le ligand, quant à lui, est généralement une molécule flexible étrangère de petite taille. La liaison entre le ligand et le récepteur introduit un signal biologique qui peut avoir diverses formes. Par exemple, certains récepteurs sont des protéines membranaires permettant le passage sélectif de certaines molécules (ions, nutriments) à l’intérieur de la cellule, d’autres sont des enzymes dont l’activité est fonction de l’affinité spécifique avec un substrat . . . La figure 1.3 en est une illustration. 1.2.2 Observations expérimentales Des études expérimentales apportent de plus en plus d’informations précieuses sur les molécules biologiques et leurs manières d’interagir. Grâce à l’analyse cristallographique par diffraction de rayons X, par RMN . . . nous avons 12 Fig. 1.3 – Exemple d’une protéine allostérique dont l’activité est modulée par la fixation non-covalente et réversible d’ une ou plusieurs molécules (ligand). La fixation de ces dernières induit un changement de la conformation des sous-unités avec pour conséquence une modification de l’ activité biologique. accès à un nombre de plus en plus élevé de structures tri-dimensionnelles de protéines (voir figures 1.4 et 1.5) ; en particulier, l’analyse de la complexation protéine-ligand permet d’avoir une image très précise des interactions se produisant au niveau même du site d’arrimage. Cependant, cette image est figée, et surtout, elle ne tient pas compte des obstacles que le ligand aura à franchir avant d’atteindre le site d’arrimage, en particulier lorsque celui-ci est enfoui au coeur de la protéine. Or, la trajectoire suivie par le ligand peut jouer un rôle essentiel pour la discrimination entre différentes molécules capables de se fixer au récepteur. De plus, l’accès du ligand à son site d’arrimage présuppose dans certains cas des changements conformationnels du ligand et parfois même de la protéine. Il serait donc capital de pouvoir prédire un couplage correct, répondant aux observations et aux fonctionnalités biologiques connues des macromolécules. Biologistes, chimistes et physiciens unissent de plus en plus leurs efforts dans cette voie. Un outil informatique performant représenterait un gain de temps non négligeable pour explorer les possibilités d’assemblage optimum entre deux molécules sans attendre quelles soient observées. 13 Fig. 1.4 – Exemple de la détermination de la structure d’une protéine par RMN : les déplacements chimiques enregistrés révèlent qu’elle présente une structure secondaire. Fig. 1.5 – Prédiction par RMN d’une interaction au niveau d’une membrane cellulaire. 1.3 1.3.1 Avancées et difficultés rencontrées Les progrès du docking Ces dernières années, afin d’atteindre ce but, plusieurs groupes ont développé des outils pour résoudre le problème du docking de deux molécules 1 . De nombreux algorithmes ont été créés et sont utilisés actuellement dans les laboratoires pharmaceutiques. On les applique par exemple à l’ingénierie des protéines, à la conception de médicaments . . . De 1 Des programmes ont été écrits afin d’assembler automatiquement un ligand (petite molécule telle qu’un médicament potentiel) et une cible macromoléculaire (habituellement une protéine, un brin d’ADN). On recense par exemple : • Accelrys qui tient compte de l’énergie et des déformations • AutoDock qui ne tient compte que des énergies, les molécules restant pratiquement rigides • 3D-Dock qui travaille sur le modèle des sphères molles (formées d’un noyau répulsif et d’une carapace plus molle attractive) sans déformation • BioMove3D qui a été conçu au LAAS et adopte le modèle des sphères dures avec quelques déformations 14 nouveaux ligands ont notamment été conçus pour des agents anti-sida et anti-cancer ou encore pour le traitement des diabètes. Fig. 1.6 – Réalisation du docking du promoteur N-Oct3 et du facteur de transcription HNF-3B. Ces programmes sont généralement axés sur l’hypothèse que les ligands formant des interactions favorables avec le récepteur doivent avoir une forte affinité de liaison. Ils explorent ainsi l’espace des conformations de façon systématique, afin de générer et d’évaluer un grand nombre de liaisons potentielles. Ces outils ont été développés soit par un travail sur la géométrie des structures et des possibilités d’emboı̂tement, soit par une étude des énergies d’interaction 2 . Diverses méthodologies permettent d’estimer l’énergie libre de formation d’un complexe macromoléculaire : elles ont permis d’identifier les facteurs qui favorisent la complexation et de mettre en évidence l’importance de tenir compte des effets en compétition dans l’interprétation de la reconnaissance protéine - ligand. Les résultats obtenus indiquent que les termes de Van der Waals (agencement/ajustement 2 Une des méthodes utilisées est la méthode ab initio (précise, mais longue) : en tenant compte de la totalité des électrons mis en jeu par chaque atomes, l’énergie de la structure moléculaire est calculée à partir des orbitales moléculaires définies comme la somme d’orbitales connues. La prédiction des structures 3D des protéines par une optimisation globale de l’énergie libre estimée a été tentée sans grand succès ces trente dernières années, notamment en raison de meilleurs résultats qui sont obtenus à présent, grâce à l’optimisation de la fonction d’énergie libre en coordonnées internes, par la dynamique moléculaire et l’approche de Monte Carlo. 15 stérique) et hydrophobes peuvent être un élément de reconnaissance moléculaire. En revanche, l’importance des interactions électrostatiques et des liaisons hydrogènes est plus variable en fonction des systèmes (ces interactions sont développées dans l’annexe A au paragraphe A.2.1). 1.3.2 Les obstacles Même si de nombreuses méthodes sont désormais performantes lorsqu’elles sont appliquées à de petits ligands et à leurs récepteurs, les algorithmes restent peu efficaces si on met en jeu des macromolécules telles que les protéines. Traiter la flexibilité des biomolécules Fig. 1.7 – Exemple du récepteur Glur2 : ce récepteur change de conformation selon le ligand avec lequel il doit interagir, d’où l’importance de prendre en compte le problème de la flexibilité lors du docking. Pendant longtemps, et encore dans certaines méthodes, on a considéré un modèle rigide pour configurer les macromolécules. Pourtant, il est aisé d’imaginer qu’en appliquant une force extérieure sur un atome (comme cela se passe lors de la mise en contact de deux molécules), la structure de la molécule s’en verra perturbée. Considérer que la molécule est rigide, indéformable ne peut donc pas donner de résultat satisfaisant pour la réalisation du couplage. D’autre part, il a été vérifié que la flexibilité conformationnelle d’une macromolécule isolée est corrélée avec sa déformation au sein des complexes (voir figure 1.7). Ainsi, lors de la 16 simulation du comportement de ces molécules biologiques, il est souvent nécessaire perturber leur structure de façon contrôlée : ceci permet d’étudier les changements conformation qui sont trop lents pour être observés spontanément lors de trajectoires dynamique moléculaire ou d’induire des conformations normalement présentes au sein complexes macromoléculaires qui sont trop grands pour être simulés directement. de de de de En ce sens, quelle que soit l’approche utilisée, il semble indispensable de s’appuyer sur les propriétés de flexibilité des macromolécules, particulièrement en ce qui concerne les molécules biologiques qui sont caractéristiques de ce phénomène. A ce niveau, il faut tenir compte des interactions existant entre les atomes d’une molécule afin de comprendre le maintien de sa stabilité et l’évolution de sa forme (cf annexe A). Elles permettent en effet d’expliquer les changements de conformation rencontrés lors des changements de milieu (pH, température . . . ), mais aussi lorsqu’on met la protéine en contact avec une surface, ou simplement un objet à lier. D’autre part, elles interviennent dans l’explication de nombreuses maladies dites conformationnelles sont dues à des repliements anormaux des protéines ; notamment les maladies à prions (Creutzfeld-Jakob) et les maladies neurodégénératives (Alzheimer, Parkinson...). De nombreux modes de vibration La difficulté provient donc de la prise en compte de ces changements de forme, mais aussi de leur nombre. La quantité d’atomes composant une molécule biologique étant considérable, le nombre d’inconnues à traiter l’est aussi. En effet, considérer la structure 3D d’une molécule comprenant N atomes implique de travailler avec 3N degrés de liberté constitués de 3 translations d’ensemble, 3 rotations (ou 2 rotations seulement pour une molécule linéaire), et 3 N - 6 (respectivement 3 N 5) mouvements correspondant aux vibrations moléculaires. L’analyse des 3 N - 6 vibrations d’une molécule à grand nombre d’atomes ne peut donc être menée qu’en mettant en oeuvre d’importants moyens de calcul. Ces vibrations peuvent cependant être décrites plus commodément en utilisant les coordonnées normales (ou généralisées), combinaisons linéaires des coordonnées cartésiennes, dont chacune” rassemble ” les mouvements de même fréquence (cf annexe B). Chacune de ces coordonnées implique alors le mouvement de plusieurs atomes et définit une direction, un sens et une amplitude pour chacun, tous vibrant à la même fréquence dans ces directions, selon un mode normal de vibration. Les principales propriétés des coordonnées normales sont les suivantes : • Tous les atomes d’un mode vibrent à la même fréquence, en phase ou en opposition de phase 17 • Les vecteurs représentant l’amplitude du déplacement de chaque atome doivent être tels que le centre de gravité de la molécule soit immobile (pas de translation) et que son orientation soit constante (pas de rotation) Tout mode de fréquence non nulle correspond donc strictement à une déformation. On peut remarquer que les déplacements de chaque atome étant pondérés par la masse de cet atome, ceci implique que les atomes lourds se déplacent moins que les atomes légers. De nombreuses méthodes s’appuient sur les modes normaux [11] [12]. Cependant, les modes normaux ont trois inconvénients : • La mise en interaction de deux molécules modifie complètement ce type de vibrations • Ils représentent des oscillateurs harmoniques découplés ; le domaine de validité des déformations induites est donc restreint et se trouve au voisinage des structures d’équilibre où l’approximation harmonique peut être utilisée • Ils représentent les vibrations propres, c’est-à-dire spontanées, de la molécule, alors que la flexibilité dans le docking est induite par l’interaction entre les molécules, sous l’action des forces extérieures Chapitre 2 Une nouvelle approche pour déformer les molécules 2.1 Mise en œuvre de la théorie Comme nous l’avons dit précédemment, les déformations d’une molécule isolée correspondent à celles que l’on retrouve lors de la formation d’un complexe. Nous nous proposons donc de retrouver les états de déformation possibles d’une molécule en nous appuyant sur la propriété de flexibilité des molécules biologiques : nous recensons dans un premier temps l’ensemble des changements de conformation pouvant se produire pour chacune des molécules prise séparément. Puis dans un second temps, nous procédons au docking en choisissant un point de contact entre deux atomes dont on force les positions relatives et en minimisant l’énergie d’interaction. Pendant ce stage, nous avons traité le cas des polymères afin de valider la méthode. Il est prévu par la suite d’adapter le programme au traitement de plus grosses molécules, des protéines par exemple, et de considérer plusieurs points d’ancrage. La technique développée dans ce projet doit permettre une analyse performante des structures et des interactions dans le domaine de la modélisation moléculaire. Les champs d’applications potentiels sont très vastes et notre outil pourra permettre de progresser dans la compréhension, l’analyse ou la prédiction : ◦ des changements conformationnels des protéines et de la flexibilité nécessaire du ligand ◦ de la perméabilité et de la sélectivité des membranes cellulaires ◦ de l’activité des médicaments ayant pour cible des récepteurs peu accessibles . . . 18 19 2.2 2.2.1 Notre approche du problème de la flexibilité Cas simple d’un système à un degré de liberté Il est bien connu qu’en tenant compte des forces intérieures Fi et extérieures Fe appliquées à un système, celui-ci peut alors être décrit par l’équation : mẍ − Fi = Fe soit, en faisant la transformée de Fourier : mω 2 − ki = ke où ki est la constante des forces internes, ke est la constante des forces externes (i.e. la transformée de Fourier de Fe à la fréquence ω) et m la masse du système. p Si on laisse la molécule vibrer spontanément, alors ke = 0, d’où ω = ki /m. Les plus basses fréquences de l’ordre de 1010 s−1 correpondant à une énergie de l’ordre de 1cm−1 . Or, en biologie, étant donnés les temps de réaction de plusieurs heures, les fréquences de vibration qui interviennent dans les interactions sont supérieures à 10−2 s−1 , soit un rapport de plus de 10 ordres de grandeur avec les fréquences propres des molécules ! Comment faire tendre ω vers 0 de manière à se rapprocher de l’état naturel de ces molécules ? Plusieurs solutions s’offrent à nous : ◦ en prenant ki = 0 : c’est-à-dire en considérant qu’il n’y a pas de forces internes qui s’appliquent dans les modèles géométriques et robotiques ◦ en prenant m → ∞ : la masse effective est alors de 1024 fois la masse réelle (une molécule devient une mole !) Nous choisissons dans ce travail de prendre une masse nulle (même si cela n’est pas ”prévu” par la mécanique qui traite par définition des systèmes matériels . . . ). Avec ki = ke 6= 0, ω tend alors vers l’infini que l’on peut ramener à 0 par analogie. ke est dans ce cas une force statique (ω = 0) et ne change pas la fréquence de vibration de la molécule ; on crée simplement un déplacement de l’atome. 2.2.2 Cas d’un système à plusieurs degrés de liberté Dans la cas d’un mobile unique, en l’absence d’interactions, ke = 0, la déformation est nulle . Or la condition m = 0 implique ke 6= 0. La force extérieure est crée par le déplacement arbitraire d’un atome de la molécule. Notre démarche vise ainsi à examiner les déformations produites pour chaque atome déplacé. A l’aide de trois atomes choisis arbitrairement, nous fixons la molécule étudiée 20 en lui interdisant les translations et les rotations 1 . 2.3 2.3.1 Méthode et élaboration du logiciel Méthode générale Nous considérons les atomes de la molécule considérée un à un et calculons à chaque fois la déformation induite par leur déplacement, ainsi que l’énergie correspondante qui a été mise en jeu. Pour déterminer les modes statiques nous avons besoin d’un modèle pour calculer l’énergie de la molécule. Notre méthode est indépendante de ce modèle qui peut être quantique, faisant intervenir les électrons, ou classique, reposant sur des potentiels empiriques d’interactions entre atomes. Bien entendu, en raison du grand nombre d’atomes rencontrés dans les molécules biologiques, le modèle quantique n’est pas adapté. cependant, dans les exemples préliminaires simples que nous avons abordés, nous avons préféré les méthodes quantiques pour bien montrer leur compatibilité avec notre approche. Le modèle que nous avons utilisé repose sur la théorie de la fonctionnelle densité (ou DFT) et le logiciel GAUSSIAN. Dans l’approximation harmonique, notre point de départ est la matrice des dérivées secondes de l’énergie par rapport aux coordonnées atomiques, que nous commencerons par calculer. Pour cela, à partir de données préalablement calculées par le logiciel GAUSSIAN (choisi pour obtenir la matrice dynamique d’une manière relativement simple), nous recueillons les valeurs propres (fréquences de vibration ωk ) et les vecteurs propres correspondants vik , à l’aide desquels on peut reconstituer la matrice dynamique D grâce à la 2 1 On peut alors s’interroger sur la légitimité de fixer ces points plutôt que le centre de gravité et le repère inertiel. L’énergie du système peut se mettre sécrire la forme : E= 1 1 1 2 M vG + ω ~ ·J ·ω ~ + < | σ > +Vext 2 2 2 où le premier terme correspond à l’énergie du centre de translation, le second à l’énergie de rotation (avec J le tenseur inertiel et ω ~ le vecteur rotaion instantanée, le troisième à la déformation, et le dernier à un potentiel extérieur quelconque. On voit bien dans le cas où la masse est nulle, que seuls les termes de déformation et Vext subsistent ; il n’y a plus de repère, les points fixés sont arbitraires. Fixer ces 3 points ne gênera donc pas notre travail. 2 Gaussian 98 est un programme de calcul de structure électronique. Conçu pour modéliser une large gamme de systèmes moléculaires à partir des lois de la mécanique quantique, il est utilisé par les chimistes, les physiciens et les ingénieurs pour prédire notamment les énergies, les structures moléculaires, les fréquences vibrationnelles . . . 21 relation : Dij = √ mi mj X vik vjk ωk2 k vik est la composante sur la coordonnée xi du mode ωk . Les coordonnées xi sont au nombre de 3N − 6. Les coordonnées fixées lors du choix des trois atomes mentionné au paragraphe 2.2.2 n’en font pas partie. mi est la masse de l’atome i. Notons que les termes de cette matrice sont en fait les constantes de force caractérisant les liaisons interatomiques de la molécule, c’est-à-dire, en quelque sorte, sa ”carte d’identité”. Une fois la matrice calculée, nous lui supprimons chaque ligne tour à tour, ainsi que la colonne correspondante que nous stockons dans B, afin de simuler les déplacements atomiques. En notant A la matrice de déformation une fois la ligne et la colonne choisies supprimées, on résout par la méthode de Gauss-Seidel (cf annexe C) le système : A · X +B =0 où le vecteur X contient les déformations obtenues pour chaque déplacement3 . On peut ainsi construire une matrice référençant toutes les déformations possibles de la molécule. En principe, tous les sites d’une molécule biologique ne sont pas actifs. Nous n’avons donc besoin de calculer qu’un nombre limité de modes statiques. Cependant, dans les exemples préliminaires que nous avons traités, nous avons considéré tous les modes de la molécule. Enfin, puisque par définition, la matrice dynamique est la dérivée seconde de l’énergie, il ne nous reste qu’à calculer l’énergie avec la relation : X E= Aij xi xj ij 2.3.2 Explication de l’algorithme Voici quelques précisions sur la conception du logiciel Flexible (cf D.1) : • La première partie est consacrée à la lecture d’un fichier GAUSSIAN afin d’en tirer les informations nécessaires (nombre N , masse mi et type des atomes i, coordonnées des atomes de la molécule non déformée, fréquences de vibration ωk et vecteurs propres vik associés) • On reconstruit la matrice dynamique avec la relation X √ vik vjk ωk2 Dij = mi mj k 3 Remarquons que cette méthode permet tout aussi bien de traiter un système linéaire (dans le cadre d’une approximation élastique : Dij = cte, l’énergie est harmonique) qu’un système non linéaire (dans le cadre d’une approximation inélastique : Dij 6= cte, l’énergie est anharmonique). Il y a donc possibilité d’introduire des effets anharmoniques. 22 • L’utilisateur choisit trois atomes à fixer en translation (ni (0, 0, 0)), en azimuth (nj (x, 0, 0)) et en longitude (nk (x, y, 0)) • La fonction RM AT permet : ◦ de changer de base en se plaçant par rapport aux atomes fixés : Pour cela, on considère les vecteurs v~1 et v~2 qui relient respectivement les points ni et nj , et ni et nk ; ces vecteurs sont alors normés puis on calcule v~3 = v~1 × v~2 afin d’obtenir une base orthonormée (v~1 , v~2 , v~3 ). La matrice U = (v~1 , v~2 , v~3 ) nous permet ainsi de trouver la nouvelle matrice D dans cette base en agissant bloc par bloc (sur des blocs de 9 éléments) avec la relation : D → U −1 D U ◦ d’échanger les lignes et les colonnes dans la matrice dynamique afin de séparer les élements fixés de ceux que nous allons déformer • La fonction LCM OD permet de choisir et de recenser les modes à traiter • La fonction LIN M ODE permet de résoudre le système A · X + B = 0 en suivant la méthode de Gauss-Seidel : Il s’agit d’une méthode itérative qui construit une suite de vecteurs xk = (xk1 . . . xkn ) qui converge vers la solution du système. On calcule xk+1 à partir de xk avec la relation : P Bi − j6=i Aij xkj k+1 xi = Aii Puis on optimise la solution en réutilisant xk+1 à la place des xk dès qu’ils sont calculés : Pn Pi−1 k+1 k A x − B − ij i j j=i+1 Aij xj j=1 k+1 xi = Aii On arrête le calcul dès que xk et xk+1 sont très proches, c’est-à-dire, avec fixé, lorsque : < maxni+1 xki − xk+1 i Enfin, on stocke les déformations obtenues avant de calculer l’énergie correspondante avec l’équation : X E= Aij xi xj ij Chapitre 3 Validation de la méthode 3.1 Exemple d’un polymère ”intelligent” : le PNIPAM Nous traitons un exemple de molécule simple afin de vérifier la validité de notre approche : l’exemple du PNIPAM, ou poly-N-isopropylacrylamide (voir figure 3.1). Fig. 3.1 – Structure en 3 dimensions de la molécule de PNIPAM, obtenue avec le logiciel de visualisation Molden. 23 24 Ce polymère ” intelligent ” intéresse particulièrement la communauté à l’heure actuelle pour ses surprenantes propriétés, ainsi que pour les perspectives qu’il offre. Thermosensible, il possède la caractéristique de s’ouvrir ou de se fermer selon la température, la transition se situant autour de 32o C (LCST ou Lower Critical Solution Temperature). D’autre part, il est soluble en eau froide mais précipite au-delà de ce seuil. On peut noter également qu’il s’adsorbe spontanément aux surfaces hydrophiles et hydrophobes. Il présente donc un fort potentiel d’application dans les milieux aqueux, en microfluidique : • pour fabriquer des vannes, en fermant les conduites à basse température et en les ouvrant à haute température • pour adsorber et désorber des molécules biologiques, ADN et protéines par exemple, sous des formes hydrophile et hydrophobe, respectivement • pour des applications biopuces, des laboratoires sur puces 3.2 Visualisation des modifications conformationnelles Un programme annexe (cf D.2) a été élaboré afin de voir sur écran de quelles manières la molécule peut se déformer. Pour cela, nous faisons appel aux coordonnées de la molécule déformée obtenues par le logiciel Flexible. Le programme de visualisation permet à l’utilisateur de choisir n’importe quel atome de la molécule ainsi que la direction dans laquelle on le déplace. Le programme peut alors retrouver le mode de déformation associé et fournir immédiatement le fichier .xyz correspondant. Ce type de fichier est construit de la manière suivante : • la première ligne correspond au nombre d’atomes de la molécule • la seconde ligne peut être vide ou contenir un commentaire • les lignes suivantes correspondent respectivement à chaque atome et contiennent son type et ses coordonnées 3 O 0.0000000000 0.1165610030 0.0000000000 H 0.7692210078 -0.4662449956 0.0000000000 H -0.7692210078 -0.4662440121 0.0000000000 Fig. 3.2 – Exemple du fichier .xyz d’une molécule d’eau non déformée donné par le logiciel GAUSSIAN. Enfin, à l’aide de logiciels de visualisation moléculaire tels que Molden ou VMD, il est alors possible de lire les fichiers .xyz et de créer des animations afin d’observer les déformations induites. 25 3.3 3.3.1 Résultats L’eau Nous obtenons bien 3N − 6, c’est-à-dire 3 modes de déformation : Fig. 3.3 – Molécule d’eau non déformée : la longueur des liaisons O − H est de 0.965 Angström, les trois atomes font un angle de 105.700 . 3.3.2 Fig. 3.4 – Premier mode de déformation obtenu : les liaisons O − H font 1.863 et 0.632 Angström, la valeur de l’angle a augmenté : 114.780 . Le PNIPAM Nous étudions ici le cas d’une molécule à deux brins, c’est-à-dire composée de 46 atomes. Il existe donc 132 modes à observer ; d’où l’intérêt d’avoir stocké l’ensemble de ces déformations calculées et d’avoir conçu un programme interactif permettant de cibler un atome particulier. Il a été observé que le greffage d’une molécule d’eau sur le PNIPAM se fait entre ces deux brins en les écartant. Nous nous intéressons donc plus particulièrement au déplacement des atomes d’hydrogène (en blanc) et d’oxygène (en rouge) sur lesquels la liaison peut se faire (voir figure 3.7) : Le résultat montre des déformations parfaitement visibles, ce qui permet de mettre directement en évidence que le déplacement d’un atome engendre bien un réarrangement conformationnel de l’ensemble de la molécule. 26 Fig. 3.5 – Second mode de déformation : la longueur des liaisons O−H est de 0.99 et 0.37 Angström, les trois atomes sont presque aligné : l’angle vaut 15.870 . Fig. 3.6 – Troisième mode de déformation : les longueurs des liaisons O−H sont voisines : 0.904 et 1.01 Angström, la valeur de l’angle est de 62.530 . Fig. 3.7 – Indiqués par les flèches, les deux atomes O et H concernés par le greffage avec l’eau. 27 Contrainte sur l’ oxygène La déformation apparaı̂t très nettement. L’écartement des deux brins se manifeste particulièrement lorsque l’on déplace l’oxygène dans la direction y . En effet, la distance séparant les carbones situés au bout des brins passe de 6.51 Angström à l’état non déformé à 6.82 . Fig. 3.8 – A gauche, la molécule de PNIPAM non déformée. A droite, déformation de la molécule de PNIPAM obtenue en déplaçant l’oxygène dans la direction y. Contrainte sur l’hydrogène On crée à présent un déplacement sur cet atome et on observe les trois modes de déformation. Les directions x et z sont les plus représentatives (cf figures 3.9 et 3.10). Il est assez remarquable d’observer les effet que crée ce déplacement jusqu’aux extrémités de la molécule. D’autre part, il semble que les atomes les plus sensibles soient les hydrogènes, le fait qu’ils soient si mobiles est peut-être une caractéristique d’interaction entre molécules biologiques. 28 Fig. 3.9 – A gauche, la molécule de PNIPAM non déformée. A droite, déformation dans la direction x : la distance N − N (azote en bleu) passe de 4.81 à 5.81 Angström et la distance C − C passe de 6.51 à 7.58 Angström. Fig. 3.10 – A gauche, la molécule de PNIPAM non déformée. A droite, déformation dans la direction z : la distance N − N (azote en bleu) passe de 4.81 à 5.05 Angström et la distance C − C passe de 6.51 à 6.61 Angström. Chapitre 4 Accrochage de deux molécules 4.1 Objectif Après avoir traiter la déformation des macromolécules, nous allons expliquer dans cette partie le développement d’un second logiciel : Greffage. Il permet d’assembler deux molécules dans l’espace avec la participation de l’utilisateur qui peut choisir sur quelle partie des molécules se fera l’arrimage, à quelle distance et sous quel angle les placer l’une par rapport à l’autre. L’objectif du module Greffage que nous avons programmé et dont les grandes lignes sont détaillées ci-dessous est double. Dans une approche de docking, nous devons être en mesure de contrôler le positionnement de deux molécules l’une par rapport à l’autre. La manière dont on met en contact ces deux entités est en effet très importante puisqu’elle influe sur l’énergie de la liaison, et par conséquent sur la force (qui est sa dérivée seconde) et l’application des modes statiques. Nous nous donnons donc la possibilité de choisir deux atomes, un sur chaque molécule, que l’on désire approcher d’une certaine distance tout en gardant une possibilité de rotation entre les deux molécules (via un angle α de torsion de la liaison fictive créée entre les deux atomes désignés). Par ailleurs, lorsque l’on doit construire une molécule à partir de sa formule chimique, on peut définir sa structure petit à petit, par fusions successives de briques élémentaires (par exemple la fusion de deux CH4 pour obtenir un C2 H6 ). 4.2 Méthode On se propose à présent d’assembler deux molécules sur la base de considérations géométriques. Pour cela, on considère en particulier deux atomes sur chacune des molécules : 29 30 • un atome à enlever : noté K (respectivement L) sur la molécule 1 (resp. 2) • un atome à connecter : noté P (respectivement Q) sur la molécule 1 (resp. 2) Définition des variables ∗ Chacun des n1 atomes de la molécule 1 est repéré par un vecteur de coordonnées cartésiennes v~1 i , i = 1, . . . , n1. De même, on a v~2 i , i = 1, . . . , n2 pour les atomes de la molécule 2. ∗ On note dP K et dQL les distances existant entre les atomes P et K, et Q et L : q q K P dP K = v~1 − v~1 et dQL = v~2 L − v~2 Q Par ailleurs, la distance dP Q reliant les atomes P et Q peut être choisie par l’utilisateur. ∗ A l’aide de ces distances, on définit les vecteurs T~1 et T~2 tels que : T~1 = (v~1 K − v~1 P )/dP K et T~2 = (v~2 L − v~2 Q )/dQL et dont le produit scalaire s’écrit : T12 = T~1 · T~2 Selon la valeur obtenue pour T12 , deux possibilités doivent être envisagées. 4.3 4.3.1 Deux cas à traiter Cas où T12 6= 1 Dans ce cas, on peut calculer la quantité R = ~ M = T1 ainsi que la matrice de rotation : T~2 − T12 T~1 R p 2 1 − T12 et construire la matrice : T~ × T~2 r 1 ~ T1 × T~2 p 2 −T − 1 − T12 0 12 p 2 A = 1 − T12 −T12 0 0 0 1 31 avec laquelle on peut calculer R1 = M · A · M t . Les nouvelles coordonnées des molécules 1 et 2 s’écrivent alors : 0i i i = 1, . . . , n1 ~ ~ V1 = V1 pour i 6= K j 0j Q P j = 1, . . . , n2 V~2 = R1 V~2 − V~2 + V~1 + T~1 · dP Q pour j 6= L Par ailleurs, on peut introduire une rotation arbitraire, sous la forme d’un angle α choisi par l’utilisateur, afin de simuler le déplacement. On obtient une seconde matrice de rotation : 1 p 0 0 1 − sin2 α p − sin α Aα = 0 2 0 sin α 1 − sin α dont il découle R2 = M · Aα · M t . En suivant la même méthode que précédemment et en introduisant la matrice (4.1), on détermine finalement les cordonnées des molécules après accrochage : 00i i i = 1, . . . , n1 V~1 = V~1 pour i 6= K 0j 00j 0Q 0Q j = 1, . . . , n2 V~2 = R2 V~2 − V~2 + V~2 · dP Q pour j 6= L 4.3.2 Cas où T12 = 1 Dans ce cas, R1 s’écrit : −T12 0 0 −T12 0 R1 = 0 0 0 −T12 Comme dans le paragraphe (4.3.1), les coordonnées des atomes des molécules sont : 0i i i = 1, . . . , n1 ~ ~ V1 = V1 pour i 6= K j 0j Q P j = 1, . . . , n2 ~ ~ ~ ~ ~ V2 = R1 V2 − V2 + V1 + T1 · dP Q pour j 6= L 32 On introduit également la rotation arbitraire α et on obtient finalement : 00i i i = 1, . . . , n1 V~1 = V~1 pour i 6= K √ 0Q 0Q 0Q 00j j = 1, . . . , n2 0j 0j 2 ~ ~ ~ ~ ~ ~ ~ V2 = I + 1 − α −I + V2 − V2 −αT1 × V2 − V2 + V2 pour j 6= L h j i Q où I~ = T~1 · V~2 − V~2 T~1 4.4 Application à la construction d’un C2H6 avec deux CH4 Nous partons de deux fichiers xyz décrivant des molécules de CH4 . On choisit alors deux atomes d’hydrogène (voir les atomes fléchés sur la figure 4.4), H1 et H2 , un sur chaque molécule, que l’on enlève pour faire la liaison. Fig. 4.1 – Exemple de deux molécules de CH4 à assembler. Les deux hydrogènes fléchés vont être retirés et laisser place à une liaison entre les carbones. On choisit également deux atomes à connecter, deux carbones, ainsi que la distance à laquelle on veut les placer l’un de l’autre. Il est par ailleurs possible de donner un angle α afin d’effectuer une torsion autour de cette liaison C − C pour optimiser l’assemblage. 33 Fig. 4.2 – Molécule de C2 H6 obtenue par greffage d’un CH4 sur un autre CH4 , on a pris une distance de 1.45 Angström. Après fusion, nous obtenons bien une molécule de C2 H6 Ce logiciel pourra donc être utilisé pour l’assemblage de macromolécules ou encore pour déterminer la structure d’une molécule. Chapitre 5 Conclusion Notre travail de stage a porté sur le développement d’un algorithme et du logiciel Flexible pour mettre en oeuvre le modèle de calcul des déformations basé sur le nouveau concept ”modes statiques”. Une part importante de notre effort a donc été consacré au développement puis à la validation du logiciel. Ce logiciel est aujourd’hui opérationnel et permet de calculer l’ensemble des modes, ou seulement une partie que l’expérimentateur peut choisir de façon manuelle ou automatique, relatifs à une molécule. Il constitue donc la première étape pour la constitution d’une base de données qui servira ensuite pour le problème général de docking des macromolécules. Par ce travail, nous sommes parvenus à élaborer une nouvelle méthode explorant les possibilités conformationnelles des molécules biologiques et permettant d’obtenir l’ensemble de ces déformations très rapidement. Nous avons ensuite validé le logiciel Flexible sur des exemples de molécules simples : les polymères P-NIPAM. Ces résultats sont donc en accord avec nos attentes. Nous obtenons effectivement 3N − 6 modes de déformation. D’autre part, les exemples précis auxquels nous nous sommes intéressés vérifient des propriétés connues. Le résultat obtenu est parfois spectaculaire, puisque créer un petit déplacement d’un atome engendre une restructuration au niveau de l’ensemble de la molécule. Bien que les résultats obtenus soient tout à fait satisfaisants, la plus grande partie du travail reste encore à faire. Il s’agira de développements selon trois axes : • l’application du logiciel ”flexible” à d’autres molécules, en particulier les biomolécules, pour constituer une véritable banque de données qui sera la source à utiliser pour les problèmes de docking. • le développement d’un ou plusieurs modèles pour fixer une ou plusieurs stratégies de détermination des sites d’interaction pour les docking • le développement d’un logiciel sur la base du modèle précédent et sa validation sur des cas concrets Le logiciel Greffage, quant à lui, donne également des résultats très satisfaisants. Ce34 35 pendant, il trouvera toute son utilité plus tard, lors du docking L’application à grande échelle de cette méthodologie pour des besoins en biologie structurale et en pharmacologie en restera bien entendu l’objectif à long terme. Annexe A Rappel sur les protéines Les protéines sont des polymères d’acides aminés liés les uns aux autres dans un ordre précis. Présentes chez les organismes vivants et essentielles à leur fonctionnement, ces macromolécules complexes et variées sont spécifiques à chaque espèce vivante et à chaque organe. Chaque cellule en fabrique en moyenne 15 000 sortes différentes, et un corps humain, près de 100 000, soit 50% du poids sec d’un être vivant. Fig. A.1 – Exemple de la structure très complexe d’une protéine, obtenue avec le logiciel de visualisation Molden. 36 37 A.1 Les acides aminés Les acides aminés sont formés d’un carbone auquel sont liés : ◦ un groupement amine N H2 ◦ un groupement acide COOH ◦ un radical variant selon la molécule considérée Les acides aminés peuvent se lier les uns aux autres par une liaison peptidique qui se fait entre le groupement acide d’un acide aminé et le groupement amine de l’autre. Fig. A.2 – Représentation de la structure d’un acide aminé : le carbone est relié à un groupement amine, un groupement acide et un radical variant selon la molécule. Fig. A.3 – Exemple de la représentation chimique de cinq acides aminés mettant en évidence les différents radicaux qui les caractérisent. 38 A.2 Structure et propriétés des protéines L’association de plusieurs acides aminés forme un polypeptide. Les chaı̂nes de polypeptides s’enroulent de telle sorte que les acides aminés hydrophobes sont placés vers l’intérieur, ce qui donne une stabilité à la molécule, Les acides aminés hydrophiles sont orientés vers l’extérieur et sont libres d’interagir avec d’autres composés chimiques. Certains sont très courts (4 ou 5 acides aminés) et d’autres gigantesques (plus de 600 acides aminés). La plupart des protéines ont entre 100 et 200 acides aminés. On utilise généralement le terme peptide pour désigner les plus petits polypeptides (moins de 50 acides aminés) et protéines pour les plus gros. A.2.1 Les forces structurales Les biomolécules sont des polymères composés d’un très grand nombre d’atomes. Les liaisons existant entre ces atomes déterminent leur forme générale et sont de deux types : ” bonded ” et ” non bonded ” (liées ou non liées) [1]. Les bonded regroupent les déformations, toujours présentes en biologie, ici classée par importance croissante : • la torsion (modification de l’angle du dièdre) • la flexion (ou bending : modification de l’angle) • l’élongation (changement de la longueur des liaisons) Les non bonded (c’est-à-dire les liaisons non covalentes) sont très importantes pour les molécules biologiques, bien que leur énergie soit d’un à trois ordres de grandeur inférieures à celles des liaisons covalentes (d’où la difficulté de les mesurer et de les calculer). Elles déterminent par exemple l’assemblage spontané de polypeptides et d’acides nucléiques lors de la création d’une membrane, mais permettent aussi la reconnaissance mutuelle de molécules complémentaires (système clef - serrure). En d’autres termes, elles caractérisent les interactions et les réactions, c’est-à-dire : • les forces de Van der Waals qui agissent à distance sur deux atomes non liés comprennent un terme en 1/r6 qui devient très attractif dans le cas des grosses molécules, et un terme en 1/r12 répulsif, néanmoins dans le cas d’interactions à courte portée : 1 1 − · cte EV dW = r12 r6 • l’interaction électrostatique (dite de Coulomb) qui est de longue portée, et de la forme : Vcc = 1 pour l’interaction charge - charge r 39 1 pour l’interaction charge - dipôle r2 1 Vdd = 3 pour l’interaction dipôle - dipôle r • la liaison hydrogène qui est attractive (entre un atome d’hydrogène et une région électronégative), de plus courte portée que celle de Van der Waals, mais plus longue qu’une liaison covalente. Elle n’est pas vraiment chimique car elle se rompt facilement et peut se reconstruire. Elle s’écrit : Vcd = VH = b a − 10 12 r r L’ensemble de ces interactions est nécessaire à la compréhension de la forme que va adopter une protéine. Fig. A.4 – Exemple de la détermination de la structure d’une protéine par RMN : les déplacements chimiques Cα et Cβ caractérisent la structure secondaire de cette molécule. A.2.2 Forme de la molécule Chacune de ces protéines a une forme tridimensionnelle et des propriétés chimiques qui lui sont propres. A la base, l’association des radicaux des acides aminés se fait en chaı̂ne linéaire et caractérise la structure primaire. Toutefois, une protéine ne garde jamais strictement cette forme. L’énergie contenue dans les liaisons hydrogène, les ponts disulfures, l’attraction entre les charges positives et négatives, et les radicaux hydrophobes ou hydrophiles, imposent à la protéine un changement de conformation, on obtient alors différentes structures [2] [3] : 40 • la structure secondaire, en hélice alpha ou feuillet bêta, due aux interactions existantes entre les différents acides aminés, qui est un repliement local dans l’espace d’une chaı̂ne polypeptidique • la structure tertiaire (tridimensionnelle), plus compacte, qui est le repliement dans l’espace d’une chaı̂ne polypeptidique et qui donne sa fonctionnalité à la protéine (notamment le site actif pour les enzymes) • la structure quaternaire qui est l’association de plusieurs chaı̂nes polypeptidiques Lorsqu’une chaı̂ne polypeptidique de plusieurs acides aminés (quelques dizaines) a adopté une structure tertiaire et a subi une maturation, alors elle devient une protéine. Fig. A.5 – Représentation de différentes structures d’une protéine : on distingue par exemple les formes secondaires (hélice alpha et feuillet bêta) et tertiaires. Annexe B Décomposition d’un mouvement en modes normaux B.1 Introduction aux modes normaux Il est possible de décomposer le mouvement compliqué, et apparemment désordonné, d’un système de points matériels en mouvements plus simples, en supposant que ces mouvements sont de petite amplitude. A chaque instant, la position du système de points sera donnée par la somme géométrique des positions qu’aurait le système s’il était seulement soumis aux mouvements élémentaires. Ces mouvements élémentaires prennent le nom de modes normaux de vibration, ou modes propres. Ils sont indépendants les uns des autres. Si la molécule arrive à vibrer réellement dans un de ces modes (ce qui est impossible pendant longtemps en raison des collisions moléculaires) aucune autre vibration ne sera excitée, elle continuera à vibrer dans ce mode. Enfin, dans chaque mode normal, les noyaux vibrent en phase et avec la même fréquence. On peut obtenir le nombre des modes normaux de vibration à l’aide de considérations simples. Chacun des N atomes d’une molécule polyatomique non linéaire a trois degrés de liberté. En effet, il peut se déplacer indépendamment selon chacun des trois axes. La molécule dans son ensemble a donc 3N degrés de liberté. Parmi ces 3N degrés de liberté, trois correspondent à une translation de la molécule entière le long des trois axes et trois correspondent à une rotation de la molécule autour de chacun des axes. Ceci laisse 3N − 6 degrés de liberté de vibration. On démontre qu’il existe précisément 3N − 6 modes normaux de vibration. Une molécule linéaire possède 3N − 5 modes normaux car elle a seulement deux degrés de liberté de rotation (on ne tient pas compte de la rotation autour de l’axe internucléaire). Ce problème se traite théoriquement de façon tout à fait analogue à celui de la molécule diatomique. La molécule peut vibrer dans chaque mode normal avec une amplitude de 41 42 plus en plus grande à mesure que l’énergie de vibration devient de plus en plus grande. B.2 Principe Nous nous proposons donc dans cette annexe de traiter le cas d’une chaı̂ne linéaire composée de N atomes identiques, équidistants de a et de masse m [4]. Le déplacement de l’atome n (n = 1, . . . , N ) par rapport à sa position d’équilibre Rn = na est noté un et vérifie les conditions de Born - von Karman : un = un+N . Le système est peut être décrit par l’hamiltonien : N X p2n + V (u) H(p, u) = 2m n=1 où pn est la quantité de mouvement relative à l’atome n et V (u) le potentiel harmonique : V (u) = 1X un Dn,n0 un0 2 n,n0 n, n0 = 1, . . . , N (B.1) où D est la matrice dynamique. Si l’on ne considère que les interactions entre proches voisins, l’équation (B.1) peut s’écrire : N CX V (u) = (un+1 − un )2 (B.2) 2 n=1 D’autre part, en utilisant l’écriture matricielle suivante : u1 p1 u2 p2 u = .. p = .. p, u ∈ RN . . uN pN l’équation (B.1) s’écrit encore : 1 V (u) = ut Du 2 B.3 Calcul des modes propres Afin d’obtenir les équations du mouvement des atomes, nous écrivons les équations de Hamilton : · ∂H ∂H · pn = − un = ∂pn ∂un 43 soit en notation matricielle : p m · u= dont on déduit : · p= −Du ·· m u= −Du (B.3) (B.4) Remarque importante : On reconnaı̂t dans l’équation (B.4) l’équation fondamentale de la dynamique d’un système à ressort, où la force appliquées serait −ku, avec k la constante de force (ou de raideur). Par identification, on peut donc assimiler D à une matrice contenant les constantes de forces agissant sur le système. Il apparaı̂t ainsi qu’elle relie une action de contrainte à un mouvement relatif. En se plaçant dans une base orthonormée, nous notons Qυ les N vecteurs propres D dans cette base : Qυ1 Qυ 2 υ Q = .. υ = 0, 1, . . . , N − 1 . QυN Ils vérifient donc la relation d’orthonormalisation : (Qυ )+ Qυ = δυυ0 ainsi que la relation de fermeture : X Qυ (Qυ )+ = I (B.5) υ Avec les valeurs propres dυ , ils sont solution du système : DQυ = dυ Qυ On en déduit que les valeurs propres dυ de la matrice D sont données par : dυ = (Qυ )+ DQυ (B.6) En considérant les relations (B.5) et (B.6), et en s’appuyant par ailleurs sur le théorème spectral 1 , D s’écrit : X D= dυ Qυ (Qυ )+ υ 1 D’après le théorème spectral, si λ est valeur propre d’une matrice A, f (λ) est valeur propre de f (A) avec la même multiplicité. 44 On peut alors exprimer le déplacement un (t) à l’aide des vecteurs de la base Qυn : X un (t) = aυ (t)Qυn υ soit sous forme matricielle : u(t) = X aυ (t)Qυ (B.7) υ En reportant l’équation (B.7) dans les équations du mouvement (B.3), nous pouvons écrire pour chaque mode υ = 0, . . . , N − 1 : · m aυ (t) = −dυ aυ (t) dont la solution générale s’écrit : · aυ (t) = aυ exp(− ı ωυ t) où les ωυ = p dυ /m sont les fréquences propres de vibrations. Finalement, après calcul des constantes, et en introduisant le vecteur d’onde kυ = 2πυ/aN (dans le cas de systèmes périodiques dans lesquels on ne considère qu’une cellule élémentaire), on obtient : 1 X · un (t) = √ aυ exp[− ı (kυ na − ωυ t)] + cte N υ Cette relation traduit une décomposition possible en (N −1) modes propres du déplacement un (t) d’un atome n autour de sa position d’équilibre. Annexe C Résolution de systèmes linéaires : méthode de Gauss-Seidel C.1 Position du problème La résolution de systèmes linéaires par des méthodes directes dépendent en particulier de la capacité du calculateur. Au delà d’un certain nombre d’équations à un certain nombre d’inconnues, les méthodes directes deviennent inappropriées. Nous avons alors recours aux méthodes itératives. Pour ce faire, nous résolvons le système A · X = B, où A est une matrice inversible, en ~ ∈ Rn , où X ~ = [x1 . . . xn ]T . Le vecteur optimal est construisant une suite de vecteurs X généralement obtenu après un certain nombre d’itérations lorsqu’on atteint une précision souhaitée appelée également critère d’arrêt. C.2 C.2.1 Principe Ecriture du système T Les méthodes itératives consistent à utiliser un vecteur initial X 0 = [x01 . . . x0n ] afin de produire une suite de vecteurs du type : X k+1 = F k x1k−1 . . . xk−1 n Résoudre le système A · X = B où A est une matrice carrée d’ordre n peut s’écrire sous une autre forme identique (M − N ) · X = B en décomposant A = M − N . Donc, à partir d’un vecteur initial X 0 , on génère une suite de la façon suivante : 1 X = M −1 · N · X 0 + M −1 · B 2 X = M −1 · N · X 1 + M −1 · B ··· k+1 X = M −1 · N · X k + M −1 · B 45 46 Cette suite est représentée par la relation itérative suivante : X k+1 = T.X k + V où T = M −1 · N et V = M −1 · B. Cependant, nous ne pouvons pas savoir si le vecteur estimé se dirige vers la solution optimale si un critère de convergence n’est pas défini. Pour cela, un vecteur d’erreur est établi par la relation : k = X k − X • = T · k−1 Autrement dit, la convergence existe si l’erreur tend vers 0 lorsqu’on se rapproche de la solution optimale : X • ≈ X k si lim k = 0 k→1 Remarque : La convergence se produit lorsque le résidu ou la précision k reste inférieur à . k−1 C.2.2 Décomposition de la matrice A La décomposition de la matrice A est rendue nécessaire pour assurer la convergence de la méthode. Nous créerons trois matrices D, L, U , telles que A = D − L − U . D est une matrice diagonale : a1,1 0 . . . . . . 0 .. ... ... 0 0 . . . . . . . . . D= . . a . . i,j . .. .. .. . 0 . 0 0 . . . . . . 0 an,n L est une matrice inférieure : 0 0 .. . .. . . . . . . . a1,n .. .. . ai,j . .. .. . 0 . ... .. . an−1,n ... 0 0 0 ... ... ... .. . 0 . ai,j . . ... a2,1 0 . . .. L = .. . .. .. . 0 an,1 . . . . . . an,n−1 0 U est une matrice supérieure : U = 0 a1,2 . 0 .. .. . . . . .. . 0 0 ... 47 C.3 C.3.1 Méthode de Gauss-Seidel Description de la méthode La méthode de Gauss-Seidel est une des méthodes itératives permettant de résoudre ce type de système : On pose A = M − N où M = D − L et N = U . Dans ces conditions : T = (D − L)−1 · U · X k+1 =T (D − L)−1 · U · X k + (D − L)−1 · B On peut donc écrire le système A · X = B sous la forme itérative suivante : (D − L) · X k+1 = U · X k + B soit X k+1 = (D − L)−1 · U · X k + (D − L)−1 · B Remarque : les pivots ai,j doivent être non nuls, dans le cas contraire il suffit d’intervertir les lignes pour remplir la condition nécessaire. C.3.2 Condition d’arrêt On note r un vecteur résidu tel que rk = b − A · X k , de sorte que le critère d’arrêt soit : k r < avec choisi petit (C.1) kBk Une autre technique consiste à utiliser un autre test d’arrêt basé sur : k X − X k−1 < kX k k Lorsque l’optimum est voisin de 0, on se contente du critère d’arrêt suivant : k X − X k−1 < C.3.3 Algorithme On choisit un vecteur initial X 0 et un critère d’arrêt . On crée : • D avec di,j = ai,j • L avec : li,j = −ai,j pour i > j li,j = 0 pour i ≤ j (C.2) (C.3) 48 • U avec : ui,j = −ai,j pour i < j ui,j = 0 pour i ≥ j Enfin, tant que les conditions (C.1), (C.2) et (C.3) sont vérifées, on calcule rk = B −A·X k et X k+1 = (D − L)−1 · U · X k + (D − L)−1 · B Annexe D Programmes D.1 Flexibilité des macromolécules : calcul des déformations #include <stdio.h> #include <string.h> #include <stdlib.h> #include <math.h> #include <time.h> #include "memoire.h" #include "fichiers_es.h" #include "atomes.h" void BasseCasse(char *); void RMat(int , int , int , int , double *, int *, int *, double **); double Norme(double *, int ); void ProdVect(double *, double *, double *); void NewMat(int , double *, double *, double *, int, int *, double **, double *); void Rotate(double **, double **); void RotateX(double **, double *); void NewLine(int , int , int , int , int *, int *, double **, double *); void Exch(int , int , int , double **, double *); void LCmod(int **, int, int, int, int ); void LinMode(int , int , int , int, int, int , double , double , double *, int *, int *, double **, double **); double Energie(int , double *, double **); void BasseCasse(char *ligne) { char *p = ligne; while (*p) { 49 50 *p = tolower(*p); p++; } } /* Traitement du fichier */ int main(int argc, char *argv[]) { char buffer[255], s[10][80]; FILE *pf = NULL; FILE *fi = NULL; FILE *ff = NULL; int compteur = 0, i, j, k, l, n, q, at, lg, Natomes = 0, Ndegres, cyc = 0; int ifich, ni, nj, nk, nx, *nl, *gg, **CMOD,*Param; double *x, *y, *z, *xx, *dx, err=0.0001, En, *aux; int lab, numatom, typatom, iblob; double *freq, **vtp0b, **vtp0h, **vtp, *m, *m3, massetot = 0., **D, **M, **kk; char c[] = { ’x’, ’y’, ’z’ }, blob[40]; char a[6]; char b[2]; char ch[2]; char com[134]; struct atome *atomes1, *atomes2; time_t t1, t2; /* l’instruction suivante est ncessaire pour utiliser les fcts de fichiers_es */ wd_init(); pf = fopen(argv[2], "r"); if (!pf) { fprintf(stderr, "Pas de fichier !\n\n"); return (-1); } while (NULL != fgets(buffer, (int) (int) sizeof buffer, pf)) { BasseCasse(buffer); if (strstr(buffer, "has atomic number")) Natomes++; } printf("Nombre d’atomes : %d\n", Natomes); 51 /* Attention : si molcule linaire -> enlever 5 degrs ! */ Ndegres = 3 * Natomes - 6; printf("Nombre de degres de liberte : %d\n", Ndegres); freq = vec(Ndegres); vtp0b = mat(Natomes, 9); vtp0h = mat(3 * Natomes , 5); vtp = mat(3 * Natomes, Ndegres); D = mat(3 * Natomes, 3 * Natomes); M = mat(3 * Natomes + 2, Ndegres); kk = mat (Natomes, 3); m = vec(Natomes); m3 = vec(3 * Ndegres); aux=vec(3*Natomes); nl = ivec(Natomes); gg= ivec(Natomes); Param = ivec(10); for (i=0;i<9;i++) Param[i]=0; CMOD = imat(3*Natomes, 3*Natomes); x = vec(Natomes); y = vec(Natomes); z = vec(Natomes); xx = vec(3 * Natomes); dx = vec(3 * Natomes); for (i=0;i<3*Natomes;i++){ for (j=0;j<Ndegres;j++){ vtp[i][j] = 0.; } } for (i=0;i<3*Natomes+2;i++){ for (j=0;j<Ndegres;j++){ M[i][j] = 0.; } } for (i=0;i<Natomes;i++){ for (j=0;j<3;j++){ kk[i][j] = -1.; } } /* Stockage nombre d’atomes */ Param[0]=Natomes; 52 Param[1]=Ndegres; sauvegarde_ivecteur(Param,10,"Parametres"); for (i = 0; i < Natomes; i++){ for (j = 0; j < Natomes; j++){ D[i][j] = 0.; } } rewind(pf); while (NULL != fgets(buffer, (int) sizeof buffer, pf)) { BasseCasse(buffer); compteur++; if (strstr(buffer, "standard orientation")) { break; } } printf("Trouv ! ligne = %d\n", compteur); printf("%s", buffer); fgets(buffer, (int) sizeof buffer, pf); printf("%s", buffer); fgets(buffer, (int) sizeof buffer, pf); printf("%s", buffer); fgets(buffer, (int) sizeof buffer, pf); printf("%s", buffer); fgets(buffer, (int) sizeof buffer, pf); printf("%s", buffer); printf("%d\n\n", Natomes); atomes1 = atoms(Natomes); q = 0; for (i = 0; i < Natomes; i++) { fgets(buffer, (int) sizeof buffer, pf); sscanf(buffer, "%d %d %d %lf %lf %lf", &lab, &numatom, &typatom, &x[i], &y[i], &z[i]); printf("%s %f %f %f\n", atm[numatom].symb, x[i], y[i], z[i]); strcpy(atomes1[q].symb,atm[numatom].symb); atomes1[q].x = x[i]; atomes1[q].y = y[i]; atomes1[q].z = z[i]; q++; } 53 sauvegarde_ivecteur(Param,10,"Parametres"); sauvegarde_xyz(Natomes,com,atomes1, "coord_i.xyz"); /* suite du traitement */ rewind(pf); compteur = 0; while (NULL != fgets(buffer, (int) sizeof buffer, pf)) { BasseCasse(buffer); compteur++; if (strstr(buffer, "harmonic frequencies")) { break; } } printf("Trouv ! ligne = %d\n", compteur); printf("%s", buffer); fgets(buffer, (int) sizeof buffer, pf); printf("%s", buffer); fgets(buffer, (int) sizeof buffer, pf); printf("%s", buffer); /* Choix de la precision du traitement */ sprintf(a,"haute"); if(strcmp(a,argv[1])){ /* Debut des cycles avec des vecteurs propres de basse precision*/ cyc = 0; while (cyc < Ndegres / 3) { fgets(buffer, (int) sizeof buffer, pf); fgets(buffer, (int) sizeof buffer, pf); fgets(buffer, (int) sizeof buffer, pf); /* Lecture de la ligne Frequencies -- */ sscanf(buffer, " Frequencies -- %lf %lf %lf ", &freq[3 * cyc], &freq[3 * cyc + 1], &freq[3 * cyc + 2]); for (i = 0; i < 3; i++) printf("%d %f\n", i + 3 * cyc, freq[3 * cyc + i]); for (i = 0; i < 6; i++) fgets(buffer, (int) sizeof buffer, pf); /* Lecture des vecteurs propres */ for (i = 0; i < Natomes; i++) { fgets(buffer, (int) sizeof buffer, pf); 54 sscanf(buffer, "%d %d %lf %lf %lf %lf %lf %lf %lf %lf %lf", &iblob, &iblob, &vtp0b[i][0], &vtp0b[i][1], &vtp0b[i][2], &vtp0b[i][3], &vtp0b[i][4], &vtp0b[i][5], &vtp0b[i][6], &vtp0b[i][7], &vtp0b[i][8]); } /* Rearrangement et stockage dans vtp[3*Natomes][3*Natomes] */ for (l = 0; l < 3; l++) { n = 0; for (j = 0; j < Natomes; j++) for (k = 0; k < 3; k++) { vtp[n][+3 * cyc + l] = vtp0b[j][l * 3 + k]; n++; } } cyc += 1; } } /* fin des cycles avec des vecteurs propres de basse precision*/ else{ /*debut des cycles avec des vecteurs propres de haute precision*/ cyc = 0; while (cyc < Ndegres / 5) { fgets(buffer, (int) sizeof buffer, pf); fgets(buffer, (int) sizeof buffer, pf); fgets(buffer, (int) sizeof buffer, pf); /* Lecture de la ligne Frequencies --- */ sscanf(buffer, " Frequencies --- %lf %lf %lf %lf %lf", &freq[5 * cyc], &freq[5 * cyc + 1], &freq[5 * cyc + 2], &freq[5 * cyc + 3], &freq[5 * cyc + 4]); for (i = 0; i < 5; i++) 55 printf("%d %f\n", i + 5 * cyc, freq[i + 5 * cyc]); for (i = 0; i < 6; i++) fgets(buffer, (int) sizeof buffer, pf); /* Lecture des vecteurs propres */ for (i = 0; i < 3 * Natomes; i++) { fgets(buffer, (int) sizeof buffer, pf); sscanf(buffer, "%d %d %d %lf %lf %lf %lf %lf", &iblob, &iblob, &iblob, &vtp0h[i][0], &vtp0h[i][1], &vtp0h[i][2], &vtp0h[i][3], &vtp0h[i][4]); } /* Rearrangement et stockage dans vtp[3*Natomes][3*Natomes] */ for (j = 0; j < 5; j++) { for (i = 0; i < 3 * Natomes; i++){ vtp[i][5 * cyc +j] = vtp0h[i][j]; } } cyc += 1; } if(Ndegres % 5 != 1){ fgets(buffer, (int) sizeof buffer, pf); fgets(buffer, (int) sizeof buffer, pf); fgets(buffer, (int) sizeof buffer, pf); if(Ndegres % 5 == 1){ sscanf(buffer, " Frequencies --- %lf",&freq[5 * cyc]); printf("%d %f\n", 5 * cyc, freq[5 * cyc ]); for (i = 0; i < 6; i++) fgets(buffer, (int) sizeof buffer, pf); for (i = 0; i < 3 * Natomes; i++) { fgets(buffer, (int) sizeof buffer, pf); sscanf(buffer, "%d %d %d %lf", &iblob, &iblob, &iblob,&vtp0h[i][0]); } } if(Ndegres % 5 == 2){ 56 sscanf(buffer, " Frequencies --- %lf %lf", &freq[5 * cyc], &freq[5 * cyc + 1] ); for (i = 0; i < 2; i++) printf("%d %f\n", i + 5 * cyc, freq[5 * cyc + i]); for (i = 0; i < 6; i++) fgets(buffer, (int) sizeof buffer, pf); for (i = 0; i < 3 * Natomes; i++) { fgets(buffer, (int) sizeof buffer, pf); sscanf(buffer, "%d %d %d %lf %lf", &iblob,&iblob, &iblob, &vtp0h[i][0], &vtp0h[i][1]); } for (j = 0; j < 2; j++) { for (i = 0; i < 3 * Natomes; i++){ vtp[i][j + 5 * cyc] = vtp0h[i][j]; } } } if(Ndegres % 5 == 3){ sscanf(buffer, " Frequencies --- %lf %lf %lf", &freq[5 * cyc],&freq[5 * cyc + 1],&freq[5 * cyc + 2]); for (i = 0; i < 3; i++) printf("%d %f\n", i + 5 * cyc, freq[5 * cyc + i]); for (i = 0; i < 6; i++) fgets(buffer, (int) sizeof buffer, pf); for (i = 0; i < 3 * Natomes; i++) { fgets(buffer, (int) sizeof buffer, pf); sscanf(buffer, "%d %d %d %lf %lf %lf", &iblob,&iblob,&iblob, &vtp0h[i][0], &vtp0h[i][1], &vtp0h[i][2]); } for (j = 0; j < 3; j++) { for (i = 0; i < 3 * Natomes; i++){ vtp[i][j + 5 * cyc] = vtp0h[i][j]; } } 57 } if(Ndegres % 5 == 4){ sscanf(buffer, " Frequencies --- %lf %lf %lf %lf", &freq[5 * cyc], &freq[5 * cyc + 1],&freq[5 * cyc + 2],&freq[5 * cyc + 3]); for (i = 0; i < 4; i++) printf("%d %f\n", i + 5 * cyc, freq[5 * cyc + i]); for (i = 0; i < 6; i++) fgets(buffer, (int) sizeof buffer, pf); for (i = 0; i < 3 * Natomes; i++) { fgets(buffer, (int) sizeof buffer, pf); sscanf(buffer, "%d %d %d %lf %lf %lf %lf", &iblob, &iblob, &iblob, &vtp0h[i][0], &vtp0h[i][1], &vtp0h[i][2], &vtp0h[i][3]); } for (j = 0; j < 4; j++) { for (i = 0; i < 3 * Natomes; i++){ vtp[i][j + 5 * cyc] = vtp0h[i][j]; } } } } } /* fin des cycles avec des vecteurs propres de haute precision*/ /* Affichage des valeurs propres et des vecteurs propres */ for (i = 0; i < Ndegres; i++) { printf("\nFrequence : %f cm-1\n", freq[i]); n = 0; printf(" x y z\n"); for (j = 0; j < Natomes; j++) { for (k = 0; k < 3; k++){ printf(" %d %f", j+1, vtp[n][i]); n++; } printf("\n"); } 58 } /* sauvegarde des valeurs propres et vecteurs propres */ sauvegarde_vecteur(freq,Ndegres,"valpropres0"); sauvegarde_matrice(vtp,3*Natomes,3*Natomes,"vectpropres0"); /* suite du traitement */ rewind(pf); compteur = 0; while (NULL != fgets(buffer, (int) sizeof buffer, pf)) { BasseCasse(buffer); compteur++; if (strstr(buffer, " thermochemistry ")) { break; } } printf("Trouv ! ligne = %d\n", compteur); fgets(buffer, (int) sizeof buffer, pf); fgets(buffer, (int) sizeof buffer, pf); printf("%s", buffer); for (j = 0; j < Natomes; j++) { fgets(buffer, (int) sizeof buffer, pf); sscanf(buffer, " Atom %d has atomic number %d and mass &iblob, &iblob, &m[j]); massetot += m[j]; printf("Masse de %d = %f\n", j + 1, m[j]); /* Propagation des masses */ for (k = 0; k < 3; k++) { m3[3 * j + k] = m[j]; printf("%d %f\n", 3 * j + k, m3[3 * j + k]); } xx[3 * j] = x[j]; xx[3 * j + 1] = y[j]; xx[3 * j + 2] = z[j]; } %lf", 59 /* sauvegarde des positions */ sauvegarde_vecteur(xx,3*Natomes,"positions0"); /* sauvegarde des masses */ sauvegarde_vecteur(m3,3*Natomes,"masses3"); printf("Masse moleculaire : %10.7f\n", massetot); /* multiplication des vect prores par sqrt(mi) */ for (i = 0; i < 3 * Natomes; i++) { for (j = 0; j < Ndegres; j++) { vtp[i][j] *= sqrt(m3[i]); } } for (j=0; j < Ndegres; j++) { for (i=0;i < 3* Natomes;i++){ aux[i]=vtp[i][j]; } Norme(aux,3*Natomes); for (i=0;i < 3* Natomes;i++){ vtp[i][j]=aux[i]; } } sauvegarde_matrice(vtp,3*Natomes,3*Natomes,"vectpropres1"); /* Affichage des vecteurs propres */ printf("Affichage vectpropres * sqrt(mi)\n"); for (i = 0; i < 3 * Natomes; i++) { for (j = 0; j < Ndegres; j++) { printf("%f\t", vtp[i][j]); } printf("\n"); } /* Calcul de la Matrice dynamique */ for (i = 0; i < 3 * Natomes; i++) { for (j = 0; j < 3 * Natomes; j++) { D[i][j] = 0.; for (k = 0; k < Ndegres; k++) { D[i][j] += vtp[i][k] * vtp[j][k] * freq[k] * freq[k]; } D[i][j] *= 1.; } } 60 /* Sauvegarde matrice dynamique recalcule */ sauvegarde_matrice(D,3*Natomes,3*Natomes,"matricedyn0"); printf("Matrice recalculee d’apres gaussian\n"); Affich_Mat(3 * Natomes, 3 * Natomes, D, "\t", "\n"); for (i = 0; i < 3 * Natomes; i++) { for (j = 0; j < 3 * Natomes; j++) { D[i][j] *= sqrt((m3[i] * m3[j])); } } sauvegarde_matrice(D,3*Natomes,3*Natomes,"matricedyn_masses0"); /* Affichage de la matrice dynamique */ printf("Matrice dynamique multiplie par masses\n"); Affich_Mat(3 * Natomes, 3 * Natomes, D, "\t", "\n"); printf("Atome fixe en Translation : "); /* coord de ni = (0,0,0) */ scanf("%d", &ni); printf("Atome fixe en Azimuth : "); /* coord de nj = (x,0,0) */ scanf("%d", &nj); printf("Atome fixe en Longitude : "); /* coord de nk = (x,y,0) */ scanf("%d", &nk); for (j = 0; j < Natomes; j++) { /* numero de ligne de l’atome j */ nl[j] = j; gg[nl[j]]=j; printf("%d\n",nl[j]); } RMat(Natomes, ni, nj, nk, xx, nl, gg, D); LCmod(CMOD, ni, nj, nk, Natomes); sauvegarde_imatrice(CMOD,3*Natomes,3*Natomes,"choix_modes"); k = 0; for (j = 0; j < Natomes ; j++){ for (i = 0; i <= 2 ;i++) { if (CMOD[j][i] == 1) {/*par defaut on traite tous les modes, plus tard on pourra choisir */ LinMode(Natomes, j, i, k, nj, nk, En, err, dx, nl, gg, D, M); kk[j][i] = k; k = k+1; } } 61 } Affich_Mat(3 * Natomes + 2, 3 * Natomes - 6, M, "\t", "\n"); sauvegarde_matrice(M,3 * Natomes + 2, 3 * Natomes - 6,"matrice_dx"); /* printf("Choisir un mode a observer ? (y or n) "); scanf("%s", ch); sprintf(b,"n"); atomes2 = atoms(Natomes); while(strcmp(b,ch)){ printf("Choix de l’atome: "); scanf("%d", &at); printf("Choix de la ligne: "); scanf("%d", &lg); k = kk[at][lg]; printf("%d\n",k); if (k == -1){ printf("Ce mode n’a pas ete calcule"); return; } q = 0; for (i = 0; i < Natomes; i++) { strcpy(atomes2[q].symb,atomes1[q].symb); atomes2[q].x = atomes1[q].x + M[3 * i][k]; atomes2[q].y = atomes1[q].y + M[3 * i + 1][k]; atomes2[q].z = atomes1[q].z + M[3 * i + 2][k]; q++; } strcpy(com,"molecule deformee"); sauvegarde_xyz(Natomes, com, atomes2, "coord_f.xyz"); fi = fopen("coord_i.xyz", "a"); ff = fopen("coord_f.xyz", "r"); while (NULL != fgets(buffer,255, ff)){ fprintf(fi, "%s", buffer); } printf("Choisir un mode a observer ? (y or n) "); scanf("%s", ch); 62 sprintf(b,"n"); } */ /* retour au programme principal */ return 0; } void RMat(int Natomes, int ni, int nj, int nk, double *xx, int *nl, int *gg, double **D) { int i, j, k; double *V1, *V2, *V3, ee; V1=vec(3); V2=vec(3); V3=vec(3); puts("RMAT\n"); printf("Natomes=%d\n",Natomes); for (i = 0; i <= 2; i++) { V1[i] = xx[3 * nl[nj] + i] - xx[3 * nl[ni] + i]; V2[i] = xx[3 * nl[nk] + i] - xx[3 * nl[ni] + i]; } ee = Norme(V1, 3); ProdVect(V1, V2, V3); ee = Norme(V3, 3); ProdVect(V3, V1, V2); Affich_Mat(3 * Natomes, 3 * Natomes, D, "\t", "\n"); sauvegarde_matrice(D,3*Natomes,3*Natomes,"matricedynavantNewmat"); NewMat(Natomes, V1, V2, V3, ni, nl, D, xx); puts("Aprs NewMat\n"); Affich_Mat(3 * Natomes, 3 * Natomes, D, "\t", "\n"); /* sauvegarde de matrice dynamique aprs rotation */ sauvegarde_matrice(D,3*Natomes,3*Natomes,"matricedynapresNewmat"); puts("entre NewMat et NewLine\n"); NewLine(ni, nj, nk, Natomes, nl, gg, D, xx); sauvegarde_matrice(D,3*Natomes,3*Natomes,"matricedynapresNewLine"); Affich_Mat(3 * Natomes, 3 * Natomes, D, "\t", "\n"); } 63 double Norme(double *V, int n) { int i; double ee; ee = 0.; for (i = 0; i < n; i++) { ee += V[i] * V[i]; } ee = sqrt(ee); for (i = 0; i < n; i++) { V[i] = (ee==0?V[i]:V[i]/ee); } return (ee); } void ProdVect(double vi[3], { puts("ProdVect\n"); vk[0] = vi[1] * vj[2] vk[1] = vi[2] * vj[0] vk[2] = vi[0] * vj[1] } double vj[3], double vk[3]) vi[2] * vj[1]; vi[0] * vj[2]; vi[1] * vj[0]; void NewMat(int Natomes, double *V1, double *V2, double *V3, int ni, int *nl, double **D, double *xx) { int i, j, k, l, kk, ll,oo; double **UU, **DU, *X3; UU=mat(3,3); DU=mat(3,3); X3=vec(3); puts("NewMat\n"); for (i = 0; i <= 2; i++) { UU[i][0] = V1[i]; UU[i][1] = V2[i]; UU[i][2] = V3[i]; } sauvegarde_matrice(UU,3,3,"matriceUU"); for (k = 0; k <= 2; k++) { kk = 3 * nl[ni] + k; X3[k] = xx[kk]; 64 } for (i = 0; i < Natomes; i++) { for (k = 0; k <= 2; k++) { kk = 3 * nl[i] + k; xx[kk] -= X3[k]; } } for (i = 0; i < Natomes; i++) { for (k = 0; k <= 2; k++) { kk = 3 * nl[i] + k; X3[k] = xx[kk]; } RotateX(UU, X3); puts("aprs RotateX\n"); for (k = 0; k <= 2; k++) { kk = 3 * nl[i] + k; xx[kk] = X3[k]; } } for (i = 0; i < Natomes; i++) { for (j = i; j < Natomes; j++) { for (k = 0; k <= 2; k++) { kk = 3 * nl[i] + k; for (l = 0; l <= 2; l++) { ll = 3 * nl[j] + l; DU[k][l] = D[kk][ll]; } } Rotate(UU, DU); puts("aprs Rotate\n"); for (k = 0; k <= 2; k++) { for (l = 0; l <= 2; l++) { kk = 3 * nl[i] + k; ll = 3 * nl[j] + l; D[kk][ll] = DU[k][l]; if (i != j) { D[ll][kk] = D[kk][ll]; } } 65 } } } puts("Fin NewMat\n"); } void Rotate(double **R, double **M) { double **MM; int i, j, k, l; MM=mat(3,3); puts("Rotate\n"); for (i = 0; i <= 2; i++) { for (j = 0; j <= 2; j++) { MM[i][j] = 0.; }; }; for (i = 0; i <= 2; i++) { for (j = 0; j <= 2; j++) { for (k = 0; k <= 2; k++) { for (l = 0; l <= 2; l++) { MM[i][j] += R[k][i] * R[l][j] * M[k][l]; } } } } for (i = 0; i <= 2; i++) { for (j = 0; j <= 2; j++) { M[i][j] = MM[i][j]; } } } void RotateX(double **R, double *X) { double *XX; int i, j, k, l; XX=vec(3); puts("RotateX\n"); for (i = 0; i <= 2; i++) { XX[i] = 0.; }; 66 for (i = 0; i <= 2; i++) { for (k = 0; k <= 2; k++) { XX[i] += R[k][i] * X[k]; } } for (i = 0; i <= 2; i++) { X[i] = XX[i]; } } void NewLine(int ni, int nj, int nk, int Natomes, int *nl, int *gg, double **D, double *xx) { int n1, n2, i, nnl; puts("Newline\n"); for (i = 0; i <= 2; i++) { n1 = 3 * nl[ni] + i; n2 = 3 * Natomes + i - 3; Exch(Natomes, n1, n2, D, xx); } nnl=nl[ni]; nl[ni] = Natomes - 1; nl[gg[Natomes -1]]=nnl; nnl = gg[Natomes-1]; gg[Natomes - 1]=ni; gg[ni]=nnl; for (i = 0; i <= 2; i++) { n1 = 3 * nl[nj] + i; n2 = 3 * Natomes + i - 6; Exch(Natomes, n1, n2, D, xx); } nnl=nl[nj]; nl[nj] = Natomes - 2; nl[gg[Natomes -2]]=nnl; nnl = gg[Natomes-2]; gg[Natomes - 2]=nj; gg[nj]=nnl; for (i = 0; i <= 2; i++) { n1 = 3 * nl[nk] + i; n2 = 3 * Natomes + i - 9; 67 Exch(Natomes, n1, n2, D, xx); } nnl=nl[nk]; nl[nk] = Natomes - 3; nl[gg[Natomes -3]]=nnl; nnl = gg[Natomes-3]; gg[Natomes - 3]=nk; gg[nl[nk]]=nnl; n1 = 3 * Natomes - 7; n2 = n1 + 1; Exch(Natomes, n1, n2, D, xx); puts("Fin de NewLine\n"); } void Exch(int Natomes, int n1, int n2, double **D, double *xx) { int i, j; double v[3*Natomes], x; puts("Exch\n"); for (i = 0; i < 3*Natomes; i++) { v[i] = D[n1][i]; D[n1][i] = D[n2][i]; D[n2][i] = v[i]; } for (i = 0; i < 3*Natomes; i++) { v[i] = D[i][n1]; D[i][n1] = D[i][n2]; D[i][n2] = v[i]; } x = xx[n1]; xx[n1] = xx[n2]; xx[n2] = x; } void LCmod(int **CMOD, int ni, int nj, int nk, int Natomes) { int i, j; puts("LCmod\n"); 68 for (j = 0; j < Natomes; j++) { for (i = 0; i <= 2; i++) { CMOD[j][i] = 1; } } CMOD[ni][0]=0; CMOD[ni][1]=0; CMOD[ni][2]=0; CMOD[nj][1]=0; CMOD[nj][2]=0; CMOD[nk][2]=0; } void LinMode(int Natomes, int N, int in, int k, int nj, int nk, double En, double err, double *dx,int *nl, int *gg, double **D, double **M) { double eps, *ddx; int i, j, n, nn, ii, it; ddx=vec(3 * Natomes); puts("LinMode\n"); eps = 10. * err; it = 3 * Natomes - 6; for (i = 0; i < 3 * Natomes; i++) { dx[i] = 0.; } ii = 3 * nl[N] + in; if (ii == it) { ii = it - 1; } printf("ii=%d\n",ii); dx[ii] = 1.; while (eps > err) { for (i = 0; i < it ; i++) { ddx[i] = dx[i]; if (i != ii) { for (j = 0; j < it ; j++) { if (i != j) { dx[i] += D[i][j] * dx[j]; } } 69 dx[i] = -dx[i] / D[i][i]; } ddx[i] -= dx[i]; } eps = Norme(ddx,it); /* normalisation de ddx pas ncessaire !*/ } En = Energie(Natomes, dx, D); printf("Energie = %f\n",En); for (n = 0; n < Natomes - 3; n++) { nn = 3 * n; ii = gg[n] * 3; M[ii][k] = dx[nn]; M[ii + 1][k] = dx[nn + 1]; M[ii + 2][k] = dx[nn + 2]; } nn = 3 * Natomes - 9; M[3 * nk][k] = dx[nn]; M[3 * nk + 1][k] = dx[nn + 1]; M[3 * nj][k] = dx[nn + 2]; M[3 * Natomes][k] = En; M[3 * Natomes + 1][k] = 3 * N + in; } double Energie(int Natomes, double *dx, double **D) { int i, j, it; double E; puts("Energie\n"); it = 3 * Natomes - 6; E = 0.; for (i = 0; i < it; i++) { for (j = i + 1; j < it; j++) { E += dx[i] * dx[j] * D[i][j]; } E += dx[i] * dx[i] * D[i][i] /2.; } return (E); } 70 D.2 Visualisation de la déformation #include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> #include "fichiers_es.h" /*#include "atomes.h"*/ #include "memoire.h" /* Entrer les arguments dans l’ordre suivant : matrice des positions initiales, matrice des deformations, matrice des modes choisis */ int main(int argc, char *argv[]) { int k, q, i, j, iff, n, Natomes, atm, l, N = 0, **CMOD; double f, **m, **M, **kk; char buffer[500]; char b[2]; char ch[2]; char com[134]; struct atome *atomes1, *atomes2; FILE *pf = NULL; FILE *ff = NULL; FILE *fi = NULL; FILE *ff2 = NULL; FILE *fc = NULL; FILE *fm = NULL; Natomes = 100; f=0.2; m = mat(Natomes, 3); M = mat(3 * Natomes + 2, 3 * Natomes - 6); kk = mat (Natomes, 3); CMOD = imat(3*Natomes, 3*Natomes); for (i=0;i<Natomes;i++){ for (j=0;j<3;j++){ kk[i][j] = -1.; } } 71 /* Traitement du fichier des positions de la molecule non deformee */ N = Nbre_atomes_rasmol_xyz(argv[1]); Natomes = N; atomes1 = atoms(Natomes); atomes2 = atoms(Natomes); lecture_xyz(Natomes, com, atomes1, argv[1]); for (i = 0; i < Natomes; i++){ m[i][0] = atomes1[i].x; m[i][1] = atomes1[i].y; m[i][2] = atomes1[i].z; } strcpy(com,"molecule non deformee"); sauvegarde_xyz(Natomes, com, atomes1, "mol_initiale.xyz"); sauvegarde_xyz(Natomes, com, atomes1, "mol_def.xyz"); /* Traitement du fichier des deformations */ pf = fopen(argv[2], "r"); for (i = 0; i < 3 * Natomes + 2; i++) { for (j = 0; j < 3 * Natomes - 6; j++) { fgets(buffer,(int) sizeof buffer, pf); sscanf(buffer,"%lf", &M[i][j]); } } /* Traitement du fichier des modes choisis */ fc = fopen(argv[3], "r"); for (i = 0; i < 3 * Natomes ;i++){ for (j = 0; j < 3 * Natomes ; j++){ fgets(buffer,(int) sizeof buffer, fc); sscanf(buffer,"%d", &CMOD[i][j]); } } k = 0; for (j = 0; j < Natomes ; j++){ for (i = 0; i <= 2 ;i++) { if (CMOD[j][i] == 1){ kk[j][i] = k; k = k+1; } } } 72 /* Choix du mode a observer */ /*printf("Choisir un mode a observer ? (y or n) "); scanf("%s", ch); sprintf(b,"n"); while(strcmp(b,ch)){ */ printf("Choix de l’atome : "); scanf("%d", &atm); printf("Choix de la ligne: "); scanf("%d", &l); k = kk[atm - 1][l]; printf("mode =%d\n",k); if (k == -1){ printf("Ce mode n’a pas ete calcule"); return; } /* Creations de positions intermediaires pour construire l’animation */ f=0.; for(iff=1; iff<=5; iff++){ f += .2; q = 0; for (i = 0; i < Natomes; i++) { strcpy(atomes2[q].symb,atomes1[q].symb); atomes2[q].x = atomes1[q].x + f * M[3 * i][k]; atomes2[q].y = atomes1[q].y + f * M[3 * i + 1][k]; atomes2[q].z = atomes1[q].z + f * M[3 * i + 2][k]; q++; } strcpy(com,"molecule deformee"); sauvegarde_xyz(Natomes, com, atomes2, "mol_def_aux.xyz"); fi = fopen("mol_def.xyz", "a"); ff = fopen("mol_def_aux.xyz", "r"); while (NULL != fgets(buffer,255, ff)){ fprintf(fi,"%s", buffer); } fflush(fi); } f = 1.; for(iff= 4; iff>= 1; iff--){ f -= 0.2; 73 q = 0; for (i = 0; i < Natomes; i++) { strcpy(atomes2[q].symb,atomes1[q].symb); atomes2[q].x = atomes1[q].x + f * M[3 * i][k]; atomes2[q].y = atomes1[q].y + f * M[3 * i + 1][k]; atomes2[q].z = atomes1[q].z + f * M[3 * i + 2][k]; q++; } strcpy(com,"molecule deformee"); sauvegarde_xyz(Natomes, com, atomes2, "mol_def_aux2.xyz"); ff2 = fopen("mol_def_aux2.xyz", "r"); while (NULL != fgets(buffer,255, ff2)){ fprintf(fi, "%s", buffer); } } fflush(fi); fm = fopen("mol_initiale.xyz", "r"); while (NULL != fgets(buffer,255, fm)){ fprintf(fi, "%s", buffer); } fflush(fi); /*printf("Choisir un mode a observer ? (y or n) "); scanf("%s", ch); sprintf(b,"n"); } */ return 0; } D.3 #include #include #include #include #include #include Accrochage de deux molécules <stdio.h> <stdlib.h> <math.h> "bib_math.h" "fichiers_es.h" "memoire.h" void Prod3Mat (double **, double **, double **, double **); 74 int main(int argc, char *argv[]) { int i, j, k, l; int N=0, n1, n2, nK, nP, nQ, nL; double d_PQ, d_PK, d_QL, p, T12, R, alpha, angle; double *V1_K, *V1_P, *V2_L, *V2_Q, *U1,*U2, *U3, *T1, *T2, *T3, *P, *s; double **m1, **m2, **M,**M_t, **A, **A_alpha, **aux, **R1, **R2, **mm1, **mm2, **mmm1, **mmm2, **dm2, **dmm2, **PP, **I; char com[134]; struct atome *atomes1, *atomes2, *atomesf; wd_init(); n1 = 100; n2 = 100; V1_K = vec(3); V1_P = vec(3); V2_L = vec(3); V2_Q = vec(3); U1 = vec(3); U2 = vec(3); U3 = vec(3); T1 = vec(3); T2 = vec(3); T3 = vec(3); P = vec(3); s = vec(n2); M = mat(3,3); M_t = mat(3,3); A = mat(3,3); A_alpha = mat(3,3); aux = mat(3,3); R1 = mat(3,3); R2 = mat(3,3); m1 = mat(3,n1); m2 = mat(3,n2); mm1 = mat(3,n1); mm2 = mat(3,n2); dm2 = mat(3,n2); dmm2 = mat(3,n2); mmm1 = mat(3,n1); 75 mmm2 = mat(3,n2); PP = mat(3,n2); I = mat(3,n2); /* Lecture des positions des atomes */ N = Nbre_atomes_rasmol_xyz(argv[1]); n1 = N; atomes1 = atoms(n1); printf("nombre d’atomes dans la molecule 1 : n1 = %d \n", n1); lecture_xyz(n1,com,atomes1,argv[1]); for (i = 0; i < n1; i++){ m1[0][i] = atomes1[i].x; m1[1][i] = atomes1[i].y; m1[2][i] = atomes1[i].z; } printf("Matrice m1 : positions des atomes de la molecule 1\n"); Affich_Mat(3, n1, m1, "\t", "\n"); N = Nbre_atomes_rasmol_xyz(argv[2]); n2 = N; atomes2 = atoms(n2); printf("nombre d’atomes dans la molecule 2 : n2 = %d \n", n2); lecture_xyz(n2,com,atomes2,argv[2]); for (i = 0; i < n2; i++){ m2[0][i] = atomes2[i].x; m2[1][i] = atomes2[i].y; m2[2][i] = atomes2[i].z; } printf("Matrice m2 : positions des atomes de la molecule 2\n"); Affich_Mat(3, n2, m2, "\t", "\n"); atomesf = atoms(n1+n2-2); /* Choix des atomes a connecter */ printf("Atome K a enlever sur molecule1: "); scanf("%d", &nK); printf("Atome P a connecter sur molecule1 : "); scanf("%d", &nP); GET_VEC(m1, 1 ,nK, 0, 2, V1_K); GET_VEC(m1, 1 ,nP, 0, 2, V1_P); printf("Atome L a enlever sur molecule2 : "); 76 scanf("%d", &nL); printf("Atome Q a connecter sur molecule2 : "); scanf("%d", &nQ); GET_VEC(m2, 1 ,nL, 0, 2, V2_L); GET_VEC(m2, 1 ,nQ, 0, 2, V2_Q); printf("Choix de l’angle de rotation (degrs) : "); scanf("%lf",&angle); alpha = sin(angle*3.1415926/180.); /* Calcul des distances entre atomes */ diffvect(3,V1_K,V1_P,U1); d_PK = sqrt(prodscal(3,U1,U1)); diffvect(3,V2_L,V2_Q,U2); d_QL = sqrt(prodscal(3,U2,U2)); printf("Choix de la distance de greffage : "); scanf("%lf",&d_PQ); MULT_VEC_CSTE(3,1./d_PK,U1, T1); MULT_VEC_CSTE(3,1./d_QL,U2, T2); T12 = prodscal(3, T1, T2); printf("T12 = %f\n",T12); if (T12 != 1){ R = sqrt(1 - T12 * T12); prodvect (T1, T2, P); p = sqrt(prodscal(3,P,P)); PUT_VEC(T1,1,0,0,2,M); comblinvect(3,1,T2,-T12,T1,T3); MULT_VEC_CSTE(3,1./R,T3,T3); PUT_VEC(T3,1,1,0,2,M); MULT_VEC_CSTE(3,1./p,P,P); PUT_VEC(P,1,2,0,2,M); printf("Matrice M\n"); Affich_Mat(3, 3, M, "\t", "\n"); TRANSP_MAT(3, M, M_t); 77 A[0][0] = - T12; A[0][1] = - R; A[0][2] = 0; A[1][0] = R; A[1][1] = - T12; A[1][2] = 0; A[2][0] = 0; A[2][1] = 0; A[2][2] = 1; printf("Matrice A\n"); Affich_Mat(3, 3, A, "\t", "\n"); A_alpha [0][0] = 1; A_alpha [0][1] = 0; A_alpha [0][2] = 0; A_alpha [1][0] = 0; A_alpha [1][1] = sqrt(1 - alpha * alpha); A_alpha [1][2] = - alpha; A_alpha [2][0] = 0; A_alpha [2][1] = alpha; A_alpha [2][2] = sqrt(1 - alpha * alpha); printf("Matrice A_alpha\n"); Affich_Mat(3, 3, A_alpha, "\t", "\n"); /*MULT_MAT(3, A, M_t, aux); printf("Matrice A\n"); Affich_Mat(3, 3, A, "\t", "\n"); MULT_MAT(3, M, aux, R1);*/ Prod3Mat (M, A, M_t, R1); printf("Matrice R1\n"); Affich_Mat(3, 3, R1, "\t", "\n"); for (i = 0; i < 3; i++){ for (j = 0; j < n1; j++){ if (j != nK){ mm1[i][j] = m1[i][j]; } } } for (i = 0; i < 3; i++){ 78 for (j = 0; j < n2; j++){ dm2[i][j] = m2[i][j] - m2[i][nQ]; } } for (i=0;i<3;i++){ for (j=0;j<n2;j++){ if (j != nL){ mm2[i][j]=0.0; for (k=0;k<3;k++){ mm2[i][j]+=R1[i][k]*dm2[k][j]; } mm2[i][j] += V1_P[i] + T1[i] * d_PQ; } } } printf("Matrice mm2\n"); Affich_Mat(3, n2, mm2, "\t", "\n"); /* rotation arbitraire alpha*/ /*MULT_MAT(3, M, A_alpha, aux); MULT_MAT(3, aux, M_t, R2);*/ Prod3Mat (M, A_alpha, M_t, R2); printf("Matrice R2\n"); Affich_Mat(3, 3, R2, "\t", "\n"); for (i = 0; i < 3; i++){ for (j = 0; j < n1; j++){ if (j != nK){ mmm1[i][j] = m1[i][j]; } } } printf("Matrice mmm1\n"); Affich_Mat(3, n1, mmm1, "\t", "\n"); for (i = 0; i < 3; i++){ for (j = 0; j < n2; j++){ dmm2[i][j] = mm2[i][j] - mm2[i][nQ]; 79 } } for (i = 0; i < 3; i++){ for (j = 0; j < n2; j++){ if (j != nL){ mmm2[i][j] = 0; for (k = 0;k < 3;k++){ mmm2[i][j] += R2[i][k] * dmm2[k][j]; } mmm2[i][j] += mm2[i][nQ]; } } } printf("Matrice mmm2\n"); Affich_Mat(3, n2, mmm2, "\t", "\n"); } else{ R1[0][0] = - T12; R1[0][1] = 0; R1[0][2] = 0; R1[1][0] = 0; R1[1][1] = - T12; R1[1][2] = 0; R1[2][0] = 0; R1[2][1] = 0; R1[2][2] = - T12; printf("Matrice R1\n"); Affich_Mat(3, 3, R1, "\t", "\n"); for (i = 0; i < 3; i++){ for (j = 0; j < n1; j++){ if (j != nK){ mm1[i][j] = m1[i][j]; } } } for (i = 0; i < 3; i++){ for (j = 0; j < n2; j++){ 80 dm2[i][j] = m2[i][j] - m2[i][nQ]; } } for (i = 0; i < 3; i++){ for (j = 0; j < n2; j++){ if (j != nL){ mm2[i][j] = 0; for (k = 0;k < 3;k++){ mm2[i][j] += R1[i][k] * dm2[k][j]; } mm2[i][j] += V1_P[i] + T1[i] * d_PQ; } } } printf("Matrice mm2\n"); Affich_Mat(3, n2, mm2, "\t", "\n"); for (i = 0; i < 3; i++){ for (j = 0; j < n1; j++){ if (j != nK){ mmm1[i][j] = mm1[i][j]; } } } printf("Matrice mmm1\n"); Affich_Mat(3, n1, mmm1, "\t", "\n"); for (j = 0; j < n2; j++){ if (j != nL){ for (i = 0; i < 3; i++){ s[j] += T1[i] * dm2[i][j]; } } } for (j = 0; j < n2; j++){ if (j != nL){ for (i = 0; i < 3; i++){ I[i][j] = s[j] * T1[i]; } 81 } } for (i = 0; i < 3; i++){ for (j = 0; j < n2; j++){ dmm2[i][j] = mm2[i][j] - mm2[i][nQ]; } } for (k PP[0][k] = PP[1][k] = PP[2][k] = } = 0; k < n2; k++){ T1[1] * dmm2[2][k] - T1[2] * dmm2[1][k]; T1[2] * dmm2[0][k] - T1[0] * dmm2[2][k]; T1[0] * dmm2[1][k] - T1[1] * dmm2[0][k]; for (i = 0; i < 3; i++){ for (j = 0; j < n2; j++){ if (j != nL){ mmm2[i][j] = 0; mmm2[i][j] = I[i][j] + sqrt(1 - alpha * alpha) * ( - I[i][j] + dmm2[i][j]) - alpha * PP[i][j] + mm2[i][nQ]; } } } printf("Matrice mmm2\n"); Affich_Mat(3, n2, mmm2, "\t", "\n"); } j=0; for (i = 0; i < n1; i++){ if (i != nK) { strcpy(atomesf[j].symb,atomes1[i].symb); atomesf[j].x=mmm1[0][i]; atomesf[j].y=mmm1[1][i]; atomesf[j].z=mmm1[2][i]; j++; } } for (i = 0; i < n2; i++){ if (i != nL) { 82 strcpy(atomesf[j].symb,atomes2[i].symb); atomesf[j].x=mmm2[0][i]; atomesf[j].y=mmm2[1][i]; atomesf[j].z=mmm2[2][i]; j++; } } strcpy(com,"Fichier final"); sauvegarde_xyz(n1+n2-2,com,atomesf, "final.xyz"); } void Prod3Mat (double **mm, double **X, double **mm_t, double **m) { double **aux; int i, j, k, l; aux = mat(3,3); for (i = 0; i <= 2; i++) { for (j = 0; j <= 2; j++) { aux[i][j] = 0.; } } for (i = 0; i <= 2; i++) { for (j = 0; j <= 2; j++) { for (k = 0; k <= 2; k++) { for (l = 0; l <= 2; l++) { aux[i][j] += mm[i][k] * X[k][l] * mm_t[l][j]; } } } } for (i = 0; i <= 2; i++) { for (j = 0; j <= 2; j++) { m[i][j] = aux[i][j]; } } return ; } Bibliographie [1] A.I. Kitaigorodsky, Molecular crystals and molecules, Academic Press New York and London, (1973) chap. 3 et 4 [2] G.E. Schulz, R.H. Schirmer Principles of protein structure, Springer-Verlag, (1978) chap. 3 [3] A.M. Lesk, Introduction to protein architecture, The structural biology of proteins, Oxford University Press (1999) [4] C. Kittel, Physique de l’état solide, Dunod, (1998) chap. 4 [5] G.R. Smith, M.J.E. Sternberg, Prediction of protein-protein interactions by docking methods, Current Opinion in Strut. Biol. (2002) vol. 12 p. 28-35 [6] M.F. Thorpe, M. Lei, Macromolecular flexibility, Philosophical Magazine, (2004) vol. 84 no.13-16 p. 1323-1331 [7] K. Bastard, A. Thureau, R. Lavery, C. Prévost, Docking macromolecules with flexible segments, Jounal of Computational Chemistry (2003) vol. 24 p. 1910-1920 [8] M.L. Teodoro, G.N. Phillips Jr, L.E. Kavraki A dimensionality reduction approach to modeling protein flexibility, ACM Press, (2002) p. 299-308 [9] M. Moll, M. Shah, D.C. Sorensen, L.E. Kavraki, A study of modeling molecular flexibility using main modes of motion, Oxford University Press, (2005) [10] J. Cortès, T. Siméon, V. Ruiz de Angulo, D.Guieysse, M. Remaud-Siméon, V. Tran, A path planning approach for computing large-amplitude motions of flexible molecules, Oxford University Press, (2005) [11] P. Durand, G. Trinquier, Y.H. Sanejouand, A new approach for determining lowfrequency normal modes in macromolecules, Biopolymers, (1994) vol. 34 p.759-771 [12] F. Tama, Y.H. Sanejouand Conformational change of proteins arising from normal mode calculations, Protein Engeniering, (2001) vol. 14 83