libStatGen Software  1
PileupElementBaseQual.cpp
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 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends