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

ULSimpleMergerDelegate.m

/*
   Project: UL

   Copyright (C) 2005 Michael Johnston & Jordi Villa-Freixa

   Author: Michael Johnston

   Created: 2005-06-15 16:52:34 +0200 by michael johnston

   This application 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.

   This application 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
   Library General Public License for more details.

   You should have received a copy of the GNU General Public
   License along with this library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/

#include "ULSimpleMergerDelegate.h"


@implementation ULSimpleMergerDelegate

-(void) _synchroniseFrameWithConfiguration
{
      int i, atomCount;
      id index, confNames, coordinates, obj;
      NSEnumerator* indexEnumerator;
      NSMutableArray* newNames, *newCoords;

      //we need the atoms to be in the same order in the frame and the configuration
      //this means sorting the atom name list retrieved from the configuration file
      //and also sorting the coordinates matrix based on the frame.
      //The residues are in the correct order already. It is the order of the atoms
      //in each residue that we are correcting. 

      confNames = [configuration valueForKey:@"AtomNames"];
      coordinates = [[configuration valueForKey:@"Coordinates"] matrixRows];
      newNames = [NSMutableArray arrayWithCapacity: 1];
      newCoords = [NSMutableArray arrayWithCapacity: 1];

      GSPrintf(buildOutput, @"\nBefore syncronisation\n");

      for(i = 0; i< [indexes count]; i++)
      {
            GSPrintf(buildOutput, @"%-8d%-12@%-12@\n",i, 
                  [[topologyFrame valueForKey:@"AtomNames"] objectAtIndex: i],
                  [indexes objectAtIndex: i]);
      }

      indexEnumerator = [indexes objectEnumerator];
      while(index = [indexEnumerator nextObject])
      {
            if(![index isEqual: @"Missing"])    
            {
                  obj = [confNames objectAtIndex: [index intValue]];
                  [newNames addObject: obj];
                  obj = [coordinates objectAtIndex: [index intValue]];
                  [newCoords addObject: obj];
            }
      }

      [configuration setObject: newNames forKey:@"AtomNames"];
      [[configuration valueForKey: @"Coordinates"] setValue: newCoords forKey: @"MatrixRows"];
      [[configuration valueForKey: @"Coordinates"] setValue: 
            [NSNumber numberWithInt: [newCoords count]] 
            forKey: @"Rows"];

      GSPrintf(buildOutput, @"\nSynchronising\n");
      
      //renumber indexes to reflect changes

      for(atomCount = 0, i=0; i<[indexes count]; i++)
            if(![[indexes objectAtIndex: i] isEqual: @"Missing"])
            {
                  [indexes removeObjectAtIndex: i];
                  [indexes insertObject: [NSNumber numberWithInt: atomCount] 
                        atIndex: i];
                  atomCount++;
            }

      for(i = 0; i< [indexes count]; i++)
      {
            GSPrintf(buildOutput, @"%-8d%-12@%-12@\n",i, 
                  [[topologyFrame valueForKey:@"AtomNames"] objectAtIndex: i],
                  [indexes objectAtIndex: i]);
      }
      GSPrintf(buildOutput, @"\n");

}

- (id) _createSystem
{     
      ULSystem* system;
      int* buffer;

      system = [ULSystem new];

      //we have to remove the partial charges of the atoms that are missing
      //unfortuantly gnustep has yet to implement removeObjectsWithIndexes: :-()

      buffer = (int*)malloc([totalMissingAtoms count]*sizeof(int));
      [totalMissingAtoms getIndexes: buffer 
                  maxCount: [totalMissingAtoms count]
                  inIndexRange: NULL];
      [[topologyFrame valueForKey: @"PartialCharges"] 
                  removeObjectsFromIndices: buffer numIndices: [totalMissingAtoms count]];
      [[topologyFrame valueForKey: @"LibraryNames"] 
                  removeObjectsFromIndices: buffer numIndices: [totalMissingAtoms count]];
      free(buffer);
      
      [configuration setValue: [topologyFrame valueForKey:@"LibraryNames"] forKey: @"LibraryNames"];
      [configuration setValue: [topologyFrame valueForKey:@"PartialCharges"] forKey: @"PartialCharges"];
      [configuration setValue: [topologyFrame valueForKey:@"BondedAtoms"] forKey: @"BondedAtoms"];

      NSDebugLLog(@"ULSimpleMergerDelegate", @"There are %d library names", 
                  [[configuration valueForKey: @"LibraryNames"] count]);
      NSDebugLLog(@"ULSimpleMergerDelegate", @"There are %d pdb names",
                   [[configuration valueForKey: @"AtomNames"] count]);
      NSDebugLLog(@"ULSimpleMergerDelegate", @"There are %d partial charges", 
                  [[configuration valueForKey: @"PartialCharges"] count]);

      [system setValue: configuration forKey: @"Configuration"];

      return system;
}

//FIXME: This shouldnt begin with init

- (void) initWithConfiguration: (NSDictionary*) conf topologyFrame: (NSDictionary*) frame
{
      int i;
      id path;

      configuration = conf;
      topologyFrame = frame;  

      if(indexes == nil)
            indexes = [[NSMutableArray arrayWithCapacity:1] retain];
      else
            [indexes removeAllObjects];

      if(totalMissingAtoms == nil)
            totalMissingAtoms = [[NSMutableIndexSet indexSet] retain];
      else  
            [totalMissingAtoms removeAllIndexes];

      numberOfResidues = [[topologyFrame valueForKey:@"ResidueList"] count];  
      bondedAtomsList = [topologyFrame valueForKey:@"BondedAtoms"];
      
      path = [[NSUserDefaults standardUserDefaults] stringForKey: @"BuildOutput"];
      buildOutput = fopen([path cString], "a");
      
      if(extraAtomsDict == nil)
            extraAtomsDict = [[NSMutableDictionary dictionary] retain];
      else
            [extraAtomsDict removeAllObjects];

      if(missingAtomsDict == nil)
            missingAtomsDict = [[NSMutableDictionary dictionary] retain];
      else 
            [missingAtomsDict removeAllObjects];
}

- (void) matchedConfigurationAtom: (int) confAtomIndex toTopologyAtom: (int) topAtomIndex
{
      [indexes addObject: [NSNumber numberWithInt: confAtomIndex]];
}

- (void) foundTopologyAtomNotInConfiguration: (int) topIndex
{
      [indexes addObject: @"Missing"];
      [missingAtoms addObject: [NSNumber numberWithInt: topIndex]];
      [totalMissingAtoms addIndex: topIndex];
}

- (void) foundMoleculeWithExtraAtoms: (int) confMoleculeIndex
{

}

- (void) foundDuplicateConfigurationAtoms: (NSArray*) confAtomIndexes
{

}

- (void) foundConfigurationAtomNotInTopology: (int) confIndex
{
      [unidentifiedAtoms addObject: [NSNumber numberWithInt: confIndex]];
}

- (id) finalise
{
      int i, j;
      int oldValue, newValue;
      int* buffer;
      id bondedAtoms, system;
      
      //synchronize the pdb atom order with the frame atom order
      
      [self _synchroniseFrameWithConfiguration];
      
      //now remove all the missing atoms from the bondedAtomList
      
      buffer = (int*)malloc([totalMissingAtoms count]*sizeof(int));
      [totalMissingAtoms getIndexes: buffer 
                  maxCount: [totalMissingAtoms count]
                  inIndexRange: NULL];
      [bondedAtomsList removeObjectsFromIndices: buffer numIndices: [totalMissingAtoms count]];
      free(buffer);
      
      //renumber the connectivity matrix

      for(i=0; i<[bondedAtomsList count]; i++)
      {
            bondedAtoms  = [bondedAtomsList objectAtIndex: i];

            NSDebugLLog(@"ULSimpleMergerDelegate", @"Atom number %d (%@)", i, 
                        [[configuration valueForKey:@"AtomNames"] objectAtIndex: i]);
            NSDebugLLog(@"ULSimpleMergerDelegate", @"Bonded atoms %@", bondedAtoms);

            for(j=0; j < [bondedAtoms count]; j++)
            {
                  oldValue = [[bondedAtoms objectAtIndex: j] intValue];
                  newValue = [[indexes objectAtIndex: oldValue] intValue];
                  NSDebugLLog(@"ULSimpleMergerDelegate", @"Old value %d (%@)", oldValue, 
                              [[topologyFrame valueForKey:@"AtomNames"] objectAtIndex: oldValue]);
                  NSDebugLLog(@"ULSimpleMergerDelegate", @"New value %d (%@)", newValue, 
                              [[configuration valueForKey:@"AtomNames"] objectAtIndex: newValue]);
                  [bondedAtoms removeObjectAtIndex: j];
                  [bondedAtoms insertObject: [NSNumber numberWithInt: newValue] 
                        atIndex: j];
            }
      }

      system = [self _createSystem];
      fclose(buildOutput);
      return system;
}

- (void) didBeginMolecule: (int) index
{
      if(missingAtoms == nil)
            missingAtoms = [[NSMutableArray arrayWithCapacity:1] retain];
      else
            [missingAtoms removeAllObjects];

      if(unidentifiedAtoms == nil)
            unidentifiedAtoms = [[NSMutableArray arrayWithCapacity:1] retain];
      else
            [unidentifiedAtoms removeAllObjects];

      currentResidueIndex = index;
}

- (void) didEndMolecule: (int) index
{
      int newAtomsInResidue;
      NSEnumerator* missingAtomEnum, *bondedAtomsEnum, *anEnum;
      id atom, bondedAtoms,anObj, bondedAtom, list;
      id residueName, atomName, atomList;

      if([missingAtoms count] != 0)
      {
            GSPrintf(buildOutput , @"\nConfiguration residue %d is missing atoms %@\n", index, missingAtoms);
            residueName = [[topologyFrame objectForKey: @"ResidueList"] objectAtIndex: index];
            atomList = [NSMutableArray array];
            [missingAtomsDict setObject: atomList 
                  forKey: [NSString stringWithFormat: @"%@%d", residueName, index]];
            anEnum = [missingAtoms objectEnumerator];
            while(anObj = [anEnum  nextObject])
            {
                  atomName =  [[topologyFrame valueForKey:@"AtomNames"] 
                                    objectAtIndex: [anObj intValue]];
                  [atomList addObject: atomName];
                  GSPrintf(buildOutput, @"%@ ", atomName);
            }
            GSPrintf(buildOutput,@"\n");  
      }

      if([unidentifiedAtoms count] != 0)
      {
            GSPrintf(buildOutput, @"Configuration residue %d contains unidentified atoms (%@)\n", 
                        index, unidentifiedAtoms);
            residueName = [[topologyFrame objectForKey: @"ResidueList"] objectAtIndex: index];
            atomList = [NSMutableArray array];
            [extraAtomsDict setObject: atomList 
                  forKey: [NSString stringWithFormat: @"%@%d", residueName, index]];
            anEnum = [unidentifiedAtoms objectEnumerator];
            while(anObj = [anEnum  nextObject])
            {
                  atomName = [[configuration valueForKey:@"AtomNames"] 
                              objectAtIndex: [anObj intValue]];
                  [atomList addObject: atomName];
                  GSPrintf(buildOutput, @"%@ ", atomName);
            }
            GSPrintf(buildOutput, @"\n"); 
      }
      
      //remove from the connectivity matrix
      //all references to the missing atoms     

      missingAtomEnum = [missingAtoms objectEnumerator];
      while(atom = [missingAtomEnum nextObject])
      {
            //get the atoms bonded to the missing atom

            bondedAtoms = [bondedAtomsList objectAtIndex: [atom intValue]];
            bondedAtomsEnum = [bondedAtoms objectEnumerator];

            while(bondedAtom = [bondedAtomsEnum nextObject])
            {
                  list = [bondedAtomsList objectAtIndex: [bondedAtom intValue]];
                  [list removeObject: atom];
            }
      }

      //we have to update the configurations atomsPerResidue array if there are unidentified atoms
      //because those atoms will be removed from the atomName array and the coordinate matrix.
      //If we dont atomsPerResidue will be incorrect when we create the system object

      if([unidentifiedAtoms count] != 0)
      {
            //anObj is the atomPerResidue array
            anObj =  [configuration valueForKey:@"AtomsPerResidue"]; 
            newAtomsInResidue = [[anObj objectAtIndex: index] intValue] - [unidentifiedAtoms count];
            [anObj removeObjectAtIndex: index]; 
            [anObj insertObject: [NSNumber numberWithInt: newAtomsInResidue] atIndex: index];
      }

      fflush(buildOutput);
}

- (NSDictionary*) extraAtoms
{
      return extraAtomsDict;
}

- (NSDictionary*) missingAtoms
{
      return missingAtomsDict;
} 

@end

Generated by  Doxygen 1.6.0   Back to index