1 module dhtslib.fastq; 2 import dhtslib.bgzf; 3 import std.range.interfaces : InputRange, inputRangeObject; 4 5 /* 6 * Represents a complete fastq read record. 7 */ 8 struct FastqRecord 9 { 10 string id; 11 string sequence; 12 string extra; 13 string qscores; 14 } 15 16 /* 17 * Parses a bgzipped, gzipped, or plain-text fastq file 18 * into a range of FastqRecords. 19 */ 20 struct FastqFile 21 { 22 BGZFile f; 23 InputRange!string lines; 24 FastqRecord rec; 25 bool last; 26 27 this(string fn) 28 { 29 f = BGZFile(fn); 30 lines = f.byLineCopy.inputRangeObject; 31 popFront; 32 } 33 34 /// Explicit postblit to avoid 35 /// https://github.com/blachlylab/dhtslib/issues/122 36 this(this) 37 { 38 this.f = f; 39 this.lines = lines; 40 this.rec = rec; 41 this.last = last; 42 } 43 44 FastqRecord front() 45 { 46 return rec; 47 } 48 49 void popFront() 50 { 51 //get id line 52 rec.id = lines.front; 53 lines.popFront; 54 55 //get seq line 56 rec.sequence = lines.front; 57 lines.popFront; 58 59 //get extra line 60 rec.extra = lines.front; 61 lines.popFront; 62 63 //get qscore line 64 rec.qscores = lines.front; 65 if(!lines.empty) 66 lines.popFront; 67 else 68 last = true; 69 } 70 71 bool empty() 72 { 73 return lines.empty && last; 74 } 75 76 } 77 78 /// 79 debug(dhtslib_unittest) unittest 80 { 81 import std.stdio; 82 import htslib.hts_log; 83 import std.algorithm : map; 84 import std.array : array; 85 import std.path : buildPath,dirName; 86 hts_set_log_level(htsLogLevel.HTS_LOG_INFO); 87 hts_log_info(__FUNCTION__, "Testing FastqFile"); 88 hts_log_info(__FUNCTION__, "Loading test file"); 89 90 auto fqs = FastqFile(buildPath(dirName(dirName(dirName(__FILE__))),"htslib","test","fastqs.fq")); 91 assert(fqs.array.length == 125); 92 // assert(bg.array == ["122333444455555"]); 93 }