Logo Search packages:      
Sourcecode: adun.app version File versions  Download package

Atom.m

/* Copyright 2003  Alexander V. Diemand

    This file is part of MolTalk.

    MolTalk is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    MolTalk is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with MolTalk; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 */
 
/* vim: set filetype=objc: */


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>


#include "Atom.oh"
#include "Coordinates.oh"
#include "Matrix53.oh"

static char inferElementFromAtomName (char *name);

static char *atom_element_names = {
      "Xx", "H", "He", "Li", "Be", "B", "C", "N", "O", "F", "Ne", "Na", "Mg", "Al", "Si", "P", "S", "Cl", "Ar", "K", "Ca", "Sc", "Ti", "V", "Cr", "Mn", "Fe", "Co", "Ni", "Cu", "Zn", "Ga", "Ge", "As", "Se", "Br", "Kr", "Rb", "Sr", "Y", "Zr", "Nb", "Mo", "Tc", "Ru", "Rh", "Pd", "Ag", "Cd", "In", "Sn", "Sb", "Te", "I", "Xe", "Cs", "Ba", 
      "57","58","59","60","61","62","63","64","65","66","67","68","69","70",
      "Lu", "Hf", "Ta", "W", "Re", "Os", "Ir", "Pt", "Au", "Hg", "Tl", "Pb", "Bi", "Po", "At", "Rn", NULL 
};



@implementation Atom


-(id)init   //@nodoc
{
    [super init];
    bonds=nil;
    name=nil;
    number=nil;
    temperature=0.0f;
    element=ELEMENT_ID_Unknown;
    charge=(char)0;
    return self;
}


-(void)dealloc    //@nodoc
{
      //NSLog(@"Atom__dealloc");
      if (bonds) {
            Atom *atm2;
            NSEnumerator *benum = [bonds keyEnumerator];
            while ((atm2 = [benum nextObject]))
            {
                  [atm2 dropBondTo: self];
            }
            [bonds removeAllObjects];
            RELEASE(bonds);
      }
      if (name)
      {
            RELEASE(name);
      }
      if (number)
      {
            RELEASE(number);
      }
      [super dealloc];
}


/*
 *   returns atom's serial number
 */
-(NSNumber*)number
{
      return number;
}


/*
 *   returns atom's name
 */
-(NSString*)name
{
      return name;
}


/*
 *   returns string of atom's number, name and coordinates
 */
-(NSString*)description
{
      return [NSString stringWithFormat:@"Atom:%@ %@",number,name];
}


/*
 *   return element id of atom
 */
-(enum element_id)element
{
      return element;
}


/*
 *   return element name of atom
 */
-(NSString*)elementName
{
      if (element < 0)
      {
            return @"Xx";
      } else {
            return [NSString stringWithCString:(atom_element_names)];
      }
}


/*
 *   returns the atom's assigned temperature factor
 */
-(float)temperature
{
      return temperature;
}


/*
 *
 */
-(int)charge
{
      if (charge > 127)
      {
            return (int)charge - 256;
      } else {
            return (int)charge;
      }
}


/*
 *   add bond from atm2 to this atom
 */
-(void)bondTo:(Atom*)atm2
{
      if (!bonds)
      {
            bonds = [NSMutableDictionary new];
      }
      id bonded = [bonds objectForKey: [atm2 number]];
      if (bonded != nil)
      { /* dont add twice */
            return;
      }
      //NSLog(@"adding bond from %@%@ to %@%@",[self number], [self name], [atm2 number], [atm2 name]);
      [bonds setObject: atm2 forKey: [atm2 number]];
        [atm2 bondTo: self];
}


/*
 *   returns enumerator over all bonded atoms
 */
-(NSEnumerator*)allBondedAtoms
{
      if (!bonds)
      {
            return nil;
      }
      return [[bonds allValues] reverseObjectEnumerator];
}


/*
 *   remove a bond from atm2 to this atom
 */
-(void)dropBondTo:(Atom*)atm2
{
      id bonded = [bonds objectForKey: [atm2 number]];
      if (bonded != nil)
      {
            [bonds removeObjectForKey: [atm2 number]];
            [atm2 dropBondTo: self];
      }
}


/*
 *   remove all bonds from this atom
 */
-(void)dropAllBonds
{
      if (bonds) {
            NSEnumerator *benum = [self allBondedAtoms];
            Atom *atm2;
            while ((atm2 = [benum nextObject]))
            {
                  [self dropBondTo: atm2];
            }
            [bonds removeAllObjects];
            RELEASE(bonds);
            bonds = nil;
      }
}


