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

ULSystem.m

/*
   Project: UL

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

   Author: Michael Johnston

   Created: 2005-05-23 14:11:40 +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 "ULSystem.h"

@implementation ULSystem

- (id) init
{
      self = [super init];

      return self;
}

- (void) setConfiguration: (NSMutableDictionary*) conf
{
      if(configuration != nil)
            [configuration release];

      configuration = conf;
      [configuration retain];
      [metadata setObject: [configuration objectForKey: @"SystemName"]
            forKey: @"Name"];
}

- (void) setTopology: (id) top
{
      if(topology != nil)
            [topology release];

      topology = top;
      [topology retain];
}

- (id) Topology
{
      return topology;
}

- (id) Configuration
{
      return configuration;
}

- (void) dealloc
{
      [topology release];
      [configuration release];
      [super dealloc];
}

/*******
NSCoding Methods
********/


- (void) _encodeArrayOfDoubles: (NSArray*) array 
            usingCoder: (NSCoder*) encoder 
            forKey: (NSString*) key
{
      int i;
      int bytesLength, numberElements;
      double* bytes;

      numberElements = [array count];
      bytes = (double*)malloc(numberElements*sizeof(double));
      bytesLength = numberElements*sizeof(double);
      for(i=0; i<numberElements; i++)
            bytes[i] = [[array objectAtIndex: i] doubleValue];
      [encoder encodeBytes: (uint8_t*)bytes length: bytesLength forKey: key];
      free(bytes);
}

- (NSMutableArray*) _decodeArrayOfDoublesForKey: key usingCoder: (NSCoder*) decoder
{
      int i;
      int bytesLength, numberElements;
      double* bytes;
      NSMutableArray* array;

      bytes = (double*)[decoder decodeBytesForKey: key returnedLength: &bytesLength];
      array = [NSMutableArray arrayWithCapacity: 1];
      numberElements = bytesLength/sizeof(double);
      for(i=0; i<numberElements; i++)
            [array addObject: [NSNumber numberWithDouble: bytes[i]]];   

      return array;
}

- (void) _encodeArrayOfStrings: (NSArray*) array 
            usingCoder: (NSCoder*) encoder 
            forKey: (NSString*) key
{
      NSString* string;

      string = [array componentsJoinedByString: @"\\"];
      [encoder encodeObject: string forKey: key];
}

- (NSMutableArray*) _decodeArrayOfStringsForKey: key usingCoder: (NSCoder*) decoder
{
      id array;
      id string;

      string = [decoder decodeObjectForKey: key];
      array = [string componentsSeparatedByString: @"\\"];
      return array;
}

//we could store the bonded atoms as an index set....

- (void) _encodeBondedAtomsWithCoder: (NSCoder*) encoder
{
      int* bondedAtomsArray;
      int* numberBondedAtomsArray;
      int counter, length, i, j, numberOfAtoms;
      id bondedAtoms, atom;

      bondedAtoms = [configuration objectForKey: @"BondedAtoms"];
      numberOfAtoms = [bondedAtoms count];
      numberBondedAtomsArray = (int*)malloc(numberOfAtoms*sizeof(int));
      for(length = 0, i=0; i<numberOfAtoms; i++)
      {
            numberBondedAtomsArray = [[bondedAtoms objectAtIndex: i] count];
            length += numberBondedAtomsArray[i];
      }
      bondedAtomsArray = (int*)malloc(length*sizeof(int));
      for(i=0, counter= 0; i<numberOfAtoms; i++)
      {
            atom = [bondedAtoms objectAtIndex: i];
            for(j=0; j< numberBondedAtomsArray; j++)
            {
                  bondedAtomsArray = [[atom objectAtIndex: j] intValue];
                  counter ++;
            }
      }     

      [encoder encodeBytes: (uint8_t*)bondedAtomsArray 
            length: length*sizeof(int)          
            forKey: @"BondedAtomsArray"];
      [encoder encodeBytes: (uint8_t*)numberBondedAtomsArray
            length: numberOfAtoms*sizeof(int)         
            forKey: @"NumberBondedAtomsArray"];
}

