18#include "SamInterface.h"
19#include "SamRecordHelper.h"
24SamInterface::SamInterface()
30SamInterface::~SamInterface()
43 "Cannot read header since the file pointer is null");
52 std::string errorMessages =
"";
57 buffer.ReadLine(filePtr);
61 if (
ifeof(filePtr) ||
62 ((buffer.Length() != 0) && (buffer[0] !=
'@')) )
70 if(buffer.Length() != 0)
86 myFirstRecord = buffer;
92 std::cerr <<
"Failed to parse " << numInvalid <<
" header lines";
93 std::cerr <<
". No valid header lines.\n";
106 if((filePtr == NULL) || (filePtr->
isOpen() ==
false))
110 "Cannot write header since the file pointer is null");
118 std::string headerString =
"";
121 int32_t headerLen = headerString.length();
125 numWrite =
ifwrite(filePtr, headerString.c_str(), headerLen);
126 if(numWrite != headerLen)
129 "Failed to write the SAM header.");
143 if((filePtr == NULL) || (filePtr->
isOpen() ==
false))
147 "filePtr does not point to an open file.");
153 if(myFirstRecord.Length() != 0)
155 buffer = myFirstRecord;
156 myFirstRecord.Clear();
162 buffer.ReadLine(filePtr);
164 if ((
ifeof(filePtr)) && (buffer.Length() == 0))
168 "No more records in the file.");
173 tokens.ReplaceColumns(buffer,
'\t');
179 if (tokens.Length() < 11)
181 errorString =
"Too few columns (";
182 errorString += tokens.Length();
183 errorString +=
") in the Record, expected at least 11.";
185 errorString.c_str());
198 if(!tokens[1].AsInteger(flagInt))
200 errorString =
"flag, ";
201 errorString += tokens[1].c_str();
202 errorString +=
", is not an integer.";
204 errorString.c_str());
206 else if((flagInt < 0) || (flagInt > UINT16_MAX))
208 errorString =
"flag, ";
209 errorString += tokens[1].c_str();
210 errorString +=
", is not between 0 and (2^16)-1 = 65535.";
212 errorString.c_str());
214 else if(!record.
setFlag(flagInt))
227 if(!tokens[3].AsInteger(posInt))
229 errorString =
"position, ";
230 errorString += tokens[3].c_str();
231 errorString +=
", is not an integer.";
233 errorString.c_str());
235 else if((posInt < INT32_MIN) || (posInt > INT32_MAX))
238 errorString =
"position, ";
239 errorString += tokens[3].c_str();
240 errorString +=
", does not fit in a 32 bit signed int.";
242 errorString.c_str());
251 if(!tokens[4].AsInteger(mapInt))
253 errorString =
"map quality, ";
254 errorString += tokens[4].c_str();
255 errorString +=
", is not an integer.";
257 errorString.c_str());
259 else if((mapInt < 0) || (mapInt > UINT8_MAX))
261 errorString =
"map quality, ";
262 errorString += tokens[4].c_str();
263 errorString +=
", is not between 0 and (2^8)-1 = 255.";
265 errorString.c_str());
286 if(!tokens[7].AsInteger(matePosInt))
288 errorString =
"mate position, ";
289 errorString += tokens[7].c_str();
290 errorString +=
", is not an integer.";
292 errorString.c_str());
301 if(!tokens[8].AsInteger(insertInt))
303 errorString =
"insert size, ";
304 errorString += tokens[8].c_str();
305 errorString +=
", is not an integer.";
307 errorString.c_str());
331 for (
int i = 11; i < tokens.Length(); i++)
333 String & nugget = tokens[i];
335 if (nugget.Length() < 6 || nugget[2] !=
':' || nugget[4] !=
':')
338 errorString =
"Invalid Tag Format: ";
339 errorString += nugget.c_str();
340 errorString +=
", should be cc:c:x*.";
342 errorString.c_str());
348 if(!record.
addTag((
const char *)nugget, nugget[3],
349 (
const char *)nugget + 5))
367 recordString +=
"\t";
368 recordString += record.
getFlag();
369 recordString +=
"\t";
371 recordString +=
"\t";
373 recordString +=
"\t";
375 recordString +=
"\t";
377 recordString +=
"\t";
379 recordString +=
"\t";
381 recordString +=
"\t";
383 recordString +=
"\t";
385 recordString +=
"\t";
391 recordString +=
"\t";
395 recordString +=
"\n";
399 ifwrite(filePtr, recordString.c_str(), recordString.Length());
409 tokens.AddColumns(buffer,
'\t');
411 for (
int i = 1; i < tokens.Length(); i++)
413 tags.Add(tokens[i].Left(2), i - 1);
414 values.Push(tokens[i].SubStr(3));
419bool SamInterface::isEOF(
IFILE filePtr)
422 if(myFirstRecord.Length() != 0)
428 return(GenericSamInterface::isEOF(filePtr));
static bool genSamTagsString(SamRecord &record, String &returnString, char delim='\t')
Helper to append the SAM string representation of all the tags to the specified string.
Class providing an easy to use interface to get/set/operate on the fields in a SAM/BAM record.
const char * getReferenceName()
Get the reference sequence name (RNAME) of the record.
SequenceTranslation
Enum containing the settings on how to translate the sequence if a reference is available.
bool setReadName(const char *readName)
Set QNAME to the passed in name.
int32_t getInsertSize()
Get the inferred insert size of the read pair (ISIZE) or observed template length (TLEN).
int32_t get1BasedPosition()
Get the 1-based(SAM) leftmost position (POS) of the record.
void clearTags()
Clear the tags in this record.
bool setInsertSize(int32_t insertSize)
Sets the inferred insert size (ISIZE)/observed template length (TLEN).
uint32_t getTagLength()
Returns the length of the BAM formatted tags.
bool setMateReferenceName(SamFileHeader &header, const char *mateReferenceName)
Set the mate/next fragment's reference sequence name (RNEXT) to the specified name,...
const char * getMateReferenceNameOrEqual()
Get the mate/next fragment's reference sequence name (RNEXT), returning "=" if it is the same as the ...
bool setMapQuality(uint8_t mapQuality)
Set the mapping quality (MAPQ).
bool addTag(const char *tag, char vtype, const char *value)
Add the specified tag,vtype,value to the record.
void resetRecord()
Reset the fields of the record to a default value.
bool setFlag(uint16_t flag)
Set the bitwise FLAG to the specified value.
bool set1BasedPosition(int32_t position)
Set the leftmost position (POS) using the specified 1-based (SAM format) value.
uint16_t getFlag()
Get the flag (FLAG).
int32_t get1BasedMatePosition()
Get the 1-based(SAM) leftmost mate/next fragment's position (PNEXT).
const SamStatus & getStatus()
Returns the status associated with the last method that sets the status.
bool setCigar(const char *cigar)
Set the CIGAR to the specified SAM formatted cigar string.
bool setSequence(const char *seq)
Sets the sequence (SEQ) to the specified SAM formatted sequence string.
bool set1BasedMatePosition(int32_t matePosition)
Set the mate/next fragment's leftmost position (PNEXT) using the specified 1-based (SAM format) value...
const char * getCigar()
Returns the SAM formatted CIGAR string.
uint8_t getMapQuality()
Get the mapping quality (MAPQ) of the record.
const char * getReadName()
Returns the SAM formatted Read Name (QNAME).
bool setQuality(const char *quality)
Sets the quality (QUAL) to the specified SAM formatted quality string.
bool setReferenceName(SamFileHeader &header, const char *referenceName)
Set the reference sequence name (RNAME) to the specified name, using the header to determine the refe...
const char * getQuality()
Returns the SAM formatted quality string (QUAL).
const char * getSequence()
Returns the SAM formatted sequence string (SEQ), translating the base as specified by setSequenceTran...
This class is used to track the status results of some methods in the BAM classes.
const char * getStatusMessage() const
Return the status message for this object.
Status
Return value enum for StatGenFile methods.
@ NO_MORE_RECS
NO_MORE_RECS: failed to read a record since there are no more to read either in the file or section i...
@ SUCCESS
method completed successfully.
@ FAIL_IO
method failed due to an I/O issue.
@ FAIL_PARSE
failed to parse a record/header - invalid format.
@ FAIL_ORDER
FAIL_ORDER: method failed because it was called out of order, like trying to read a file without open...
void setStatus(Status newStatus, const char *newMessage)
Set the status with the specified status enum and message.
Status getStatus() const
Return the enum for this status object.
void addError(Status newStatus, const char *newMessage)
Add the specified error message to the status message, setting the status to newStatus if the current...