CCL Home Page
Up Directory CCL cexio
/* cexio.c
 * RasMol2 Molecular Graphics
 * Roger Sayle, August 1995
 * Version 2.6
 */
#include 
#include "rasmol.h"
#include "molecule.h"

#include "cx.h"
#include "cx_molecule.h"

#define PROP_ATSYM   "atomic symbol"
#define PROP_BONDO   "bond order"

#define PROP_MNAME   "molname"
#define PROP_ALABS   "atomname"
#define PROP_RESID   "resname"
#define PROP_CHAIN   "chain"
#define PROP_RESNO   "resno"
#define PROP_COORD   "coordinates"
#define PROP_BVALU   "bvalue"
#define PROP_CHARG   "charge"

static cx_String prop_alabs;
static cx_String prop_resid;
static cx_String prop_chain;
static cx_String prop_resno;
static cx_String prop_coord;
static cx_String prop_tempr;


static cx_String get_atom_tuple( mol, prop )
    cx_Object mol;  cx_String prop;
{
    cx_Object tupleseq, tuple;
    cx_String result;
    register int i,j;

    if( (tupleseq = cx_prefix2atuples(mol,prop)) )
    {   tuple = cx_next(tupleseq);
    } else tuple = (cx_Object)NULL;
 
    if( !tuple )
    {   /* No such property! */
        cx_destroy( tupleseq );
        return( (cx_String)NULL );
    }
 
    /* Ambiguous atom property prefix! */
    /* cx_next(tupleseq) or !cx_atend(tupleseq) */

    cx_destroy(tupleseq);
    return( cx_atomtuple_name(tuple) );
}
 

static int process_cx_atom( atom, serno )
    cx_Object atom;  int serno;
{
    register Group __far *group;
    register Atom __far *ptr;
    register int refno,resno;
    register int elem,chain;
    cx_String prop;
    float x,y,z,t;

    /* Test for valid 3D co-ordinates */
    if( !(prop=cx_sprop(atom,prop_coord)) )
        return( False );
    if( sscanf(prop,"%g,%g,%g",&x,&y,&z) != 3 )
        return( False );

    /* Determine Chain */
    prop = cx_sprop(atom,prop_chain);
    if( prop && *prop ) 
    {   chain = *prop;
    } else chain = ' ';

    if( CurChain && (CurChain->ident!=chain) )
    {   CurChain = CurMolecule->clist;
        while( CurChain )
            if( CurChain->ident != chain )
            {   CurChain = CurChain->cnext;
            } else break;
    }
    if( !CurChain ) CreateChain( chain );

    /* Determine Residue */
    resno = cx_iprop(atom,prop_resno);
    prop = cx_sprop(atom,prop_resid);
    if( !prop || !*prop ) 
    {   refno = FindResNo("MOL");
    } else refno = FindResNo(prop);

    if( !CurGroup || CurGroup->refno!=refno || CurGroup->serno!=resno )
    {   group = CurChain->glist;
        CurGroup = (Group __far*)0;
        CurAtom = (Atom __far*)0;

        while( group && group->serno <= resno )
        {   CurGroup = group;
            if( (group->serno==resno) && (group->refno==refno) ) break;
            group = group->gnext;
        }

        if( !group || (group->serno>resno) ) 
        {   CreateGroup( 8 );
            CurGroup->serno = resno;
            CurGroup->refno = refno;
            ProcessGroup( False );
        }
    }

    /* Process Atom */
    ptr = CreateAtom();
    ptr->serno = serno;

    if( !(prop=cx_sprop(atom,prop_alabs)) )
    {   prop = cx_sprop(atom,PROP_ATSYM);
        if( !prop ) prop = "Du  ";
        ptr->refno = SimpleAtomType(prop);
    } else ptr->refno = ComplexAtomType(prop);

    t = cx_rprop(atom,prop_tempr);
    ptr->temp = (short)(t*100.0);

    ptr->xorg =  (Long)(x*250.0);
    ptr->yorg =  (Long)(y*250.0);
    ptr->zorg = -(Long)(z*250.0);
    ProcessAtom( ptr );
    return( True );
}


static int process_cx_bond( bond )
    cx_Object bond;
{
    cx_Object atoms,atom;
    register int src,dst;
    register int i,flag;

    i = cx_iprop(bond,PROP_BONDO);
    if( i==2 )
    {   flag = DoubBondFlag;
    } else if( i == 3 )
    {   flag = TripBondFlag;
    } else flag = NormBondFlag;

    atoms = cx_stream(bond,CX_OB_ATOM);
    if( atom = cx_next(atoms) )
        if( src = cx_iprop(atom,"_serno") )
            if( atom = cx_next(atoms) )
                if( dst = cx_iprop(atom,"_serno") )
                    CreateBond(src,dst,flag);
    cx_destroy(atoms);
}


static void load_cx_molecule( mol )
    cx_Object *mol;
{
    cx_String molname;
    cx_Object atoms,atom;
    cx_Object bonds,bond;
    register int serno;
    register int i;

    if( (molname = cx_sprop(mol,PROP_MNAME)) )
    {   for( i=0; molname[i] && (i<62); i++ )
            InfoMoleculeName[i] = molname[i];
        while( i && molname[i-1]==' ' ) i--;
        InfoMoleculeName[i] = '\0';
    }

    /* Molecule must have 3d co-ordinates */
    prop_coord = get_atom_tuple(mol,PROP_COORD);
    if( !prop_coord ) return;

    prop_alabs = get_atom_tuple(mol,PROP_ALABS);
    prop_resid = get_atom_tuple(mol,PROP_RESID);
    if( !(prop_tempr=get_atom_tuple(mol,PROP_BVALU)) )
        prop_tempr = get_atom_tuple(mol,PROP_CHARG);

    prop_chain = get_atom_tuple(mol,PROP_CHAIN);
    prop_resno = get_atom_tuple(mol,PROP_RESNO);

    serno = 1;
    atoms = cx_stream(mol,CX_OB_ATOM);
    while( atom = cx_next(atoms) )
    {   if( process_cx_atom(atom,serno) )
        {   cx_set_iprop(atom,"_serno",serno++);
        } else cx_set_iprop(atom,"_serno",0);
    }
    cx_destroy(atoms);

    bonds = cx_stream(mol,CX_OB_BOND);
    while( bond = cx_next(bonds) )
        process_cx_bond(bond);
    cx_destroy(bonds);
}


int LoadCEXMolecule( fp )
    FILE *fp;
{
    register cx_Object obj;

    cx_molecule_pkg();
    while( (obj = cx_receive(NULL,fp,NULL)) ) 
    {   if( cx_type(obj) == CX_OB_MOLECULE )
        {   load_cx_molecule(obj);
            cx_destroy(obj);
            break;
        } else cx_destroy(obj);
    }
    /* cx_cleanup(); */
    return( True );
}
 
 
int SaveCEXMolecule( filename )
    char *filename;
{
    if( !Database )
        return( False );
    return( True );
}
 

Modified: Thu Oct 12 16:00:00 1995 GMT
Page accessed 2537 times since Sat Apr 17 22:32:55 1999 GMT