/* Copyright (C) 2001 Damir Zucic */

/*=============================================================================

				reset_psi.c

Purpose:
	Reset the psi angle in each residue. Each psi angle will be changed
	to +180 degrees.  The chain will be messed up!  Please note that if
	you modify  default angle you will also have to modify the function
	ApplyStructure_ (),  because  it assumes  that you  are using  +180
	degrees here.

Input:
	(1) Pointer to MolComplexS structure, with macromolecular data.

Output:
	(1) Psi angle changed to -180 degrees (in each residue).
	(2) Return value.

Return value:
	(1) Positive on success.
	(2) Negative on failure.

========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		ExtractNCACO_ (VectorS *, VectorS *, VectorS *, VectorS *,
			       AtomS *, size_t, size_t);
double		PsiFromNCACO_ (VectorS *, VectorS *, VectorS *, VectorS *);
int		RotateAtom_ (AtomS *, VectorS *, VectorS *, double);

/*======change psi angle to +180 degrees; do it for each residue:============*/

int ResetPsi_ (MolComplexS *mol_complexSP)
{
int			residuesN;
int			residueI;
ResidueS		*curr_residueSP;
size_t			atom_startI, atom_endI, atomI;
AtomS			*atomSP;
int			n;
static VectorS		N_vectorS, CA_vectorS, C_vectorS, O_vectorS;
double			psi, delta_psi;

/* Prepare the number of residues: */
residuesN = mol_complexSP->residuesN;

/* Scan the macromolecular complex: */
for (residueI = 0; residueI < residuesN; residueI++)
	{
	/* Pointer to the current residue: */
	curr_residueSP = mol_complexSP->residueSP + residueI;

	/* Prepare the atomic index range: */
	atom_startI = curr_residueSP->residue_startI;
	atom_endI   = curr_residueSP->residue_endI;

	/* Extract N, CA, C and O coordinates: */
	n = ExtractNCACO_ (&N_vectorS, &CA_vectorS, &C_vectorS, &O_vectorS,
			   mol_complexSP->atomSP, atom_startI, atom_endI);

	/* All four atoms are required to reset the psi angle: */
	if (n < 4) continue;

	/* If this point  is reached,  the coordinates */
	/* for all four required atoms were retrieved. */

	/* Calculate the psi angle (radians): */
	psi =  PsiFromNCACO_ (&N_vectorS, &CA_vectorS, &C_vectorS, &O_vectorS);

	/* Prepare the rotation angle: */
	delta_psi = 3.1415927 - psi;

	/* Now rotate the O atom about the CA-C bond: */
	for (atomI = atom_startI; atomI <= atom_endI; atomI++)
		{
		/* Pointer to the current atom: */
		atomSP = mol_complexSP->atomSP + atomI;

		/* Check is it the O atom: */
		if (strcmp (atomSP->raw_atomS.pure_atom_nameA, "O") != 0)
			{
			continue;
			}

		/* Rotate the O atom about CA-C bond: */
		RotateAtom_ (atomSP, &CA_vectorS, &C_vectorS, delta_psi);
		}
	}

/* Return positive value on success: */
return 1;
}

/*===========================================================================*/


