/*
	file: calc.c
	contains calculation routines for access. 
*/



#include <string.h>
#include <assert.h>
#include "area.h"
#include "accessc.h"
#include "hydropho_cal.h"

#define  ACCESS_PROGRAM   "access"    // call  from  /usr/local/bin, if you want other path , add path before 'access'
#define  MODULE_AREA      "AREA"
// #define  RUN_VOLUME       TRUE 
#define  RUN_VOLUME       FALSE

/* global variables */
int	lastNum;
char	lastName[MAX_NAME_LEN];
char 	tmp_input[MAX_FNAME_LEN];
char 	tmp_radii[MAX_FNAME_LEN];
char 	tmp_access[MAX_FNAME_LEN];
char 	tmp_contact[MAX_FNAME_LEN];
float	radius[NUM_RAD_TYPES][NUM_ATM];
float	contactTotal, accessTotal;
FILE	*accessfp, *contactfp;

int     NRes, maxNObs;
OUT_FEATURE_REC *ofres;
ATOM_REC atomArr[MAX_INDEX_PDB];

/* subroutines */
void 	init_data(), do_access(), call_access(), do_radii(), radasn();
void	print_run(), print_atom_header(), print_output_header();
void	calc_totals(), load_tables(), print_res_header(), output_atom();
void	output_res(), read_write_header();
int	convert_pdb();

float   calc_fracasa( float resAsa, char *resName );
float   calc_sidefrac_area(float sideAsa, char *resName);
void    add_asa( char *atom, char *res, float *sideasa, float *sfe, float atomAsa );

void    setResTypeSeq(char *resSeq );
void    do_hydrophobicity();
void    calc_access_c();

/*************************************************************/
/* Main calculation loop
*/
void do_area(dir_shiftxp, outFname)
char *dir_shiftxp;
char *outFname;
{
	init_data(dir_shiftxp);

	calc_access(atomArr, maxNObs);   //// CONTACT_FLAG = 1 in area.h

    save_access_result(atomArr, atomFname, maxNObs);


	do_radii();  

    do_hydrophobicity();

    if(RUN_VOLUME) do_volume(outFname, ofres);

    output_res_all(ofres, NRes);  // save result outfile by residue

}	/* do_area */

/*************************************************************/
/* initialise data
*/
void init_data(dir_shiftxp)
char *dir_shiftxp;
{
	strcpy(lastName, "");
	contactTotal = accessTotal = 0;

	// set covalent radius and vanderwaals radius from tables.c
    // update: load ave_area, aa_ave, side_ave_area and vol from vadar.main.tables.c

	load_tables(dir_shiftxp);  

	/* convert pdb file to that which access can read */
    // get_temp_file(tmp_radii);  // tmp_radii = vadar.0.xxx  get just temperary file name with clock in /libc/unix.lib.c
	// NRes = convert_pdb(tmp_radii);    // convert pdb to use as input file of access program in util.c

	NRes = convert_pdb_accessc(atomArr, &maxNObs);    // convert pdb to use as input atomArray of accessc 
        
    // printf("Num Res after convert_pdb_accessc in calc.c: %d\n", NRes);

    // outfeature structure array     
    ofres = (OUT_FEATURE_REC *)malloc(sizeof(OUT_FEATURE_REC) * NRes);
    assert(ofres != NULL);
}	/* init_data */


/*************************************************************/
/* calculate accessible/contact area 
*  	- call fortran access program
*/
void call_access(type_flag)
int	type_flag;
{
    FILE *tempfp;
    char shellstring[MAX_LINE_LEN];
	
	get_temp_file(tmp_input);   // vadar.1.xxxx
	tempfp = (FILE *)fopen(tmp_input, "w");
	fprintf(tempfp, "%s\n", tmp_radii);

	if (type_flag == ACCESS_FLAG) {        // ACCESS_FLAG = 0 in area.h
		get_temp_file(tmp_access);
		fprintf(tempfp, "%s\n", tmp_access);  
	}
	else  {
		get_temp_file(tmp_contact);
		fprintf(tempfp, "%s\n", tmp_contact);  // vadar.2.xxxx
	}

	fprintf(tempfp, "%f %f %d\n", FRACERROR, probeRadius, type_flag);

	fclose(tempfp);
	
    // temp_input has inut datafile(vadar.0.xxx) and outfile(vadar.2.xxx) and parameters to calculate ASA
	sprintf(shellstring, "%s < %s > /dev/null",  ACCESS_PROGRAM,  tmp_input);  // access < vadar.1.xxxx > /dev/null
	prog_execute(shellstring);
	
    printf("AccessStr: %s\n", shellstring);   
	//unlink(tmp_input);

	/* get rid of temp files no longer used */
	// unlink(tmp_radii);

}	/* call_access */



