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