// // BCNucleotideRNA.m // BioCocoa // // Created by John Timmer on 8/11/04. // Copyright (c) 2003-2009 The BioCocoa Project. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. // 3. The name of the author may not be used to endorse or promote products // derived from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT // NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #import "BCNucleotideRNA.h" #import "BCNucleotideDNA.h" static BCNucleotideRNA *adenosineRepresentation = nil; static BCNucleotideRNA *uridineRepresentation = nil; static BCNucleotideRNA *cytidineRepresentation = nil; static BCNucleotideRNA *guanidineRepresentation = nil; static BCNucleotideRNA *anyBaseRepresentation = nil; static BCNucleotideRNA *purineRepresentation = nil; static BCNucleotideRNA *pyrimidineRepresentation = nil; static BCNucleotideRNA *strongRepresentation = nil; static BCNucleotideRNA *weakRepresentation = nil; static BCNucleotideRNA *aminoRepresentation = nil; static BCNucleotideRNA *ketoRepresentation = nil; static BCNucleotideRNA *HRepresentation = nil; static BCNucleotideRNA *VRepresentation = nil; static BCNucleotideRNA *DRepresentation = nil; static BCNucleotideRNA *BRepresentation = nil; static BCNucleotideRNA *gapRepresentation = nil; static BCNucleotideRNA *undefinedRepresentation = nil; static NSMutableDictionary *customBases = nil; @implementation BCNucleotideRNA #if 0 #pragma mark â CLASS METHODS #endif //////////////////////////////////////////////////////////////////////////// // THIS METHOD CREATES THE SINGLETON REFERENCES TO ALL THE STANDARD BASES //////////////////////////////////////////////////////////////////////////// + (void) initBases { // FIND OUR BUNDLE AND LOAD UP THE BASE DEFINITIONS NSBundle *biococoaBundle = [NSBundle bundleForClass: [BCNucleotideRNA class]]; NSString *filePath = [biococoaBundle pathForResource: @"nucleotides" ofType: @"plist"]; if ( filePath == nil ) return; NSStringEncoding enc; NSError *error; NSMutableString *tempString = [NSMutableString stringWithContentsOfFile: filePath usedEncoding: &enc error: &error]; // we adapt the DNA setup for use as RNA by replacing the thymidines with uridines [tempString replaceOccurrencesOfString: @">T<" withString: @">U<" options: NSLiteralSearch range: NSMakeRange(0, [tempString length])]; [tempString replaceOccurrencesOfString: @"thymidine" withString: @"uridine" options: NSLiteralSearch range: NSMakeRange(0, [tempString length])]; NSMutableDictionary *baseDefinitions = [tempString propertyList]; if ( baseDefinitions == nil ) return; customBases = [baseDefinitions retain]; // GO THROUGH AND CREATE EACH SINGLETON BASE DEFINITION, USING THE DICTIONARY NSDictionary *tempDict = [baseDefinitions objectForKey: @"A"]; if ( tempDict != nil && [tempDict isKindOfClass: [NSDictionary class]] ) { adenosineRepresentation = [[BCNucleotideRNA alloc] initWithSymbolChar: 'A']; [baseDefinitions removeObjectForKey: @"A"]; } tempDict = [baseDefinitions objectForKey: @"U"]; if ( tempDict != nil && [tempDict isKindOfClass: [NSDictionary class]] ) { uridineRepresentation = [[BCNucleotideRNA alloc] initWithSymbolChar: 'U']; [baseDefinitions removeObjectForKey: @"U"]; } tempDict = [baseDefinitions objectForKey: @"C"]; if ( tempDict != nil && [tempDict isKindOfClass: [NSDictionary class]] ) { cytidineRepresentation = [[BCNucleotideRNA alloc] initWithSymbolChar: 'C']; [baseDefinitions removeObjectForKey: @"C"]; } tempDict = [baseDefinitions objectForKey: @"G"]; if ( tempDict != nil && [tempDict isKindOfClass: [NSDictionary class]] ) { guanidineRepresentation = [[BCNucleotideRNA alloc] initWithSymbolChar: 'G']; [baseDefinitions removeObjectForKey: @"G"]; } tempDict = [baseDefinitions objectForKey: @"N"]; if ( tempDict != nil && [tempDict isKindOfClass: [NSDictionary class]] ) { anyBaseRepresentation = [[BCNucleotideRNA alloc] initWithSymbolChar: 'N']; [baseDefinitions removeObjectForKey: @"N"]; } tempDict = [baseDefinitions objectForKey: @"R"]; if ( tempDict != nil && [tempDict isKindOfClass: [NSDictionary class]] ) { purineRepresentation = [[BCNucleotideRNA alloc] initWithSymbolChar: 'R']; [baseDefinitions removeObjectForKey: @"R"]; } tempDict = [baseDefinitions objectForKey: @"Y"]; if ( tempDict != nil && [tempDict isKindOfClass: [NSDictionary class]] ) { pyrimidineRepresentation = [[BCNucleotideRNA alloc] initWithSymbolChar: 'Y']; [baseDefinitions removeObjectForKey: @"Y"]; } tempDict = [baseDefinitions objectForKey: @"S"]; if ( tempDict != nil && [tempDict isKindOfClass: [NSDictionary class]] ) { strongRepresentation = [[BCNucleotideRNA alloc] initWithSymbolChar: 'S']; [baseDefinitions removeObjectForKey: @"S"]; } tempDict = [baseDefinitions objectForKey: @"W"]; if ( tempDict != nil && [tempDict isKindOfClass: [NSDictionary class]] ) { weakRepresentation = [[BCNucleotideRNA alloc] initWithSymbolChar: 'W']; [baseDefinitions removeObjectForKey: @"W"]; } tempDict = [baseDefinitions objectForKey: @"M"]; if ( tempDict != nil && [tempDict isKindOfClass: [NSDictionary class]] ) { aminoRepresentation = [[BCNucleotideRNA alloc] initWithSymbolChar: 'M']; [baseDefinitions removeObjectForKey: @"M"]; } tempDict = [baseDefinitions objectForKey: @"K"]; if ( tempDict != nil && [tempDict isKindOfClass: [NSDictionary class]] ) { ketoRepresentation = [[BCNucleotideRNA alloc] initWithSymbolChar: 'K']; [baseDefinitions removeObjectForKey: @"K"]; } tempDict = [baseDefinitions objectForKey: @"H"]; if ( tempDict != nil && [tempDict isKindOfClass: [NSDictionary class]] ) { HRepresentation = [[BCNucleotideRNA alloc] initWithSymbolChar: 'H']; [baseDefinitions removeObjectForKey: @"H"]; } tempDict = [baseDefinitions objectForKey: @"V"]; if ( tempDict != nil && [tempDict isKindOfClass: [NSDictionary class]] ) { VRepresentation = [[BCNucleotideRNA alloc] initWithSymbolChar: 'V']; [baseDefinitions removeObjectForKey: @"V"]; } tempDict = [baseDefinitions objectForKey: @"D"]; if ( tempDict != nil && [tempDict isKindOfClass: [NSDictionary class]] ) { DRepresentation = [[BCNucleotideRNA alloc] initWithSymbolChar: 'D']; [baseDefinitions removeObjectForKey: @"D"]; } tempDict = [baseDefinitions objectForKey: @"B"]; if ( tempDict != nil && [tempDict isKindOfClass: [NSDictionary class]] ) { BRepresentation = [[BCNucleotideRNA alloc] initWithSymbolChar: 'B']; [baseDefinitions removeObjectForKey: @"B"]; } tempDict = [baseDefinitions objectForKey: @"-"]; if ( tempDict != nil && [tempDict isKindOfClass: [NSDictionary class]] ) { gapRepresentation = [[BCNucleotideRNA alloc] initWithSymbolChar: '-']; [baseDefinitions removeObjectForKey: @"-"]; } tempDict = [baseDefinitions objectForKey: @"?"]; if ( tempDict != nil && [tempDict isKindOfClass: [NSDictionary class]] ) { undefinedRepresentation = [[BCNucleotideRNA alloc] initWithSymbolChar: '?']; [baseDefinitions removeObjectForKey: @"?"]; } // hang on to the dictionary, in case there are custom bases customBases = [baseDefinitions retain]; } + (id) objectForSavedRepresentation: (NSString *)aSymbol { return [BCNucleotideRNA symbolForChar: [aSymbol characterAtIndex: 0]]; } //////////////////////////////////////////////////////////////////////////// // THE FOLLOWING IS A METHOD FOR OBTAINING REFERENCES TO THE // INDIVIDUAL BASE REPRESENTATIONS WHEN GIVEN A SINGLE LETTER CODE // // THIS WILL NOT WORK WITH CUSTOM BASES, SINCE THEIR SYMBOLS ARE NOT KNOWN IN ADVACE //////////////////////////////////////////////////////////////////////////// + (id) symbolForChar: (unsigned char)entry { switch ( entry ) { case 'A' : case 'a' : { return [BCNucleotideRNA adenosine]; break; } case 'U' : case 'u' : { return [BCNucleotideRNA uridine]; break; } case 'C' : case 'c' : { return [BCNucleotideRNA cytidine]; break; } case 'G' : case 'g' : { return [BCNucleotideRNA guanidine]; break; } case 'N' : case 'n' : { return [BCNucleotideRNA anyBase]; break; } case 'R' : case 'r' : { return [BCNucleotideRNA purine]; break; } case 'Y' : case 'y' : { return [BCNucleotideRNA pyrimidine]; break; } case 'W' : case 'w' : { return [BCNucleotideRNA weak]; break; } case 'S' : case 's' : { return [BCNucleotideRNA strong]; break; } case 'M' : case 'm' : { return [BCNucleotideRNA amino]; break; } case 'K' : case 'k' : { return [BCNucleotideRNA keto]; break; } case 'H' : case 'h' : { return [BCNucleotideRNA H]; break; } case 'V' : case 'v' : { return [BCNucleotideRNA V]; break; } case 'D' : case 'd' : { return [BCNucleotideRNA D]; break; } case 'B' : case 'b' : { return [BCNucleotideRNA B]; break; } case '-' : { return [BCNucleotideRNA gap]; break; } default : return [BCNucleotideRNA undefined]; } } //////////////////////////////////////////////////////////////////////////// // THE FOLLOWING ARE METHODS FOR OBTAINING REFERENCES TO THE // INDIVIDUAL BASE REPRESENTATIONS //////////////////////////////////////////////////////////////////////////// + (BCNucleotideRNA *) adenosine { if ( adenosineRepresentation == nil ) [BCNucleotideRNA initBases]; return adenosineRepresentation; } + (BCNucleotideRNA *) uridine { if ( uridineRepresentation == nil ) [BCNucleotideRNA initBases]; return uridineRepresentation; } + (BCNucleotideRNA *) cytidine { if ( cytidineRepresentation == nil ) [BCNucleotideRNA initBases]; return cytidineRepresentation; } + (BCNucleotideRNA *) guanidine { if ( guanidineRepresentation == nil ) [BCNucleotideRNA initBases]; return guanidineRepresentation; } + (BCNucleotideRNA *) anyBase { if ( anyBaseRepresentation == nil ) [BCNucleotideRNA initBases]; return anyBaseRepresentation; } + (BCNucleotideRNA *) purine { if ( purineRepresentation == nil ) [BCNucleotideRNA initBases]; return purineRepresentation; } + (BCNucleotideRNA *) pyrimidine { if ( pyrimidineRepresentation == nil ) [BCNucleotideRNA initBases]; return pyrimidineRepresentation; } + (BCNucleotideRNA *) strong { if ( strongRepresentation == nil ) [BCNucleotideRNA initBases]; return strongRepresentation; } + (BCNucleotideRNA *) weak { if ( weakRepresentation == nil ) [BCNucleotideRNA initBases]; return weakRepresentation; } + (BCNucleotideRNA *) amino { if ( aminoRepresentation == nil ) [BCNucleotideRNA initBases]; return aminoRepresentation; } + (BCNucleotideRNA *) keto { if ( ketoRepresentation == nil ) [BCNucleotideRNA initBases]; return ketoRepresentation; } + (BCNucleotideRNA *) H { if ( HRepresentation == nil ) [BCNucleotideRNA initBases]; return HRepresentation; } + (BCNucleotideRNA *) V { if ( VRepresentation == nil ) [BCNucleotideRNA initBases]; return VRepresentation; } + (BCNucleotideRNA *) D { if ( DRepresentation == nil ) [BCNucleotideRNA initBases]; return DRepresentation; } + (BCNucleotideRNA *) B { if ( BRepresentation == nil ) [BCNucleotideRNA initBases]; return BRepresentation; } + (BCNucleotideRNA *) gap { if ( gapRepresentation == nil ) [BCNucleotideRNA initBases]; return gapRepresentation; } + (BCNucleotideRNA *) undefined { if ( undefinedRepresentation == nil ) [BCNucleotideRNA initBases]; return undefinedRepresentation; } + (BCNucleotideRNA *) customBase: (NSString *)baseName { if ( customBases == nil ) [BCNucleotideRNA initBases]; id aBase = [customBases objectForKey: baseName]; if ( aBase == nil) return nil; if ( [aBase isKindOfClass: [BCNucleotideRNA class]] ) return aBase; if ( [aBase isKindOfClass: [NSDictionary class]] ) { aBase = [[[BCNucleotideRNA alloc] initWithDictionary: aBase] autorelease]; if ( aBase != nil ) { [customBases setObject: aBase forKey: baseName]; return aBase; } } return nil; } //////////////////////////////////////////////////////////////////////////// // OBJECT METHODS //////////////////////////////////////////////////////////////////////////// #if 0 #pragma mark â #pragma mark â OBJECT METHODS #pragma mark â #pragma mark âINITIALIZATION METHODS #endif - (id) initWithSymbolChar: (unsigned char)aSymbol { self = [super initWithSymbolChar: aSymbol]; if ( self == nil ) return nil; // we hang onto the dictionary in order to establish complement realtionships // once all the bases are generated symbolInfo = [[customBases objectForKey: symbolString] copy]; // get basic information about this base name = [symbolInfo objectForKey: @"Name"]; if (name == nil) return nil; else [name retain]; [self setMonoisotopicMass: [[symbolInfo objectForKey:@"MonoisotopicMass"] floatValue]]; [self setAverageMass: [[symbolInfo objectForKey:@"AverageMass"] floatValue]]; return self; } #if 0 #pragma mark âBASE INFORMATION METHODS #endif - (BOOL) isBase { if ( self == [BCNucleotideRNA gap] || self == [BCNucleotideRNA undefined] ) return NO; return YES; } #if 0 #pragma mark âBASE RELATIONSHIP METHODS #endif /////////////////////////////////////////////////////////// // BASE RELATIONSHIP METHODS /////////////////////////////////////////////////////////// - (BCNucleotideDNA *) DNABaseEquivalent { if ( self != [BCNucleotideRNA uridine] ) return [BCNucleotideDNA performSelector: NSSelectorFromString( name )]; return [BCNucleotideDNA thymidine]; } @end