Package Bio :: Package Ais
[hide private]
[frames] | no frames]

Source Code for Package Bio.Ais

  1  # Copyright 2002 by Katharine Lindner.  All rights reserved. 
  2  # This code is part of the Biopython distribution and governed by its 
  3  # license.  Please see the LICENSE file that should have been included 
  4  # as part of this package. 
  5  """ 
  6  Immune system simulation based on ideas from Immunocomputing: a survey. 
  7  I.Antoniou, S.Gutnikov, V.Ivanov, Yu.Melnikov, A.Tarakanov 
  8  12. Forrest S., Perelson A. Aleen L. and Cherukuri R.  
  9  Self-nonself disctimination in a computer. Proc. of IEEE symposium on reseqrch 
 10  in security and privacy. Oakland, USA, 1994, 202-212. 
 11   
 12   
 13  Immune system simulation. 
 14  Accepts an initial set of sequences to be protected. 
 15  Creates a set of randomly scrambled sequences and uses a lazy check to remove 
 16  those that trigger on members of the protected set. 
 17  The detector for a suspicious sequence checks for a close match to a scrambled sequence. 
 18  The detectors start out with equal weights.  When a detector finds a suspicious antigen, 
 19  its weight is incremented so its chances of being selected in the future increases. 
 20  Intended only for experimentation. 
 21  """ 
 22   
 23  import os 
 24  import sys 
 25  import string 
 26  import random 
 27  from urllib import FancyURLopener 
 28  from urllib import urlencode 
 29   
 30  from Bio.SGMLExtractor import SGMLExtractorHandle 
 31  from Bio.NetCatch import NetCatch 
 32  from Bio.NetCatch import ExtractUrls 
 33  from Bio.Seq import Seq 
 34  from Bio.Align.Generic import Alignment 
 35  from Bio.Align.AlignInfo import SummaryInfo 
 36  from Bio.Alphabet import DNAAlphabet 
 37  from Bio.Alphabet import Gapped 
 38  from Bio.SGMLExtractor import SGMLExtractorHandle 
 39  from Bio.HotRand import HotRandom 
 40   
 41   
 42   
 43   
 44   