- (void) _decodeBondedAtomsWithCoder: (NSCoder*) decoder
{
      int i, j, check;
      int length, numberElements, count;
      int* numberBondedAtomsArray;
      int* bondedAtomsArray;
      NSMutableArray* bondedAtoms, *list;
      NSNumber* index;

      numberBondedAtomsArray = (int*)[decoder decodeBytesForKey: @"NumberBondedAtomsArray"
                                    returnedLength: &length];
      numberElements = length/sizeof(int);
      bondedAtomsArray = (int*)[decoder decodeBytesForKey: @"BondedAtomsArray"
                              returnedLength: &length];
      check = length/sizeof(int);   

      bondedAtoms = [NSMutableArray arrayWithCapacity:1];
      for(i=0, count = 0; i<numberElements; i++)
      {
            list = [NSMutableArray arrayWithCapacity:1];
            for(j=0; j<numberBondedAtomsArray; j++)
            {
                  index = [NSNumber numberWithInt: bondedAtomsArray];
                  [list addObject: index];
                  count++;
            }
            [bondedAtoms addObject: list];
      }

      if(check!=count)
            [NSException raise: NSInternalInconsistencyException
                  format: [NSString stringWithFormat:
                   @"Bonded atoms decode - Decoded %d indexes. Used %d.", check, count]];

      [configuration setObject: bondedAtoms forKey: @"BondedAtoms"];
}

- (void) _encodeIndexArray: (NSArray*) indexArray
            forKey: (NSString*) key 
            usingCoder: (NSCoder*) encoder 
{
      int i, j,count;
      int totalRanges, totalSets, length;
      int* rangesPerSet;
      NSRange* totalRangeArray, *rangeArray;

      totalSets = [indexArray count];

      for(totalRanges= 0,i=0; i<totalSets; i++)
            totalRanges += [[indexArray objectAtIndex: i] numberOfRanges];
      
      totalRangeArray = (NSRange*)malloc(totalRanges*sizeof(NSRange));
      rangesPerSet = (int*)malloc(totalSets*sizeof(int));
      for(count = 0,i=0; i<totalSets; i++)
      {
            rangeArray = [[indexArray objectAtIndex: i] indexSetToRangeArrayOfLength: &length];
            rangesPerSet = length;
            for(j=0; j<length; j++)
            {
                  totalRangeArray = rangeArray;
                  count++;
            }
            free(rangeArray);
      }

      [encoder encodeBytes: (uint8_t*)totalRangeArray 
            length: totalRanges*sizeof(NSRange) 
            forKey: key];
      [encoder encodeBytes: (uint8_t*)rangesPerSet 
            length: totalSets*sizeof(int) 
            forKey: [NSString stringWithFormat: @"%@.RangesPerSet", key]];
}

- (NSArray*) _decodeIndexArrayForKey: (NSString*) key usingCoder: (NSCoder*) decoder
{
      int i, j, count;
      int totalRanges, totalSets, length;
      int* rangesPerSet;
      NSRange* totalRangeArray, *rangeArray;
      NSIndexSet* set;
      id array;

      totalRangeArray = (NSRange*)[decoder decodeBytesForKey: key returnedLength: &length];
      totalRanges = length/sizeof(NSRange);
      rangesPerSet = (int*)[decoder decodeBytesForKey:
                        [NSString stringWithFormat: @"%@.RangesPerSet", key] 
                        returnedLength: &length];
      totalSets = length/sizeof(int);

      array = [NSMutableArray arrayWithCapacity: 1];

      for(count = 0, i=0; i<totalSets; i++)
      {
            rangeArray = (NSRange*)malloc(rangesPerSet[i]*sizeof(NSRange));
            for(j=0; j<rangesPerSet; j++)
            {     
                  rangeArray = totalRangeArray;
                  count++;
            }
            set = [NSIndexSet indexSetFromRangeArray: rangeArray 
                        ofLength: rangesPerSet];
            [array addObject: set];
            free(rangeArray);
      }

      if(totalRanges != count)
            [NSException raise: NSInternalInconsistencyException
                  format: [NSString stringWithFormat: 
                  @"Did not decode the same number of ranges encoded. %d %d", count, totalRanges]];
      
      return array;
}

- (id) _decodeInteractionForKey: (NSString*) key usingCoder: (NSCoder*) decoder 
{
      NSMutableDictionary* interaction;
      id object;

      interaction = [NSMutableDictionary dictionaryWithCapacity: 1];
      object = [decoder decodeObjectForKey: 
                  [NSString stringWithFormat: @"%@.ElementsPerInteraction", key]];
      [interaction setObject: object forKey: @"ElementsPerInteraction"];
      object = [decoder decodeObjectForKey: 
                  [NSString stringWithFormat: @"%@.InteractionsPerResidue", key]];
      [interaction setObject: object forKey: @"InteractionsPerResidue"];
      object = [decoder decodeObjectForKey: 
                  [NSString stringWithFormat: @"%@.InteractionType", key]];
      [interaction setObject: object forKey: @"InteractionType"];
      object = [decoder decodeObjectForKey: 
                  [NSString stringWithFormat: @"%@.Matrix", key]];
      [interaction setObject: object forKey: @"Matrix"];
      object = [self _decodeIndexArrayForKey:
                  [NSString stringWithFormat: @"%@.ResidueInteractions", key]
                  usingCoder: decoder];
      [interaction setObject: object forKey: @"ResidueInteractions"];

      return interaction;
}