/*************************************************************/
/* calculate vanderwals and covalent radii

part of this function's result will be use on volume program
So, if it only need a AREA, then ".atom" file does not need.
Just use the out file of access program using "rename(tmp_contact, asaAtomFname)"    

*/
void do_radii()
{
int 		ret, i, ai;
ATOM_REC	atom;
FILE		*pdbfp;
float           sideAsa, sfe;

	/* open input files */
	// accessfp = fopen(tmp_access, "r");
	// contactfp = fopen(tmp_contact, "r");
	// pdbfp = fopen(pdbFname, "r");

    // calculate and print out ASA
	// print_atom_header();   // print out atom header into outfile.atom (fp:atomfp). It will be used on volume program 

	/* read initial atoms */
	lastNum = -111;
    sideAsa = sfe = 0.0;

	// ret = read_atom(pdbfp, &atom);
	// while ( (ret != EOF) && (ret != -1) ) {

    i = 0;
    // i: residue, ai: atom asa array
	for(ai = 1; ai <= maxNObs; ai++) {
        atom = atomArr[ai];

		/* assign radius */
		//radasn(&atom, COV);
		//radasn(&atom, VAN);

		/* print output for one atom */
                /*
		 "ATOM  RES   RES                           VAN.   COV.       ASA\n");
		 "NAME  NAME  NUM   X       Y       Z       RADII  RADII      ASA\n");
                 */

		//output_atom(atom);

		if ( atom.resNum != lastNum ) {
    	   ofres[i].resASA = contactTotal;
           ofres[i].resFracASA = calc_fracasa( contactTotal, lastName );
	   	   ofres[i].sideASA = sideAsa;
	   	   ofres[i].sideFracASA = calc_sidefrac_area(sideAsa, lastName);
	       ofres[i].sfe = sfe/1000.0;
 
           // initialize 
           if (-111 != lastNum) i++; 

			contactTotal = atom.contactArea;
			lastNum = atom.resNum;
			strcpy(lastName, atom.resName);

            // 2011.08.24 switch with original resnum and insCode
            // ofres[i].resNum  = atom.resNum;
            ofres[i].resNum  = atom.origResNum;
            ofres[i].insCode = atom.insCode; 

            strcpy(ofres[i].resName, atom.resName);

            sideAsa = sfe = 0.0;

        } else {
			contactTotal += atom.contactArea;
			add_asa(atom.atomName, atom.resName, &sideAsa, &sfe, atom.contactArea); 
        }

		//ret = read_atom(pdbfp, &atom);
	}

        ofres[i].resASA = contactTotal;
    	ofres[i].resFracASA = calc_fracasa( contactTotal, lastName );
    	ofres[i].sideASA = sideAsa;
    	ofres[i].sideFracASA = calc_sidefrac_area(sideAsa, lastName);
    	ofres[i].sfe = sfe/1000.0;

        //	fclose(pdbfp);

        /* get rid of temp files no longer used */
        //	unlink(tmp_access);
        //	unlink(tmp_contact);    // output file of access program  (ASA by each atom)  

        if (i < 2) {
	        show_err(TRUE, MODULE_AREA, "cannot calculate area with acceess becasue of too short(<2) residues"); 
            printf("cannot calculate area with acceess becasue of too short(<2) residues\n");
        }

}	/* do_radii */


/*************************************************************
* calculate area totals for residues
*/
void calc_totals(atom)
ATOM_REC *atom;
{
/*
        float fracAsa = 0.0;

	if ( atom->resNum == lastNum ) {
		contactTotal += atom->contactArea;
		accessTotal += atom->accessArea;  
	}
	else {
		if ( -111 != lastNum ) {
                    output_res_all( fracAsa );
                }

		contactTotal = atom->contactArea;
		accessTotal = atom->accessArea;
		lastNum = atom->resNum;
		strcpy(lastName, atom->resName);
	}		
*/

}	/* calc_totals */

    

