1 use std::cast::transmute;
2 use std::from_str::FromStr;
3 use std::libc::{FILE, STDOUT_FILENO, c_int, fdopen, fputc, fputs, fwrite, size_t};
6 use std::vec::bytes::copy_memory;
9 static LINE_LEN: uint = 60;
10 static LOOKUP_SIZE: uint = 4 * 1024;
11 static LOOKUP_SCALE: f32 = (LOOKUP_SIZE - 1) as f32;
13 // Random number generator constants
14 static IM: u32 = 139968;
15 static IA: u32 = 3877;
16 static IC: u32 = 29573;
18 static ALU: &'static str = "GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTG\
19 GGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGA\
20 GACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAA\
21 AATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAAT\
22 CCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAAC\
23 CCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTG\
24 CACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAA";
26 static NULL_AMINO_ACID: AminoAcid = AminoAcid { c: ' ' as u8, p: 0.0 };
28 static MESSAGE_1: &'static str = ">ONE Homo sapiens alu\n";
29 static MESSAGE_2: &'static str = ">TWO IUB ambiguity codes\n";
30 static MESSAGE_3: &'static str = ">THREE Homo sapiens frequency\n";
32 static IUB: [AminoAcid, ..15] = [
33 AminoAcid { c: 'a' as u8, p: 0.27 },
34 AminoAcid { c: 'c' as u8, p: 0.12 },
35 AminoAcid { c: 'g' as u8, p: 0.12 },
36 AminoAcid { c: 't' as u8, p: 0.27 },
37 AminoAcid { c: 'B' as u8, p: 0.02 },
38 AminoAcid { c: 'D' as u8, p: 0.02 },
39 AminoAcid { c: 'H' as u8, p: 0.02 },
40 AminoAcid { c: 'K' as u8, p: 0.02 },
41 AminoAcid { c: 'M' as u8, p: 0.02 },
42 AminoAcid { c: 'N' as u8, p: 0.02 },
43 AminoAcid { c: 'R' as u8, p: 0.02 },
44 AminoAcid { c: 'S' as u8, p: 0.02 },
45 AminoAcid { c: 'V' as u8, p: 0.02 },
46 AminoAcid { c: 'W' as u8, p: 0.02 },
47 AminoAcid { c: 'Y' as u8, p: 0.02 },
50 static HOMO_SAPIENS: [AminoAcid, ..4] = [
51 AminoAcid { c: 'a' as u8, p: 0.3029549426680 },
52 AminoAcid { c: 'c' as u8, p: 0.1979883004921 },
53 AminoAcid { c: 'g' as u8, p: 0.1975473066391 },
54 AminoAcid { c: 't' as u8, p: 0.3015094502008 },
58 fn sum_and_scale(a: &'static [AminoAcid]) -> ~[AminoAcid] {
64 a_i.p = p * LOOKUP_SCALE;
67 result[result.len() - 1].p = LOOKUP_SCALE;
82 fn new(stdout: *FILE, alu: &'static str) -> RepeatFasta {
89 fn make(&mut self, n: uint) {
91 let stdout = self.stdout;
92 let alu_len = self.alu.len();
93 let mut buf = vec::from_elem(alu_len + LINE_LEN, 0u8);
94 let alu: &[u8] = self.alu.as_bytes();
96 copy_memory(buf, alu, alu_len);
97 let buf_len = buf.len();
98 copy_memory(buf.mut_slice(alu_len, buf_len),
106 bytes = min(LINE_LEN, n);
107 fwrite(transmute(&buf[pos]), bytes as size_t, 1, stdout);
108 fputc('\n' as c_int, stdout);
122 lookup: [AminoAcid, ..LOOKUP_SIZE],
126 fn new(stdout: *FILE, a: &[AminoAcid]) -> RandomFasta {
130 lookup: RandomFasta::make_lookup(a),
134 fn make_lookup(a: &[AminoAcid]) -> [AminoAcid, ..LOOKUP_SIZE] {
135 let mut lookup = [ NULL_AMINO_ACID, ..LOOKUP_SIZE ];
137 for (i, slot) in lookup.mut_iter().enumerate() {
138 while a[j].p < (i as f32) {
146 fn rng(&mut self, max: f32) -> f32 {
147 self.seed = (self.seed * IA + IC) % IM;
148 max * (self.seed as f32) / (IM as f32)
151 fn nextc(&mut self) -> u8 {
152 let r = self.rng(1.0);
153 for a in self.lookup.iter() {
161 fn make(&mut self, n: uint) {
163 let lines = n / LINE_LEN;
164 let chars_left = n % LINE_LEN;
165 let mut buf = [0, ..LINE_LEN + 1];
168 for i in range(0u, LINE_LEN) {
169 buf[i] = self.nextc();
171 buf[LINE_LEN] = '\n' as u8;
172 fwrite(transmute(&buf[0]),
173 LINE_LEN as size_t + 1,
177 for i in range(0u, chars_left) {
178 buf[i] = self.nextc();
180 fwrite(transmute(&buf[0]), chars_left as size_t, 1, self.stdout);
185 #[fixed_stack_segment]
187 let n: uint = FromStr::from_str(os::args()[1]).unwrap();
191 let stdout = fdopen(STDOUT_FILENO as c_int, transmute(&mode[0]));
193 fputs(transmute(&MESSAGE_1[0]), stdout);
194 let mut repeat = RepeatFasta::new(stdout, ALU);
197 fputs(transmute(&MESSAGE_2[0]), stdout);
198 let iub = sum_and_scale(IUB);
199 let mut random = RandomFasta::new(stdout, iub);
202 fputs(transmute(&MESSAGE_3[0]), stdout);
203 let homo_sapiens = sum_and_scale(HOMO_SAPIENS);
204 random.lookup = RandomFasta::make_lookup(homo_sapiens);
207 fputc('\n' as c_int, stdout);