- (void) _encodeInteraction: (NSDictionary*) interaction
            forKey: (NSString*) key 
            usingCoder: (NSCoder*) encoder
{
      [encoder encodeObject: [interaction objectForKey: @"ElementsPerInteraction"]
            forKey: [NSString stringWithFormat: @"%@.ElementsPerInteraction", key]];
      [encoder encodeObject: [interaction objectForKey: @"InteractionsPerResidue"]
            forKey: [NSString stringWithFormat: @"%@.InteractionsPerResidue", key]];
      [encoder encodeObject: [interaction objectForKey: @"InteractionType"]
            forKey: [NSString stringWithFormat: @"%@.InteractionType", key]];
      [self _encodeIndexArray: [interaction objectForKey: @"ResidueInteractions"]
            forKey: [NSString stringWithFormat: @"%@.ResidueInteractions", key]
            usingCoder: encoder];
      [encoder encodeObject: [interaction objectForKey: @"Matrix"]
            forKey: [NSString stringWithFormat: @"%@.Matrix", key]];
}

- (id) initWithCoder: (NSCoder*) decoder
{
      id object, interaction;
      id bondedInteractionKeys, bondedInteractions;   
      id nonbondedInteractionKeys, nonbondedInteractions;
      NSEnumerator* interactionsEnum;

      [super initWithCoder: decoder];

      if([decoder allowsKeyedCoding])
      {
            configuration = [[NSMutableDictionary dictionaryWithCapacity:1] retain];
            object = [decoder decodeObjectForKey: @"Coordinates"];
            [configuration setObject: object forKey: @"Coordinates"];
            object = [self _decodeArrayOfStringsForKey: @"AtomNames" usingCoder: decoder]; 
            [configuration setObject: object forKey: @"AtomNames"];
            object = [self _decodeArrayOfStringsForKey: @"LibraryNames" usingCoder: decoder]; 
            [configuration setObject: object forKey: @"LibraryNames"];
            object = [self _decodeArrayOfDoublesForKey: @"PartialCharges" usingCoder: decoder]; 
            [configuration setObject: object forKey: @"PartialCharges"];
            object = [self _decodeArrayOfDoublesForKey: @"Masses" usingCoder: decoder]; 
            [configuration setObject: object forKey: @"Masses"];
            object = [decoder decodeObjectForKey: @"Sequences"];
            [configuration setObject: object forKey: @"Sequences"];
      
            //bonded atoms          

            [self _decodeBondedAtomsWithCoder: decoder];

            topology = [[NSMutableDictionary dictionaryWithCapacity:1] retain];

            bondedInteractionKeys = [decoder decodeObjectForKey:@"BondedInteractions"];
            bondedInteractions = [NSMutableDictionary dictionaryWithCapacity:1];
            interactionsEnum = [bondedInteractionKeys objectEnumerator];
            while(interaction = [interactionsEnum nextObject])
            {
                  object = [self _decodeInteractionForKey: interaction usingCoder: decoder];
                  [bondedInteractions setObject: object forKey: interaction];
            }
            [topology setObject: bondedInteractions forKey: @"Bonded"];

            nonbondedInteractionKeys = [decoder decodeObjectForKey:@"NonbondedInteractions"];
            nonbondedInteractions = [NSMutableDictionary dictionaryWithCapacity:1];
            interactionsEnum = [nonbondedInteractionKeys objectEnumerator];
            while(interaction = [interactionsEnum nextObject])
            {
                  if([interaction isEqual: @"Interactions"])
                  {
                        object = [self _decodeIndexArrayForKey: @"InteractionsArray"
                                    usingCoder: decoder];
                        [nonbondedInteractions setObject: object forKey: interaction];
                  }
                  else
                  {
                        object = [self _decodeInteractionForKey: interaction  
                                    usingCoder: decoder];
                        [nonbondedInteractions setObject: object forKey: interaction];
                  }
            }
            [topology setObject: nonbondedInteractions forKey: @"Nonbonded"];
      }
      else
      {
            configuration = [[decoder decodeObject] retain];
            topology = [[decoder decodeObject] retain];
      }

      //backwards compatibility
      if([generaldata objectForKey: @"Class"] == nil)
            [generaldata setObject: @"ULSystem"
                  forKey: @"Class"];

      NSDebugLLog(@"ULSystem", @"Configuration %@", configuration);
      NSDebugLLog(@"ULSystem", @"Topology %@", topology);

      return self;
}

