1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
|
/* Copyright (C) 2001 Damir Zucic */
/*=============================================================================
set_psi.c
Purpose:
Set the psi angle for each selected residue in the specified complex.
A residue is treated as selected if the first atom of this residue
is selected. For proteins, this is typically the N atom (nitrogen).
Input:
(1) Pointer to MolComplexS structure.
(2) Pointer to ConfigS structure.
(3) The psi angle in degrees.
Output:
(1) Psi angle set for each selected residue in each caught complex.
(2) Return value.
Return value:
(1) Positive always (trivial).
Notes:
(1) This function uses the atoms N, CA, C of the current residue and
and the N atom of the next residue. The O atom of the current
residue is not used.
========includes:============================================================*/
#include <stdio.h>
#include <string.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xos.h>
#include <X11/Xatom.h>
#include "defines.h"
#include "typedefs.h"
/*======function prototypes:=================================================*/
int ExtractNCAC_ (VectorS *, VectorS *, VectorS *,
AtomS *, size_t, size_t);
int ExtractN_ (VectorS *, AtomS *, size_t, size_t);
double PsiFromNCACN_ (VectorS *, VectorS *, VectorS *, VectorS *,
ConfigS *);
int RotateAtom_ (AtomS *, VectorS *, VectorS *, double);
int DihedralAngles_ (MolComplexS *, ConfigS *);
/*======set psi angle(s):====================================================*/
int SetPsi_ (MolComplexS *mol_complexSP, ConfigS *configSP, double psi_new)
{
int residuesN, residueI;
size_t atomsN, atomI;
ResidueS *current_residueSP;
AtomS *first_atomSP;
size_t current_startI, current_endI;
int n;
static VectorS N_vectorS, CA_vectorS, C_vectorS;
ResidueS *next_residueSP;
size_t next_startI, next_endI;
static VectorS nextN_vectorS;
double psi_old, delta_psi;
AtomS *atomSP;
/* Copy the number of residues in the specified complex: */
residuesN = mol_complexSP->residuesN;
/* Copy the number of atoms in the specified complex: */
atomsN = mol_complexSP->atomsN;
/* Scan residues, but omit the last one: */
for (residueI = 0; residueI < residuesN - 1; residueI++)
{
/* Pointer to the current residue: */
current_residueSP = mol_complexSP->residueSP + residueI;
/* Pointer to the first atom of this residue: */
first_atomSP = mol_complexSP->atomSP +
current_residueSP->residue_startI;
/* If the first atom of this residue is not */
/* selected, the residue is not selected: */
if (first_atomSP->selectedF == 0) continue;
/* The range of atomic indices for the current residue: */
current_startI = current_residueSP->residue_startI;
current_endI = current_residueSP->residue_endI;
/* Try to extract N, CA and C coordinates for the current residue: */
n = ExtractNCAC_ (&N_vectorS, &CA_vectorS, &C_vectorS,
mol_complexSP->atomSP, current_startI, current_endI);
if (n < 3) continue;
/* The N atom of the next residue is required. */
/* Pointer to the next residue: */
next_residueSP = mol_complexSP->residueSP + residueI + 1;
/* The atomic index range for the next residue: */
next_startI = next_residueSP->residue_startI;
next_endI = next_residueSP->residue_endI;
/* Try to extract the N atom from the next residue: */
n = ExtractN_ (&nextN_vectorS,
mol_complexSP->atomSP, next_startI, next_endI);
if (n < 1) break;
/* Calculate and check the old psi: */
psi_old = PsiFromNCACN_ (&N_vectorS, &CA_vectorS, &C_vectorS,
&nextN_vectorS,
configSP);
if (psi_old == BADDIHEDANGLE) continue;
/* Calculate the difference: */
delta_psi = psi_new - psi_old;
/* Rotate the O atom of the current residue about CA-C bond: */
for (atomI = current_startI; atomI <= current_endI; atomI++)
{
/* Pointer to the current atom: */
atomSP = mol_complexSP->atomSP + atomI;
/* The only atom which should be rotated is O: */
if (strcmp (atomSP->raw_atomS.pure_atom_nameA, "O") != 0)
{
continue;
}
/* If this point is reached, rotate O about CA-C bond: */
RotateAtom_ (atomSP, &CA_vectorS, &C_vectorS, delta_psi);
}
/* Rotate all atoms after the current residue about CA-C bond: */
for (atomI = current_endI + 1; atomI < atomsN; atomI++)
{
/* Pointer to the current atom: */
atomSP = mol_complexSP->atomSP + atomI;
/* Rotate atom: */
RotateAtom_ (atomSP, &CA_vectorS, &C_vectorS, delta_psi);
}
}
/* Update dihedral angles and cis-trans flags: */
DihedralAngles_ (mol_complexSP, configSP);
/* Set the position_changedF: */
mol_complexSP->position_changedF = 1;
/* Return positive value (trivial): */
return 1;
}
/*===========================================================================*/
|