pointer ctor
Add a filedate= headerline, which is not called out specifically in the spec, but appears in the spec's example files. We could consider allowing a param here.
Add FILTER tag (§1.2.3)
Add INFO (§1.2.2) or FORMAT (§1.2.4) tag
Add FILTER tag (§1.2.3)
Add a new header line
Add a new header line -- must be formatted ##key=value
Add a new header line using HeaderRecord
Add sample to this VCF * int bcf_hdr_add_sample(bcf_hdr_t *hdr, const(char) *sample);
copy header lines from a template without overwiting existing lines
copy this header
get a header record via ID field
get a header record via a string value pair
Remove all header lines of a particular type
Remove a header line of a particular type with the key
string representation of header
Number of samples in the header
List of contigs in the header
VCF version, e.g. VCFv4.2
Pointer to htslib BCF/VCF header struct; will be freed from VCFHeader dtor
import std.exception: assertThrown; import std.stdio: writeln, writefln; hts_set_log_level(htsLogLevel.HTS_LOG_TRACE); auto hdr = VCFHeader(bcf_hdr_init("w\0"c.ptr)); hdr.addHeaderLineRaw("##INFO=<ID=NS,Number=1,Type=Integer,Description=\"Number of Samples With Data\">"); hdr.addHeaderLineKV("INFO", "<ID=DP,Number=1,Type=Integer,Description=\"Total Depth\">"); // ##INFO=<ID=AF,Number=A,Type=Float,Description="Allele Frequency"> hdr.addHeaderLine!(HeaderRecordType.Info)("AF", HeaderLengths.OnePerAltAllele, HeaderTypes.Integer, "Number of Samples With Data"); hdr.addHeaderLineRaw("##contig=<ID=20,length=62435964,assembly=B36,md5=f126cdf8a6e0c7f379d618ff66beb2da,species=\"Homo sapiens\",taxonomy=x>"); // @suppress(dscanner.style.long_line) hdr.addHeaderLineRaw("##FILTER=<ID=q10,Description=\"Quality below 10\">"); // Exercise header assert(hdr.nsamples == 0); hdr.addSample("NA12878"); assert(hdr.nsamples == 1); assert(hdr.vcfVersion == "VCFv4.2");
1 import std.exception: assertThrown; 2 import std.stdio: writeln, writefln; 3 4 hts_set_log_level(htsLogLevel.HTS_LOG_TRACE); 5 6 7 auto hdr = VCFHeader(bcf_hdr_init("w\0"c.ptr)); 8 9 hdr.addHeaderLineRaw("##INFO=<ID=NS,Number=1,Type=Integer,Description=\"Number of Samples With Data\">"); 10 hdr.addHeaderLineKV("INFO", "<ID=DP,Number=1,Type=Integer,Description=\"Total Depth\">"); 11 12 auto rec = hdr.getHeaderRecord(HeaderRecordType.Info,"ID","NS"); 13 assert(rec.recType == HeaderRecordType.Info); 14 assert(rec.key == "INFO"); 15 assert(rec.nkeys == 4); 16 assert(rec.keys == ["ID", "Number", "Type", "Description"]); 17 assert(rec.vals == ["NS", "1", "Integer", "\"Number of Samples With Data\""]); 18 assert(rec["ID"] == "NS"); 19 20 assert(rec.idx == 1); 21 22 writeln(rec.toString); 23 24 25 rec = HeaderRecord(rec.convert(hdr.hdr)); 26 27 assert(rec.recType == HeaderRecordType.Info); 28 assert(rec.key == "INFO"); 29 assert(rec.nkeys == 4); 30 assert(rec.keys == ["ID", "Number", "Type", "Description"]); 31 assert(rec.vals == ["NS", "1", "Integer", "\"Number of Samples With Data\""]); 32 assert(rec["ID"] == "NS"); 33 // assert(rec["IDX"] == "1"); 34 // assert(rec.idx == 1); 35 36 rec = hdr.getHeaderRecord(HeaderRecordType.Info,"ID","NS"); 37 38 assert(rec.recType == HeaderRecordType.Info); 39 assert(rec.getLength == "1"); 40 assert(rec.getValueType == HeaderTypes.Integer); 41 42 rec.idx = -1; 43 44 rec["ID"] = "NS2"; 45 46 hdr.addHeaderRecord(rec); 47 auto hdr2 = hdr.dup; 48 // writeln(hdr2.toString); 49 50 rec = hdr2.getHeaderRecord(HeaderRecordType.Info,"ID","NS2"); 51 assert(rec.recType == HeaderRecordType.Info); 52 assert(rec.key == "INFO"); 53 assert(rec.nkeys == 4); 54 assert(rec.keys == ["ID", "Number", "Type", "Description"]); 55 assert(rec.vals == ["NS2", "1", "Integer", "\"Number of Samples With Data\""]); 56 assert(rec["ID"] == "NS2"); 57 58 assert(rec.idx == 3); 59 60 rec = HeaderRecord.init; 61 rec.setHeaderRecordType(HeaderRecordType.Generic); 62 rec.key = "source"; 63 rec.value = "hello"; 64 hdr.addHeaderRecord(rec); 65 66 rec = hdr.getHeaderRecord(HeaderRecordType.Generic,"source","hello"); 67 assert(rec.recType == HeaderRecordType.Generic); 68 assert(rec.key == "source"); 69 assert(rec.value == "hello"); 70 assert(rec.nkeys == 0); 71 72 hdr.addHeaderLine!(HeaderRecordType.Filter)("nonsense","filter"); 73 74 rec = hdr.getHeaderRecord(HeaderRecordType.Filter,"ID","nonsense"); 75 assert(rec.recType == HeaderRecordType.Filter); 76 assert(rec.key == "FILTER"); 77 assert(rec.value == ""); 78 assert(rec.getID == "nonsense"); 79 assert(rec.idx == 4); 80 81 hdr.removeHeaderLines(HeaderRecordType.Filter); 82 83 auto expected = "##fileformat=VCFv4.2\n" ~ 84 "##INFO=<ID=NS,Number=1,Type=Integer,Description=\"Number of Samples With Data\">\n"~ 85 "##INFO=<ID=DP,Number=1,Type=Integer,Description=\"Total Depth\">\n"~ 86 "##INFO=<ID=NS2,Number=1,Type=Integer,Description=\"Number of Samples With Data\">\n"~ 87 "##source=hello\n"~ 88 "#CHROM\tPOS\tID\tREF\tALT\tQUAL\tFILTER\tINFO\n"; 89 assert(hdr.toString == expected); 90 91 rec = rec.init; 92 rec.setHeaderRecordType(HeaderRecordType.Contig); 93 rec.setID("test"); 94 rec["length"] = "5"; 95 96 hdr.addHeaderRecord(rec); 97 98 assert(hdr.sequences == ["test"]); 99 hdr.removeHeaderLines(HeaderRecordType.Generic, "source"); 100 hdr.addFilter("test","test"); 101 expected = "##fileformat=VCFv4.2\n" ~ 102 "##INFO=<ID=NS,Number=1,Type=Integer,Description=\"Number of Samples With Data\">\n"~ 103 "##INFO=<ID=DP,Number=1,Type=Integer,Description=\"Total Depth\">\n"~ 104 "##INFO=<ID=NS2,Number=1,Type=Integer,Description=\"Number of Samples With Data\">\n"~ 105 "##contig=<ID=test,length=5>\n"~ 106 "##FILTER=<ID=test,Description=\"test\">\n"~ 107 "#CHROM\tPOS\tID\tREF\tALT\tQUAL\tFILTER\tINFO\n"; 108 assert(hdr.toString == expected); 109 rec = hdr.getHeaderRecord(HeaderRecordType.Filter,"test"); 110 assert(rec.getDescription() == "\"test\""); 111 112 rec = HeaderRecord.init; 113 rec.setHeaderRecordType(HeaderRecordType.Info); 114 rec.setID("test"); 115 rec.setLength(HeaderLengths.OnePerGenotype); 116 rec.setValueType(HeaderTypes.Integer); 117 hdr.addHeaderRecord(rec); 118 119 rec = hdr.getHeaderRecord(HeaderRecordType.Info,"test"); 120 assert(rec.recType == HeaderRecordType.Info); 121 assert(rec.getLength == "G"); 122 assert(rec.getID == "test"); 123 assert(rec.getValueType == HeaderTypes.Integer); 124 125 rec = HeaderRecord.init; 126 rec.setHeaderRecordType(HeaderRecordType.Info); 127 rec.setID("test2"); 128 rec.setLength(HeaderLengths.OnePerAllele); 129 rec.setValueType(HeaderTypes.Integer); 130 hdr.addHeaderRecord(rec); 131 132 rec = hdr.getHeaderRecord(HeaderRecordType.Info,"test2"); 133 assert(rec.recType == HeaderRecordType.Info); 134 assert(rec.getLength == "R"); 135 assert(rec.getID == "test2"); 136 assert(rec.getValueType == HeaderTypes.Integer); 137 138 rec = HeaderRecord.init; 139 rec.setHeaderRecordType(HeaderRecordType.Info); 140 rec.setID("test3"); 141 rec.setLength(HeaderLengths.Variable); 142 rec.setValueType(HeaderTypes.Integer); 143 hdr.addHeaderRecord(rec); 144 145 rec = hdr.getHeaderRecord(HeaderRecordType.Info,"test3"); 146 assert(rec.recType == HeaderRecordType.Info); 147 assert(rec.getLength == "."); 148 assert(rec.getID == "test3"); 149 assert(rec.getValueType == HeaderTypes.Integer); 150 151 rec = HeaderRecord.init; 152 rec.setHeaderRecordType(HeaderRecordType.Info); 153 rec.setID("test4"); 154 rec.setLength(1); 155 rec.setValueType(HeaderTypes.Flag); 156 hdr.addHeaderRecord(rec); 157 158 rec = hdr.getHeaderRecord(HeaderRecordType.Info,"test4"); 159 assert(rec.recType == HeaderRecordType.Info); 160 assert(rec.getID == "test4"); 161 assert(rec.getValueType == HeaderTypes.Flag); 162 163 rec = HeaderRecord.init; 164 rec.setHeaderRecordType(HeaderRecordType.Info); 165 rec.setID("test5"); 166 rec.setLength(1); 167 rec.setValueType(HeaderTypes.Character); 168 hdr.addHeaderRecord(rec); 169 170 rec = hdr.getHeaderRecord(HeaderRecordType.Info,"test5"); 171 assert(rec.recType == HeaderRecordType.Info); 172 assert(rec.getLength == "1"); 173 assert(rec.getID == "test5"); 174 assert(rec.getValueType == HeaderTypes.Character); 175 176 rec = HeaderRecord.init; 177 rec.setHeaderRecordType(HeaderRecordType.Info); 178 rec.setID("test6"); 179 rec.setLength(HeaderLengths.Variable); 180 rec.setValueType(HeaderTypes.String); 181 hdr.addHeaderRecord(rec); 182 183 rec = hdr.getHeaderRecord(HeaderRecordType.Info,"test6"); 184 assert(rec.recType == HeaderRecordType.Info); 185 assert(rec.getLength == "."); 186 assert(rec.getID == "test6"); 187 assert(rec.getValueType == HeaderTypes.String); 188 189 expected = "##fileformat=VCFv4.2\n" ~ 190 "##INFO=<ID=NS,Number=1,Type=Integer,Description=\"Number of Samples With Data\">\n"~ 191 "##INFO=<ID=DP,Number=1,Type=Integer,Description=\"Total Depth\">\n"~ 192 "##INFO=<ID=NS2,Number=1,Type=Integer,Description=\"Number of Samples With Data\">\n"~ 193 "##contig=<ID=test,length=5>\n"~ 194 "##FILTER=<ID=test,Description=\"test\">\n"~ 195 "##INFO=<ID=test,Number=G,Type=Integer>\n"~ 196 "##INFO=<ID=test2,Number=R,Type=Integer>\n"~ 197 "##INFO=<ID=test3,Number=.,Type=Integer>\n"~ 198 "##INFO=<ID=test4,Number=1,Type=Flag>\n"~ 199 "##INFO=<ID=test5,Number=1,Type=Character>\n"~ 200 "##INFO=<ID=test6,Number=.,Type=String>\n"~ 201 "#CHROM\tPOS\tID\tREF\tALT\tQUAL\tFILTER\tINFO\n"; 202 writeln(hdr.toString); 203 assert(hdr.toString == expected);
VCFHeader encapsulates bcf_hdr_t* and provides convenience wrappers to manipulate the header metadata/records.