1 module bio.sam.utils.recordparser; 2 3 #line 1 "sam_alignment.rl" 4 /* 5 This file is part of BioD. 6 Copyright (C) 2012 Artem Tarasov <lomereiter@gmail.com> 7 8 Permission is hereby granted, free of charge, to any person obtaining a 9 copy of this software and associated documentation files (the "Software"), 10 to deal in the Software without restriction, including without limitation 11 the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 and/or sell copies of the Software, and to permit persons to whom the 13 Software is furnished to do so, subject to the following conditions: 14 15 The above copyright notice and this permission notice shall be included in 16 all copies or substantial portions of the Software. 17 18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 DEALINGS IN THE SOFTWARE. 25 26 */ 27 28 #line 28 "sam_alignment.d" 29 static byte[] _sam_alignment_actions = [ 30 0, 1, 0, 1, 2, 1, 4, 1, 31 6, 1, 7, 1, 8, 1, 9, 1, 32 10, 1, 11, 1, 12, 1, 13, 1, 33 14, 1, 15, 1, 16, 1, 17, 1, 34 18, 1, 19, 1, 21, 1, 22, 1, 35 23, 1, 27, 1, 28, 1, 29, 1, 36 30, 1, 31, 1, 32, 1, 33, 1, 37 34, 1, 35, 1, 36, 1, 37, 1, 38 39, 1, 40, 1, 41, 1, 42, 1, 39 43, 1, 44, 1, 45, 1, 46, 1, 40 48, 1, 49, 1, 51, 1, 53, 1, 41 57, 1, 60, 1, 61, 1, 62, 1, 42 63, 1, 64, 2, 1, 2, 2, 3, 43 38, 2, 3, 58, 2, 5, 59, 2, 44 6, 7, 2, 20, 23, 2, 24, 25, 45 2, 26, 29, 2, 47, 50, 2, 55, 46 64, 2, 56, 64, 3, 3, 52, 64, 47 3, 3, 58, 64, 3, 5, 54, 64, 48 3, 5, 59, 64, 3, 26, 1, 2 49 50 ]; 51 52 static short[] _sam_alignment_key_offsets = [ 53 0, 0, 5, 7, 10, 15, 18, 20, 54 23, 25, 28, 31, 32, 36, 39, 41, 55 44, 48, 50, 53, 60, 61, 63, 67, 56 73, 74, 80, 81, 83, 84, 91, 92, 57 96, 98, 99, 106, 110, 112, 116, 118, 58 119, 120, 121, 122, 123, 129, 130, 132, 59 133, 140, 144, 146, 150, 152, 153, 154, 60 155, 156, 157, 161, 163, 170, 173, 176, 61 179, 182, 185, 188, 191, 194, 197, 200, 62 203, 206, 209, 212, 215, 218, 219, 222, 63 225, 228, 231, 234, 237, 240, 243, 246, 64 249, 252, 255, 258, 261, 264, 267, 268, 65 269, 270, 281, 292, 303, 314, 325, 336, 66 347, 358, 369, 380, 391, 402, 413, 424, 67 435, 446, 457, 466, 469, 472, 475, 478, 68 481, 484, 487, 490, 493, 496, 499, 502, 69 505, 508, 511, 514, 517, 518, 521, 524, 70 527, 530, 533, 536, 539, 542, 545, 548, 71 551, 554, 557, 560, 563, 566, 567, 568, 72 571, 574, 577, 580, 583, 586, 589, 592, 73 595, 598, 601, 604, 607, 610, 613, 616, 74 617, 622, 623, 624, 625, 626, 627, 628, 75 629, 630, 631, 632, 633, 634, 635, 636, 76 637, 638, 639, 640, 641, 642, 643, 644, 77 647, 648, 652, 656, 660, 664, 668, 672, 78 676, 680, 684, 688, 692, 696, 700, 704, 79 708, 712, 716, 718, 724, 728, 735, 737, 80 744, 747, 752, 755, 761, 762, 765, 768, 81 771, 774, 777, 780, 783, 786, 789, 792, 82 795, 798, 801, 804, 807, 810, 813, 814, 83 814, 814, 814, 814, 814, 814, 814, 814, 84 814, 814, 814, 814 85 ]; 86 87 static char[] _sam_alignment_trans_keys = [ 88 9u, 33u, 63u, 65u, 126u, 48u, 57u, 9u, 89 48u, 57u, 42u, 33u, 60u, 62u, 126u, 9u, 90 33u, 126u, 48u, 57u, 9u, 48u, 57u, 48u, 91 57u, 9u, 48u, 57u, 42u, 48u, 57u, 9u, 92 42u, 61u, 33u, 126u, 9u, 33u, 126u, 48u, 93 57u, 9u, 48u, 57u, 43u, 45u, 48u, 57u, 94 48u, 57u, 9u, 48u, 57u, 42u, 46u, 61u, 95 65u, 90u, 97u, 122u, 9u, 33u, 126u, 65u, 96 90u, 97u, 122u, 48u, 57u, 65u, 90u, 97u, 97 122u, 58u, 65u, 66u, 72u, 90u, 102u, 105u, 98 58u, 33u, 126u, 58u, 67u, 73u, 83u, 99u, 99 102u, 105u, 115u, 44u, 43u, 45u, 48u, 57u, 100 48u, 57u, 44u, 43u, 45u, 46u, 105u, 110u, 101 48u, 57u, 46u, 105u, 48u, 57u, 48u, 57u, 102 43u, 45u, 48u, 57u, 48u, 57u, 110u, 102u, 103 97u, 110u, 58u, 48u, 57u, 65u, 70u, 97u, 104 102u, 58u, 32u, 126u, 58u, 43u, 45u, 46u, 105 105u, 110u, 48u, 57u, 46u, 105u, 48u, 57u, 106 48u, 57u, 43u, 45u, 48u, 57u, 48u, 57u, 107 110u, 102u, 97u, 110u, 58u, 43u, 45u, 48u, 108 57u, 48u, 57u, 9u, 46u, 61u, 65u, 90u, 109 97u, 122u, 9u, 48u, 57u, 9u, 48u, 57u, 110 9u, 48u, 57u, 9u, 48u, 57u, 9u, 48u, 111 57u, 9u, 48u, 57u, 9u, 48u, 57u, 9u, 112 48u, 57u, 9u, 48u, 57u, 9u, 48u, 57u, 113 9u, 48u, 57u, 9u, 48u, 57u, 9u, 48u, 114 57u, 9u, 48u, 57u, 9u, 48u, 57u, 9u, 115 48u, 57u, 9u, 9u, 48u, 57u, 9u, 48u, 116 57u, 9u, 48u, 57u, 9u, 48u, 57u, 9u, 117 48u, 57u, 9u, 48u, 57u, 9u, 48u, 57u, 118 9u, 48u, 57u, 9u, 48u, 57u, 9u, 48u, 119 57u, 9u, 48u, 57u, 9u, 48u, 57u, 9u, 120 48u, 57u, 9u, 48u, 57u, 9u, 48u, 57u, 121 9u, 48u, 57u, 9u, 9u, 9u, 61u, 68u, 122 80u, 83u, 88u, 48u, 57u, 72u, 73u, 77u, 123 78u, 61u, 68u, 80u, 83u, 88u, 48u, 57u, 124 72u, 73u, 77u, 78u, 61u, 68u, 80u, 83u, 125 88u, 48u, 57u, 72u, 73u, 77u, 78u, 61u, 126 68u, 80u, 83u, 88u, 48u, 57u, 72u, 73u, 127 77u, 78u, 61u, 68u, 80u, 83u, 88u, 48u, 128 57u, 72u, 73u, 77u, 78u, 61u, 68u, 80u, 129 83u, 88u, 48u, 57u, 72u, 73u, 77u, 78u, 130 61u, 68u, 80u, 83u, 88u, 48u, 57u, 72u, 131 73u, 77u, 78u, 61u, 68u, 80u, 83u, 88u, 132 48u, 57u, 72u, 73u, 77u, 78u, 61u, 68u, 133 80u, 83u, 88u, 48u, 57u, 72u, 73u, 77u, 134 78u, 61u, 68u, 80u, 83u, 88u, 48u, 57u, 135 72u, 73u, 77u, 78u, 61u, 68u, 80u, 83u, 136 88u, 48u, 57u, 72u, 73u, 77u, 78u, 61u, 137 68u, 80u, 83u, 88u, 48u, 57u, 72u, 73u, 138 77u, 78u, 61u, 68u, 80u, 83u, 88u, 48u, 139 57u, 72u, 73u, 77u, 78u, 61u, 68u, 80u, 140 83u, 88u, 48u, 57u, 72u, 73u, 77u, 78u, 141 61u, 68u, 80u, 83u, 88u, 48u, 57u, 72u, 142 73u, 77u, 78u, 61u, 68u, 80u, 83u, 88u, 143 48u, 57u, 72u, 73u, 77u, 78u, 61u, 68u, 144 80u, 83u, 88u, 48u, 57u, 72u, 73u, 77u, 145 78u, 61u, 68u, 80u, 83u, 88u, 72u, 73u, 146 77u, 78u, 9u, 48u, 57u, 9u, 48u, 57u, 147 9u, 48u, 57u, 9u, 48u, 57u, 9u, 48u, 148 57u, 9u, 48u, 57u, 9u, 48u, 57u, 9u, 149 48u, 57u, 9u, 48u, 57u, 9u, 48u, 57u, 150 9u, 48u, 57u, 9u, 48u, 57u, 9u, 48u, 151 57u, 9u, 48u, 57u, 9u, 48u, 57u, 9u, 152 48u, 57u, 9u, 48u, 57u, 9u, 9u, 48u, 153 57u, 9u, 48u, 57u, 9u, 48u, 57u, 9u, 154 48u, 57u, 9u, 48u, 57u, 9u, 48u, 57u, 155 9u, 48u, 57u, 9u, 48u, 57u, 9u, 48u, 156 57u, 9u, 48u, 57u, 9u, 48u, 57u, 9u, 157 48u, 57u, 9u, 48u, 57u, 9u, 48u, 57u, 158 9u, 48u, 57u, 9u, 48u, 57u, 9u, 9u, 159 9u, 48u, 57u, 9u, 48u, 57u, 9u, 48u, 160 57u, 9u, 48u, 57u, 9u, 48u, 57u, 9u, 161 48u, 57u, 9u, 48u, 57u, 9u, 48u, 57u, 162 9u, 48u, 57u, 9u, 48u, 57u, 9u, 48u, 163 57u, 9u, 48u, 57u, 9u, 48u, 57u, 9u, 164 48u, 57u, 9u, 48u, 57u, 9u, 48u, 57u, 165 9u, 9u, 33u, 63u, 65u, 126u, 9u, 9u, 166 9u, 9u, 9u, 9u, 9u, 9u, 9u, 9u, 167 9u, 9u, 9u, 9u, 9u, 9u, 9u, 9u, 168 9u, 9u, 9u, 9u, 9u, 33u, 126u, 9u, 169 9u, 44u, 48u, 57u, 9u, 44u, 48u, 57u, 170 9u, 44u, 48u, 57u, 9u, 44u, 48u, 57u, 171 9u, 44u, 48u, 57u, 9u, 44u, 48u, 57u, 172 9u, 44u, 48u, 57u, 9u, 44u, 48u, 57u, 173 9u, 44u, 48u, 57u, 9u, 44u, 48u, 57u, 174 9u, 44u, 48u, 57u, 9u, 44u, 48u, 57u, 175 9u, 44u, 48u, 57u, 9u, 44u, 48u, 57u, 176 9u, 44u, 48u, 57u, 9u, 44u, 48u, 57u, 177 9u, 44u, 48u, 57u, 9u, 44u, 9u, 44u, 178 69u, 101u, 48u, 57u, 9u, 44u, 48u, 57u, 179 9u, 44u, 46u, 69u, 101u, 48u, 57u, 9u, 180 44u, 9u, 48u, 57u, 65u, 70u, 97u, 102u, 181 9u, 32u, 126u, 9u, 69u, 101u, 48u, 57u, 182 9u, 48u, 57u, 9u, 46u, 69u, 101u, 48u, 183 57u, 9u, 9u, 48u, 57u, 9u, 48u, 57u, 184 9u, 48u, 57u, 9u, 48u, 57u, 9u, 48u, 185 57u, 9u, 48u, 57u, 9u, 48u, 57u, 9u, 186 48u, 57u, 9u, 48u, 57u, 9u, 48u, 57u, 187 9u, 48u, 57u, 9u, 48u, 57u, 9u, 48u, 188 57u, 9u, 48u, 57u, 9u, 48u, 57u, 9u, 189 48u, 57u, 9u, 48u, 57u, 9u, 9u, 0 190 ]; 191 192 static byte[] _sam_alignment_single_lengths = [ 193 0, 1, 0, 1, 1, 1, 0, 1, 194 0, 1, 1, 1, 2, 1, 0, 1, 195 2, 0, 1, 3, 1, 0, 0, 0, 196 1, 6, 1, 0, 1, 7, 1, 2, 197 0, 1, 5, 2, 0, 2, 0, 1, 198 1, 1, 1, 1, 0, 1, 0, 1, 199 5, 2, 0, 2, 0, 1, 1, 1, 200 1, 1, 2, 0, 3, 1, 1, 1, 201 1, 1, 1, 1, 1, 1, 1, 1, 202 1, 1, 1, 1, 1, 1, 1, 1, 203 1, 1, 1, 1, 1, 1, 1, 1, 204 1, 1, 1, 1, 1, 1, 1, 1, 205 1, 5, 5, 5, 5, 5, 5, 5, 206 5, 5, 5, 5, 5, 5, 5, 5, 207 5, 5, 5, 1, 1, 1, 1, 1, 208 1, 1, 1, 1, 1, 1, 1, 1, 209 1, 1, 1, 1, 1, 1, 1, 1, 210 1, 1, 1, 1, 1, 1, 1, 1, 211 1, 1, 1, 1, 1, 1, 1, 1, 212 1, 1, 1, 1, 1, 1, 1, 1, 213 1, 1, 1, 1, 1, 1, 1, 1, 214 1, 1, 1, 1, 1, 1, 1, 1, 215 1, 1, 1, 1, 1, 1, 1, 1, 216 1, 1, 1, 1, 1, 1, 1, 1, 217 1, 2, 2, 2, 2, 2, 2, 2, 218 2, 2, 2, 2, 2, 2, 2, 2, 219 2, 2, 2, 4, 2, 5, 2, 1, 220 1, 3, 1, 4, 1, 1, 1, 1, 221 1, 1, 1, 1, 1, 1, 1, 1, 222 1, 1, 1, 1, 1, 1, 1, 0, 223 0, 0, 0, 0, 0, 0, 0, 0, 224 0, 0, 0, 1 225 ]; 226 227 static byte[] _sam_alignment_range_lengths = [ 228 0, 2, 1, 1, 2, 1, 1, 1, 229 1, 1, 1, 0, 1, 1, 1, 1, 230 1, 1, 1, 2, 0, 1, 2, 3, 231 0, 0, 0, 1, 0, 0, 0, 1, 232 1, 0, 1, 1, 1, 1, 1, 0, 233 0, 0, 0, 0, 3, 0, 1, 0, 234 1, 1, 1, 1, 1, 0, 0, 0, 235 0, 0, 1, 1, 2, 1, 1, 1, 236 1, 1, 1, 1, 1, 1, 1, 1, 237 1, 1, 1, 1, 1, 0, 1, 1, 238 1, 1, 1, 1, 1, 1, 1, 1, 239 1, 1, 1, 1, 1, 1, 0, 0, 240 0, 3, 3, 3, 3, 3, 3, 3, 241 3, 3, 3, 3, 3, 3, 3, 3, 242 3, 3, 2, 1, 1, 1, 1, 1, 243 1, 1, 1, 1, 1, 1, 1, 1, 244 1, 1, 1, 1, 0, 1, 1, 1, 245 1, 1, 1, 1, 1, 1, 1, 1, 246 1, 1, 1, 1, 1, 0, 0, 1, 247 1, 1, 1, 1, 1, 1, 1, 1, 248 1, 1, 1, 1, 1, 1, 1, 0, 249 2, 0, 0, 0, 0, 0, 0, 0, 250 0, 0, 0, 0, 0, 0, 0, 0, 251 0, 0, 0, 0, 0, 0, 0, 1, 252 0, 1, 1, 1, 1, 1, 1, 1, 253 1, 1, 1, 1, 1, 1, 1, 1, 254 1, 1, 0, 1, 1, 1, 0, 3, 255 1, 1, 1, 1, 0, 1, 1, 1, 256 1, 1, 1, 1, 1, 1, 1, 1, 257 1, 1, 1, 1, 1, 1, 0, 0, 258 0, 0, 0, 0, 0, 0, 0, 0, 259 0, 0, 0, 0 260 ]; 261 262 static short[] _sam_alignment_index_offsets = [ 263 0, 0, 4, 6, 9, 13, 16, 18, 264 21, 23, 26, 29, 31, 35, 38, 40, 265 43, 47, 49, 52, 58, 60, 62, 65, 266 69, 71, 78, 80, 82, 84, 92, 94, 267 98, 100, 102, 109, 113, 115, 119, 121, 268 123, 125, 127, 129, 131, 135, 137, 139, 269 141, 148, 152, 154, 158, 160, 162, 164, 270 166, 168, 170, 174, 176, 182, 185, 188, 271 191, 194, 197, 200, 203, 206, 209, 212, 272 215, 218, 221, 224, 227, 230, 232, 235, 273 238, 241, 244, 247, 250, 253, 256, 259, 274 262, 265, 268, 271, 274, 277, 280, 282, 275 284, 286, 295, 304, 313, 322, 331, 340, 276 349, 358, 367, 376, 385, 394, 403, 412, 277 421, 430, 439, 447, 450, 453, 456, 459, 278 462, 465, 468, 471, 474, 477, 480, 483, 279 486, 489, 492, 495, 498, 500, 503, 506, 280 509, 512, 515, 518, 521, 524, 527, 530, 281 533, 536, 539, 542, 545, 548, 550, 552, 282 555, 558, 561, 564, 567, 570, 573, 576, 283 579, 582, 585, 588, 591, 594, 597, 600, 284 602, 606, 608, 610, 612, 614, 616, 618, 285 620, 622, 624, 626, 628, 630, 632, 634, 286 636, 638, 640, 642, 644, 646, 648, 650, 287 653, 655, 659, 663, 667, 671, 675, 679, 288 683, 687, 691, 695, 699, 703, 707, 711, 289 715, 719, 723, 726, 732, 736, 743, 746, 290 751, 754, 759, 762, 768, 770, 773, 776, 291 779, 782, 785, 788, 791, 794, 797, 800, 292 803, 806, 809, 812, 815, 818, 821, 823, 293 824, 825, 826, 827, 828, 829, 830, 831, 294 832, 833, 834, 835 295 ]; 296 297 static ubyte[] _sam_alignment_trans_targs = [ 298 2, 168, 168, 0, 3, 0, 4, 151, 299 0, 150, 5, 5, 0, 6, 5, 0, 300 7, 0, 8, 133, 0, 9, 0, 10, 301 116, 0, 11, 97, 0, 12, 0, 95, 302 96, 13, 0, 14, 13, 0, 15, 0, 303 16, 78, 0, 17, 17, 18, 0, 18, 304 0, 19, 61, 0, 20, 60, 60, 60, 305 60, 0, 21, 0, 191, 0, 23, 23, 306 0, 24, 24, 24, 0, 25, 0, 26, 307 28, 43, 45, 47, 57, 0, 27, 0, 308 192, 0, 29, 0, 30, 30, 30, 30, 309 33, 30, 30, 0, 31, 0, 32, 32, 310 193, 0, 193, 0, 34, 0, 35, 35, 311 36, 39, 41, 213, 0, 36, 39, 213, 312 0, 211, 0, 38, 38, 212, 0, 212, 313 0, 40, 0, 214, 0, 42, 0, 214, 314 0, 44, 0, 215, 215, 215, 0, 46, 315 0, 216, 0, 48, 0, 49, 49, 50, 316 53, 55, 219, 0, 50, 53, 219, 0, 317 217, 0, 52, 52, 218, 0, 218, 0, 318 54, 0, 220, 0, 56, 0, 220, 0, 319 58, 0, 59, 59, 221, 0, 221, 0, 320 21, 60, 60, 60, 60, 0, 19, 62, 321 0, 19, 63, 0, 19, 64, 0, 19, 322 65, 0, 19, 66, 0, 19, 67, 0, 323 19, 68, 0, 19, 69, 0, 19, 70, 324 0, 19, 71, 0, 19, 72, 0, 19, 325 73, 0, 19, 74, 0, 19, 75, 0, 326 19, 76, 0, 19, 77, 0, 19, 0, 327 16, 79, 0, 16, 80, 0, 16, 81, 328 0, 16, 82, 0, 16, 83, 0, 16, 329 84, 0, 16, 85, 0, 16, 86, 0, 330 16, 87, 0, 16, 88, 0, 16, 89, 331 0, 16, 90, 0, 16, 91, 0, 16, 332 92, 0, 16, 93, 0, 16, 94, 0, 333 16, 0, 14, 0, 14, 0, 115, 115, 334 115, 115, 115, 98, 115, 115, 0, 115, 335 115, 115, 115, 115, 99, 115, 115, 0, 336 115, 115, 115, 115, 115, 100, 115, 115, 337 0, 115, 115, 115, 115, 115, 101, 115, 338 115, 0, 115, 115, 115, 115, 115, 102, 339 115, 115, 0, 115, 115, 115, 115, 115, 340 103, 115, 115, 0, 115, 115, 115, 115, 341 115, 104, 115, 115, 0, 115, 115, 115, 342 115, 115, 105, 115, 115, 0, 115, 115, 343 115, 115, 115, 106, 115, 115, 0, 115, 344 115, 115, 115, 115, 107, 115, 115, 0, 345 115, 115, 115, 115, 115, 108, 115, 115, 346 0, 115, 115, 115, 115, 115, 109, 115, 347 115, 0, 115, 115, 115, 115, 115, 110, 348 115, 115, 0, 115, 115, 115, 115, 115, 349 111, 115, 115, 0, 115, 115, 115, 115, 350 115, 112, 115, 115, 0, 115, 115, 115, 351 115, 115, 113, 115, 115, 0, 115, 115, 352 115, 115, 115, 114, 115, 115, 0, 115, 353 115, 115, 115, 115, 115, 115, 0, 12, 354 97, 0, 10, 117, 0, 10, 118, 0, 355 10, 119, 0, 10, 120, 0, 10, 121, 356 0, 10, 122, 0, 10, 123, 0, 10, 357 124, 0, 10, 125, 0, 10, 126, 0, 358 10, 127, 0, 10, 128, 0, 10, 129, 359 0, 10, 130, 0, 10, 131, 0, 10, 360 132, 0, 10, 0, 8, 134, 0, 8, 361 135, 0, 8, 136, 0, 8, 137, 0, 362 8, 138, 0, 8, 139, 0, 8, 140, 363 0, 8, 141, 0, 8, 142, 0, 8, 364 143, 0, 8, 144, 0, 8, 145, 0, 365 8, 146, 0, 8, 147, 0, 8, 148, 366 0, 8, 149, 0, 8, 0, 6, 0, 367 4, 152, 0, 4, 153, 0, 4, 154, 368 0, 4, 155, 0, 4, 156, 0, 4, 369 157, 0, 4, 158, 0, 4, 159, 0, 370 4, 160, 0, 4, 161, 0, 4, 162, 371 0, 4, 163, 0, 4, 164, 0, 4, 372 165, 0, 4, 166, 0, 4, 167, 0, 373 4, 0, 2, 168, 168, 0, 239, 169, 374 240, 170, 241, 171, 242, 172, 243, 173, 375 244, 174, 245, 175, 246, 176, 247, 177, 376 248, 178, 249, 179, 250, 180, 2, 0, 377 4, 0, 6, 0, 8, 0, 10, 0, 378 12, 0, 14, 0, 16, 0, 19, 0, 379 21, 0, 22, 191, 0, 22, 0, 22, 380 31, 194, 0, 22, 31, 195, 0, 22, 381 31, 196, 0, 22, 31, 197, 0, 22, 382 31, 198, 0, 22, 31, 199, 0, 22, 383 31, 200, 0, 22, 31, 201, 0, 22, 384 31, 202, 0, 22, 31, 203, 0, 22, 385 31, 204, 0, 22, 31, 205, 0, 22, 386 31, 206, 0, 22, 31, 207, 0, 22, 387 31, 208, 0, 22, 31, 209, 0, 22, 388 31, 210, 0, 22, 31, 0, 22, 34, 389 37, 37, 211, 0, 22, 34, 212, 0, 390 22, 34, 36, 37, 37, 213, 0, 22, 391 34, 0, 22, 215, 215, 215, 0, 22, 392 216, 0, 22, 51, 51, 217, 0, 22, 393 218, 0, 22, 50, 51, 51, 219, 0, 394 22, 0, 22, 222, 0, 22, 223, 0, 395 22, 224, 0, 22, 225, 0, 22, 226, 396 0, 22, 227, 0, 22, 228, 0, 22, 397 229, 0, 22, 230, 0, 22, 231, 0, 398 22, 232, 0, 22, 233, 0, 22, 234, 399 0, 22, 235, 0, 22, 236, 0, 22, 400 237, 0, 22, 238, 0, 22, 0, 0, 401 0, 0, 0, 0, 0, 0, 0, 0, 402 0, 0, 0, 22, 0, 0 403 ]; 404 405 static ubyte[] _sam_alignment_trans_actions = [ 406 111, 7, 7, 11, 99, 17, 15, 3, 407 17, 0, 21, 21, 25, 23, 0, 25, 408 99, 31, 29, 3, 31, 99, 35, 114, 409 3, 35, 0, 99, 41, 45, 41, 0, 410 0, 49, 53, 51, 0, 53, 99, 59, 411 57, 3, 59, 1, 1, 99, 63, 99, 412 63, 102, 3, 63, 0, 67, 67, 67, 413 67, 71, 75, 71, 77, 79, 89, 89, 414 0, 0, 0, 0, 0, 91, 0, 0, 415 0, 0, 0, 0, 0, 93, 0, 93, 416 83, 93, 0, 93, 87, 87, 87, 87, 417 87, 87, 87, 93, 0, 93, 1, 1, 418 99, 93, 99, 93, 0, 93, 5, 5, 419 5, 5, 5, 5, 93, 0, 0, 0, 420 93, 0, 93, 0, 0, 0, 93, 0, 421 93, 0, 93, 0, 93, 0, 93, 0, 422 93, 0, 93, 85, 85, 85, 93, 0, 423 93, 85, 93, 0, 93, 5, 5, 5, 424 5, 5, 5, 93, 0, 0, 0, 93, 425 0, 93, 0, 0, 0, 93, 0, 93, 426 0, 93, 0, 93, 0, 93, 0, 93, 427 0, 93, 1, 1, 99, 93, 99, 93, 428 69, 0, 0, 0, 0, 71, 102, 3, 429 63, 102, 3, 63, 102, 3, 63, 102, 430 3, 63, 102, 3, 63, 102, 3, 63, 431 102, 3, 63, 102, 3, 63, 102, 3, 432 63, 102, 3, 63, 102, 3, 63, 102, 433 3, 63, 102, 3, 63, 102, 3, 63, 434 102, 3, 63, 102, 3, 63, 102, 63, 435 57, 3, 59, 57, 3, 59, 57, 3, 436 59, 57, 3, 59, 57, 3, 59, 57, 437 3, 59, 57, 3, 59, 57, 3, 59, 438 57, 3, 59, 57, 3, 59, 57, 3, 439 59, 57, 3, 59, 57, 3, 59, 57, 440 3, 59, 57, 3, 59, 57, 3, 59, 441 57, 59, 0, 53, 47, 53, 117, 117, 442 117, 117, 117, 3, 117, 117, 41, 117, 443 117, 117, 117, 117, 3, 117, 117, 41, 444 117, 117, 117, 117, 117, 3, 117, 117, 445 41, 117, 117, 117, 117, 117, 3, 117, 446 117, 41, 117, 117, 117, 117, 117, 3, 447 117, 117, 41, 117, 117, 117, 117, 117, 448 3, 117, 117, 41, 117, 117, 117, 117, 449 117, 3, 117, 117, 41, 117, 117, 117, 450 117, 117, 3, 117, 117, 41, 117, 117, 451 117, 117, 117, 3, 117, 117, 41, 117, 452 117, 117, 117, 117, 3, 117, 117, 41, 453 117, 117, 117, 117, 117, 3, 117, 117, 454 41, 117, 117, 117, 117, 117, 3, 117, 455 117, 41, 117, 117, 117, 117, 117, 3, 456 117, 117, 41, 117, 117, 117, 117, 117, 457 3, 117, 117, 41, 117, 117, 117, 117, 458 117, 3, 117, 117, 41, 117, 117, 117, 459 117, 117, 3, 117, 117, 41, 117, 117, 460 117, 117, 117, 3, 117, 117, 41, 117, 461 117, 117, 117, 117, 117, 117, 41, 120, 462 148, 41, 114, 3, 35, 114, 3, 35, 463 114, 3, 35, 114, 3, 35, 114, 3, 464 35, 114, 3, 35, 114, 3, 35, 114, 465 3, 35, 114, 3, 35, 114, 3, 35, 466 114, 3, 35, 114, 3, 35, 114, 3, 467 35, 114, 3, 35, 114, 3, 35, 114, 468 3, 35, 114, 35, 29, 3, 31, 29, 469 3, 31, 29, 3, 31, 29, 3, 31, 470 29, 3, 31, 29, 3, 31, 29, 3, 471 31, 29, 3, 31, 29, 3, 31, 29, 472 3, 31, 29, 3, 31, 29, 3, 31, 473 29, 3, 31, 29, 3, 31, 29, 3, 474 31, 29, 3, 31, 29, 31, 0, 25, 475 15, 3, 17, 15, 3, 17, 15, 3, 476 17, 15, 3, 17, 15, 3, 17, 15, 477 3, 17, 15, 3, 17, 15, 3, 17, 478 15, 3, 17, 15, 3, 17, 15, 3, 479 17, 15, 3, 17, 15, 3, 17, 15, 480 3, 17, 15, 3, 17, 15, 3, 17, 481 15, 17, 9, 0, 0, 11, 13, 0, 482 19, 0, 27, 0, 33, 0, 37, 0, 483 43, 0, 55, 0, 61, 0, 65, 0, 484 73, 0, 81, 0, 95, 0, 0, 0, 485 0, 0, 0, 0, 0, 0, 39, 0, 486 45, 0, 0, 0, 0, 0, 0, 0, 487 0, 0, 123, 77, 79, 97, 93, 136, 488 105, 3, 93, 136, 105, 3, 93, 136, 489 105, 3, 93, 136, 105, 3, 93, 136, 490 105, 3, 93, 136, 105, 3, 93, 136, 491 105, 3, 93, 136, 105, 3, 93, 136, 492 105, 3, 93, 136, 105, 3, 93, 136, 493 105, 3, 93, 136, 105, 3, 93, 136, 494 105, 3, 93, 136, 105, 3, 93, 136, 495 105, 3, 93, 136, 105, 3, 93, 136, 496 105, 3, 93, 136, 105, 93, 144, 108, 497 0, 0, 0, 93, 144, 108, 0, 93, 498 144, 108, 0, 0, 0, 0, 93, 144, 499 108, 93, 129, 0, 0, 0, 93, 126, 500 0, 93, 140, 0, 0, 0, 93, 140, 501 0, 93, 140, 0, 0, 0, 0, 93, 502 140, 93, 132, 3, 93, 132, 3, 93, 503 132, 3, 93, 132, 3, 93, 132, 3, 504 93, 132, 3, 93, 132, 3, 93, 132, 505 3, 93, 132, 3, 93, 132, 3, 93, 506 132, 3, 93, 132, 3, 93, 132, 3, 507 93, 132, 3, 93, 132, 3, 93, 132, 508 3, 93, 132, 3, 93, 132, 93, 0, 509 0, 0, 0, 0, 0, 0, 0, 0, 510 0, 0, 0, 0, 0, 0 511 ]; 512 513 static ubyte[] _sam_alignment_eof_actions = [ 514 0, 11, 17, 17, 25, 25, 31, 31, 515 35, 35, 41, 41, 53, 53, 59, 59, 516 63, 63, 63, 71, 71, 79, 0, 0, 517 0, 93, 93, 93, 93, 93, 93, 93, 518 93, 93, 93, 93, 93, 93, 93, 93, 519 93, 93, 93, 93, 93, 93, 93, 93, 520 93, 93, 93, 93, 93, 93, 93, 93, 521 93, 93, 93, 93, 71, 63, 63, 63, 522 63, 63, 63, 63, 63, 63, 63, 63, 523 63, 63, 63, 63, 63, 63, 59, 59, 524 59, 59, 59, 59, 59, 59, 59, 59, 525 59, 59, 59, 59, 59, 59, 59, 53, 526 53, 41, 41, 41, 41, 41, 41, 41, 527 41, 41, 41, 41, 41, 41, 41, 41, 528 41, 41, 41, 41, 35, 35, 35, 35, 529 35, 35, 35, 35, 35, 35, 35, 35, 530 35, 35, 35, 35, 35, 31, 31, 31, 531 31, 31, 31, 31, 31, 31, 31, 31, 532 31, 31, 31, 31, 31, 31, 25, 17, 533 17, 17, 17, 17, 17, 17, 17, 17, 534 17, 17, 17, 17, 17, 17, 17, 17, 535 11, 0, 0, 0, 0, 0, 0, 0, 536 0, 0, 0, 0, 0, 0, 0, 0, 537 0, 0, 0, 0, 0, 0, 0, 123, 538 97, 136, 136, 136, 136, 136, 136, 136, 539 136, 136, 136, 136, 136, 136, 136, 136, 540 136, 136, 136, 144, 144, 144, 144, 129, 541 126, 140, 140, 140, 140, 132, 132, 132, 542 132, 132, 132, 132, 132, 132, 132, 132, 543 132, 132, 132, 132, 132, 132, 132, 0, 544 0, 0, 0, 0, 0, 0, 0, 0, 545 0, 0, 0, 0 546 ]; 547 548 static int sam_alignment_start = 1; 549 static int sam_alignment_first_final = 191; 550 static int sam_alignment_error = 0; 551 552 static int sam_alignment_en_recover_from_invalid_qname = 169; 553 static int sam_alignment_en_recover_from_invalid_flag = 170; 554 static int sam_alignment_en_recover_from_invalid_rname = 171; 555 static int sam_alignment_en_recover_from_invalid_pos = 172; 556 static int sam_alignment_en_recover_from_invalid_mapq = 173; 557 static int sam_alignment_en_recover_from_invalid_cigar = 174; 558 static int sam_alignment_en_recover_from_invalid_rnext = 175; 559 static int sam_alignment_en_recover_from_invalid_pnext = 176; 560 static int sam_alignment_en_recover_from_invalid_tlen = 177; 561 static int sam_alignment_en_recover_from_invalid_seq = 178; 562 static int sam_alignment_en_recover_from_invalid_qual = 179; 563 static int sam_alignment_en_recover_from_invalid_tag = 180; 564 static int sam_alignment_en_alignment = 1; 565 static int sam_alignment_en_alignment_field_parsing_mandatoryfields_flag_parsing = 181; 566 static int sam_alignment_en_alignment_field_parsing_mandatoryfields_rname_parsing = 182; 567 static int sam_alignment_en_alignment_field_parsing_mandatoryfields_pos_parsing = 183; 568 static int sam_alignment_en_alignment_field_parsing_mandatoryfields_mapq_parsing = 184; 569 static int sam_alignment_en_alignment_field_parsing_mandatoryfields_cigar_parsing = 185; 570 static int sam_alignment_en_alignment_field_parsing_mandatoryfields_rnext_parsing = 186; 571 static int sam_alignment_en_alignment_field_parsing_mandatoryfields_pnext_parsing = 187; 572 static int sam_alignment_en_alignment_field_parsing_mandatoryfields_tlen_parsing = 188; 573 static int sam_alignment_en_alignment_field_parsing_mandatoryfields_seq_parsing = 189; 574 static int sam_alignment_en_alignment_field_parsing_mandatoryfields_qual_parsing = 190; 575 static int sam_alignment_en_alignment_tag_parsing = 251; 576 577 578 #line 419 "sam_alignment.rl" 579 580 581 import bio.sam.header; 582 import bio.bam.cigar; 583 import bio.bam.read; 584 import bio.bam.bai.bin; 585 import bio.core.utils.outbuffer; 586 import bio.core.base; 587 import std.conv; 588 import std.array; 589 import std.exception; 590 591 BamRead parseAlignmentLine(string line, SamHeader header, OutBuffer buffer=null) { 592 char* p = cast(char*)line.ptr; 593 char* pe = p + line.length; 594 char* eof = pe; 595 int cs; 596 597 if (buffer is null) 598 buffer = new OutBuffer(8192); 599 else 600 buffer.clear(); 601 602 size_t rollback_size; // needed in case of invalid data 603 604 byte current_sign = 1; 605 606 size_t read_name_beg; // position of beginning of QNAME 607 608 size_t sequence_beg; // position of SEQ start 609 int l_seq; // sequence length 610 611 uint cigar_op_len; // length of CIGAR operation 612 char cigar_op_chr; // CIGAR operation 613 614 size_t quals_length; // number of QUAL characters 615 char quals_last_char; // needed in order to handle '*' correctly 616 617 size_t cigar_op_len_start; // position of start of CIGAR operation 618 619 long int_value; // for storing temporary integers 620 float float_value; // for storing temporary floats 621 size_t float_beg; // position of start of current float 622 char arraytype; // type of last array tag value 623 size_t tag_array_length_offset; // where the length is stored in the buffer 624 625 string read_name; 626 ushort flag; 627 int pos = -1; 628 int end_pos; // for bin calculation 629 int mate_pos = -1; 630 ubyte mapping_quality = 255; 631 int template_length = 0; 632 633 size_t tag_key_beg, tagvalue_beg; 634 ubyte[] tag_key; 635 size_t rname_beg, rnext_beg; 636 637 int ref_id = -1; 638 639 640 #line 640 "sam_alignment.d" 641 { 642 cs = sam_alignment_start; 643 } 644 645 #line 480 "sam_alignment.rl" 646 647 #line 647 "sam_alignment.d" 648 { 649 int _klen; 650 uint _trans; 651 byte* _acts; 652 uint _nacts; 653 char* _keys; 654 655 if ( p == pe ) 656 goto _test_eof; 657 if ( cs == 0 ) 658 goto _out; 659 _resume: 660 _keys = &_sam_alignment_trans_keys[_sam_alignment_key_offsets[cs]]; 661 _trans = _sam_alignment_index_offsets[cs]; 662 663 _klen = _sam_alignment_single_lengths[cs]; 664 if ( _klen > 0 ) { 665 char* _lower = _keys; 666 char* _mid; 667 char* _upper = _keys + _klen - 1; 668 while (1) { 669 if ( _upper < _lower ) 670 break; 671 672 _mid = _lower + ((_upper-_lower) >> 1); 673 if ( (*p) < *_mid ) 674 _upper = _mid - 1; 675 else if ( (*p) > *_mid ) 676 _lower = _mid + 1; 677 else { 678 _trans += cast(uint)(_mid - _keys); 679 goto _match; 680 } 681 } 682 _keys += _klen; 683 _trans += _klen; 684 } 685 686 _klen = _sam_alignment_range_lengths[cs]; 687 if ( _klen > 0 ) { 688 char* _lower = _keys; 689 char* _mid; 690 char* _upper = _keys + (_klen<<1) - 2; 691 while (1) { 692 if ( _upper < _lower ) 693 break; 694 695 _mid = _lower + (((_upper-_lower) >> 1) & ~1); 696 if ( (*p) < _mid[0] ) 697 _upper = _mid - 2; 698 else if ( (*p) > _mid[1] ) 699 _lower = _mid + 2; 700 else { 701 _trans += cast(uint)((_mid - _keys)>>1); 702 goto _match; 703 } 704 } 705 _trans += _klen; 706 } 707 708 _match: 709 cs = _sam_alignment_trans_targs[_trans]; 710 711 if ( _sam_alignment_trans_actions[_trans] == 0 ) 712 goto _again; 713 714 _acts = &_sam_alignment_actions[_sam_alignment_trans_actions[_trans]]; 715 _nacts = cast(uint) *_acts++; 716 while ( _nacts-- > 0 ) 717 { 718 switch ( *_acts++ ) 719 { 720 case 0: 721 #line 27 "sam_alignment.rl" 722 { current_sign = (*p) == '-' ? -1 : 1; } 723 break; 724 case 1: 725 #line 28 "sam_alignment.rl" 726 { int_value = 0; } 727 break; 728 case 2: 729 #line 29 "sam_alignment.rl" 730 { int_value *= 10; int_value += (*p) - '0'; } 731 break; 732 case 3: 733 #line 30 "sam_alignment.rl" 734 { int_value *= current_sign; current_sign = 1; } 735 break; 736 case 4: 737 #line 37 "sam_alignment.rl" 738 { float_beg = p - line.ptr; } 739 break; 740 case 5: 741 #line 38 "sam_alignment.rl" 742 { 743 float_value = to!float(line[float_beg .. p - line.ptr]); 744 } 745 break; 746 case 6: 747 #line 48 "sam_alignment.rl" 748 { read_name_beg = p - line.ptr; } 749 break; 750 case 7: 751 #line 49 "sam_alignment.rl" 752 { read_name = line[read_name_beg .. p - line.ptr]; } 753 break; 754 case 8: 755 #line 50 "sam_alignment.rl" 756 { p--; {cs = 169; if (true) goto _again;} } 757 break; 758 case 9: 759 #line 51 "sam_alignment.rl" 760 { p--; {cs = 181; if (true) goto _again;} } 761 break; 762 case 10: 763 #line 56 "sam_alignment.rl" 764 { flag = to!ushort(int_value); } 765 break; 766 case 11: 767 #line 58 "sam_alignment.rl" 768 { p--; {cs = 170; if (true) goto _again;} } 769 break; 770 case 12: 771 #line 59 "sam_alignment.rl" 772 { p--; {cs = 182; if (true) goto _again;} } 773 break; 774 case 13: 775 #line 62 "sam_alignment.rl" 776 { rname_beg = p - line.ptr; } 777 break; 778 case 14: 779 #line 63 "sam_alignment.rl" 780 { 781 ref_id = header.getSequenceIndex(line[rname_beg .. p - line.ptr]); 782 } 783 break; 784 case 15: 785 #line 67 "sam_alignment.rl" 786 { p--; {cs = 171; if (true) goto _again;} } 787 break; 788 case 16: 789 #line 68 "sam_alignment.rl" 790 { p--; {cs = 183; if (true) goto _again;} } 791 break; 792 case 17: 793 #line 73 "sam_alignment.rl" 794 { end_pos = pos = to!uint(int_value); } 795 break; 796 case 18: 797 #line 75 "sam_alignment.rl" 798 { p--; {cs = 172; if (true) goto _again;} } 799 break; 800 case 19: 801 #line 76 "sam_alignment.rl" 802 { p--; {cs = 184; if (true) goto _again;} } 803 break; 804 case 20: 805 #line 79 "sam_alignment.rl" 806 { mapping_quality = to!ubyte(int_value); } 807 break; 808 case 21: 809 #line 81 "sam_alignment.rl" 810 { p--; {cs = 173; if (true) goto _again;} } 811 break; 812 case 22: 813 #line 82 "sam_alignment.rl" 814 { p--; {cs = 185; if (true) goto _again;} } 815 break; 816 case 23: 817 #line 85 "sam_alignment.rl" 818 { 819 buffer.capacity = 32 + read_name.length + 1; 820 buffer.putUnsafe!int(ref_id); 821 buffer.putUnsafe!int(pos - 1); 822 823 enforce(read_name.length + 1 <= 255, "Read name " ~ read_name ~ " is too long!"); 824 825 // bin will be set later 826 auto bin_mq_nl = ((cast(uint)mapping_quality) << 8) | (read_name.length + 1); 827 buffer.putUnsafe(cast(uint)bin_mq_nl); 828 829 // number of CIGAR operations will be set later 830 buffer.putUnsafe!uint(flag << 16); 831 832 buffer.putUnsafe!int(0); 833 buffer.putUnsafe!int(-1); // mate ref. id 834 buffer.putUnsafe!int(-1); // mate pos 835 buffer.putUnsafe!int(0); // tlen 836 837 buffer.putUnsafe(cast(ubyte[])read_name); 838 buffer.putUnsafe!ubyte(0); 839 840 rollback_size = buffer.length; 841 } 842 break; 843 case 24: 844 #line 111 "sam_alignment.rl" 845 { cigar_op_len = to!uint(int_value); } 846 break; 847 case 25: 848 #line 112 "sam_alignment.rl" 849 { cigar_op_chr = (*p); } 850 break; 851 case 26: 852 #line 113 "sam_alignment.rl" 853 { 854 auto op = CigarOperation(cigar_op_len, cigar_op_chr); 855 if (op.is_reference_consuming) 856 end_pos += op.length; 857 buffer.put!CigarOperation(op); 858 { 859 auto ptr = cast(uint*)(buffer.data.ptr + 3 * uint.sizeof); 860 *ptr = (*ptr) + 1; 861 } 862 } 863 break; 864 case 27: 865 #line 124 "sam_alignment.rl" 866 { 867 auto ptr = cast(uint*)(buffer.data.ptr + 3 * uint.sizeof); 868 *ptr = (*ptr) & 0xFFFF0000; 869 buffer.shrink(rollback_size); 870 end_pos = pos + 1; 871 p--; {cs = 174; if (true) goto _again;} 872 } 873 break; 874 case 28: 875 #line 131 "sam_alignment.rl" 876 { p--; {cs = 186; if (true) goto _again;} } 877 break; 878 case 29: 879 #line 137 "sam_alignment.rl" 880 { 881 if (end_pos == pos) 882 ++end_pos; 883 { 884 auto bin = reg2bin(pos - 1, end_pos - 1); // 0-based [) interval 885 auto ptr = cast(uint*)(buffer.data.ptr + 2 * uint.sizeof); 886 *ptr = (*ptr) | ((cast(uint)bin) << 16); 887 } 888 } 889 break; 890 case 30: 891 #line 148 "sam_alignment.rl" 892 { 893 { 894 auto ptr = cast(int*)(buffer.data.ptr + 5 * int.sizeof); 895 *ptr = ref_id; 896 } 897 } 898 break; 899 case 31: 900 #line 155 "sam_alignment.rl" 901 { rnext_beg = p - line.ptr; } 902 break; 903 case 32: 904 #line 156 "sam_alignment.rl" 905 { 906 { 907 auto ptr = cast(int*)(buffer.data.ptr + 5 * int.sizeof); 908 *ptr = header.getSequenceIndex(line[rnext_beg .. p - line.ptr]); 909 } 910 } 911 break; 912 case 33: 913 #line 162 "sam_alignment.rl" 914 { p--; {cs = 175; if (true) goto _again;} } 915 break; 916 case 34: 917 #line 163 "sam_alignment.rl" 918 { p--; {cs = 187; if (true) goto _again;} } 919 break; 920 case 35: 921 #line 169 "sam_alignment.rl" 922 { 923 { 924 auto ptr = cast(int*)(buffer.data.ptr + 6 * int.sizeof); 925 *ptr = to!int(int_value) - 1; 926 } 927 } 928 break; 929 case 36: 930 #line 175 "sam_alignment.rl" 931 { p--; {cs = 176; if (true) goto _again;} } 932 break; 933 case 37: 934 #line 176 "sam_alignment.rl" 935 { p--; {cs = 188; if (true) goto _again;} } 936 break; 937 case 38: 938 #line 181 "sam_alignment.rl" 939 { 940 { 941 auto ptr = cast(int*)(buffer.data.ptr + 7 * int.sizeof); 942 *ptr = to!int(int_value); 943 } 944 } 945 break; 946 case 39: 947 #line 187 "sam_alignment.rl" 948 { p--; {cs = 177; if (true) goto _again;} } 949 break; 950 case 40: 951 #line 188 "sam_alignment.rl" 952 { p--; {cs = 189; if (true) goto _again;} } 953 break; 954 case 41: 955 #line 193 "sam_alignment.rl" 956 { sequence_beg = p - line.ptr; } 957 break; 958 case 42: 959 #line 194 "sam_alignment.rl" 960 { 961 auto data = cast(ubyte[])line[sequence_beg .. p - line.ptr]; 962 l_seq = cast(int)data.length; 963 auto raw_len = (l_seq + 1) / 2; 964 965 // reserve space for base qualities, too 966 buffer.capacity = buffer.length + raw_len + l_seq; 967 968 for (size_t i = 0; i < raw_len; ++i) { 969 auto b = cast(ubyte)(Base(data[2 * i]).internal_code << 4); 970 if (2 * i + 1 < l_seq) 971 b |= cast(ubyte)(Base(data[2 * i + 1]).internal_code); 972 buffer.putUnsafe!ubyte(b); 973 } 974 975 // set l_seq 976 { 977 auto ptr = cast(int*)(buffer.data.ptr + 4 * int.sizeof); 978 *ptr = l_seq; 979 } 980 981 rollback_size = buffer.length; 982 } 983 break; 984 case 43: 985 #line 217 "sam_alignment.rl" 986 { 987 rollback_size = buffer.length; 988 p--; {cs = 178; if (true) goto _again;} 989 } 990 break; 991 case 44: 992 #line 221 "sam_alignment.rl" 993 { p--; {cs = 190; if (true) goto _again;} } 994 break; 995 case 45: 996 #line 223 "sam_alignment.rl" 997 { 998 rollback_size = buffer.length; 999 } 1000 break; 1001 case 46: 1002 #line 230 "sam_alignment.rl" 1003 { 1004 ++quals_length; 1005 quals_last_char = (*p); 1006 buffer.putUnsafe!ubyte(cast(ubyte)((*p) - 33)); 1007 } 1008 break; 1009 case 47: 1010 #line 236 "sam_alignment.rl" 1011 { 1012 // '*' may correspond either to a one-base long sequence 1013 // or to absence of information 1014 if (quals_length == 1 && quals_last_char == '*' && l_seq == 0) 1015 buffer.shrink(rollback_size); 1016 } 1017 break; 1018 case 48: 1019 #line 243 "sam_alignment.rl" 1020 { 1021 buffer.shrink(rollback_size); 1022 for (size_t i = 0; i < l_seq; ++i) 1023 buffer.putUnsafe!ubyte(0xFF); 1024 rollback_size = buffer.length; 1025 p--; {cs = 179; if (true) goto _again;} 1026 } 1027 break; 1028 case 49: 1029 #line 251 "sam_alignment.rl" 1030 { p--; {cs = 251; if (true) goto _again;} } 1031 break; 1032 case 50: 1033 #line 253 "sam_alignment.rl" 1034 { 1035 if (buffer.length - rollback_size != l_seq) { 1036 buffer.shrink(rollback_size); 1037 for (size_t i = 0; i < l_seq; ++i) 1038 buffer.putUnsafe!ubyte(0xFF); 1039 } 1040 rollback_size = buffer.length; 1041 } 1042 break; 1043 case 51: 1044 #line 278 "sam_alignment.rl" 1045 { 1046 buffer.capacity = buffer.length + 4; 1047 buffer.putUnsafe(tag_key); 1048 buffer.putUnsafe!char('A'); 1049 buffer.putUnsafe!char((*p)); 1050 } 1051 break; 1052 case 52: 1053 #line 285 "sam_alignment.rl" 1054 { 1055 buffer.capacity = buffer.length + 7; 1056 buffer.putUnsafe(tag_key); 1057 if (int_value < 0) { 1058 if (int_value >= byte.min) { 1059 buffer.putUnsafe!char('c'); 1060 buffer.putUnsafe(cast(byte)int_value); 1061 } else if (int_value >= short.min) { 1062 buffer.putUnsafe!char('s'); 1063 buffer.putUnsafe(cast(short)int_value); 1064 } else if (int_value >= int.min) { 1065 buffer.putUnsafe!char('i'); 1066 buffer.putUnsafe(cast(int)int_value); 1067 } else { 1068 throw new Exception("integer out of range"); 1069 } 1070 } else { 1071 if (int_value <= ubyte.max) { 1072 buffer.putUnsafe!char('C'); 1073 buffer.putUnsafe(cast(ubyte)int_value); 1074 } else if (int_value <= ushort.max) { 1075 buffer.putUnsafe!char('S'); 1076 buffer.putUnsafe(cast(ushort)int_value); 1077 } else if (int_value <= uint.max) { 1078 buffer.putUnsafe!char('I'); 1079 buffer.putUnsafe(cast(uint)int_value); 1080 } else { 1081 throw new Exception("integer out of range"); 1082 } 1083 } 1084 } 1085 break; 1086 case 53: 1087 #line 317 "sam_alignment.rl" 1088 { tagvalue_beg = p - line.ptr; } 1089 break; 1090 case 54: 1091 #line 319 "sam_alignment.rl" 1092 { 1093 buffer.capacity = buffer.length + 7; 1094 buffer.putUnsafe(tag_key); 1095 buffer.putUnsafe!char('f'); 1096 buffer.putUnsafe!float(float_value); 1097 } 1098 break; 1099 case 55: 1100 #line 326 "sam_alignment.rl" 1101 { 1102 { 1103 auto data = cast(ubyte[])(line[tagvalue_beg .. p - line.ptr]); 1104 buffer.capacity = buffer.length + 4 + data.length; 1105 buffer.putUnsafe(tag_key); 1106 buffer.putUnsafe!char('Z'); 1107 buffer.putUnsafe(data); 1108 buffer.putUnsafe!ubyte(0); 1109 } 1110 } 1111 break; 1112 case 56: 1113 #line 337 "sam_alignment.rl" 1114 { 1115 { 1116 auto data = cast(ubyte[])(line[tagvalue_beg .. p - line.ptr]); 1117 buffer.capacity = buffer.length + 4 + data.length; 1118 buffer.putUnsafe(tag_key); 1119 buffer.putUnsafe!char('H'); 1120 buffer.putUnsafe(data); 1121 buffer.putUnsafe!ubyte(0); 1122 } 1123 } 1124 break; 1125 case 57: 1126 #line 352 "sam_alignment.rl" 1127 { 1128 arraytype = (*p); 1129 buffer.capacity = buffer.length + 8; 1130 buffer.putUnsafe(tag_key); 1131 buffer.putUnsafe!char('B'); 1132 buffer.putUnsafe!char(arraytype); 1133 buffer.putUnsafe!uint(0); 1134 tag_array_length_offset = buffer.length - uint.sizeof; 1135 } 1136 break; 1137 case 58: 1138 #line 362 "sam_alignment.rl" 1139 { 1140 // here, we assume that compiler is smart enough to move switch out of loop. 1141 switch (arraytype) { 1142 case 'c': buffer.put(to!byte(int_value)); break; 1143 case 'C': buffer.put(to!ubyte(int_value)); break; 1144 case 's': buffer.put(to!short(int_value)); break; 1145 case 'S': buffer.put(to!ushort(int_value)); break; 1146 case 'i': buffer.put(to!int(int_value)); break; 1147 case 'I': buffer.put(to!uint(int_value)); break; 1148 default: assert(0); 1149 } 1150 { 1151 auto ptr = cast(uint*)(buffer.data.ptr + tag_array_length_offset); 1152 ++*ptr; 1153 } 1154 } 1155 break; 1156 case 59: 1157 #line 379 "sam_alignment.rl" 1158 { 1159 buffer.put!float(float_value); 1160 { 1161 auto ptr = cast(uint*)(buffer.data.ptr + tag_array_length_offset); 1162 ++*ptr; 1163 } 1164 } 1165 break; 1166 case 60: 1167 #line 400 "sam_alignment.rl" 1168 { tag_key_beg = p - line.ptr; } 1169 break; 1170 case 61: 1171 #line 401 "sam_alignment.rl" 1172 { tag_key = cast(ubyte[])(line[tag_key_beg .. p - line.ptr]); } 1173 break; 1174 case 62: 1175 #line 403 "sam_alignment.rl" 1176 { 1177 buffer.shrink(rollback_size); 1178 p--; {cs = 180; if (true) goto _again;} 1179 } 1180 break; 1181 case 63: 1182 #line 408 "sam_alignment.rl" 1183 { p--; {cs = 251; if (true) goto _again;} } 1184 break; 1185 case 64: 1186 #line 410 "sam_alignment.rl" 1187 { rollback_size = buffer.length; } 1188 break; 1189 #line 1189 "sam_alignment.d" 1190 default: break; 1191 } 1192 } 1193 1194 _again: 1195 if ( cs == 0 ) 1196 goto _out; 1197 if ( ++p != pe ) 1198 goto _resume; 1199 _test_eof: {} 1200 if ( p == eof ) 1201 { 1202 byte* __acts = &_sam_alignment_actions[_sam_alignment_eof_actions[cs]]; 1203 uint __nacts = cast(uint) *__acts++; 1204 while ( __nacts-- > 0 ) { 1205 switch ( *__acts++ ) { 1206 case 3: 1207 #line 30 "sam_alignment.rl" 1208 { int_value *= current_sign; current_sign = 1; } 1209 break; 1210 case 5: 1211 #line 38 "sam_alignment.rl" 1212 { 1213 float_value = to!float(line[float_beg .. p - line.ptr]); 1214 } 1215 break; 1216 case 8: 1217 #line 50 "sam_alignment.rl" 1218 { p--; {cs = 169; if (true) goto _again;} } 1219 break; 1220 case 11: 1221 #line 58 "sam_alignment.rl" 1222 { p--; {cs = 170; if (true) goto _again;} } 1223 break; 1224 case 15: 1225 #line 67 "sam_alignment.rl" 1226 { p--; {cs = 171; if (true) goto _again;} } 1227 break; 1228 case 18: 1229 #line 75 "sam_alignment.rl" 1230 { p--; {cs = 172; if (true) goto _again;} } 1231 break; 1232 case 21: 1233 #line 81 "sam_alignment.rl" 1234 { p--; {cs = 173; if (true) goto _again;} } 1235 break; 1236 case 27: 1237 #line 124 "sam_alignment.rl" 1238 { 1239 auto ptr = cast(uint*)(buffer.data.ptr + 3 * uint.sizeof); 1240 *ptr = (*ptr) & 0xFFFF0000; 1241 buffer.shrink(rollback_size); 1242 end_pos = pos + 1; 1243 p--; {cs = 174; if (true) goto _again;} 1244 } 1245 break; 1246 case 33: 1247 #line 162 "sam_alignment.rl" 1248 { p--; {cs = 175; if (true) goto _again;} } 1249 break; 1250 case 36: 1251 #line 175 "sam_alignment.rl" 1252 { p--; {cs = 176; if (true) goto _again;} } 1253 break; 1254 case 39: 1255 #line 187 "sam_alignment.rl" 1256 { p--; {cs = 177; if (true) goto _again;} } 1257 break; 1258 case 43: 1259 #line 217 "sam_alignment.rl" 1260 { 1261 rollback_size = buffer.length; 1262 p--; {cs = 178; if (true) goto _again;} 1263 } 1264 break; 1265 case 47: 1266 #line 236 "sam_alignment.rl" 1267 { 1268 // '*' may correspond either to a one-base long sequence 1269 // or to absence of information 1270 if (quals_length == 1 && quals_last_char == '*' && l_seq == 0) 1271 buffer.shrink(rollback_size); 1272 } 1273 break; 1274 case 48: 1275 #line 243 "sam_alignment.rl" 1276 { 1277 buffer.shrink(rollback_size); 1278 for (size_t i = 0; i < l_seq; ++i) 1279 buffer.putUnsafe!ubyte(0xFF); 1280 rollback_size = buffer.length; 1281 p--; {cs = 179; if (true) goto _again;} 1282 } 1283 break; 1284 case 50: 1285 #line 253 "sam_alignment.rl" 1286 { 1287 if (buffer.length - rollback_size != l_seq) { 1288 buffer.shrink(rollback_size); 1289 for (size_t i = 0; i < l_seq; ++i) 1290 buffer.putUnsafe!ubyte(0xFF); 1291 } 1292 rollback_size = buffer.length; 1293 } 1294 break; 1295 case 52: 1296 #line 285 "sam_alignment.rl" 1297 { 1298 buffer.capacity = buffer.length + 7; 1299 buffer.putUnsafe(tag_key); 1300 if (int_value < 0) { 1301 if (int_value >= byte.min) { 1302 buffer.putUnsafe!char('c'); 1303 buffer.putUnsafe(cast(byte)int_value); 1304 } else if (int_value >= short.min) { 1305 buffer.putUnsafe!char('s'); 1306 buffer.putUnsafe(cast(short)int_value); 1307 } else if (int_value >= int.min) { 1308 buffer.putUnsafe!char('i'); 1309 buffer.putUnsafe(cast(int)int_value); 1310 } else { 1311 throw new Exception("integer out of range"); 1312 } 1313 } else { 1314 if (int_value <= ubyte.max) { 1315 buffer.putUnsafe!char('C'); 1316 buffer.putUnsafe(cast(ubyte)int_value); 1317 } else if (int_value <= ushort.max) { 1318 buffer.putUnsafe!char('S'); 1319 buffer.putUnsafe(cast(ushort)int_value); 1320 } else if (int_value <= uint.max) { 1321 buffer.putUnsafe!char('I'); 1322 buffer.putUnsafe(cast(uint)int_value); 1323 } else { 1324 throw new Exception("integer out of range"); 1325 } 1326 } 1327 } 1328 break; 1329 case 54: 1330 #line 319 "sam_alignment.rl" 1331 { 1332 buffer.capacity = buffer.length + 7; 1333 buffer.putUnsafe(tag_key); 1334 buffer.putUnsafe!char('f'); 1335 buffer.putUnsafe!float(float_value); 1336 } 1337 break; 1338 case 55: 1339 #line 326 "sam_alignment.rl" 1340 { 1341 { 1342 auto data = cast(ubyte[])(line[tagvalue_beg .. p - line.ptr]); 1343 buffer.capacity = buffer.length + 4 + data.length; 1344 buffer.putUnsafe(tag_key); 1345 buffer.putUnsafe!char('Z'); 1346 buffer.putUnsafe(data); 1347 buffer.putUnsafe!ubyte(0); 1348 } 1349 } 1350 break; 1351 case 56: 1352 #line 337 "sam_alignment.rl" 1353 { 1354 { 1355 auto data = cast(ubyte[])(line[tagvalue_beg .. p - line.ptr]); 1356 buffer.capacity = buffer.length + 4 + data.length; 1357 buffer.putUnsafe(tag_key); 1358 buffer.putUnsafe!char('H'); 1359 buffer.putUnsafe(data); 1360 buffer.putUnsafe!ubyte(0); 1361 } 1362 } 1363 break; 1364 case 58: 1365 #line 362 "sam_alignment.rl" 1366 { 1367 // here, we assume that compiler is smart enough to move switch out of loop. 1368 switch (arraytype) { 1369 case 'c': buffer.put(to!byte(int_value)); break; 1370 case 'C': buffer.put(to!ubyte(int_value)); break; 1371 case 's': buffer.put(to!short(int_value)); break; 1372 case 'S': buffer.put(to!ushort(int_value)); break; 1373 case 'i': buffer.put(to!int(int_value)); break; 1374 case 'I': buffer.put(to!uint(int_value)); break; 1375 default: assert(0); 1376 } 1377 { 1378 auto ptr = cast(uint*)(buffer.data.ptr + tag_array_length_offset); 1379 ++*ptr; 1380 } 1381 } 1382 break; 1383 case 59: 1384 #line 379 "sam_alignment.rl" 1385 { 1386 buffer.put!float(float_value); 1387 { 1388 auto ptr = cast(uint*)(buffer.data.ptr + tag_array_length_offset); 1389 ++*ptr; 1390 } 1391 } 1392 break; 1393 case 62: 1394 #line 403 "sam_alignment.rl" 1395 { 1396 buffer.shrink(rollback_size); 1397 p--; {cs = 180; if (true) goto _again;} 1398 } 1399 break; 1400 case 64: 1401 #line 410 "sam_alignment.rl" 1402 { rollback_size = buffer.length; } 1403 break; 1404 #line 1404 "sam_alignment.d" 1405 default: break; 1406 } 1407 } 1408 } 1409 1410 _out: {} 1411 } 1412 1413 #line 481 "sam_alignment.rl" 1414 1415 BamRead read; 1416 read.raw_data = buffer.data[]; 1417 return read; 1418 } 1419 1420 unittest { 1421 import std.algorithm; 1422 import std.math; 1423 1424 auto line = "ERR016155.15021091\t185\t20\t60033\t25\t66S35M\t=\t60033\t0\tAGAAAAAACTGGAAGTTAATAGAGTGGTGACTCAGATCCAGTGGTGGAAGGGTAAGGGATCTTGGAACCCTATAGAGTTGCTGTGTGCCAGGGCCAGATCC\t#####################################################################################################\tX0:i:1\tX1:i:0\tXC:i:35\tMD:Z:17A8A8\tRG:Z:ERR016155\tAM:i:0\tNM:i:2\tSM:i:25\tXT:A:U\tBQ:Z:@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\tY0:B:c,1,2,3\tY1:B:f,13.263,-3.1415,52.63461"; 1425 1426 auto header = new SamHeader("@SQ\tSN:20\tLN:1234567"); 1427 auto alignment = parseAlignmentLine(line, header); 1428 assert(alignment.name == "ERR016155.15021091"); 1429 assert(equal(alignment.sequence(), "AGAAAAAACTGGAAGTTAATAGAGTGGTGACTCAGATCCAGTGGTGGAAGGGTAAGGGATCTTGGAACCCTATAGAGTTGCTGTGTGCCAGGGCCAGATCC")); 1430 assert(alignment.cigarString() == "66S35M"); 1431 assert(alignment.flag == 185); 1432 assert(alignment.position == 60032); 1433 assert(alignment.mapping_quality == 25); 1434 assert(alignment.mate_position == 60032); 1435 assert(alignment.ref_id == 0); 1436 assert(alignment.mate_ref_id == 0); 1437 assert(to!ubyte(alignment["AM"]) == 0); 1438 assert(to!ubyte(alignment["SM"]) == 25); 1439 assert(to!string(alignment["MD"]) == "17A8A8"); 1440 assert(equal(to!(byte[])(alignment["Y0"]), [1, 2, 3])); 1441 assert(equal!approxEqual(to!(float[])(alignment["Y1"]), [13.263, -3.1415, 52.63461])); 1442 assert(to!char(alignment["XT"]) == 'U'); 1443 1444 import bio.bam.reference; 1445 1446 auto info = ReferenceSequenceInfo("20", 1234567); 1447 1448 auto invalid_cigar_string = "1\t100\t20\t50000\t30\tMZABC\t=\t50000\t0\tACGT\t####"; 1449 alignment = parseAlignmentLine(invalid_cigar_string, header); 1450 assert(equal(alignment.sequence(), "ACGT")); 1451 1452 auto invalid_tag_and_qual = "2\t100\t20\t5\t40\t27M30X5D\t=\t3\t10\tACT\t !\n\tX1:i:7\tX3:i:zzz\tX4:i:5"; 1453 alignment = parseAlignmentLine(invalid_tag_and_qual, header); 1454 assert(alignment.base_qualities == [255, 255, 255]); // i.e. invalid 1455 assert(to!ubyte(alignment["X1"]) == 7); 1456 assert(alignment["X3"].is_nothing); 1457 assert(to!ubyte(alignment["X4"]) == 5); 1458 }