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.");
138 SamStatus& samStatus)
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');
177 String errorString =
"";
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...
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...