/*********************************************************************
 * PURPOSE: calculate frac ASA 
 * INPUT:   a single residue
 */
float calc_fracasa(resAsa, resName)
float resAsa;
char *resName;
{
        return( resAsa/standardAsa[res2num(resName)] );
}


/*.........................................................................
 * PURPOSE: to get the fraction of the side chain area
 *                      as compared to the standard tables.
 */
float calc_sidefrac_area(sideAsa, resName)
float sideAsa;
char *resName;
{
	float   normAsa;

	normAsa = sidestandAsa[res2num(resName)];
	if (normAsa == 0)
	        return 1.0;
	else
	        return sideAsa / normAsa;
}       /* get_frac_area */


/*************************************************************
*  assign radius.  if flag == 0 then assign covalent radius,
*  otherwise assign vanderwaals radius.
*/
void radasn(atom, flag)
ATOM_REC	*atom;
int		flag;
{
int 		ret = 1;
char		atomName[MAX_NAME_LEN];
char 		msg[MAX_LINE_LEN];

	strcpy(atomName, atom->atomName);

	if ( EQUAL(atomName, "CA") ) {
		if (EQUAL(atom->resName, "DEU"))
			atom->rad[flag] = radius[flag][C4D];
		else atom->rad[flag] = radius[flag][C4H];
	}
	else if ( EQUAL(atomName, "C") ) {
		atom->rad[flag] = radius[flag][C3];
	}
	else if ( EQUAL(atomName, "O") ) {
		atom->rad[flag] = radius[flag][O1];
	}
	else if ( EQUAL(atomName, "N") ) {
		atom->rad[flag] = radius[flag][N3H];
	}

	/* residue ALA */
	else if ( EQUAL(atom->resName, "ALA") ) {
		if ( EQUAL(atomName, "CB") )
			atom->rad[flag] = radius[flag][C4HHH];
		else ret = -1; 
	}

	/* residue ARG */
	else if ( EQUAL(atom->resName, "ARG") ) {
		if ( (EQUAL(atomName, "NEH2")) || (EQUAL(atomName, "NH2")) ||
			 (EQUAL(atomName, "NEH1")) || (EQUAL(atomName, "NH1")) )
			atom->rad[flag] = radius[flag][N3HH];
		else if ( EQUAL(atomName, "CZ") )
			atom->rad[flag] = radius[flag][C3];
		else if ( EQUAL(atomName, "NE") )
			atom->rad[flag] = radius[flag][N3H];
		else if ( (EQUAL(atomName, "CD")) || (EQUAL(atomName, "CG")) ||
			 (EQUAL(atomName, "CB")) )
			atom->rad[flag] = radius[flag][C4HH];
		else ret = -1; 
	}

	/* residue ASN */
	else if ( EQUAL(atom->resName, "ASN") ) {
		if ( EQUAL(atomName, "ND2") )
			atom->rad[flag] = radius[flag][N3HH];
		else if ( EQUAL(atomName, "OD1") )
			atom->rad[flag] = radius[flag][O1];
		else if ( (EQUAL(atomName, "AD1")) || (EQUAL(atomName, "AD2")) ||
			 (EQUAL(atomName, "NOD1")) || (EQUAL(atomName, "NOD2")) )
			atom->rad[flag] = radius[flag][O1N3HH];
		else if ( EQUAL(atomName, "CG") )
			atom->rad[flag] = radius[flag][C3];
		else if ( EQUAL(atomName, "CB") )
			atom->rad[flag] = radius[flag][C4HH];
		else ret = -1; 
	}

	/* residue ASP */
	else if ( EQUAL(atom->resName, "ASP") ) {
		if ( (EQUAL(atomName, "OD2")) || (EQUAL(atomName, "OD1")) )
			atom->rad[flag] = radius[flag][O1O2H];
		else if ( EQUAL(atomName, "CG") )
			atom->rad[flag] = radius[flag][C3];
		else if ( EQUAL(atomName, "CB") )
			atom->rad[flag] = radius[flag][C4HH];
		else ret = -1; 
	}

	/* residue CYS */
	else if ( EQUAL(atom->resName, "CYS") ) {
		if ( EQUAL(atomName, "SG") ) 
			atom->rad[flag] = radius[flag][S2];
		else if ( EQUAL(atomName, "CB") ) 
			atom->rad[flag] = radius[flag][C4HH];
		else ret = -1; 
	}

	/* residue GLN */
	else if ( EQUAL(atom->resName, "GLN") ) {
		if ( EQUAL(atomName, "NE2") )
			atom->rad[flag] = radius[flag][N3HH];
		else if ( EQUAL(atomName, "OE1") )
			atom->rad[flag] = radius[flag][O1];
		else if ( (EQUAL(atomName, "AE1")) || (EQUAL(atomName, "AE2")) || 
		     (EQUAL(atomName, "NOE1")) || (EQUAL(atomName, "NOE2")) ) 
			atom->rad[flag] = radius[flag][O1O2H];
		else if ( EQUAL(atomName, "CD") )
			atom->rad[flag] = radius[flag][C3];
		else if ( (EQUAL(atomName, "CB")) || (EQUAL(atomName, "CG")) ) 
			atom->rad[flag] = radius[flag][C4HH];
		else ret = -1; 
	}

	/* residue GLU */
	else if ( EQUAL(atom->resName, "GLU") ) {
		if ( (EQUAL(atomName, "OE2")) || (EQUAL(atomName, "OE1")) ) 
			atom->rad[flag] = radius[flag][O1O2H];
		else if ( EQUAL(atomName, "CD") ) 
			atom->rad[flag] = radius[flag][C3];
		else if ( (EQUAL(atomName, "CG")) || (EQUAL(atomName, "CB")) ) 
			atom->rad[flag] = radius[flag][C4HH];
		else ret = -1; 
	}

	/* residue GLY */
	else if ( EQUAL(atom->resName, "GLY") ) {
		ret = -1; 
	}

	/* residue HIS */
	else if ( EQUAL(atom->resName, "HIS") ) {
		if ( (EQUAL(atomName, "CD2")) || (EQUAL(atomName, "CE1")) ) 
			atom->rad[flag] = radius[flag][C3H];
		else if ( EQUAL(atomName, "NE2") ) 
			atom->rad[flag] = radius[flag][N3H];
		else if ( EQUAL(atomName, "ND1") ) 
			atom->rad[flag] = radius[flag][N3];
		else if ( EQUAL(atomName, "CG") ) 
			atom->rad[flag] = radius[flag][C3];
		else if ( EQUAL(atomName, "CB") ) 
			atom->rad[flag] = radius[flag][C4HH];
		else ret = -1; 
	}

	/* residue ILE */
	else if ( EQUAL(atom->resName, "ILE") ) {
		if ( (EQUAL(atomName, "CD1")) || (EQUAL(atomName, "CG2")) ||
		     (EQUAL(atomName, "CD")) )
			atom->rad[flag] = radius[flag][C4HHH];
		else if ( EQUAL(atomName, "CG1") ) 
			atom->rad[flag] = radius[flag][C4HH];
		else if ( EQUAL(atomName, "CB") ) 
			atom->rad[flag] = radius[flag][C4H];
		else ret = -1; 
	}

	/* residue LEU */
	else if ( EQUAL(atom->resName, "LEU") ) {
		if ( (EQUAL(atomName, "CD2")) || (EQUAL(atomName, "CD1")) )
			atom->rad[flag] = radius[flag][C4HHH];
		else if ( EQUAL(atomName, "CG") ) 
			atom->rad[flag] = radius[flag][C4H];
		else if ( EQUAL(atomName, "CB") ) 
			atom->rad[flag] = radius[flag][C4HH];
		else ret = -1; 
	}

	/* residue DEU */
	else if ( EQUAL(atom->resName, "DEU") ) {
		if ( (EQUAL(atomName, "CD2")) || (EQUAL(atomName, "CD1")) )
			atom->rad[flag] = radius[flag][C4DDD];
		else if ( EQUAL(atomName, "CG") ) 
			atom->rad[flag] = radius[flag][C4D];
		else if ( EQUAL(atomName, "CB") ) 
			atom->rad[flag] = radius[flag][C4DD];
		else ret = -1; 
	}

	/* residue LYS */
	else if ( EQUAL(atom->resName, "LYS") ) {
		if ( EQUAL(atomName, "NZ") ) 
			atom->rad[flag] = radius[flag][N4HHH];
		else if ( (EQUAL(atomName, "CE")) || (EQUAL(atomName, "CD")) ||
			 (EQUAL(atomName, "CG")) || (EQUAL(atomName, "CB")) )
			atom->rad[flag] = radius[flag][C4HH];
		else ret = -1; 
	}

	/* residue MET */
	else if ( EQUAL(atom->resName, "MET") ||   EQUAL(atom->resName, "MSE") ) {
		if ( EQUAL(atomName, "CE") ) 
			atom->rad[flag] = radius[flag][C4HHH];
		else if ( EQUAL(atomName, "SD") ) 
			atom->rad[flag] = radius[flag][S2];
		else if ( (EQUAL(atomName, "CB")) || (EQUAL(atomName, "CG")) ) 
			atom->rad[flag] = radius[flag][C4HH];
		else ret = -1; 
	}

	/* residue PHE */
	else if ( EQUAL(atom->resName, "PHE") ) {
		if ( (EQUAL(atomName, "CD2")) || (EQUAL(atomName, "CE2")) || 
		     (EQUAL(atomName, "CZ")) || (EQUAL(atomName, "CE1")) || 
		     (EQUAL(atomName, "CD1")) )
			atom->rad[flag] = radius[flag][C3H];
		else if ( EQUAL(atomName, "CG") ) 
			atom->rad[flag] = radius[flag][C3];
		else if ( EQUAL(atomName, "CB") ) 
			atom->rad[flag] = radius[flag][C4HH];
		else ret = -1; 
	}

	/* residue PRO */
	else if ( EQUAL(atom->resName, "PRO") ) {
		if ( (EQUAL(atomName, "CG")) || (EQUAL(atomName, "CD")) ||
		     (EQUAL(atomName, "CB")) )
			atom->rad[flag] = radius[flag][C4HH];
		else ret = -1; 
	}

	/* residue SER */
	else if ( EQUAL(atom->resName, "SER") ) {
		if ( (EQUAL(atomName, "OG")) || (EQUAL(atomName, "OG1")) ) 
			atom->rad[flag] = radius[flag][O2H];
		else if ( EQUAL(atomName, "CB") ) 
			atom->rad[flag] = radius[flag][C4HH];
		else if ( EQUAL(atomName, "P") || EQUAL(atomName, "O1P") || EQUAL(atomName, "O2P") || EQUAL(atomName, "O3P") || 
		          EQUAL(atomName, "PD") || EQUAL(atomName, "OE1") || EQUAL(atomName, "OE2") || EQUAL(atomName, "OE3") )  // for Phosahorylated case
			atom->rad[flag] = radius[flag][P4];
		else ret = -1; 
	}

	/* residue THR */
	else if ( EQUAL(atom->resName, "THR") ) {
		if ( EQUAL(atomName, "CG2") ) 
			atom->rad[flag] = radius[flag][C4HHH];
		else if ( (EQUAL(atomName, "OG")) || (EQUAL(atomName, "OG1")) )
			atom->rad[flag] = radius[flag][O2H];
		else if ( EQUAL(atomName, "CB") ) 
			atom->rad[flag] = radius[flag][C4H];
		else if ( EQUAL(atomName, "P") || EQUAL(atomName, "O1P") || EQUAL(atomName, "O2P") || EQUAL(atomName, "O3P") ||
		          EQUAL(atomName, "PD") || EQUAL(atomName, "OE1") || EQUAL(atomName, "OE2") || EQUAL(atomName, "OE3") )  // for Phosahorylated case
			atom->rad[flag] = radius[flag][P4];
		else ret = -1; 
	}

	/* residue TRP */
	else if ( EQUAL(atom->resName, "TRP") ) {
		if ( (EQUAL(atomName, "CD2")) || (EQUAL(atomName, "CE2")) ||
			 (EQUAL(atomName, "CG")) )
			atom->rad[flag] = radius[flag][C3];
		else if ( (EQUAL(atomName, "CE3")) || (EQUAL(atomName, "CZ3")) ||
			 (EQUAL(atomName, "CH2")) || (EQUAL(atomName, "CEH2")) ||
			 (EQUAL(atomName, "CZ2")) || (EQUAL(atomName, "CD1")) ) 
			atom->rad[flag] = radius[flag][C3H];
		else if ( EQUAL(atomName, "NE1") ) 
			atom->rad[flag] = radius[flag][N3H];
		else if ( EQUAL(atomName, "CB") ) 
			atom->rad[flag] = radius[flag][N3H];
		else ret = -1; 
	}

	/* residue TYR */
	else if ( EQUAL(atom->resName, "TYR") ) {
		if ( (EQUAL(atomName, "OH")) || (EQUAL(atomName, "OEH")) )
			atom->rad[flag] = radius[flag][O2H];
		else if ( (EQUAL(atomName, "CD2")) || (EQUAL(atomName, "CE2")) ||
		     (EQUAL(atomName, "CE1")) || (EQUAL(atomName, "CD1")) )
			atom->rad[flag] = radius[flag][C3H];
		else if ( (EQUAL(atomName, "CZ")) || (EQUAL(atomName, "CG")) )
			atom->rad[flag] = radius[flag][C3];
		else if ( EQUAL(atomName, "CB") )
			atom->rad[flag] = radius[flag][C4HH];
		else if ( EQUAL(atomName, "P") || EQUAL(atomName, "O1P") || EQUAL(atomName, "O2P") || EQUAL(atomName, "O3P") ||
		          EQUAL(atomName, "PD") || EQUAL(atomName, "OE1") || EQUAL(atomName, "OE2") || EQUAL(atomName, "OE3") )  // for Phosahorylated case
			atom->rad[flag] = radius[flag][P4];
		else ret = -1; 
	}

	/* residue VAL */
	else if ( EQUAL(atom->resName, "VAL") ) {
		if ( (EQUAL(atomName, "CG2")) || (EQUAL(atomName, "CG1")) )
			atom->rad[flag] = radius[flag][C4HHH];
		else if ( EQUAL(atomName, "CB") ) 
			atom->rad[flag] = radius[flag][C4H];
		else ret = -1; 
	}

	/* residue ZN */
	else if ( EQUAL(atom->resName, "ZN") ) {
		atom->rad[flag] = radius[flag][Z2ION];
	}

	/* residue HEM */
	else if ( EQUAL(atom->resName, "HEM") ) {
		if ( EQUAL(atomName, "FE") ) 
			atom->rad[flag] = radius[flag][FE];
		else if ( (EQUAL(atomName, "CHA")) || (EQUAL(atomName,"CHB")) ||
		     (EQUAL(atomName, "CHC")) || (EQUAL(atomName,"CHD")) || 
		     (EQUAL(atomName, "CAB")) || (EQUAL(atomName, "CAC")) ) 
			atom->rad[flag] = radius[flag][C3H];
		else if ( (EQUAL(atomName, "N A")) || (EQUAL(atomName, "N B")) || 
		     (EQUAL(atomName, "N C")) || (EQUAL(atomName, "N D")) ) 
			atom->rad[flag] = radius[flag][N3];
		else if ( (EQUAL(atomName, "C1A")) || (EQUAL(atomName, "C2A")) || 
		     (EQUAL(atomName, "C3A")) || (EQUAL(atomName, "C4A")) || 
		     (EQUAL(atomName, "CGA")) || (EQUAL(atomName, "C1B")) || 
		     (EQUAL(atomName, "C2B")) || (EQUAL(atomName, "C3B")) || 
		     (EQUAL(atomName, "C4B")) || (EQUAL(atomName, "C1C")) || 
		     (EQUAL(atomName, "C2C")) || (EQUAL(atomName, "C3C")) || 
		     (EQUAL(atomName, "C4C")) || (EQUAL(atomName, "C1D")) || 
			 (EQUAL(atomName, "C2D")) || (EQUAL(atomName, "C3D")) ||
			 (EQUAL(atomName, "C4D")) || (EQUAL(atomName, "CGD")) ) 
			atom->rad[flag] = radius[flag][C3];
		else if ( (EQUAL(atomName, "CMA")) || (EQUAL(atomName, "CMB")) || 
		     (EQUAL(atomName, "CMC")) || (EQUAL(atomName, "CMD")) ) 
			atom->rad[flag] = radius[flag][C4HHH];
		else if ( (EQUAL(atomName, "CAA")) || (EQUAL(atomName, "CBA")) || 
		     (EQUAL(atomName, "CAD")) || (EQUAL(atomName, "CBD")) ) 
			atom->rad[flag] = radius[flag][C4HH];
		else if ( (EQUAL(atomName, "O1A")) || (EQUAL(atomName, "O2A")) || 
		     (EQUAL(atomName, "O1D")) || (EQUAL(atomName, "O2D")) ) 
			atom->rad[flag] = radius[flag][O1O2H];
		else if ( (EQUAL(atomName, "CBB")) || (EQUAL(atomName, "CBC")) )
			atom->rad[flag] = radius[flag][C3HH];
		else ret = -1; 
	}

	/* assignment of radius for acetyl group */
	else if (EQUAL(atom->resName, "ACE")) {
		if (EQUAL(atomName, "CH3"))
			atom->rad[flag] = radius[flag][C4HHH];
		else ret = -1;
	}

	/* if resName didn't match any of above cases, return -2 */
	else ret = -2;

	/* additional atom name check */
	if ( (EQUAL(atomName, "OT")) || (EQUAL(atomName, "OXT")) ||
		 (EQUAL(atomName, "OT1"))  || (EQUAL(atomName, "OT2")) ) {
		atom->rad[flag] = radius[flag][O1O2H];
		ret = 1;
	}

	/* error check */
	if (ret == -1) {
		sprintf(msg, "Residue %d: Incorrect atom name %s", 
			atom->resNum, atom->atomName);
		unlink(tmp_radii);
		show_err(TRUE, MODULE_AREA, msg); 
	}
	if (ret == -2) {
		sprintf(msg, "Residue %d: Incorrect residue name %s", 
			atom->resNum, atom->resName);
		unlink(tmp_radii);
		show_err(TRUE, MODULE_AREA, msg); 
	}

}	/* radasn */


