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

ResultsConverter.m

/*
   Project: ResultsConverter

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

   Author: Michael Johnston

   Created: 2005-11-15 12:12:31 +0100 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 "ResultsConverter.h"

@implementation ResultsConverter

- (void) _printInfo: (ULSimulation*) resultsObject
{
      [resultsObject printAvailableInfo];
}

- (void) _printHelp
{
      GSPrintf(stderr, @"\nUsage: ResultsConverter [mode=modevalue] [options]\n");
      GSPrintf(stderr, @"All Options must be specified as option=value pairs\n\n");
      GSPrintf(stderr, @"Options common to all modes.\n");
      GSPrintf(stderr, @"  Required:\n");
      GSPrintf(stderr, @"\tTrajectory            A valid adun results output directory.\n"); 
      GSPrintf(stderr, @"  Optional:\n");
      GSPrintf(stderr, @"\tSubsystems            A comma seperated list of subsystems. Defaults to all\n\n");

      GSPrintf(stderr, @"Info specific options (Mode=Info):\n");
      GSPrintf(stderr, @"  Required:\n");
      GSPrintf(stderr, @"\tNone\n");      
      GSPrintf(stderr, @"  Optional:\n");
      GSPrintf(stderr, @"\tNone\n\n");    
      
      GSPrintf(stderr, @"Energy options (Mode=Energy):\n");
      GSPrintf(stderr, @"  Required:\n");
      GSPrintf(stderr, @"\tOutput                Output file name\n"); 
      GSPrintf(stderr, @"  Optional:\n");
      GSPrintf(stderr, @"\tTerms                 A comma seperated list of energy terms. Defaults to all\n");
      GSPrintf(stderr, @"\tUnit                  KCalMol|JouleMol|Simulation. Defaults to KCalMol\n");
      GSPrintf(stderr, @"\tStart                 The initial frame\n");
      GSPrintf(stderr, @"\tLength                The number of frames\n");
      GSPrintf(stderr, @"\tStepsize              The stepsize. Defaults to 1\n\n");

      GSPrintf(stderr, @"Configuration options (Mode=Configuration):\n");
      GSPrintf(stderr, @"  Required:\n");
      GSPrintf(stderr, @"\tNone\n");
      GSPrintf(stderr, @"  Optional:\n");
      GSPrintf(stderr, @"\tStart                 The initial frame\n");
      GSPrintf(stderr, @"\tLength                The number of frames\n");
      GSPrintf(stderr, @"\tStepsize              The stepsize. Defaults to 1\n\n");
}     

- (void) _processArguements
{
      int i, j;
      NSMutableArray* arguments;
      NSDictionary* defaults;
      NSEnumerator *enumerator;
      id arg, array, invalidArgs, optionalArgs, commandLineArgs;  
      id mode, value;

      processedArgs = [NSMutableDictionary dictionaryWithCapacity: 1];
      arguments = [[[NSProcessInfo processInfo] arguments] mutableCopy];
      invalidArgs = [NSMutableArray arrayWithCapacity: 1];

      //remove the first object - program name
      
      [arguments removeObjectAtIndex: 0];

      //check if the arguments all have valid format argname=value(s)

      NSDebugLLog(@"Arguments", @"Checking arguments format");

      enumerator = [arguments objectEnumerator];            
      while(arg = [enumerator nextObject])
      {
            array = [arg componentsSeparatedByString: @"="];
            if([array count] == 2)
                  [processedArgs setObject: [array objectAtIndex: 1]
                        forKey: [array objectAtIndex: 0]];
            else
                  [invalidArgs addObject: array];
      }

      if([invalidArgs count] != 0)
      {
            GSPrintf(stderr, 
            @"\nError - The format of some options is invalid. Options must be in Option=Value pairs:\n");

            for(i=0; i< [invalidArgs count]; i++)
                  GSPrintf(stderr, @"%@\n", [invalidArgs objectAtIndex: i]);
            [self _printHelp];
            exit(1);
      }     

      commandLineArgs = [[processedArgs allKeys] mutableCopy];

      //check Mode is present and valid
      
      NSDebugLLog(@"Arguments", @"Checking for mode presence");

      if((mode = [processedArgs objectForKey: @"Mode"]) == nil)
      {
            GSPrintf(stderr, @"\nMode must be specified.\n");
            [self _printHelp];
            exit(1);
      }
      
      if((validOptions = [validOptions objectForKey: mode]) == nil)     
      {
            GSPrintf(stderr, @"\nInvalid value for mode.\n");
            [self _printHelp];
            exit(1);
      }

      [commandLineArgs removeObject: @"Mode"];

      //check required args are present
      NSDebugLLog(@"Arguments", @"Checking for required args");
      
      enumerator = [[validOptions objectForKey: @"RequiredArgs"] objectEnumerator];
      while(arg = [enumerator nextObject])
            if([processedArgs objectForKey: arg] == nil)
            {
                  GSPrintf(stderr, @"\nRequired arguement - %@ - not present\n", arg);
                  [self _printHelp];
                  exit(1);
            }

      [commandLineArgs removeObjectsInArray: [validOptions objectForKey: @"RequiredArgs"]];
      
      //check each of the remaining options are in the optionalArgs list
      
      NSDebugLLog(@"Arguments", @"Checking for optional args");
      
      [invalidArgs removeAllObjects];
      enumerator = [commandLineArgs objectEnumerator];
      optionalArgs = [validOptions valueForKey:@"OptionalArgs"];
      while(arg = [enumerator nextObject])
            if(![optionalArgs containsObject: arg])
                  [invalidArgs addObject: arg];

      if([invalidArgs count] != 0)
      {
            GSPrintf(stderr, @"Detected %d unknown argument(s)\n", [invalidArgs count]);
            for(i=0; i< [invalidArgs count]; i++)
                  GSPrintf(stderr, @"%@\n", [invalidArgs objectAtIndex: i]);
            [self _printHelp];
            exit(1);
      }

      //check which options were not given - insert these and give them default values
      
      NSDebugLLog(@"Arguments", @"Applying default values for missing args");

      enumerator = [[validOptions valueForKey:@"OptionalArgs"] objectEnumerator];
      defaults = [NSDictionary dictionaryWithObjects: [validOptions objectForKey: @"OptionDefaults"]
                  forKeys: [validOptions objectForKey:@"OptionalArgs"]];
      while(arg = [enumerator nextObject])
            if([processedArgs objectForKey: arg] == nil)
                  [processedArgs setObject: [defaults valueForKey: arg]
                        forKey: arg];
      
      NSDebugLLog(@"Arguments", @"Complete.");
}

- (void) _validateArgs
{     
      int i, j;
      NSMutableArray* arguments;
      NSEnumerator *enumerator;
      NSError* error;
      id arg , value;   
      id subsystems, array;

      enumerator = [processedArgs keyEnumerator];
      while(arg = [enumerator nextObject])
      {
            //catch "All" values
            value = [processedArgs valueForKey: arg];
            
            if([value isEqual: @"All"])
            {
                  if([arg isEqual: @"Subsystems"])
                        value = [results availableSubsystems];
                  else if([arg isEqual: @"Terms"])
                  {
                        subsystems = [results availableSubsystems];
                        value = [NSMutableArray arrayWithCapacity: 1];
                        for(i=0; i<[subsystems count]; i++)
                        {
                              array = [results availableTermsForSubsystem: 
                                          [subsystems objectAtIndex: i]]; 
                              [value removeObjectsInArray: array];
                              [value addObjectsFromArray: array];
                        }
                  }
                  else
                        [NSException raise: NSInvalidArgumentException
                              format: @"Option %@ cannot be set to All", arg];
            }
            else
                  if(![self validateValue: &value forKey: arg error:  &error])
                        [NSException raise: NSInvalidArgumentException
                              format: @"Invalid format for arguement %@", arg];

            [processedArgs setObject: value forKey: arg];
      }
}

- (Class) _loadBundle: (NSString*) pluginName fromDir: (NSString*) pluginDir 
{
      NSBundle *pluginBundle;
      NSString *pluginPath;
      NSString *temp;
      Class pluginClass;

      NSDebugLLog(@"ResultsConverter", 
            @"Plugin dir is %@. Plugin Name is %@", 
            pluginDir, pluginName);

      //add check to see if bundle actually exists

      pluginBundle = [NSBundle bundleWithPath: 
                        [pluginDir stringByAppendingPathComponent: 
                        pluginName]];
      if(pluginBundle == nil)
            [NSException raise: NSInvalidArgumentException 
                  format: @"Specified plugin does not exist"];    

      NSDebugLLog(@"ResultsConverter", @"Plugin Bundle is %@", pluginBundle);
      NSDebugLLog(@"ResultsConverter", 
            @"Dynamicaly Loading Plugin from Directory: %@.\n\n", 
            [pluginBundle bundlePath]);

      if(pluginClass = [pluginBundle principalClass])
      {
            NSDebugLLog(@"ResultsConverter", 
                  @"Found plugin (plugin=%@).\n", 
                  [pluginClass description]);
      }
      else
            [NSException raise: NSInternalInconsistencyException
                   format: @"Specified plugin has no principal class"];

      NSDebugLLog(@"ResultsConverter", @"Loaded plugin\n");

      return pluginClass;
}

- (void) _loadConverterBundle
{
      NSString* pluginDir;
      Class pluginClass;

      pluginDir = [NSHomeDirectory() stringByAppendingPathComponent: @"adun/Plugins/Analysis"];
      
      if([[processedArgs valueForKey:@"Mode"] isEqual:@"Energy"])
            pluginClass = [self _loadBundle: @"EnergyConverter" fromDir: pluginDir];            
      else if([[processedArgs valueForKey:@"Mode"] isEqual:@"Configuration"])
            pluginClass = [self _loadBundle: @"ConformationConverter" fromDir: pluginDir];            
      else
            [NSException raise: @"NSInvalidArgumentException"
                  format: @"Unknown mode %@", [processedArgs valueForKey:@"Mode"]];

      plugin = [pluginClass new];

      if(![plugin conformsToProtocol:@protocol(ULAnalysisPlugin)])
      {
            [NSException raise: NSInternalInconsistencyException 
                  format: @"Specified plugins (%@) principal class does not conform to\
 ULAnalysisPlugin protocol", [pluginClass description]];
      }
}

- (void) _outputDataSets: (NSArray*) dataSets
{
      int i;
      NSString *outputDir;
      NSEnumerator* tableEnum, *dataSetEnum;
      NSString* format, *holder;
      id table, dataSet;

      outputDir = [processedArgs objectForKey: @"Trajectory"]; 
      dataSetEnum = [dataSets objectEnumerator];
      if([dataSets count] > 0)
      {
            i = 0;
            while(dataSet = [dataSetEnum nextObject])
            {
                  tableEnum = [[dataSet dataMatrices] objectEnumerator];
                  while(table = [tableEnum nextObject])
                  {     
                        holder = [NSString stringWithFormat: @"%@.%@", 
                                    [table name],
                                    [processedArgs objectForKey: @"Output"]];
                        holder = [outputDir stringByAppendingPathComponent: holder];            
                        [table writeMatrixToFile: holder];
                        i++;  
                  }     
            }
      }
}

- (id) init
{
      NSString* path;

      path =      [[[NSBundle mainBundle] bundlePath] 
                  stringByAppendingPathComponent: @"converterOptions.plist"];
      validOptions = [NSMutableDictionary dictionaryWithContentsOfFile: path]; 
      NSDebugLLog(@"ResultsConverter", @"Valid Options are %@", validOptions);
      
      return self;
}

- (void) main
{
      int i;
      FILE* file_p;
      NSMutableDictionary *defaults = [NSMutableDictionary dictionary];
      NSEnumerator *subsystemEnum;
      NSArray *resultsTables;
      id subsystems, subsystem, dict, options;
      id output, storage;
      NSError* error;

      GSPrintf(stderr, @"Processing Arguments\n");

      [self _processArguements];

      //create the results object and set the options

      GSPrintf(stderr, @"Accessing Results\n");
      
      results = [[ULSimulation alloc] initWithName: @"Results"];
      storage = [[ULFileSystemSimulationStorage alloc] initForReadingSimulationDataAtPath: 
                   [processedArgs valueForKey: @"Trajectory"]];
      if(![storage isAccessible])
      {           
            error = [storage accessError];
            NSLog(@"Error - %@", [[error userInfo] objectForKey: NSLocalizedDescriptionKey]);
            exit(1);
      }
      [results setDataStorage: storage];
      [results loadData];
      
      options = [results optionsDict];

      NSDebugLLog(@"ResultsConverter", 
            @"Results class %@. Options %@", 
            NSStringFromClass([results class]), options);

      GSPrintf(stderr, @"Validating Arguments against Results\n");
      
      [self _validateArgs];

      NSDebugLLog(@"ResultsConverter",
             @"Processed and Validated Args\n%@",
            processedArgs); 

      //convert 

      if(![[processedArgs valueForKey:@"Mode"] isEqual: @"Info"])
      {
            [self _loadConverterBundle];
            options = [plugin pluginOptions: [NSArray arrayWithObject: results]];

            [options setValue: [processedArgs valueForKey: @"Subsystems"]
                   forKeyPath: @"Subsystems.Selection"];
            [options setValue: [processedArgs valueForKey: @"Start"]
                   forKeyPath: @"Frames.Start"];
            [options setValue: [processedArgs valueForKey: @"Length"] 
                  forKeyPath: @"Frames.Length"];
            [options setValue: [processedArgs valueForKey: @"Stepsize"] 
                  forKeyPath: @"Stepsize"];

            if([processedArgs objectForKey: @"Unit"] != nil)
                  [options setValue: [processedArgs valueForKey: @"Unit"] 
                        forKey: @"EnergyUnit"]; 

            if([[processedArgs valueForKey:@"Mode"] isEqual: @"Energy"])
            {
                  subsystemEnum = [[options valueForKey: @"Subsystems"] keyEnumerator];
                  while(subsystem = [subsystemEnum nextObject])
                        if(![subsystem isEqual: @"Selection"])
                        {
                              dict = [options valueForKeyPath: 
                                          [NSString stringWithFormat: 
                                                @"Subsystems.%@", subsystem]];
                              [dict setObject: [processedArgs valueForKey: @"Terms"] 
                                    forKey: @"Selection"];
                        }
            }

            GSPrintf(stderr, @"Performing Conversion\n");

            output = [plugin processInputs: [NSArray arrayWithObject: results]
                         userOptions: options]; 

            if(output != nil)
            {
                  resultsTables = [output objectForKey: @"ULAnalysisPluginDataSets"];
                  if(resultsTables != nil)
                        [self _outputDataSets: resultsTables];
            }
      }
      else
            [self _printInfo: results];

      GSPrintf(stderr, @"Complete\n");
}

/*******
Arg Validation
*****/

- (BOOL) validateTerms: (id*) terms error: (NSError**) error
{
      if([*terms isKindOfClass: [NSArray class]])
            return YES;
      else if([*terms isKindOfClass: [NSString class]])
      {
            *terms = [*terms componentsSeparatedByString: @","];
            return YES;
      }
      else
            return NO;
}

- (BOOL) validateSubsystems: (id*) subsystems error: (NSError**) error
{
      if([*subsystems isKindOfClass: [NSArray class]])
            return YES;
      else if([*subsystems isKindOfClass: [NSString class]])
      {
            *subsystems = [*subsystems componentsSeparatedByString: @","];
            return YES;
      }
      else
            return NO;
}


@end

Generated by  Doxygen 1.6.0   Back to index