45 -def match_sequence( first, second, threshold ):
46 len_first = len( first ) 47 len_second = len( second ) 48 if( len_first > len_second ): 49 len_min = len_second 50 else: 51 len_min = len_first 52 if( threshold > len_min ): 53 threshold = len_min 54 max_match = 0 55 match_count = 0 56 for j in range( 0, len_min ): 57 if( first[ j ] == second[ j ] ): 58 match_count = match_count + 1 59 if( match_count > max_match ): 60 max_match = match_count 61 else: 62 match_count = 0 63 if( max_match >= threshold ): 64 return 1 65 else: 66 return 0
67
68 -class Lymphocyte:
69
70 - def __init__( self, residues ):
71 self.residues = residues 72 self.may_be_autoimmune = 1 73 self.weight = 1
74 75
76 -class Immune:
77 """ 78 friendly should be an instance of Align. It should contain the set of 79 protected sequences. 80 """ 81
82 - def __init__( self, friendly_seq, alphabet = 'acgt', tuner_dict = None, 83 hot_mode = 0 ):
84 self.hot_mode = hot_mode 85 if hot_mode: 86 self.hot_random = HotRandom() 87 self.set_defaults() 88 89 try: 90 self.tuner_dict = tuner_dict 91 except: 92 self.tuner_dict= self.default_tuner_dict 93 self.tune() 94 self.build_align( friendly_seq ) 95 self.friendly = friendly 96 self.alphabet = alphabet[:] 97 self.lymphocyte_factory()
98
99 - def set_defaults( self ):
100 self.default_tuner_dict = { \ 101 'num_lymphocytes' : 20, \ 102 'num_tosses' : 5, \ 103 'threshold' : 5, \ 104 'segment_size' : 60, \ 105 'replicant_num' : 1 \ 106 }
107
108 - def tune( self ):
109 for ( key, val ) in self.tuner_dict: 110 key = key.strip() 111 val = int( val.strip() ) 112 self.__dict__[ key ] = val
113
114 - def build_align( self, seq ):
115 align = Alignment( Gapped( DNAAlphabet() ) ) 116 alphabet = self.alphabet 117 len_seq = len( seq ) 118 step = self.segment_size 119 for j in range( 0, len_seq, step ): 120 segment = seq[j : j + step] 121 align.add_sequence( name, segment ) 122 self.friendly = align
123
124 - def select_at_random( self, items ):
125 max_select = len( items ) 126 if self.hot_mode: 127 selector = self.hot_random.hot_rand( max_select ) 128 else: 129 selector = random.randint( 0, max_select ) 130 return selector
131
132 - def guess_gaps( self, seq ):
133 """ 134 Fill gaps with random selction from alphabet 135 """ 136 seq = seq.lower() 137 for dest_index in range( 0, len( seq ) ): 138 if( seq[ dest_index ] not in self.alphabet ): 139 source_index = self.select_at_random( self.alphabet ) 140 seq = seq[ :dest_index] + self.alphabet[ source_index ] + seq[ dest_index + 1: ] 141 return seq
142
143 - def scramble( self, seq ):
144 """ 145 Substitute residues in sequence at random. 146 """ 147 num_tosses = self.num_tosses 148 seq = seq[:].lower() 149 for toss in range( 0, num_tosses ): 150 dest_index = self.select_at_random( seq ) 151 source_index = self.select_at_random( self.alphabet ) 152 seq = seq[ :dest_index] + self.alphabet[ source_index ] + seq[ dest_index + 1: ] 153 154 return seq
155 156
157 - def found_antigen( self, detector, mystery_sequence ):
158 detector = detector.lower() 159 mystery_sequence = mystery_sequence.lower() 160 return( match_sequence( detector, mystery_sequence, self.threshold ) )
161
162 - def lazy_auto_immune_check( self, seq ):
163 auto_immune = 0 164 for candidate in self.friendly.get_all_seqs(): 165 if( self.found_antigen( seq, candidate.seq.data ) ): 166 auto_immune = 1 167 break 168 return auto_immune
169 170
171 - def compute_accum_weight( self ):
172 accum_weight = 0 173 for index in range( 0, len( self.lymphocytes ) ): 174 lymphocyte = self.lymphocytes[ index ] 175 accum_weight = accum_weight + lymphocyte.weight 176 lymphocyte.accum_weight = accum_weight 177 self.lymphocytes[ index ] = lymphocyte 178 self.accum_weight = accum_weight 179 return self.accum_weight
180
181 - def search_accum_weight( self, t):
182 last = len( self.lymphocytes ) - 1 183 min = 0; max = last 184 while 1: 185 if max < min: 186 if( min <= last ): 187 return min 188 else: 189 return last 190 m = (min + max) / 2 191 if self.lymphocytes[ m ].accum_weight < t: 192 min = m + 1 193 elif self.lymphocytes[ m ].accum_weight > t: 194 max = m - 1 195 else: 196 return m
197
198 - def pick_a_lymphocyte( self ):
199 """ 200 Random selection biased by weight 201 """ 202 if self.hot_mode: 203 weight = self.hot_random.hot_rand( self.accum_weight ) 204 else: 205 weight = random.randint( self.accum_weight ) 206 index = self.search_accum_weight( weight ) 207 return index
208
209 - def random_test( self, mystery_sequence ):
210 """ 211 A single test probably won't catch a corrupted sequence. 212 Lots of tests are required 213 """ 214 index = self.pick_a_lymphocyte() 215 mystery_sequence = mystery_sequence.lower() 216 lymphocyte = self.lymphocytes[ index ] 217 detector = lymphocyte.residues 218 suspicious = self.found_antigen( detector, mystery_sequence ) 219 if suspicious: 220 auto_immune = 0 221 if( lymphocyte.may_be_autoimmune ): 222 auto_immune = self.lazy_auto_immune_check( detector ) 223 if( auto_immune ): 224 del self.lymphocytes[ index ] 225 self.create_lymphocyte() 226 suspicious = 0 227 else: 228 lymphocyte.may_be_autoimmune = auto_immune 229 lymphocyte.weight = lymphocyte.weight + 1 230 self.lymphocytes[ index ] = lymphocyte 231 self.compute_accum_weight() 232 return suspicious
233 234
235 - def create_lymphocyte( self ):
236 lymphocyte = self.guess_gaps( self.consensus.data ) 237 lymphocyte = self.scramble( lymphocyte ) 238 self.lymphocytes.append( Lymphocyte( lymphocyte ) ) 239 self.compute_accum_weight()
240 241 242
243 - def lymphocyte_factory( self ):
244 num_lymphocytes = self.num_lymphocytes 245 self.lymphocytes = [] 246 summary_info = SummaryInfo( self.friendly ) 247 consensus = summary_info.dumb_consensus() 248 self.consensus = consensus 249 for j in range( 0, num_lymphocytes ): 250 lymphocyte = self.guess_gaps( consensus.data ) 251 lymphocyte = self.scramble( lymphocyte ) 252 self.lymphocytes.append( Lymphocyte( lymphocyte ) ) 253 self.compute_accum_weight()
254