/*.........................................................................
 * PURPOSE: to add up the side chain asa for a residue
 *                      this is everything except the N, C, and O.
 */
void add_asa(atom, res, sideasa, sfe, atomAsa)
char *atom, *res;
float *sideasa;
float *sfe;
float atomAsa;
{
int resnum, atmnum;

        resnum = res2num(res);
        atmnum = atm2num(atom);

        if ( ( 0 != strcmp(atom, "N") ) &&
                ( 0 != strcmp(atom, "C") ) && ( 0 != strcmp(atom, "O") ) ) {

                *sideasa += atomAsa;

                /* casa */
                if (atom[0] == 'C')
                        *sfe += ((atomAsa - aaAve[resnum][atmnum])* 16);

                /* sasa */
                else if (atom[0] == 'S')
                        *sfe += ((atomAsa - aaAve[resnum][atmnum]) * 21);

                else if (atom[0] == 'N') {

                        /* npasa */
                        if ((0 == strcmp(atom, "NZ"))
                                || (0 == strcmp(atom, "NH2"))
                                || (0 == strcmp(atom, "ND1")) )
                                /*
                                *sfe += ((atomAsa -aaAve[resnum][atmnum]) * -50);
                                */
                                *sfe += ((atomAsa) * -50);

                        /* nasa */
                        else *sfe += ((atomAsa) * -6);
                        /*
                        else *sfe += ((atomAsa -aaAve[resnum][atmnum]) * -6);
                        */
                }

                else if ((atom[0] == 'O') && (0 != strcmp(atom, "OXT")) ) {

                        /* omasa */
                        if ( (0 == strcmp(atom, "OD1")) || (0 == strcmp(atom, "OE1")) )
                        /*
                                *sfe += ((atomAsa -aaAve[resnum][atmnum]) * -24);
                                */
                                *sfe += ((atomAsa) * -24);

                        /* oasa */
                        /*
                        else *sfe += ((atomAsa -aaAve[resnum][atmnum]) * -6);
                        */
                        else *sfe += ((atomAsa) * -6);
                }
        }

}       /* add_asa */


void do_hydrophobicity()
{
        // set ResSequence and calculate hydrophobicity
        char    *resSeq;
        float   *hydroScore;
        int     i;

        resSeq=(char *)malloc(sizeof(char) * NRes);
        hydroScore=(float *)malloc(sizeof(float) * NRes);

        setResTypeSeq(resSeq);  // make residue type (1 char) sequence for calculating hydrophobicity
        calc_hydrophobicity(resSeq, NRes, hydroScore, 7, 1);

        for(i=0; i < NRes; i++)  {
            ofres[i].hydrophobicity = hydroScore[i];
        }

}


// prepare AA sequence for hydrophobicity calculation
void setResTypeSeq( char *resSeq ) {
        int i=0;



        for(i=0; i < NRes; i++)  {
            resSeq[i] = aa3to1(ofres[i].resName);

/*
            if(resSeq[i] == '?')
                printf("%d %s\n",i+1, ofres[i].resName);
*/
        }  
}



