libStatGen Software
1
|
00001 /* 00002 * Copyright (C) 2010 Regents of the University of Michigan 00003 * 00004 * This program is free software: you can redistribute it and/or modify 00005 * it under the terms of the GNU General Public License as published by 00006 * the Free Software Foundation, either version 3 of the License, or 00007 * (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00016 */ 00017 00018 #include <stdexcept> 00019 00020 #include "PileupElementBaseQual.h" 00021 00022 PileupElementBaseQual::PileupElementBaseQual() 00023 : PileupElement(), 00024 myBases(NULL), 00025 myQualities(NULL), 00026 myAllocatedSize(0), 00027 myIndex(-1), 00028 myAddDelAsBase(false) 00029 { 00030 myAllocatedSize = 1024; 00031 myBases = (char*)malloc(myAllocatedSize + 1); 00032 myQualities = (char*)malloc(myAllocatedSize + 1); 00033 if((myBases == NULL ) || (myQualities == NULL)) 00034 { 00035 // TODO, check for malloc failures. 00036 std::cerr << "Failed Memory Allocation\n"; 00037 } 00038 } 00039 00040 // NOTE that this method does not actually copy, it just resets. 00041 PileupElementBaseQual::PileupElementBaseQual(const PileupElementBaseQual& q) 00042 : PileupElement(), 00043 myBases(NULL), 00044 myQualities(NULL), 00045 myAllocatedSize(0), 00046 myIndex(-1) 00047 { 00048 myAllocatedSize = 1024; 00049 myBases = (char*)malloc(myAllocatedSize + 1); 00050 myQualities = (char*)malloc(myAllocatedSize + 1); 00051 myAddDelAsBase = q.myAddDelAsBase; 00052 if((myBases == NULL ) || (myQualities == NULL)) 00053 { 00054 // TODO, check for malloc failures. 00055 std::cerr << "Failed Memory Allocation\n"; 00056 } 00057 } 00058 00059 00060 PileupElementBaseQual::~PileupElementBaseQual() 00061 { 00062 if(myBases != NULL) 00063 { 00064 free(myBases); 00065 myBases = NULL; 00066 } 00067 if(myQualities != NULL) 00068 { 00069 free(myQualities); 00070 myQualities = NULL; 00071 } 00072 } 00073 00074 00075 // Add an entry to this pileup element. 00076 void PileupElementBaseQual::addEntry(SamRecord& record) 00077 { 00078 // Call the base class: 00079 PileupElement::addEntry(record); 00080 00081 // Increment the index 00082 ++myIndex; 00083 00084 // if the index has gone beyond the allocated space, double the size. 00085 if(myIndex >= myAllocatedSize) 00086 { 00087 char* tempBuffer = (char*)realloc(myBases, myAllocatedSize * 2); 00088 if(tempBuffer == NULL) 00089 { 00090 std::cerr << "Memory Allocation Failure\n"; 00091 // TODO 00092 return; 00093 } 00094 myBases = tempBuffer; 00095 tempBuffer = (char*)realloc(myQualities, myAllocatedSize * 2); 00096 if(tempBuffer == NULL) 00097 { 00098 std::cerr << "Memory Allocation Failure\n"; 00099 // TODO 00100 return; 00101 } 00102 myQualities = tempBuffer; 00103 myAllocatedSize = myAllocatedSize * 2; 00104 } 00105 00106 Cigar* cigar = record.getCigarInfo(); 00107 00108 if(cigar == NULL) 00109 { 00110 throw std::runtime_error("Failed to retrieve cigar info from the record."); 00111 } 00112 00113 00114 int32_t readIndex = 00115 cigar->getQueryIndex(getRefPosition(), record.get0BasedPosition()); 00116 00117 // If the readPosition is N/A, this is a deletion. 00118 if(readIndex != CigarRoller::INDEX_NA) 00119 { 00120 char base = record.getSequence(readIndex); 00121 char qual = record.getQuality(readIndex); 00122 if(qual == UNSET_QUAL) 00123 { 00124 qual = ' '; 00125 } 00126 myBases[myIndex] = base; 00127 myQualities[myIndex] = qual; 00128 } 00129 else if(myAddDelAsBase) 00130 { 00131 // This version adds deletions as bases. 00132 myBases[myIndex] = '-'; 00133 myQualities[myIndex] = '0'; 00134 } 00135 else 00136 { 00137 // Do not add a deletion. 00138 // Did not add any entries, so decrement the index counter since the 00139 // index was not used. 00140 --myIndex; 00141 } 00142 } 00143 00144 void PileupElementBaseQual::analyze() 00145 { 00146 if(getRefPosition() != UNSET_POSITION) 00147 { 00148 myBases[myIndex+1] = '\0'; 00149 myQualities[myIndex+1] = '\0'; 00150 std::cout << getChromosome() << "\t" << getRefPosition() << "\tN\t" << myIndex+1 << "\t"; 00151 std::cout << myBases << "\t"; 00152 std::cout << myQualities; 00153 std::cout << "\n"; 00154 } 00155 } 00156 00157 void PileupElementBaseQual::reset(int refPosition) 00158 { 00159 // Call the base class. 00160 PileupElement::reset(refPosition); 00161 00162 myIndex = -1; 00163 } 00164