/* * VcfRecord.cpp * * Created on: May 1, 2013 * Author: nek3d */ #include "VcfRecord.h" #include "SingleLineDelimTextFileReader.h" bool VcfRecord::initFromFile(SingleLineDelimTextFileReader *fileReader) { setFileIdx(fileReader->getFileIdx()); fileReader->getField(0, _chrName); _chrId = fileReader->getCurrChromdId(); fileReader->getField(1, _startPosStr); _startPos = str2chrPos(_startPosStr); _startPos--; // VCF is one-based. Here we intentionally don't decrement the string version, //because we'll still want to output the one-based number in the print methods, even though //internally we decrement the integer to comply with the 0-based format common to other records. fileReader->getField(4, _varAlt); fileReader->getField(3, _varRef); if (_varAlt[0] == '<') { // this is a structural variant. Need to parse the tags to find the endpos, // UNLESS it's an insertion. if (!(_varAlt[1] == 'I' && _varAlt[2] == 'N' && _varAlt[3] == 'S')) { _endPos = _startPos + fileReader->getVcfSVlen(); } else { //for insertions, treat as zero-length records _endPos = _startPos; } } else { //endPos is just the startPos plus the length of the variant _endPos = _startPos + _varRef.size(); } int2str(_endPos, _endPosStr); fileReader->getField(2, _name); fileReader->getField(5, _score); _plusFields.setNumOffsetFields(numFixedFields); return _plusFields.initFromFile(fileReader); } void VcfRecord::clear() { BedPlusInterval::clear(); _varRef.clear(); _varAlt.clear(); } void VcfRecord::print(string &outBuf) const { outBuf.append(_chrName); outBuf.append("\t"); outBuf.append(_startPosStr); printOtherFields(outBuf); } void VcfRecord::print(string &outBuf, int start, int end) const { outBuf.append(_chrName); outBuf.append("\t"); outBuf.append(_startPosStr); printOtherFields(outBuf); } void VcfRecord::print(string &outBuf, const string & start, const string & end) const { outBuf.append(_chrName); outBuf.append("\t"); outBuf.append(_startPosStr); printOtherFields(outBuf); } void VcfRecord::printNull(string &outBuf) const { outBuf.append(".\t-1\t."); for (int i=3; i < _numPrintFields; i++) { outBuf.append("\t."); } } void VcfRecord::printOtherFields(string &outBuf) const { outBuf.append("\t"); outBuf.append(_name); outBuf.append("\t"); outBuf.append(_varRef); outBuf.append("\t"); outBuf.append(_varAlt); outBuf.append("\t"); outBuf.append(_score); outBuf.append("\t"); _plusFields.printFields(outBuf); } const string &VcfRecord::getField(int fieldNum) const { //a request for any of the first six fields will retrieve //chrom, start, name, varRef, varAlt, score, in that order. switch (fieldNum) { case 1: return _chrName; break; case 2: return _startPosStr; break; case 3: return _name; case 4: return _varRef; break; case 5: return _varAlt; break; case 6: return _score; default: return BedPlusInterval::getField(fieldNum); break; } } bool VcfRecord::isNumericField(int fieldNum) { switch (fieldNum) { case 1: return false; //_chrName; break; case 2: return true; //_startPosStr; break; case 3: return false; //_name; case 4: return false; //_varRef; break; case 5: return false; //_varAlt; break; case 6: return true; //_score; default: return BedPlusInterval::isNumericField(fieldNum); break; } }