RasMol2
|
Announce,
ChangeLog,
ChangeLog.1,
ChangeLog.2,
ChangeLog.3,
ChangeLog.4,
INSTALL,
Imakefile,
Makefile,
Makefile.bak,
Makefile.in,
Makefile.nt,
Makefile.pc,
PROJECTS,
README,
TODO,
abstree.c,
abstree.h,
applemac.c,
bitmaps.h,
command.c,
command.h,
data,
doc,
font.h,
graphics.h,
molecule.c,
molecule.h,
mswin,
mswin31.c,
outfile.c,
outfile.h,
pixutils.c,
pixutils.h,
rasmac.c,
rasmol.c,
rasmol.h,
rasmol.hlp,
rasmol.sh,
raswin.c,
render.c,
render.h,
script.c,
script.h,
tokens.h,
transfor.c,
transfor.h,
vms,
x11win.c,
|
|
|
/* molecule.c
* RasMol2 Molecular Graphics
* Roger Sayle, October 1994
* Version 2.5
*/
#include "rasmol.h"
#ifdef IBMPC
#include
#include
#endif
#ifdef APPLEMAC
#include
#endif
#ifndef sun386
#include
#endif
#include
#include
#include
#include
#define MOLECULE
#include "molecule.h"
#include "command.h"
#include "abstree.h"
#include "transfor.h"
#include "render.h"
#define GroupPool 8
#define HBondPool 32
#define BondPool 32
#define AtomPool 32
#define NoLadder 0x00
#define ParaLadder 0x01
#define AntiLadder 0x02
#define Cos70Deg 0.34202014332567
#define FeatHelix 1
#define FeatSheet 2
#define FeatTurn 3
#define SourceNone 0
#define SourcePDB 1
#define SourceCalc 2
#define MaxHBondDist ((Long)300*300)
#define MaxBondDist ((Long)475*475)
#define MinBondDist ((Long)100*100)
#define AbsMaxBondDist 500
typedef struct {
int init, term;
char chain;
char type;
} FeatEntry;
#ifdef APPLEMAC
#define AllocSize 256
typedef struct _AllocRef {
struct _AllocRef *next;
void *data[AllocSize];
int count;
} AllocRef;
static AllocRef *AllocList;
#endif
#define FeatSize 32
typedef struct _Feature {
struct _Feature __far *fnext;
FeatEntry data[FeatSize];
int count;
} Feature;
typedef struct {
char src[4];
char dst[4];
} ConvTable;
#define MAXALCATOM 5
static ConvTable AlcAtomTable[MAXALCATOM] = {
{ { 'S', 'O', '2', ' ' }, { ' ', 'S', '2', ' ' } }, /* 1 */
{ { 'C', 'A', 'R', ' ' }, { ' ', 'C', ' ', ' ' } }, /* 2 */
{ { 'N', 'A', 'R', ' ' }, { ' ', 'N', ' ', ' ' } }, /* 3 */
{ { 'N', 'A', 'M', ' ' }, { ' ', 'N', ' ', ' ' } }, /* 4 */
{ { 'N', 'P', 'L', '3' }, { ' ', 'N', '3', ' ' } }, /* 5 */
};
static Molecule __far *FreeMolecule;
static HBond __far *FreeHBond;
static Chain __far *FreeChain;
static Group __far *FreeGroup;
static Atom __far *FreeAtom;
static Bond __far *FreeBond;
static char PDBInsert;
static Feature __far *FeatList;
static HBond __far * __far *CurHBond;
static Molecule __far *CurMolecule;
static Chain __far *CurChain;
static Group __far *CurGroup;
static Atom __far *CurAtom;
static Atom __far *ConnectAtom;
static int InfoStrucSource;
static int HMinMaxFlag;
static int MMinMaxFlag;
static int MemSize;
static char Record[82];
static FILE *DataFile;
/* Macros for commonly used loops */
#define ForEachAtom for(chain=Database->clist;chain;chain=chain->cnext) \
for(group=chain->glist;group;group=group->gnext) \
for(aptr=group->alist;aptr;aptr=aptr->anext)
#define ForEachBond for(bptr=Database->blist;bptr;bptr=bptr->bnext)
#ifdef APPLEMAC
/* External RasMac Function Declaration! */
void SetFileInfo( char*, OSType, OSType, short );
#endif
static void FatalDataError(ptr)
char *ptr;
{
char buffer[80];
sprintf(buffer,"Database Error: %s!",ptr);
RasMolFatalExit(buffer);
}
static void FetchRecord()
{
register char *ptr;
register int ch;
ptr = Record + 1;
if( !feof(DataFile) )
{ do {
ch = getc(DataFile);
if( (ch=='\n') || (ch==EOF) )
{ *ptr = 0;
return;
} else if( (ch=='\r') )
{ ch = getc(DataFile);
if( ch != '\n' )
ungetc(ch,DataFile);
*ptr = 0;
return;
} else *ptr++ = ch;
} while( ptr < Record+80 );
/* skip to the end of the line! */
do { ch = getc(DataFile);
} while( (ch!='\n') && (ch!='\r') && (ch!=EOF) );
if( ch=='\r' )
{ ch = getc(DataFile);
if( ch != '\n' )
ungetc(ch,DataFile);
}
}
*ptr = 0;
}
static void ExtractString( len, src, dst )
int len; char *src, *dst;
{
register char *ptr;
register char ch;
register int i;
ptr = dst;
for( i=0; i='0') && (ch<='9') )
{ result = (10*result)+(ch-'0');
} else if( ch=='-' )
neg = True;
}
return( neg? -result : result );
}
void DescribeMolecule()
{
char buffer[40];
if( CommandActive )
WriteChar('\n');
CommandActive=False;
if( *InfoMoleculeName )
{ WriteString("Molecule name ....... ");
WriteString(InfoMoleculeName);
WriteChar('\n');
}
if( *InfoClassification )
{ WriteString("Classification ...... ");
WriteString(InfoClassification);
WriteChar('\n');
}
if( Database && (MainGroupCount>1) )
{ WriteString("Secondary Structure . ");
if( InfoStrucSource==SourceNone )
{ WriteString("No Assignment\n");
} else if( InfoStrucSource==SourcePDB )
{ WriteString("PDB Data Records\n");
} else WriteString("Calculated\n");
}
if( *InfoIdentCode )
{ WriteString("Brookhaven Code ..... ");
WriteString(InfoIdentCode);
WriteChar('\n');
}
if( InfoChainCount>1 )
{ sprintf(buffer,"Number of Chains .... %d\n",InfoChainCount);
WriteString(buffer);
}
sprintf(buffer,"Number of Groups .... %d",MainGroupCount);
WriteString(buffer);
if( HetaAtomCount )
{ sprintf(buffer," (%d)\n",HetaGroupCount);
WriteString(buffer);
} else WriteChar('\n');
sprintf(buffer,"Number of Atoms ..... %ld",MainAtomCount);
WriteString(buffer);
if( HetaAtomCount )
{ sprintf(buffer," (%d)\n",HetaAtomCount);
WriteString(buffer);
} else WriteChar('\n');
if( InfoBondCount )
{ sprintf(buffer,"Number of Bonds ..... %ld\n",InfoBondCount);
WriteString(buffer);
}
if( InfoSSBondCount != -1 )
{ WriteString("Number of Bridges ... ");
sprintf(buffer,"%d\n\n",InfoSSBondCount);
WriteString(buffer);
}
if( InfoHBondCount != -1 )
{ WriteString("Number of H-Bonds ... ");
sprintf(buffer,"%d\n",InfoHBondCount);
WriteString(buffer);
}
if( InfoHelixCount != -1 )
{ WriteString("Number of Helices ... ");
sprintf(buffer,"%d\n",InfoHelixCount);
WriteString(buffer);
WriteString("Number of Strands ... ");
sprintf(buffer,"%d\n",InfoLadderCount);
WriteString(buffer);
WriteString("Number of Turns ..... ");
sprintf(buffer,"%d\n",InfoTurnCount);
WriteString(buffer);
}
}
#ifdef APPLEMAC
/* Avoid System Memory Leaks! */
static void RegisterAlloc( data )
void *data;
{
register AllocRef *ptr;
if( !AllocList || (AllocList->count==AllocSize) )
{ ptr = (AllocRef *)_fmalloc( sizeof(AllocRef) );
if( !ptr ) FatalDataError("Memory allocation failed");
ptr->next = AllocList;
ptr->data[0] = data;
ptr->count = 1;
AllocList = ptr;
} else AllocList->data[AllocList->count++] = data;
}
#else
#define RegisterAlloc(x)
#endif
static void CreateChain( ident )
char ident;
{
register Chain __far *prev;
if( !CurMolecule )
{ if( !(CurMolecule = FreeMolecule) )
{ MemSize += sizeof(Molecule);
CurMolecule = (Molecule __far *)_fmalloc(sizeof(Molecule));
if( !CurMolecule ) FatalDataError("Memory allocation failed");
RegisterAlloc( CurMolecule );
} else FreeMolecule = (void __far*)0;
CurChain = (void __far*)0;
CurMolecule->slist = (void __far*)0;
CurMolecule->hlist = (void __far*)0;
CurMolecule->blist = (void __far*)0;
CurMolecule->clist = (void __far*)0;
Database = CurMolecule;
}
/* Handle chain breaks! */
if( !(prev=CurChain) )
if( (prev=CurMolecule->clist) )
while( prev->cnext )
prev = prev->cnext;
if( !(CurChain = FreeChain) )
{ MemSize += sizeof(Chain);
CurChain = (Chain __far *)_fmalloc(sizeof(Chain));
if( !CurChain ) FatalDataError("Memory allocation failed");
RegisterAlloc( CurChain );
} else FreeChain = FreeChain->cnext;
if( prev )
{ prev->cnext = CurChain;
} else CurMolecule->clist = CurChain;
CurChain->cnext = (void __far*)0;
CurChain->ident = ident;
CurChain->glist = (void __far*)0;
CurChain->blist = (void __far*)0;
ConnectAtom = (void __far*)0;
CurGroup = (void __far*)0;
InfoChainCount++;
}
static void CreateGroup( pool )
int pool;
{
register Group __far *ptr;
register int i;
if( !(ptr = FreeGroup) )
{ MemSize += pool*sizeof(Group);
ptr = (Group __far *)_fmalloc( pool*sizeof(Group) );
if( !ptr ) FatalDataError("Memory allocation failed");
RegisterAlloc( ptr );
for( i=1; ignext = FreeGroup;
FreeGroup = ptr++;
}
} else FreeGroup = ptr->gnext;
if( CurGroup )
{ CurGroup->gnext = ptr;
} else CurChain->glist = ptr;
CurGroup = ptr;
CurAtom = (void __far*)0;
ptr->gnext = (void __far*)0;
ptr->alist = (void __far*)0;
ptr->struc = 0;
ptr->flag = 0;
ptr->col1 = 0;
ptr->col2 = 0;
}
static Atom __far *CreateAtom()
{
register Atom __far *ptr;
register int i;
if( !(ptr = FreeAtom) )
{ MemSize += AtomPool*sizeof(Atom);
ptr = (Atom __far *)_fmalloc( AtomPool*sizeof(Atom) );
if( !ptr ) FatalDataError("Memory allocation failed");
RegisterAlloc( ptr );
for( i=1; ianext = FreeAtom;
FreeAtom = ptr++;
}
} else FreeAtom = ptr->anext;
if( CurAtom )
{ CurAtom->anext = ptr;
} else CurGroup->alist = ptr;
ptr->anext = (void __far*)0;
CurAtom = ptr;
SelectCount++;
ptr->flag = SelectFlag | NonBondFlag;
ptr->label = (void*)0;
ptr->radius = 375;
ptr->altl = ' ';
ptr->mbox = 0;
ptr->col = 0;
return( ptr );
}
static void ProcessAtom( ptr )
Atom __far *ptr;
{
if( GetElemNumber(ptr) == 1 )
{ ptr->flag |= HydrogenFlag;
HasHydrogen = True;
}
if( !(ptr->flag&(HydrogenFlag|HeteroFlag)) )
ptr->flag |= NormAtomFlag;
#ifdef INVERT
ptr->yorg = -ptr->yorg;
#endif
if( HMinMaxFlag || MMinMaxFlag )
{ if( ptr->xorg < MinX )
{ MinX = ptr->xorg;
} else if( ptr->xorg > MaxX )
MaxX = ptr->xorg;
if( ptr->yorg < MinY )
{ MinY = ptr->yorg;
} else if( ptr->yorg > MaxY )
MaxY = ptr->yorg;
if( ptr->zorg < MinZ )
{ MinZ = ptr->zorg;
} else if( ptr->zorg > MaxZ )
MaxZ = ptr->zorg;
} else
{ MinX = MaxX = ptr->xorg;
MinY = MaxY = ptr->yorg;
MinZ = MaxZ = ptr->zorg;
}
if( ptr->flag & HeteroFlag )
{ if( HMinMaxFlag )
{ if( ptr->temp < MinHetaTemp )
{ MinHetaTemp = ptr->temp;
} else if( ptr->temp > MaxHetaTemp )
MaxHetaTemp = ptr->temp;
} else MinHetaTemp = MaxHetaTemp = ptr->temp;
HMinMaxFlag = True;
HetaAtomCount++;
} else
{ if( MMinMaxFlag )
{ if( ptr->temp < MinMainTemp )
{ MinMainTemp = ptr->temp;
} else if( ptr->temp > MaxMainTemp )
MaxMainTemp = ptr->temp;
} else MinMainTemp = MaxMainTemp = ptr->temp;
MMinMaxFlag = True;
MainAtomCount++;
}
}
static int FindResNo( ptr )
char *ptr;
{
register int refno;
for( refno=0; refno='0') && (ch<='9') )
{ result = (10*result)+(ch-'0');
} else if( ch=='-' )
neg = True;
}
/* Handle Chem3D PDB Files! */
if( Record[offset+3]=='.' )
result /= 10;
return( neg? -result : result );
}
static void ProcessPDBColourMask()
{
register MaskDesc *ptr;
register char *mask;
register int i;
if( MaskCount==MAXMASK )
FatalDataError("Too many COLOR records in file");
ptr = &UserMask[MaskCount];
mask = ptr->mask;
ptr->flags = 0;
for( i=7; i<12; i++ )
if( (*mask++ = Record[i]) != '#' )
ptr->flags |= SerNoFlag;
for( i=13; i<21; i++ )
*mask++ = Record[i];
*mask++ = Record[22];
for( i=23; i<27; i++ )
if( (*mask++ = Record[i]) != '#' )
ptr->flags |= ResNoFlag;
*mask++ = Record[27];
ptr->r = (int)(ReadPDBCoord(31)>>2) + 5;
ptr->g = (int)(ReadPDBCoord(39)>>2) + 5;
ptr->b = (int)(ReadPDBCoord(47)>>2) + 5;
ptr->radius = (short)(5*ReadValue(55,6))>>1;
MaskCount++;
}
static Bond __far *ProcessBond( src, dst, flag )
Atom __far *src, __far *dst;
int flag;
{
register Bond __far *ptr;
register int i;
if( !(ptr = FreeBond) )
{ MemSize += BondPool*sizeof(Bond);
ptr = (Bond __far *)_fmalloc( BondPool*sizeof(Bond) );
if( !ptr ) FatalDataError("Memory allocation failed");
RegisterAlloc( ptr );
for( i=1; ibnext = FreeBond;
FreeBond = ptr++;
}
} else FreeBond = ptr->bnext;
ptr->flag = flag | SelectFlag;
ptr->srcatom = src;
ptr->dstatom = dst;
ptr->radius = 0;
ptr->col = 0;
return( ptr );
}
static void ConnectAtoms( src, dst, flag )
int src, dst, flag;
{
register Chain __far *chain;
register Group __far *group;
register Atom __far *aptr;
register Atom __far *sptr;
register Atom __far *dptr;
register Bond __far *bptr;
register int done;
if( src == dst )
return;
sptr = (void __far*)0;
dptr = (void __far*)0;
done = False;
for( chain=Database->clist; chain && !done; chain=chain->cnext )
for( group=chain->glist; group && !done; group=group->gnext )
for( aptr=group->alist; aptr; aptr=aptr->anext )
{ if( aptr->serno == src )
{ sptr = aptr;
if( dptr )
{ done = True;
break;
}
} else if( aptr->serno == dst )
{ dptr = aptr;
if( sptr )
{ done = True;
break;
}
}
}
/* Both found! */
if( done )
{ /* Reset Non-bonded flags! */
sptr->flag &= ~NonBondFlag;
dptr->flag &= ~NonBondFlag;
bptr = ProcessBond( sptr, dptr, flag );
bptr->bnext = CurMolecule->blist;
CurMolecule->blist = bptr;
InfoBondCount++;
}
}
static void PDBConnectAtoms( src, dst )
int src, dst;
{
register Bond __far *bptr;
register int bs,bd;
ForEachBond
{ bs = bptr->srcatom->serno;
bd = bptr->dstatom->serno;
if( ((bs==src)&&(bd==dst)) || ((bs==dst)&&(bd==src)) )
{ if( bptr->flag & NormBondFlag )
{ /* Convert Single to Double */
bptr->flag &= ~(NormBondFlag);
bptr->flag |= DoubBondFlag;
} else if( bptr->flag & DoubBondFlag )
{ /* Convert Double to Triple */
bptr->flag &= ~(DoubBondFlag);
bptr->flag |= TripBondFlag;
}
return;
}
}
ConnectAtoms( src, dst, NormBondFlag );
}
static void ProcessPDBGroup( heta, serno )
int heta, serno;
{
PDBInsert = Record[27];
if( !CurChain || (CurChain->ident!=Record[22]) )
CreateChain( Record[22] );
CreateGroup( GroupPool );
CurGroup->refno = FindResNo( &Record[18] );
CurGroup->serno = serno;
/* Solvents should be hetero! */
if( IsSolvent(CurGroup->refno) )
heta = True;
if( heta )
{ HetaGroupCount++;
if( HMinMaxFlag )
{ if( serno > MaxHetaRes )
{ MaxHetaRes = serno;
} else if( serno < MinHetaRes )
MinHetaRes = serno;
} else MinHetaRes = MaxHetaRes = serno;
} else
{ MainGroupCount++;
if( MMinMaxFlag )
{ if( serno > MaxMainRes )
{ MaxMainRes = serno;
} else if( serno < MinMainRes )
MinMainRes = serno;
} else MinMainRes = MaxMainRes = serno;
}
}
static void ProcessPDBAtom( heta )
int heta;
{
auto char name[4];
register Bond __far *bptr;
register Atom __far *ptr;
register Long dx,dy,dz;
register int serno;
register int refno;
register int i;
/* Ignore Pseudo Atoms!! */
if( (Record[13]==' ') && (Record[14]=='Q') )
return;
dx = ReadPDBCoord(31);
dy = ReadPDBCoord(39);
dz = ReadPDBCoord(47);
/* Ignore XPLOR Pseudo Atoms!! */
if( (dx==9999000L) && (dy==9999000L) && (dz==9999000L) )
return;
serno = (int)ReadValue(23,4);
if( !CurGroup || (CurGroup->serno!=serno)
|| (CurChain->ident!=Record[22])
|| (PDBInsert!=Record[27]) )
ProcessPDBGroup( heta, serno );
/* Solvents should be hetero! */
if( IsSolvent(CurGroup->refno) )
heta = True;
ptr = CreateAtom();
if( isdigit(Record[14]) )
{ name[1] = ToUpper(Record[13]);
name[2] = name[3] = ' ';
name[0] = ' ';
} else for( i=0; i<4; i++ )
name[i] = ToUpper(Record[i+13]);
for( refno=0; refnorefno = refno;
ptr->altl = Record[17];
ptr->serno = (int)ReadValue(7,5);
ptr->temp = (int)ReadValue(61,6);
ptr->xorg = dx/4;
ptr->yorg = dy/4;
ptr->zorg = -dz/4;
if( heta )
ptr->flag |= HeteroFlag;
ProcessAtom( ptr );
if( IsAlphaCarbon(refno) && IsProtein(CurGroup->refno) )
{ if( ConnectAtom )
{ dx = ConnectAtom->xorg - ptr->xorg;
dy = ConnectAtom->yorg - ptr->yorg;
dz = ConnectAtom->zorg - ptr->zorg;
/* Break backbone if CA-CA > 7.00A */
if( dx*dx+dy*dy+dz*dz < (Long)1750*1750 )
{ bptr = ProcessBond(ptr,ConnectAtom,NormBondFlag);
bptr->bnext = CurChain->blist;
CurChain->blist = bptr;
} else ptr->flag |= BreakFlag;
}
ConnectAtom = ptr;
} else if( IsSugarPhosphate(refno) && IsNucleo(CurGroup->refno) )
{ if( ConnectAtom )
{ bptr = ProcessBond(ConnectAtom,ptr,NormBondFlag);
bptr->bnext = CurChain->blist;
CurChain->blist = bptr;
}
ConnectAtom = ptr;
}
}
static FeatEntry __far *AllocFeature()
{
register Feature __far *ptr;
if( !FeatList || (FeatList->count==FeatSize) )
{ ptr = (Feature __far*)_fmalloc(sizeof(Feature));
if( !ptr ) FatalDataError("Memory allocation failed");
/* Features are always deallocated! */
ptr->fnext = FeatList;
ptr->count = 0;
FeatList = ptr;
} else ptr = FeatList;
return( &(ptr->data[ptr->count++]) );
}
#ifdef FUNCPROTO
static void UpdateFeature( FeatEntry __far*, int );
#endif
static void UpdateFeature( ptr, mask )
FeatEntry __far *ptr; int mask;
{
register Chain __far *chain;
register Group __far *group;
for( chain=Database->clist; chain; chain=chain->cnext )
if( chain->ident == ptr->chain )
{ group=chain->glist;
while( group && (group->sernoinit) )
group = group->gnext;
while( group && (group->serno<=ptr->term) )
{ group->struc |= mask;
group = group->gnext;
}
return;
}
}
static void ProcessPDBFeatures()
{
register Feature __far *next;
register Feature __far *ptr;
register int i;
InfoTurnCount = 0;
InfoHelixCount = 0;
InfoLadderCount = 0;
InfoStrucSource = SourcePDB;
for( ptr=FeatList; ptr; ptr=next )
{ if( Database )
for( i=0; icount; i++ )
if( ptr->data[i].type==FeatHelix )
{ UpdateFeature( &ptr->data[i], HelixFlag );
InfoHelixCount++;
} else if( ptr->data[i].type==FeatSheet )
{ UpdateFeature( &ptr->data[i], SheetFlag );
InfoLadderCount++;
} else /* FeatTurn */
{ UpdateFeature( &ptr->data[i], TurnFlag );
InfoTurnCount++;
}
/* Deallocate Memory */
next = ptr->fnext;
_ffree( ptr );
}
}
int LoadPDBMolecule( fp )
FILE *fp;
{
register FeatEntry __far *ptr;
register int srcatm, dstatm;
register char *src, *dst;
register int model;
model = True;
FeatList = (void __far*)0;
DataFile = fp;
do {
FetchRecord();
if( !strncmp("ATOM",Record+1,4) )
{ if( model ) ProcessPDBAtom(False);
} else if( !strncmp("HETA",Record+1,4) )
{ if( model ) ProcessPDBAtom(True);
} else if( !strncmp("SHEE",Record+1,4) )
{ if( !model ) continue;
/* Remaining SHEET record fields */
/* 39-40 .... Strand Parallelism */
/* 33 ....... Same Chain as 22? */
ptr = AllocFeature();
ptr->type = FeatSheet;
ptr->chain = Record[22];
ptr->init = (int)ReadValue(23,4);
ptr->term = (int)ReadValue(34,4);
} else if( !strncmp("HELI",Record+1,4) )
{ if( !model ) continue;
/* Remaining HELIX record fields */
/* 39-40 .... Helix Classification */
/* 32 ....... Same Chain as 20? */
ptr = AllocFeature();
ptr->type = FeatHelix;
ptr->chain = Record[20];
ptr->init = (int)ReadValue(22,4);
ptr->term = (int)ReadValue(34,4);
} else if( !strncmp("TURN",Record+1,4) )
{ if( !model ) continue;
ptr = AllocFeature();
ptr->type = FeatTurn;
ptr->chain = Record[20];
ptr->init = (int)ReadValue(21,4);
ptr->term = (int)ReadValue(32,4);
} else if( !strncmp("CONE",Record+1,4) )
{ if( !model ) continue;
if( (srcatm = (int)ReadValue(7,5)) )
{ if( (dstatm = (int)ReadValue(12,5)) )
if( dstatm > srcatm )
PDBConnectAtoms( srcatm, dstatm );
if( !Record[17] ) continue;
if( (dstatm = (int)ReadValue(17,5)) )
if( dstatm > srcatm )
PDBConnectAtoms( srcatm, dstatm );
if( !Record[22] ) continue;
if( (dstatm = (int)ReadValue(22,5)) )
if( dstatm > srcatm )
PDBConnectAtoms( srcatm, dstatm );
if( !Record[27] ) continue;
if( (dstatm = (int)ReadValue(27,5)) )
if( dstatm > srcatm )
PDBConnectAtoms( srcatm, dstatm );
}
} else if( !strncmp("COLO",Record+1,4) )
{ ProcessPDBColourMask();
} else if( !strncmp("TER",Record+1,3) )
{ if( !Record[4] || (Record[4]==' ') )
{ ConnectAtom = (void __far*)0;
CurGroup = (void __far*)0;
CurChain = (void __far*)0;
}
} else if( !strncmp("HEAD",Record+1,4) )
{ ExtractString(40,Record+11,InfoClassification);
ExtractString( 4,Record+63,InfoIdentCode);
} else if( !strncmp("COMP",Record+1,4) )
{ if( Record[10]==' ' ) /* First COMPND record */
ExtractString(60,Record+11,InfoMoleculeName);
} else if( !strncmp("CRYS",Record+1,4) )
{ dst = InfoSpaceGroup;
for( src=Record+56; *src && srcrefno = FindResNo( "MOL" );
CurGroup->serno = 1;
MinMainRes = MaxMainRes = 1;
MinHetaRes = MaxHetaRes = 0;
MainGroupCount = 1;
}
int LoadXYZMolecule( fp )
FILE *fp;
{
auto char type[12];
auto double xpos, ypos, zpos;
auto double charge, u, v, w;
auto int atoms;
register Atom __far *ptr;
register char *src,*dst;
register int i,count;
DataFile = fp;
/* Number of Atoms */
FetchRecord();
sscanf(Record+1,"%d",&atoms);
/* Molecule (step) Description */
FetchRecord();
src = Record+1;
while( *src == ' ' )
src++;
dst = InfoMoleculeName;
for( i=0; i<78; i++ )
if( *src ) *dst++ = *src++;
*dst = '\0';
if( atoms )
{ CreateMolGroup();
for( i=0; iserno = i;
xpos = ypos = zpos = 0.0;
count = sscanf(Record+1,"%s %lg %lg %lg %lg %lg %lg %lg",
type, &xpos, &ypos, &zpos, &charge, &u, &v, &w );
ptr->refno = SimpleAtomType(type);
ptr->xorg = (Long)(250.0*xpos);
ptr->yorg = (Long)(250.0*ypos);
ptr->zorg = -(Long)(250.0*zpos);
if( (count==5) || (count==8) )
{ ptr->temp = (short)(100.0*charge);
} else ptr->temp = 0;
ProcessAtom( ptr );
}
}
return( True );
}
static int FindSybylResNo( ptr )
char *ptr;
{
register char *src,*dst;
register int i, j;
auto char name[4];
src = ptr;
dst = name;
if( ptr[1] && (ptr[1]!='.') )
{ *dst++ = ToUpper(*src); src++;
*dst++ = ToUpper(*src); src++;
} else
{ *dst++ = ToUpper(*src); src++;
*dst++ = ' ';
}
if( *src )
{ src++;
if( *src == 'a' )
{ *dst++ = ' ';
*dst = ' ';
} else if( *src == 'p' )
{ *dst++ = '3';
*dst = ' ';
} else
{ *dst++ = *src++;
if( *src && (*src!='+') )
{ *dst = *src;
} else *dst = ' ';
}
} else
{ *dst++ = ' ';
*dst = ' ';
}
for( j=0; jMOLECULE",Record+1,17) )
{ FetchRecord(); /* Molecule Name */
src = Record+1;
while( *src==' ' )
src++;
dst = InfoMoleculeName;
while( (*dst++ = *src++) );
FetchRecord();
atoms = bonds = structs = features = sets = 0;
sscanf(Record+1,"%d %d %d %d %d", &atoms, &bonds, &structs,
&features, &sets );
FetchRecord(); /* Molecule Type */
FetchRecord(); /* Charge Type */
} else if( !strncmp("@ATOM",Record+1,13) )
{ if( !atoms ) continue;
CreateMolGroup();
for( i=0; irefno = FindSybylResNo( type );
ptr->serno = serno;
/* ptr->serno = i; */
ptr->xorg = (Long)(250.0*xpos);
ptr->yorg = (Long)(250.0*ypos);
ptr->zorg = -(Long)(250.0*zpos);
ProcessAtom( ptr );
}
} else if( !strncmp("@BOND",Record+1,13) )
for( i=0; irefno = FindAlchemyResNo();
ptr->temp = (int)ReadValue(41,8);
ptr->serno = (int)ReadValue(1,5);
/* ptr->serno = i+1; */
ptr->xorg = ReadValue(13,7)/4;
ptr->yorg = ReadValue(22,7)/4;
ptr->zorg = -ReadValue(31,7)/4;
ProcessAtom( ptr );
}
for( i=0; iserno!=resno) )
{ CreateGroup( GroupPool );
CurGroup->refno = FindResNo(Record+12);
CurGroup->serno = resno;
if( !init )
{ MinMainRes = resno;
MaxMainRes = resno;
init = True;
} else if( resno > MaxMainRes )
{ MaxMainRes = resno;
} else if( resno < MinMainRes )
MinMainRes = resno;
MainGroupCount++;
}
ptr = CreateAtom();
for( refno=0; refnorefno = refno;
ptr->temp = (int)ReadValue(61,9);
ptr->serno = (int)ReadValue(1,5);
/* ptr->serno = serno+1; */
ptr->xorg = ReadValue(21,8)/4;
ptr->yorg = ReadValue(31,8)/4;
ptr->zorg = -ReadValue(41,8)/4;
ProcessAtom( ptr );
}
return( True );
}
int LoadMDLMolecule( fp )
FILE *fp;
{
register Bond __far *bptr;
register Atom __far *src;
register Atom __far *dst;
register Atom __far *ptr;
register int atoms, bonds;
register int srcatm,dstatm;
register int i,type,done;
register Long dx, dy, dz;
register Card dist2;
register Real scale;
DataFile = fp;
FetchRecord(); /* Molecule Name */
ExtractString(78,Record+1,InfoMoleculeName);
FetchRecord(); /* Program Details */
FetchRecord(); /* Comments */
FetchRecord();
atoms = (int)ReadValue(1,3);
bonds = (int)ReadValue(4,3);
if( !atoms )
return( False );
CreateMolGroup();
for( i=1; i<=atoms; i++ )
{ FetchRecord();
ptr = CreateAtom();
ptr->refno = SimpleAtomType(Record+32);
switch( (int)ReadValue(37,3) )
{ case(1): ptr->temp = 300; break;
case(2): ptr->temp = 200; break;
case(3): ptr->temp = 100; break;
case(5): ptr->temp = -100; break;
case(6): ptr->temp = -200; break;
case(7): ptr->temp = -300; break;
default: ptr->temp = 0;
}
ptr->serno = i;
ptr->xorg = ReadValue(1,10)/40;
ptr->yorg = ReadValue(11,10)/40;
ptr->zorg = -ReadValue(21,10)/40;
ProcessAtom( ptr );
}
for( i=0; iblist; bptr; bptr=bptr->bnext )
if( bptr->flag & NormBondFlag )
{ src = bptr->srcatom;
dst = bptr->dstatom;
if( (src->refno==2) && (dst->refno==2) )
{ dx = dst->xorg - src->xorg;
dy = dst->yorg - src->yorg;
dz = dst->zorg - src->zorg;
if( dx || dy || dz )
{ dist2 = dx*dx + dy*dy + dz*dz;
scale = 385.0/sqrt(dist2);
break;
}
}
}
if( bptr )
{ for( ptr=CurGroup->alist; ptr; ptr=ptr->anext )
{ ptr->xorg = (Long)(ptr->xorg*scale);
ptr->yorg = (Long)(ptr->yorg*scale);
ptr->zorg = (Long)(ptr->zorg*scale);
}
MinX = (Long)(MinX*scale); MaxX = (Long)(MaxX*scale);
MinY = (Long)(MinY*scale); MaxY = (Long)(MaxY*scale);
MinZ = (Long)(MinZ*scale); MaxZ = (Long)(MaxZ*scale);
}
return( True );
}
int SavePDBMolecule( filename )
char *filename;
{
register double x, y, z;
register Group __far *prev;
register Chain __far *chain;
register Group __far *group;
register Atom __far *aptr;
register char *ptr;
register int count;
register char ch;
register int i;
if( !Database )
return( False );
DataFile = fopen( filename, "w" );
if( !DataFile )
{ if( CommandActive )
WriteChar('\n');
WriteString("Error: Unable to create file!\n\n");
CommandActive=False;
return( False );
}
if( *InfoClassification || *InfoIdentCode )
{ fputs("HEADER ",DataFile);
ptr = InfoClassification;
for( i=11; i<=50; i++ )
putc( (*ptr ? *ptr++ : ' '), DataFile );
fprintf(DataFile,"13-JUL-93 %.4s\n",InfoIdentCode);
}
if( *InfoMoleculeName )
fprintf(DataFile,"COMPND %.60s\n",InfoMoleculeName);
prev = (void __far*)0;
count = 1;
ForEachAtom
if( aptr->flag&SelectFlag )
{ if( prev && (chain->ident!=ch) )
fprintf( DataFile, "TER %5d %.3s %c%4d \n",
count++, Residue[prev->refno], ch, prev->serno);
if( aptr->flag&HeteroFlag )
{ fputs("HETATM",DataFile);
} else fputs("ATOM ",DataFile);
fprintf( DataFile, "%5d %.4s %.3s %c%4d ",
count++, ElemDesc[aptr->refno], Residue[group->refno],
chain->ident, group->serno );
x = (double)aptr->xorg/250.0;
y = (double)aptr->yorg/250.0;
z = (double)aptr->zorg/250.0;
#ifdef INVERT
fprintf(DataFile,"%8.3f%8.3f%8.3f",x,-y,-z);
#else
fprintf(DataFile,"%8.3f%8.3f%8.3f",x,y,-z);
#endif
fprintf(DataFile," 1.00%6.2f\n",aptr->temp/100.0);
ch = chain->ident;
prev = group;
}
if( prev )
fprintf( DataFile, "TER %5d %.3s %c%4d \n",
count, Residue[prev->refno], ch, prev->serno);
fputs("END \n",DataFile);
fclose( DataFile );
#ifdef APPLEMAC
SetFileInfo(filename,'RSML','TEXT',131);
#endif
return( True );
}
int SaveXYZMolecule( filename )
char *filename;
{
return( True );
}
int SaveCIFMolecule( filename )
char *filename;
{
if( !filename )
return( False );
return( True );
}
int SaveAlchemyMolecule( filename )
char *filename;
{
register Real x, y, z;
register float xpos, ypos, zpos;
register Chain __far *chain;
register Group __far *group;
register Atom __far *aptr;
register Bond __far *bptr;
register char *ptr;
register int atomno;
register int bondno;
register int num;
if( !Database )
return( False );
DataFile = fopen( filename, "w" );
if( !DataFile )
{ if( CommandActive )
WriteChar('\n');
WriteString("Error: Unable to create file!\n\n");
CommandActive=False;
return( False );
}
atomno = 0;
ForEachAtom
if( aptr->flag & SelectFlag )
{ aptr->mbox = 0;
atomno++;
}
bondno = 0;
ForEachBond
if( (bptr->srcatom->flag&bptr->dstatom->flag) & SelectFlag )
{ if( bptr->flag&AromBondFlag )
{ bptr->srcatom->mbox = -1;
bptr->dstatom->mbox = -1;
} else if( !(bptr->flag&HydrBondFlag) )
{ num = (bptr->flag&DoubBondFlag)? 2 : 1;
if( bptr->srcatom->mbox>0 )
bptr->srcatom->mbox += num;
if( bptr->dstatom->mbox>0 )
bptr->dstatom->mbox += num;
}
bondno++;
}
fprintf(DataFile,"%5d ATOMS, %5d BONDS, ",atomno,bondno);
fprintf(DataFile," 0 CHARGES, %s\n", InfoMoleculeName );
atomno = 1;
ForEachAtom
if( aptr->flag & SelectFlag )
{ aptr->mbox = atomno;
fprintf(DataFile,"%5d ",atomno++);
switch( GetElemNumber(aptr) )
{ case( 6 ): if( aptr->mbox == -1 )
{ ptr = "CAR ";
} else if( aptr->mbox == 1 )
{ ptr = "C3 ";
} else ptr = "C2 ";
fputs( ptr, DataFile );
break;
case( 7 ): if( aptr->mbox == -1 )
{ ptr = "NAR ";
} else ptr = "N2 ";
fputs( ptr, DataFile );
break;
case( 8 ): if( aptr->mbox == 2 )
{ ptr = "O2 ";
} else ptr = "O3 ";
fputs( ptr, DataFile );
break;
case( 1 ): fputs( "H ", DataFile ); break;
default: ptr = ElemDesc[aptr->refno];
if( *ptr==' ' )
{ fprintf(DataFile,"%.3s ",ptr+1);
} else fprintf(DataFile,"%.4s",ptr);
}
x = aptr->xorg/250.0;
y = aptr->yorg/250.0;
z = aptr->zorg/250.0;
/* Apply Current Viewpoint Rotation Matrix */
xpos = (float)(x*RotX[0] + y*RotX[1] + z*RotX[2]);
ypos = (float)(x*RotY[0] + y*RotY[1] + z*RotY[2]);
zpos = (float)(x*RotZ[0] + y*RotZ[1] + z*RotZ[2]);
#ifdef INVERT
fprintf(DataFile," %8.4f %8.4f %8.4f",xpos,-ypos,-zpos);
#else
fprintf(DataFile," %8.4f %8.4f %8.4f",xpos,ypos,-zpos);
#endif
fprintf(DataFile," %7.4f\n",aptr->temp/1000.0);
}
bondno = 1;
ForEachBond
if( (bptr->srcatom->flag&bptr->dstatom->flag) & SelectFlag )
{ fprintf(DataFile,"%5d %5d %5d ", bondno++,
bptr->srcatom->mbox, bptr->dstatom->mbox );
if( bptr->flag & AromBondFlag )
{ ptr = "AROMATIC\n";
} else if( bptr->flag & TripBondFlag )
{ ptr = "TRIPLE\n";
} else if( bptr->flag & DoubBondFlag )
{ ptr = "DOUBLE\n";
} else ptr = "SINGLE\n";
fputs( ptr, DataFile );
}
ForEachAtom
if( aptr->flag & SelectFlag )
aptr->mbox = 0;
fclose( DataFile );
#ifdef APPLEMAC
SetFileInfo(filename,'RSML','TEXT',131);
#endif
return( True );
}
static void TestBonded( sptr, dptr, flag )
Atom __far *sptr, __far *dptr;
int flag;
{
register Bond __far *bptr;
register Long dx, dy, dz;
register Long max, dist;
if( flag )
{ /* Sum of covalent radii with 0.5A tolerance */
dist = Element[GetElemNumber(sptr)].covalrad +
Element[GetElemNumber(dptr)].covalrad + 125;
max = dist*dist;
} else
{ /* Fast Bio-Macromolecule Bonding Calculation */
if( (sptr->flag|dptr->flag) & HydrogenFlag )
{ max = MaxHBondDist;
} else max = MaxBondDist;
}
dx = sptr->xorg-dptr->xorg; if( (dist=dx*dx)>max ) return;
dy = sptr->yorg-dptr->yorg; if( (dist+=dy*dy)>max ) return;
dz = sptr->zorg-dptr->zorg; if( (dist+=dz*dz)>max ) return;
if( dist > MinBondDist )
{ /* Reset Non-bonded flags! */
sptr->flag &= ~NonBondFlag;
dptr->flag &= ~NonBondFlag;
if( (sptr->flag|dptr->flag) & HydrogenFlag )
{ flag = HydrBondFlag;
} else flag = NormBondFlag;
bptr = ProcessBond(sptr,dptr,flag);
bptr->bnext = CurMolecule->blist;
CurMolecule->blist = bptr;
InfoBondCount++;
}
}
static void ReclaimHBonds( ptr )
HBond __far *ptr;
{
register HBond __far *temp;
if( (temp = ptr) )
{ while( temp->hnext )
temp=temp->hnext;
temp->hnext = FreeHBond;
FreeHBond = ptr;
}
}
static void ReclaimBonds( ptr )
Bond __far *ptr;
{
register Bond __far *temp;
if( (temp = ptr) )
{ while( temp->bnext )
temp=temp->bnext;
temp->bnext = FreeBond;
FreeBond = ptr;
}
}
void CreateMoleculeBonds( info, flag )
int info, flag;
{
register int i, x, y, z;
register Long tx, ty, tz;
register Long mx, my, mz;
register Long dx, dy, dz;
register int lx, ly, lz, hx, hy, hz;
register Atom __far *aptr, __far *dptr;
register Chain __far *chain;
register Group __far *group;
char buffer[40];
if( !Database )
return;
dx = (MaxX-MinX)+1;
dy = (MaxY-MinY)+1;
dz = (MaxZ-MinZ)+1;
InfoBondCount = 0;
ReclaimBonds( CurMolecule->blist );
CurMolecule->blist = (void __far*)0;
ResetVoxelData();
for( chain=Database->clist; chain; chain=chain->cnext )
{ ResetVoxelData();
for( group=chain->glist; group; group=group->gnext )
for( aptr=group->alist; aptr; aptr=aptr->anext )
{ /* Initially non-bonded! */
aptr->flag |= NonBondFlag;
mx = aptr->xorg-MinX;
my = aptr->yorg-MinY;
mz = aptr->zorg-MinZ;
tx = mx-AbsMaxBondDist;
ty = my-AbsMaxBondDist;
tz = mz-AbsMaxBondDist;
lx = (tx>0)? (int)((VOXORDER*tx)/dx) : 0;
ly = (ty>0)? (int)((VOXORDER*ty)/dy) : 0;
lz = (tz>0)? (int)((VOXORDER*tz)/dz) : 0;
tx = mx+AbsMaxBondDist;
ty = my+AbsMaxBondDist;
tz = mz+AbsMaxBondDist;
hx = (txnext) );
i += VOXORDER;
}
}
x = (int)((VOXORDER*mx)/dx);
y = (int)((VOXORDER*my)/dy);
z = (int)((VOXORDER*mz)/dz);
i = VOXORDER2*x + VOXORDER*y + z;
aptr->next = (Atom __far*)HashTable[i];
HashTable[i] = (void __far*)aptr;
}
VoxelsClean = False;
}
if( info )
{ if( CommandActive )
WriteChar('\n');
CommandActive=False;
sprintf(buffer,"Number of Bonds ..... %ld\n\n",InfoBondCount);
WriteString(buffer);
}
}
Atom __far *FindGroupAtom( group, n )
Group __far *group; Byte n;
{
register Atom __far *ptr;
ptr = group->alist;
while( ptr )
{ if( ptr->refno == n )
return( ptr );
ptr = ptr->anext;
}
return( (Atom __far*)0 );
}
void TestDisulphideBridge( group1, group2, cys1 )
Group __far *group1, __far *group2;
Atom __far *cys1;
{
register HBond __far *ptr;
register Atom __far *cys2;
register int dx, dy, dz;
register Long max,dist;
if( !(cys2=FindGroupAtom(group2,20)) )
return;
max = (Long)750*750;
dx = (int)(cys1->xorg-cys2->xorg); if( (dist=(Long)dx*dx)>max ) return;
dy = (int)(cys1->yorg-cys2->yorg); if( (dist+=(Long)dy*dy)>max ) return;
dz = (int)(cys1->zorg-cys2->zorg); if( (dist+=(Long)dz*dz)>max ) return;
if( !(ptr = FreeHBond) )
{ MemSize += sizeof(HBond);
ptr = (HBond __far*)_fmalloc(sizeof(HBond));
if( !ptr ) FatalDataError("Memory allocation failed");
RegisterAlloc( ptr );
} else FreeHBond = ptr->hnext;
ptr->dst = cys1;
if( !(ptr->dstCA=FindGroupAtom(group1,1)) )
ptr->dstCA = cys1;
ptr->src = cys2;
if( !(ptr->srcCA=FindGroupAtom(group2,1)) )
ptr->srcCA = cys2;
ptr->offset = 0;
ptr->energy = 0;
ptr->flag = 0;
ptr->col = 0;
ptr->hnext = CurMolecule->slist;
CurMolecule->slist = ptr;
group1->flag |= CystineFlag;
group2->flag |= CystineFlag;
InfoSSBondCount++;
}
void FindDisulphideBridges()
{
register Chain __far *chn1;
register Chain __far *chn2;
register Group __far *group1;
register Group __far *group2;
register Atom __far *cys;
char buffer[40];
if( !Database ) return;
ReclaimHBonds( CurMolecule->slist );
InfoSSBondCount = 0;
for(chn1=Database->clist;chn1;chn1=chn1->cnext)
for(group1=chn1->glist;group1;group1=group1->gnext)
if( IsCysteine(group1->refno) && (cys=FindGroupAtom(group1,20)) )
{ for(group2=group1->gnext;group2;group2=group2->gnext)
if( IsCysteine(group2->refno) )
TestDisulphideBridge(group1,group2,cys);
for(chn2=chn1->cnext;chn2;chn2=chn2->cnext)
for(group2=chn2->glist;group2;group2=group2->gnext)
if( IsCysteine(group2->refno) )
TestDisulphideBridge(group1,group2,cys);
}
if( CommandActive )
WriteChar('\n');
CommandActive=False;
sprintf(buffer,"Number of Bridges ... %d\n\n",InfoSSBondCount);
WriteString(buffer);
}
#ifdef FUNCPROTO
static void CreateHydrogenBond( Atom __far*, Atom __far*,
Atom __far*, Atom __far*, int, int );
static int IsHBonded( Atom __far*, Atom __far*, HBond __far* );
static void TestLadder( Chain __far* );
#endif
static void CreateHydrogenBond( srcCA, dstCA, src, dst, energy, offset )
Atom __far *srcCA, __far *dstCA;
Atom __far *src, __far *dst;
int energy, offset;
{
register HBond __far *ptr;
register int i,flag;
if( !(ptr = FreeHBond) )
{ MemSize += HBondPool*sizeof(HBond);
ptr = (HBond __far *)_fmalloc( HBondPool*sizeof(HBond) );
if( !ptr ) FatalDataError("Memory allocation failed");
RegisterAlloc( ptr );
for( i=1; ihnext = FreeHBond;
FreeHBond = ptr++;
}
} else FreeHBond = ptr->hnext;
if( (offset>=-128) && (offset<127) )
{ ptr->offset = (Char)offset;
} else ptr->offset = 0;
flag = ZoneBoth? src->flag&dst->flag : src->flag|dst->flag;
ptr->flag = flag & SelectFlag;
ptr->src = src;
ptr->dst = dst;
ptr->srcCA = srcCA;
ptr->dstCA = dstCA;
ptr->energy = energy;
ptr->col = 0;
*CurHBond = ptr;
ptr->hnext = (void __far*)0;
CurHBond = &ptr->hnext;
InfoHBondCount++;
}
/* Coupling constant for Electrostatic Energy */
/* QConst = -332 * 0.42 * 0.2 * 1000.0 [*250.0] */
#define QConst (-6972000.0)
#define MaxHDist ((Long)2250*2250)
#define MinHDist ((Long)125*125)
/* Protein Donor Atom Coordinates */
static int hxorg,hyorg,hzorg;
static int nxorg,nyorg,nzorg;
static Atom __far *best1CA;
static Atom __far *best2CA;
static Atom __far *best1;
static Atom __far *best2;
static Atom __far *optr;
static int res1,res2;
static int off1,off2;
static int CalculateBondEnergy( group )
Group __far *group;
{
register double dho,dhc;
register double dnc,dno;
register Atom __far *cptr;
register Long dx,dy,dz;
register Long dist;
register int result;
if( !(cptr=FindGroupAtom(group,2)) ) return(0);
if( !(optr=FindGroupAtom(group,3)) ) return(0);
dx = hxorg-optr->xorg;
dy = hyorg-optr->yorg;
dz = hzorg-optr->zorg;
dist = dx*dx+dy*dy+dz*dz;
if( dist < MinHDist )
return( -9900 );
dho = sqrt((double)dist);
dx = hxorg-cptr->xorg;
dy = hyorg-cptr->yorg;
dz = hzorg-cptr->zorg;
dist = dx*dx+dy*dy+dz*dz;
if( dist < MinHDist )
return( -9900 );
dhc = sqrt((double)dist);
dx = nxorg-cptr->xorg;
dy = nyorg-cptr->yorg;
dz = nzorg-cptr->zorg;
dist = dx*dx+dy*dy+dz*dz;
if( dist < MinHDist )
return( -9900 );
dnc = sqrt((double)dist);
dx = nxorg-optr->xorg;
dy = nyorg-optr->yorg;
dz = nzorg-optr->zorg;
dist = dx*dx+dy*dy+dz*dz;
if( dist < MinHDist )
return( -9900 );
dno = sqrt((double)dist);
result = (int)(QConst/dho - QConst/dhc + QConst/dnc - QConst/dno);
if( result<-9900 )
{ return( -9900 );
} else if( result>-500 )
return( 0 );
return( result );
}
void CalcHydrogenBonds()
{
register int energy, offset, refno;
register Chain __far *chn1, __far *chn2;
register Group __far *group1;
register Group __far *group2;
register Group __far *best;
register Atom __far *ca1;
register Atom __far *ca2;
register Atom __far *pc1;
register Atom __far *po1;
register Atom __far *n1;
register Long max,dist;
register int pos1,pos2;
register int dx,dy,dz;
register double dco;
char buffer[40];
if( !Database ) return;
ReclaimHBonds( CurMolecule->hlist );
CurMolecule->hlist = (void __far*)0;
CurHBond = &CurMolecule->hlist;
InfoHBondCount = 0;
if( MainAtomCount > 10000 )
{ if( CommandActive )
WriteChar('\n');
WriteString("Please wait... ");
CommandActive=True;
}
for(chn1=Database->clist;chn1;chn1=chn1->cnext)
{ if( !chn1->glist ) continue;
if( IsProtein(chn1->glist->refno) )
{ pc1 = po1 = (void __far*)0;
pos1 = 0;
for(group1=chn1->glist;group1;group1=group1->gnext)
{ pos1++;
if( pc1 && po1 )
{ dx = (int)(pc1->xorg - po1->xorg);
dy = (int)(pc1->yorg - po1->yorg);
dz = (int)(pc1->zorg - po1->zorg);
} else
{ pc1 = FindGroupAtom(group1,2);
po1 = FindGroupAtom(group1,3);
continue;
}
pc1 = FindGroupAtom(group1,2);
po1 = FindGroupAtom(group1,3);
if( !IsAmino(group1->refno) || IsProline(group1->refno) )
continue;
if( !(ca1=FindGroupAtom(group1,1)) ) continue;
if( !(n1=FindGroupAtom(group1,0)) ) continue;
dist = (Long)dx*dx + (Long)dy*dy + (Long)dz*dz;
dco = sqrt( (double)dist )/250.0;
nxorg = (int)n1->xorg; hxorg = nxorg + (int)(dx/dco);
nyorg = (int)n1->yorg; hyorg = nyorg + (int)(dy/dco);
nzorg = (int)n1->zorg; hzorg = nzorg + (int)(dz/dco);
res1 = res2 = 0;
/* Only Hydrogen Bond within a single chain! */
/* for(chn2=Database->clist;chn2;chn2=chn2->cnext) */
chn2 = chn1;
{ /* Only consider non-empty peptide chains! */
if( !chn2->glist || !IsProtein(chn2->glist->refno) )
continue;
pos2 = 0;
for(group2=chn2->glist;group2;group2=group2->gnext)
{ pos2++;
if( (group2==group1) || (group2->gnext==group1) )
continue;
if( !IsAmino(group2->refno) )
continue;
if( !(ca2=FindGroupAtom(group2,1)) )
continue;
dx = (int)(ca1->xorg-ca2->xorg);
if( (dist=(Long)dx*dx) > MaxHDist )
continue;
dy = (int)(ca1->yorg-ca2->yorg);
if( (dist+=(Long)dy*dy) > MaxHDist )
continue;
dz = (int)(ca1->zorg-ca2->zorg);
if( (dist+=(Long)dz*dz) > MaxHDist )
continue;
if( (energy = CalculateBondEnergy(group2)) )
{ if( chn1 == chn2 )
{ offset = pos1 - pos2;
} else offset = 0;
if( energyglist->refno) )
for(group1=chn1->glist;group1;group1=group1->gnext)
{ if( !IsPurine(group1->refno) ) continue;
/* Find N1 of Purine Group */
if( !(n1=FindGroupAtom(group1,21)) )
continue;
/* Maximum N1-N3 distance 5A */
refno = NucleicCompl(group1->refno);
max = (Long)1250*1250;
best = (void __far*)0;
for(chn2=Database->clist;chn2;chn2=chn2->cnext)
{ /* Only consider non-empty peptide chains! */
if( (chn1==chn2) || !chn2->glist ||
!IsNucleo(chn2->glist->refno) )
continue;
for(group2=chn2->glist;group2;group2=group2->gnext)
if( group2->refno == (Byte)refno )
{ /* Find N3 of Pyramidine Group */
if( !(ca1=FindGroupAtom(group2,23)) )
continue;
dx = (int)(ca1->xorg - n1->xorg);
if( (dist=(Long)dx*dx) >= max )
continue;
dy = (int)(ca1->yorg - n1->yorg);
if( (dist+=(Long)dy*dy) >= max )
continue;
dz = (int)(ca1->zorg - n1->zorg);
if( (dist+=(Long)dz*dz) >= max )
continue;
best1 = ca1;
best = group2;
max = dist;
}
}
if( best )
{ /* Find the sugar phosphorous atoms */
ca1 = FindGroupAtom( group1, 7 );
ca2 = FindGroupAtom( best, 7 );
CreateHydrogenBond( ca1, ca2, n1, best1, 0, 0 );
if( IsGuanine(group1->refno) )
{ /* Guanine-Cytosine */
if( (ca1=FindGroupAtom(group1,22)) && /* G.N2 */
(ca2=FindGroupAtom(best,26)) ) /* C.O2 */
CreateHydrogenBond( (void __far*)0, (void __far*)0,
ca1, ca2, 0, 0 );
if( (ca1=FindGroupAtom(group1,28)) && /* G.O6 */
(ca2=FindGroupAtom(best,24)) ) /* C.N4 */
CreateHydrogenBond( (void __far*)0, (void __far*)0,
ca1, ca2, 0, 0 );
} else /* Adenine-Thymine */
if( (ca1=FindGroupAtom(group1,25)) && /* A.N6 */
(ca2=FindGroupAtom(best,27)) ) /* T.O4 */
CreateHydrogenBond( (void __far*)0, (void __far*)0,
ca1, ca2, 0, 0 );
}
}
}
if( CommandActive )
WriteChar('\n');
CommandActive=False;
sprintf(buffer,"Number of H-Bonds ... %d\n",InfoHBondCount);
WriteString(buffer);
}
static int IsHBonded( src, dst, ptr )
Atom __far *src, __far *dst;
HBond __far *ptr;
{
while( ptr && (ptr->srcCA==src) )
if( ptr->dstCA == dst )
{ return( True );
} else ptr=ptr->hnext;
return( False );
}
static void FindAlphaHelix( pitch, flag )
int pitch, flag;
{
register HBond __far *hbond;
register Chain __far *chain;
register Group __far *group;
register Group __far *first;
register Group __far *ptr;
register Atom __far *srcCA;
register Atom __far *dstCA;
register int res,dist,prev;
/* Protein chains only! */
hbond = Database->hlist;
for( chain=Database->clist; chain; chain=chain->cnext )
if( (first=chain->glist) && IsProtein(first->refno) )
{ prev = False; dist = 0;
for( group=chain->glist; hbond && group; group=group->gnext )
{ if( IsAmino(group->refno) && (srcCA=FindGroupAtom(group,1)) )
{ if( dist==pitch )
{ res = False;
dstCA=FindGroupAtom(first,1);
while( hbond && hbond->srcCA == srcCA )
{ if( hbond->dstCA==dstCA ) res=True;
hbond = hbond->hnext;
}
if( res )
{ if( prev )
{ if( !(first->struc&HelixFlag) )
InfoHelixCount++;
ptr = first;
do {
ptr->struc |= flag;
ptr = ptr->gnext;
} while( ptr != group );
} else prev = True;
} else prev = False;
} else while( hbond && hbond->srcCA==srcCA )
hbond = hbond->hnext;
} else prev = False;
if( group->struc&HelixFlag )
{ first = group; prev = False; dist = 1;
} else if( dist==pitch )
{ first = first->gnext;
} else dist++;
}
} else if( first && IsNucleo(first->refno) )
while( hbond && !IsAminoBackbone(hbond->src->refno) )
hbond = hbond->hnext;
}
static Atom __far *cprevi, __far *ccurri, __far *cnexti;
static HBond __far *hcurri, __far *hnexti;
static Group __far *curri, __far *nexti;
static void TestLadder( chain )
Chain __far *chain;
{
register Atom __far *cprevj, __far *ccurrj, __far *cnextj;
register HBond __far *hcurrj, __far *hnextj;
register Group __far *currj, __far *nextj;
register int count, result, found;
/* Already part of atleast one ladder */
found = curri->flag & SheetFlag;
nextj = nexti->gnext;
hnextj = hnexti;
while( hnextj && hnextj->srcCA==cnexti )
hnextj = hnextj->hnext;
while( True )
{ if( nextj )
if( IsProtein(chain->glist->refno) )
{ count = 1;
do {
cnextj = FindGroupAtom(nextj,1);
if( count == 3 )
{ if( IsHBonded(cnexti,ccurrj,hnexti) &&
IsHBonded(ccurrj,cprevi,hcurrj) )
{ result = ParaLadder;
} else if( IsHBonded(cnextj,ccurri,hnextj) &&
IsHBonded(ccurri,cprevj,hcurri) )
{ result = ParaLadder;
} else if( IsHBonded(cnexti,cprevj,hnexti) &&
IsHBonded(cnextj,cprevi,hnextj) )
{ result = AntiLadder;
} else if( IsHBonded(ccurrj,ccurri,hcurrj) &&
IsHBonded(ccurri,ccurrj,hcurri) )
{ result = AntiLadder;
} else result = NoLadder;
if( result )
{ curri->struc |= SheetFlag;
currj->struc |= SheetFlag;
if( found ) return;
found = True;
}
} else count++;
cprevj = ccurrj; ccurrj = cnextj;
currj = nextj; hcurrj = hnextj;
while( hnextj && hnextj->srcCA==cnextj )
hnextj = hnextj->hnext;
} while( (nextj = nextj->gnext) );
} else if( IsNucleo(chain->glist->refno) )
while( hnextj && !IsAminoBackbone(hnextj->src->refno) )
hnextj = hnextj->hnext;
if( (chain = chain->cnext) )
{ nextj = chain->glist;
} else return;
}
}
static void FindBetaSheets()
{
register Chain __far *chain;
register int ladder;
register int count;
hnexti = Database->hlist;
for( chain=Database->clist; chain; chain=chain->cnext )
if( (nexti = chain->glist) )
if( IsProtein(nexti->refno) )
{ count = 1;
ladder = False;
do {
cnexti = FindGroupAtom(nexti,1);
if( count == 3 )
{ TestLadder( chain );
if( curri->struc & SheetFlag )
{ if( !ladder )
{ InfoLadderCount++;
ladder = True;
}
} else ladder = False;
} else count++;
cprevi = ccurri; ccurri = cnexti;
curri = nexti; hcurri = hnexti;
while( hnexti && hnexti->srcCA==cnexti )
hnexti = hnexti->hnext;
} while( (nexti = nexti->gnext) );
} else if( IsNucleo(nexti->refno) )
while( hnexti && !IsAminoBackbone(hnexti->src->refno) )
hnexti = hnexti->hnext;
}
static void FindTurnStructure()
{
static Atom __far *aptr[5];
register Chain __far *chain;
register Group __far *group;
register Group __far *prev;
register Atom __far *ptr;
register Long ux,uy,uz,mu;
register Long vx,vy,vz,mv;
register int i,found,len;
register Real CosKappa;
for( chain=Database->clist; chain; chain=chain->cnext )
if( chain->glist && IsProtein(chain->glist->refno) )
{ len = 0; found = False;
for( group=chain->glist; group; group=group->gnext )
{ ptr = FindGroupAtom(group,1);
if( ptr && (ptr->flag&BreakFlag) )
{ found = False;
len = 0;
} else if( len==5 )
{ for( i=0; i<4; i++ )
aptr[i] = aptr[i+1];
len = 4;
} else if( len==2 )
prev = group;
aptr[len++] = ptr;
if( len==5 )
{ if( !(prev->struc&(HelixFlag|SheetFlag)) &&
aptr[0] && aptr[2] && aptr[4] )
{ ux = aptr[2]->xorg - aptr[0]->xorg;
uy = aptr[2]->yorg - aptr[0]->yorg;
uz = aptr[2]->zorg - aptr[0]->zorg;
vx = aptr[4]->xorg - aptr[2]->xorg;
vy = aptr[4]->yorg - aptr[2]->yorg;
vz = aptr[4]->zorg - aptr[2]->zorg;
mu = ux*ux + uy*uy + uz*uz;
mv = vx*vx + vz*vz + vy*vy;
if( mu && mv )
{ CosKappa = (Real)(ux*vx + uy*vy + uz*vz);
CosKappa /= sqrt( (Real)mu*mv );
if( CosKappastruc |= TurnFlag;
}
}
}
found = prev->struc&TurnFlag;
prev = prev->gnext;
} /* len==5 */
}
}
}
void DetermineStructure()
{
register Chain __far *chain;
register Group __far *group;
char buffer[40];
if( !Database )
return;
if( InfoHBondCount<0 )
CalcHydrogenBonds();
if( InfoHelixCount>=0 )
for( chain=Database->clist; chain; chain=chain->cnext )
for( group=chain->glist; group; group=group->gnext )
group->struc = 0;
InfoStrucSource = SourceCalc;
InfoLadderCount = 0;
InfoHelixCount = 0;
InfoTurnCount = 0;
if( InfoHBondCount )
{ FindAlphaHelix(4,Helix4Flag);
FindBetaSheets();
FindAlphaHelix(3,Helix3Flag);
FindAlphaHelix(5,Helix5Flag);
FindTurnStructure();
}
if( CommandActive )
WriteChar('\n');
CommandActive=False;
sprintf(buffer,"Number of Helices ... %d\n",InfoHelixCount);
WriteString(buffer);
sprintf(buffer,"Number of Strands ... %d\n",InfoLadderCount);
WriteString(buffer);
sprintf(buffer,"Number of Turns ..... %d\n",InfoTurnCount);
WriteString(buffer);
}
void RenumberMolecule( start )
int start;
{
register Chain __far *chain;
register Group __far *group;
register int hinit, minit;
register int resno;
if( !Database )
return;
hinit = minit = False;
for( chain=Database->clist; chain; chain=chain->cnext )
{ resno = start;
for( group=chain->glist; group; group=group->gnext )
{ if( group->alist->flag & HeteroFlag )
{ if( hinit )
{ if( resno > MaxHetaRes )
{ MaxHetaRes = resno;
} else if( resno < MinHetaRes )
MinHetaRes = resno;
} else MinHetaRes = MaxHetaRes = resno;
hinit = True;
} else
{ if( minit )
{ if( resno > MaxMainRes )
{ MaxMainRes = resno;
} else if( resno < MinMainRes )
MinMainRes = resno;
} else MinMainRes = MaxMainRes = resno;
minit = True;
}
group->serno = resno++;
}
}
}
static void ReclaimAtoms( ptr )
Atom __far *ptr;
{
register Atom __far *temp;
if( (temp = ptr) )
{ while( temp->anext )
temp=temp->anext;
temp->anext = FreeAtom;
FreeAtom = ptr;
}
}
static void ResetDatabase()
{
Database = CurMolecule = (void __far*)0;
MainGroupCount = HetaGroupCount = 0;
InfoChainCount = HetaAtomCount = 0;
MainAtomCount = InfoBondCount = 0;
SelectCount = 0;
InfoStrucSource = SourceNone;
InfoSSBondCount = InfoHBondCount = -1;
InfoHelixCount = InfoLadderCount = -1;
InfoTurnCount = -1;
CurGroup = (void __far*)0;
CurChain = (void __far*)0;
CurAtom = (void __far*)0;
MinX = MinY = MinZ = 0;
MaxX = MaxY = MaxZ = 0;
MinMainTemp = MaxMainTemp = 0;
MinHetaTemp = MaxHetaTemp = 0;
MinMainRes = MaxMainRes = 0;
MinHetaRes = MaxHetaRes = 0;
*InfoMoleculeName = 0;
*InfoClassification = 0;
*InfoIdentCode = 0;
*InfoSpaceGroup = 0;
*InfoFileName = 0;
VoxelsClean = False;
HMinMaxFlag = False;
MMinMaxFlag = False;
HasHydrogen = False;
ElemNo = MINELEM;
ResNo = MINRES;
MaskCount = 0;
}
void DestroyDatabase()
{
register void __far *temp;
register Group __far *gptr;
if( Database )
{ ReclaimHBonds( Database->slist );
ReclaimHBonds( Database->hlist );
ReclaimBonds( Database->blist );
while( Database->clist )
{ ReclaimBonds(Database->clist->blist);
if( (gptr = Database->clist->glist) )
{ ReclaimAtoms(gptr->alist);
while( gptr->gnext )
{ gptr = gptr->gnext;
ReclaimAtoms(gptr->alist);
}
gptr->gnext = FreeGroup;
FreeGroup = Database->clist->glist;
}
temp = Database->clist->cnext;
Database->clist->cnext = FreeChain;
FreeChain = Database->clist;
Database->clist = temp;
}
FreeMolecule = Database;
Database = (void __far*)0;
}
ResetDatabase();
}
void PurgeDatabase()
{
#ifdef APPLEMAC
register AllocRef *ptr;
register AllocRef *tmp;
register int i;
/* Avoid Memory Leaks */
for( ptr=AllocList; ptr; ptr=tmp )
{ for( i=0; icount; i++ )
_ffree( ptr->data[i] );
tmp = ptr->next;
_ffree( ptr );
}
#endif
}
void InitialiseDatabase()
{
FreeMolecule = (void __far*)0;
FreeHBond = (void __far*)0;
FreeChain = (void __far*)0;
FreeGroup = (void __far*)0;
FreeAtom = (void __far*)0;
FreeBond = (void __far*)0;
#ifdef APPLEMAC
AllocList = (void*)0;
#endif
ResetDatabase();
}
|