BasePair.d (4771B)
1 import std.stdio; 2 import std.range; 3 import std.algorithm; 4 5 6 static immutable AminoAcid.Desc aD[]=[ 7 AminoAcid.Desc("Alanine", "Ala", 'A'), 8 AminoAcid.Desc("Cyxteine", "Cys", 'C'), 9 AminoAcid.Desc("Aspartic acid", "Asp", 'D'), 10 AminoAcid.Desc("Glutamic acid", "Glu", 'E'), 11 AminoAcid.Desc("Phenylalanine", "Phe", 'F'), 12 AminoAcid.Desc("Glycine", "Gly", 'G'), 13 AminoAcid.Desc("Histidine", "His", 'H'), 14 AminoAcid.Desc("Isoleucine", "Ile", 'I'), 15 AminoAcid.Desc("Lysine", "Lys", 'K'), 16 AminoAcid.Desc("Leucine", "Leu", 'L'), 17 AminoAcid.Desc("Methionine", "Met", 'M'), 18 AminoAcid.Desc("Asparagine", "Asn", 'N'), 19 AminoAcid.Desc("Proline", "Pro", 'P'), 20 AminoAcid.Desc("Glutamine", "Gln", 'Q'), 21 AminoAcid.Desc("Arginine", "Arg", 'R'), 22 AminoAcid.Desc("Serine", "Ser", 'S'), 23 AminoAcid.Desc("Threonine", "Thr", 'T'), 24 AminoAcid.Desc("Valine", "Val", 'V'), 25 AminoAcid.Desc("Tryptophan", "Trp", 'W'), 26 AminoAcid.Desc("Tyrosine", "Tyr", 'Y'), 27 ]; 28 immutable(AminoAcid.Desc)* findAA(char shortcut){ 29 auto res=aD.assumeSorted.find!"a.shortcut==b"(shortcut); 30 if(res.empty){ 31 return null; 32 } 33 return &(res.front()); 34 } 35 36 struct AminoAcid{ 37 struct Desc{ 38 string longname; 39 string shortname; 40 char shortcut; 41 } 42 immutable(AminoAcid.Desc) *desc; 43 bool start; 44 bool stop; 45 this(char sname, bool start=false, bool stop=false){ 46 desc=findAA(sname); 47 this.start=start; 48 this.stop=stop; 49 } 50 string toString(bool shrt=true){ 51 if(start){ 52 return "START"; 53 } 54 else if(stop){ 55 return "STOP"; 56 } 57 else if(desc==null) 58 return "*"; 59 return (shrt) ? desc.shortname : desc.longname; 60 } 61 char toChar(){ 62 if(desc==null) 63 return ' '; 64 return desc.shortcut; 65 } 66 } 67 68 struct AminoAcidTable{ 69 private immutable static char[] AminoAcids = "FFLLSSSSYY**CC*WLLLLPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG"; 70 private immutable static char[] Starts = "---M---------------M---------------M----------------------------"; 71 private immutable static char[] Base1 = "TTTTTTTTTTTTTTTTCCCCCCCCCCCCCCCCAAAAAAAAAAAAAAAAGGGGGGGGGGGGGGGG"; 72 private immutable static char[] Base2 = "TTTTCCCCAAAAGGGGTTTTCCCCAAAAGGGGTTTTCCCCAAAAGGGGTTTTCCCCAAAAGGGG"; 73 private immutable static char[] Base3 = "TCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAG"; 74 75 AminoAcid table[char[3]]; 76 void initialize(){ 77 char am[3]; 78 AminoAcid ac; 79 for(uint i=0; i<AminoAcids.length; i++){ 80 am[0]=Base1[i]; 81 am[1]=Base2[i]; 82 am[2]=Base3[i]; 83 table[am]=AminoAcid(AminoAcids[i],(Starts[i]!='-'),(AminoAcids[i]=='*')); 84 } 85 } 86 87 AminoAcid* opIndex(in DNS.Codon c){ 88 return (c.c in table); 89 } 90 91 AminoAcid* opIndex(in RNS.Codon c){ 92 return opIndex(c.dns); 93 } 94 95 auto opCall(Range)(Range r) if(isInputRange!Range && (is(ElementType!Range == RNS.Codon) || is(ElementType!Range == DNS.Codon))){ 96 return r.map!(a=>*this[a]); 97 } 98 99 auto opCall(in DNS d){ 100 return d.seq.map!(a=>*this[a]); 101 } 102 auto opCall(in RNS d){ 103 return d.seq.map!(a=>*this[a]); 104 } 105 } 106 template CodonSeq(){ 107 struct Codon{ 108 char[3]c; 109 this(char[3] c){ 110 this.c=c; 111 } 112 this(Range)(Range r){ 113 foreach(i; 0..3){ 114 c[i]=cast(char)r.front; 115 r.popFront(); 116 } 117 } 118 } 119 } 120 ///Swaps A with B and C with A 121 void BaseSwap(ref char str[3], in char A, in char B, in char C){ 122 foreach(ref c; str){ 123 if(c==A){ 124 c=B; 125 } 126 else if(c==C){ 127 c=A; 128 } 129 } 130 } 131 ///Swaps A with B and vice versa 132 void BaseSwap(ref char str[3], in char A, in char B){ 133 foreach(ref c; str){ 134 if(c==A){ 135 c=B; 136 } 137 else if(c==B){ 138 c=A; 139 } 140 } 141 } 142 143 RNS.Codon rns(in DNS.Codon d){ 144 RNS.Codon c=RNS.Codon(d.c); 145 c.c.BaseSwap('A','U','T'); 146 c.c.BaseSwap('G','C'); 147 return c; 148 } 149 DNS.Codon dns(in RNS.Codon d){ 150 DNS.Codon c=DNS.Codon(d.c); 151 c.c.BaseSwap('A','T','U'); 152 c.c.BaseSwap('G','C'); 153 return c; 154 } 155 156 struct DNS{ 157 mixin CodonSeq; 158 Codon seq[]; 159 this(Range)(Range r) if(isInputRange!Range && is(ElementType!Range==Codon)){ 160 r.copy(seq.appender); 161 } 162 this(Range)(Range r) if(isInputRange!Range && isSomeChar!(ElementType!Range)){ 163 foreach(s; r.chunks(3)){ 164 seq~=Codon(s); 165 } 166 } 167 auto rns(){ 168 return seq.map!(a=>a.rns); 169 } 170 auto aa(ref AminoAcidTable aat){ 171 return aat(seq); 172 } 173 } 174 struct RNS{ 175 mixin CodonSeq; 176 Codon seq[]; 177 this(Range)(Range r) if(isInputRange!Range && isSomeChar!(ElementType!Range)){ 178 foreach(s; r.chunks(3)){ 179 seq~=Codon(s); 180 } 181 } 182 this(Range)(Range r) if(isInputRange!Range && is(ElementType!Range==Codon)){ 183 auto app=appender(seq); 184 r.copy(app); 185 seq=app.data; 186 } 187 auto dns(){ 188 return seq.map!(a=>a.dns); 189 } 190 auto aa(ref AminoAcidTable aat){ 191 return aat(seq); 192 } 193 } 194 195 static AminoAcidTable aat; 196 197 auto aaString(Range)(Range r){ 198 return r.map!(a=>a.toChar()); 199 } 200 auto aalString(Range)(Range r){ 201 return r.map!(a=>a.toString()).joiner(",\t"); 202 } 203 204 void main(string args[]){ 205 aat.initialize(); 206 DNS d=DNS(args[1]); 207 writeln(aat(d).aaString()); 208 }