1 /* Copyright (C) 2001 Damir Zucic */
2
3 /*=============================================================================
4
5 edit_phi.c
6
7 Purpose:
8 Edit phi angle. If edit_single_bondF is zero, edit phi for every
9 selected residue in the specified macromolecular complex. If the
10 flag edit_single_bondF is different from zero, edit only the phi
11 angle for the bond specified by the given atomic array indices.
12 A residue is treated as selected if the first atom of this
13 residue is selected. For protein residues, this is typically N
14 atom (nitrogen).
15
16 Input:
17 (1) Pointer to MolComplexS structure.
18 (2) Pointer to RuntimeS structure.
19 (3) Pointer to ConfigS structure.
20 (4) Rotation angle.
21
22 Output:
23 (1) Phi angle changed for chosen residue(s).
24 (2) Return value.
25
26 Return value:
27 (1) Positive always (trivial).
28
29 ========includes:============================================================*/
30
31 #include <stdio.h>
32
33 #include <string.h>
34
35 #include <X11/Xlib.h>
36 #include <X11/Xutil.h>
37 #include <X11/Xos.h>
38 #include <X11/Xatom.h>
39
40 #include "defines.h"
41 #include "typedefs.h"
42
43 /*======function prototypes:=================================================*/
44
45 int ExtractNCA_ (VectorS *, VectorS *, AtomS *, size_t, size_t);
46 int RotateAtom_ (AtomS *, VectorS *, VectorS *, double);
47 int DihedralAngles_ (MolComplexS *, ConfigS *);
48
49 /*======change phi angle for selected residues:==============================*/
50
EditPhi_(MolComplexS * mol_complexSP,RuntimeS * runtimeSP,ConfigS * configSP,double delta_phi)51 int EditPhi_ (MolComplexS *mol_complexSP,
52 RuntimeS *runtimeSP, ConfigS *configSP,
53 double delta_phi)
54 {
55 int residuesN, residueI;
56 size_t atomsN;
57 ResidueS *residueSP;
58 size_t atom_startI, atom_endI, atomI;
59 AtomS *atomSP;
60 int n;
61 static VectorS N_vectorS, CA_vectorS;
62
63 /* Copy the number of residues in the current complex: */
64 residuesN = mol_complexSP->residuesN;
65
66 /* Copy the number of atoms in the current complex: */
67 atomsN = mol_complexSP->atomsN;
68
69 /* Scan residues: */
70 for (residueI = 0; residueI < residuesN; residueI++)
71 {
72 /* Pointer to the current residue: */
73 residueSP = mol_complexSP->residueSP + residueI;
74
75 /* Prepare the atomic index range: */
76 atom_startI = residueSP->residue_startI;
77 atom_endI = residueSP->residue_endI;
78
79 /* Pointer to the first atom: */
80 atomSP = mol_complexSP->atomSP + atom_startI;
81
82 /* Check the edit_single_bondF flag. If this flag is equal */
83 /* to zero, the current selection should be taken into */
84 /* account. Otherwise, the selection should be ignored. */
85
86 /* Editing of a single phi angle requested: */
87 if (runtimeSP->edit_single_bondF)
88 {
89 /* Check the array indices of N and CA: */
90 if ((runtimeSP->atom1_arrayI < atom_startI) ||
91 (runtimeSP->atom1_arrayI > atom_endI) ||
92 (runtimeSP->atom2_arrayI < atom_startI) ||
93 (runtimeSP->atom2_arrayI > atom_endI))
94 {
95 continue;
96 }
97 }
98
99 /* Editing of phi angles for all selected residues requested: */
100 else
101 {
102 /* If the first atom of the current residue is */
103 /* not selected, the residue is not selected: */
104 if (atomSP->selectedF == 0) continue;
105 }
106
107 /* Extract N and CA coordinates: */
108 n = ExtractNCA_ (&N_vectorS, &CA_vectorS,
109 mol_complexSP->atomSP, atom_startI, atom_endI);
110 if (n < 2) continue;
111
112 /* Change the phi angle: */
113 for (atomI = atom_startI; atomI <= atom_endI; atomI++)
114 {
115 /* Pointer to the current atom: */
116 atomSP = mol_complexSP->atomSP + atomI;
117
118 /* Do not rotate H, N and CA: */
119 if ((strcmp (atomSP->raw_atomS.pure_atom_nameA, "H") == 0) ||
120 (strcmp (atomSP->raw_atomS.pure_atom_nameA, "N") == 0) ||
121 (strcmp (atomSP->raw_atomS.pure_atom_nameA, "CA") == 0))
122 {
123 continue;
124 }
125
126 /* Rotate the current atom about N-CA bond: */
127 RotateAtom_ (atomSP, &N_vectorS, &CA_vectorS, delta_phi);
128 }
129
130 /* Rotate all atoms after the current residue about N-CA bond: */
131 for (atomI = atom_endI + 1; atomI < atomsN; atomI++)
132 {
133 /* Pointer to the current atom: */
134 atomSP = mol_complexSP->atomSP + atomI;
135
136 /* Rotate atom: */
137 RotateAtom_ (atomSP, &N_vectorS, &CA_vectorS, delta_phi);
138 }
139 }
140
141 /* Update dihedral angles and cis-trans flags: */
142 DihedralAngles_ (mol_complexSP, configSP);
143
144 /* Return positive value (trivial): */
145 return 1;
146 }
147
148 /*===========================================================================*/
149
150
151