/* Copyright (C) 2006 Damir Zucic */

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

			weighted_hydrophobicity.c

Purpose:
	Calculate the (average) weighted hydrophobicity.

Input:
	(1) Pointer to the storage where the minimal weighted hydrophobicity
	    will be stored.
	(2) Pointer to the storage where the maximal weighted hydrophobicity
	    will be stored.
	(3) Pointer to RuntimeS structure.

Output:
	(1) Weighted hydrophobicity calculated and stored.
	(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"

/*======calculate the weighted hydrophobicity:===============================*/

int WeightedHydrophobicity_ (double *min_valueP, double *max_valueP,
			     RuntimeS *runtimeSP)
{
int             residuesN, residueI;   /* Do not use size_t instead of int ! */
int		used_residuesN;
static int	window_width = 11, half_window_width = 5;
static double	weightA[11] =  {+1.0, +1.0, +1.0, +1.0, +1.0,
				 0.0,
				-1.0, -1.0, -1.0, -1.0, -1.0};
int		windowI, combinedI;
double		hydrophobicity, weighted_hydrophobicity = 0;

/*------prepare some parameters:---------------------------------------------*/

/* The number of residues in sequence buffer: */
residuesN = (int) runtimeSP->residuesN;
if (residuesN == 0) return -1;

/*------calculate the weighted hydrophobicity:--------------------------------*/

/* Initialize the extreme values: */
*min_valueP = +999999.0;
*max_valueP = -999999.0;

/* Scan the sequence: */
for (residueI = 0; residueI < residuesN; residueI++)
	{
	/* Reset the number of residues used for weighting: */
	used_residuesN = 0;

	/* Reset the weighted hydrophobicity: */
	weighted_hydrophobicity = 0.0;

	/* Scan the sliding window: */
	for (windowI = 0; windowI < window_width; windowI++)
		{
		/* Prepare and check the combined index: */
		combinedI = residueI - half_window_width + windowI;
		if (combinedI < 0) continue;
		if (combinedI >= residuesN) continue;

		/* The hydrophobicity of the residue defined by combinedI: */
		hydrophobicity =
			(double) *(runtimeSP->hydrophobicityP + combinedI);

		/* Update the weighted hydrophobicity: */
		weighted_hydrophobicity += hydrophobicity * weightA[windowI];

		/* Increase the number of residues used for averaging: */
		used_residuesN++;
		}

	/* Check how many residues were used: */
	if (used_residuesN == window_width)
		{
		weighted_hydrophobicity /= (double) window_width;
		}
	else weighted_hydrophobicity = 0.0;

	/* Store the weighted hydrophobicity: */
	*(runtimeSP->weighted_hydrophobicityP + residueI) =
						weighted_hydrophobicity;

	/* Dummy values should not be used to determine extremes: */
	if (used_residuesN != window_width) continue;

	/* Find the extreme values: */
	if (weighted_hydrophobicity < *min_valueP)
		{
		*min_valueP = weighted_hydrophobicity;
		}
	if (weighted_hydrophobicity > *max_valueP)
		{
		*max_valueP = weighted_hydrophobicity;
		}

	/* End of residueI loop: */
	}

/*---------------------------------------------------------------------------*/

return 1;
}

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