- (void) encodeWithCoder: (NSCoder*) encoder
{
      int i;
      id key, interactionsDict, interaction;
      NSEnumerator* interactionsEnum;

      [super encodeWithCoder: encoder];

      if([encoder allowsKeyedCoding])
      {
            NSDebugLLog(@"ULSystem", @"Encoding configuration %@", configuration);
            [encoder encodeObject: [configuration objectForKey: @"Coordinates"]
                  forKey: @"Coordinates"];
            [self _encodeArrayOfStrings: [configuration objectForKey: @"AtomNames"]
                  usingCoder: encoder
                  forKey: @"AtomNames"];
            [self _encodeArrayOfStrings: [configuration objectForKey: @"LibraryNames"]
                  usingCoder: encoder
                  forKey: @"LibraryNames"];
            [self _encodeArrayOfDoubles: [configuration objectForKey: @"PartialCharges"]
                  usingCoder: encoder
                  forKey: @"PartialCharges"];
            [self _encodeArrayOfDoubles: [configuration objectForKey: @"Masses"]
                  usingCoder: encoder
                  forKey: @"Masses"];
            [encoder encodeObject: [configuration objectForKey: @"Sequences"]
                  forKey: @"Sequences"];

            [self _encodeBondedAtomsWithCoder: encoder];
      
            NSDebugLLog(@"ULSystem", @"Encoding topology %@", topology);

            interactionsDict = [topology objectForKey: @"Bonded"];
            [encoder encodeObject: [interactionsDict allKeys]
                  forKey: @"BondedInteractions"];
            interactionsEnum = [interactionsDict keyEnumerator];
            while(interaction = [interactionsEnum nextObject])
                  [self _encodeInteraction: [interactionsDict valueForKey: interaction]
                        forKey: interaction
                        usingCoder: encoder];
            
            interactionsDict = [topology objectForKey: @"Nonbonded"];
            [encoder encodeObject: [interactionsDict allKeys]
                  forKey: @"NonbondedInteractions"];
            interactionsEnum = [interactionsDict keyEnumerator];
            while(interaction = [interactionsEnum nextObject])
                  if([interaction isEqual: @"Interactions"])
                        [self _encodeIndexArray: [interactionsDict valueForKey: interaction]
                              forKey: @"InteractionsArray"
                              usingCoder: encoder];
                  else
                        [self _encodeInteraction: [interactionsDict valueForKey: interaction]
                              forKey: interaction
                              usingCoder: encoder];
      }
      else
      {
            [encoder encodeObject: configuration];
            [encoder encodeObject: topology];
      }
}

/********
RemoteSystemAccess Methods
********/

- (bycopy NSArray*) transmitMatrixRowsForPath: (NSString*) matrixPath
{
      return [[self valueForKeyPath: matrixPath] matrixRows];     
}

- (bycopy NSArray*) transmitMatrixRowsForConfiguration
{
      return [[self valueForKeyPath: @"Configuration.Coordinates"] matrixRows];     
}

- (bycopy NSMutableArray*) transmitAtomTypes
{
      return [self valueForKeyPath: @"Configuration.AtomNames"];
}

- (bycopy NSMutableArray*) transmitMasses
{
      return [self valueForKeyPath: @"Configuration.Masses"];
}

- (bycopy NSMutableArray*) transmitPartialCharges
{
      return [self valueForKeyPath: @"Configuration.PartialCharges"];
}

/***
Couldnt send the indexset array directly so tried 
using range arrays for index sets. This wouldnt transmit
as a whole object (bycopy) but only worked if transmitting a
range at a time (not bycopy). Now we archive the entire
thing into a data object. Transmit the data object and then 
unarchive this.
*/

- (bycopy id) transmitNonbondedInteractions
{
      return [NSArchiver archivedDataWithRootObject: [self valueForKeyPath: @"Topology.Nonbonded.Interactions"]];
}


@end

Generated by  Doxygen 1.6.0   Back to index