/*
 *   set serial number to the new one
 */
-(id)setNumber: (int)serial
{
      number = RETAIN([NSNumber numberWithInt: serial]);
      return self;
}


/*
 *   set the charge of the atom
 */
-(id)setCharge: (int)chrg
{
      charge = (char)chrg;
      printf("Atom_setCharge: %d:%d\n",(int)chrg,(int)charge);
      return self;
}


/*
 *   set the element id of the atom
 */
-(id)setElement: (enum element_id)p_element
{
      element = p_element;
      return self;
}
-(id)setElementWithName: (char*)p_element
{
      char *ename;
      int idx=0;
      if (!p_element)
      {
            return self;
      }
      int len = strlen(p_element);
      if (len>2)
      {
            return self;
      }
      /* make second character lowercase */
      if (len==2 && p_element[1]<=90 && p_element[1]>=65)
      {
            p_element=p_element+32;
      }
      while ((ename = atom_element_names[idx])) 
      {
            if (ename[0]==p_element[0] && ename[1]==p_element[1])
            {
                  return [self setElement:idx];
            }
            idx++;
      }
      NSLog(@"Unknown element name: %s",p_element);
      return self;
}


/*
 *   creation of an atom with number, name and explicitly setting coordinates
 */
+(Atom*)atomWithNumber:(unsigned int)num name:(char*)nm X:(double)x Y:(double)y Z:(double)z B:(float)b
{
      Atom *atom = [Atom new];
      [atom setX:x Y:y Z:z];
      atom->temperature = b;
      atom->number = RETAIN([NSNumber numberWithInt: num]);
      
      /* before any clean up we do the element inference from the name */
      /* name = Element[2chars,right justified],remoteness[1char],branch#[1digit] */
      atom->element = inferElementFromAtomName (nm);
      
      /* pad name */
      unsigned int len=strlen(nm);
      unsigned int i=0;
      while (nm[i]==' ')
      {
            i++;
            if (i>=(len-1))
            {
                  break;
            }
      }
      unsigned int j=len-1;
      while (nm[j] == ' ')
      {
            j--;
            if (j==i)
            {
                  break;
            }
      }
      nm='\0';
      nm += i;
      atom->name = RETAIN([NSString stringWithCString: nm]);
      
      //printf("Atom_atomWithNumber:%d name:%s X:%1.1f Y:%1.1f Z:%1.1f\n",num,nm,x,y,z);
      return AUTORELEASE(atom);
}


char inferElementFromAtomName (char *name)
{
      switch (name[0])
      {
      case 'C':
            switch (name[1])
            {
            case 'U':
                  return ELEMENT_ID_Cu;
            case 'D':
                  return ELEMENT_ID_Cd;
            case 'A':
                  return ELEMENT_ID_Ca;
            case 'O':
                  return ELEMENT_ID_Co;
            case 'R':
                  return ELEMENT_ID_Cr;
            }
            break;
      case 'N':
            if (name[1]=='I')
                  return ELEMENT_ID_Ni;
            if (name[1]=='A')
                  return ELEMENT_ID_Na;
            break;
      case 'P':
            if (name[1]=='B')
                  return ELEMENT_ID_Pb;
            break;
      case 'S':
            if (name[1]=='N')
                  return ELEMENT_ID_Sn;
            if (name[1]=='E')
                  return ELEMENT_ID_Se;
            break;
      case 'M':
            if (name[1]=='G')
                  return ELEMENT_ID_Mg;
            if (name[1]=='N')
                  return ELEMENT_ID_Mn;
            break;
      case 'H':
            if (name[1]=='G')
                  return ELEMENT_ID_Hg;
            return ELEMENT_ID_H;
            break;
      case 'Z':
            if (name[1]=='N')
                  return ELEMENT_ID_Zn;
            break;
      case ' ':
            switch (name[1])
            {
            case 'H':
                  return ELEMENT_ID_H;
            case 'O':
                  return ELEMENT_ID_O;
            case 'C':
                  return ELEMENT_ID_C;
            case 'N':
                  return ELEMENT_ID_N;
            case 'P':
                  return ELEMENT_ID_P;
            case 'F':
                  return ELEMENT_ID_F;
            case 'K':
                  return ELEMENT_ID_K;
            case 'S':
                  return ELEMENT_ID_S;
            }
            break;
      default:
            if (name[1] == 'H')
                  return ELEMENT_ID_H;
      }
      return ELEMENT_ID_Unknown;
}

@end


Generated by  Doxygen 1.6.0   Back to index