gnMultiSpec.cpp Source File

Main Page Namespace List Class Hierarchy Alphabetical List Compound List File List Compound Members File Members

# gnMultiSpec.cpp

Go to the documentation of this file.

    00001 /////////////////////////////////////////////////////////////////////////////
    00002 // File:            gnMultiSpec.cpp
    00003 // Purpose:         abstract Spec class
    00004 // Description:     Defines a basic interface for all specs
    00005 // Changes:
    00006 // Version:         libGenome 0.5.1
    00007 // Author:          Aaron Darling
    00008 // Modified by:
    00009 // Copyright:       (c) Aaron Darling
    00010 // Licenses:        See COPYING file for details
    00011 /////////////////////////////////////////////////////////////////////////////
    00012
    00013 #include "gn/gnDefs.h"
    00014
    00015 #include <string>
    00016 #include <vector>
    00017 #include "gn/gnMultiSpec.h"
    00018 #include "gn/gnBaseSource.h"
    00019 #include "gn/gnBaseFeature.h"
    00020 #include "gn/gnDebug.h"
    00021 #include "gn/gnException.h"
    00022
    00023 void gnMultiSpec::Clear()
    00024 {
    00025         gnBaseSpec::Clear();
    00026         uint32 list_size = m_headerList.size();
    00027         for(uint32 i=0; i < list_size; i++)
    00028                 delete m_headerList[i];
    00029         m_headerList.clear();
    00030 }
    00031
    00032 gnSeqI gnMultiSpec::GetLength() const
    00033 {
    00034         gnSeqI subLen = 0;      //aggregate the lower levels.
    00035         for(uint32 i=0; i < GetSpecListLength(); i++)
    00036                 subLen += GetSpec(i)->GetLength();
    00037         return subLen;
    00038 }
    00039
    00040 //Return the index of the subspec which contains the base in question
    00041 uint32 gnMultiSpec::GetSpecIndexByBase( const gnSeqI baseI ) const{
    00042         gnSeqI cur_length = 0;
    00043         for(uint32 i=0; i < GetSpecListLength(); i++){
    00044                 cur_length += GetSpec(i)->GetLength();
    00045                 if(baseI < cur_length)
    00046                         return i;
    00047         }
    00048         //if we made it here then the base was out of bounds
    00049         Throw_gnEx(SeqIndexOutOfBounds());
    00050 }
    00051
    00052 uint32 gnMultiSpec::GetSpecIndexByName( const string& name ) const{
    00053         for(uint32 i=0; i < GetSpecListLength(); i++){
    00054                 if(name == GetSpec(i)->GetName())
    00055                         return i;
    00056         }
    00057         Throw_gnEx(SpecIndexOutOfBounds());
    00058 }
    00059
    00060 //returns the starting base pair index of the given subspec.
    00061 gnSeqI gnMultiSpec::GetSpecStartBase( const uint32 specI ) const{
    00062         uint32 i;
    00063         if(specI >= GetSpecListLength())
    00064                 Throw_gnEx(SpecIndexOutOfBounds());
    00065
    00066         gnSeqI start_base = 0;
    00067         for(i=0; i < specI; i++){
    00068                 start_base += GetSpec(i)->GetLength();
    00069         }
    00070         return start_base;
    00071 }
    00072
    00073 gnSeqI gnMultiSpec::GetSpecEndBase( const uint32 specI ) const{
    00074         uint32 i;
    00075         if(specI >= GetSpecListLength())
    00076                 Throw_gnEx(SpecIndexOutOfBounds());
    00077
    00078         gnSeqI end_base = 0;
    00079         for(i=0; i <= specI; i++){
    00080                 end_base += GetSpec(i)->GetLength();
    00081         }
    00082         return end_base;
    00083 }
    00084
    00085 void gnMultiSpec::CropStart( gnSeqI cropLen ){
    00086         gnSeqI curbase = 0;
    00087         for(uint32 specI = 0; specI < GetSpecListLength(); specI++){
    00088                 curbase += GetSpec(specI)->GetLength();
    00089                 if(curbase <= cropLen){
    00090                         //delete the spec completely
    00091                         gnBaseSpec *tmp_spec = GetSpec(specI);
    00092                         RemoveSpec(specI);
    00093                         delete tmp_spec;
    00094                         specI--;
    00095                 }else{
    00096                         //recurse and break
    00097                         gnSeqI sub_len = cropLen - (curbase - GetSpec(specI)->GetLength());
    00098                         GetSpec(specI)->CropStart(sub_len);
    00099                         break;
    00100                 }
    00101         }
    00102 }
    00103
    00104 void gnMultiSpec::CropEnd( gnSeqI cropLen ){
    00105         gnSeqI curbase = 0;
    00106         gnSeqI cropbase = GetLength() - cropLen;  //last base to keep
    00107         boolean trash_the_rest = false;
    00108         for(uint32 specI = 0; specI < GetSpecListLength(); specI++){
    00109                 curbase += GetSpec(specI)->GetLength();
    00110                 if(trash_the_rest){
    00111                         //delete the spec entirely
    00112                         gnBaseSpec *tmp_spec = GetSpec(specI);
    00113                         RemoveSpec(specI);
    00114                         delete tmp_spec;
    00115                         specI--;
    00116                         continue;
    00117                 }else if(curbase > cropbase){
    00118                         GetSpec(specI)->CropEnd(curbase - cropbase);
    00119                         trash_the_rest = true;
    00120                 }else if(curbase == cropbase)
    00121                         trash_the_rest = true;
    00122         }
    00123 }
    00124
    00125 void gnMultiSpec::AddHeader( gnBaseHeader* head, const uint32 i)
    00126 {
    00127         uint32 index = i == UINT32_MAX ? m_headerList.size() : i;
    00128         m_headerList.insert(m_headerList.begin() + index, head);
    00129 }
    00130
    00131 gnBaseHeader* gnMultiSpec::GetHeader( const string& name, uint32& i) const{
    00132         for(; i < m_headerList.size(); i++){
    00133                 if( m_headerList[i]->GetHeaderName() == name)
    00134                         return m_headerList[i];
    00135         }
    00136         Throw_gnEx(HeaderIndexOutOfBounds());
    00137 }
    00138
    00139 void gnMultiSpec::RemoveHeader( uint32 i)
    00140 {
    00141         if(i <= m_headerList.size()){
    00142                 m_headerList.erase(m_headerList.begin() + i);
    00143         }
    00144         Throw_gnEx(HeaderIndexOutOfBounds());
    00145 }
    00146
    00147 boolean gnMultiSpec::SeqRead(const gnSeqI start, gnSeqC* buf, uint32& bufLen, const uint32 contigI ) const{
    00148         if( bufLen == 0 )
    00149                 return true;
    00150         if(contigI == ALL_CONTIGS){
    00151                 gnSeqI curpos = 0;
    00152                 uint32 readBytes = 0;
    00153                 uint32 remainingBytes = bufLen;
    00154                 uint32 curSpecI = 0;
    00155                 //seek to start spec.
    00156                 for(curSpecI=0; curSpecI < GetSpecListLength(); curSpecI++){
    00157                         curpos += GetSpec(curSpecI)->GetLength();
    00158                         if(curpos > start)
    00159                                 break;
    00160                 }
    00161                 if(curpos <= start)
    00162                         Throw_gnEx(SeqIndexOutOfBounds());
    00163                 //read until we're done;
    00164                 while((remainingBytes > 0) && (curSpecI < GetSpecListLength())) {
    00165                         gnSeqI readable = GetSpec(curSpecI)->GetLength();
    00166                         //check for circular
    00167                         uint32 start_pos = readBytes == 0 ? start - (curpos - readable) : 0;
    00168                         uint32 to_read = readable - start_pos >= remainingBytes ? remainingBytes : readable - start_pos;
    00169                         boolean success = GetSpec(curSpecI)->SeqRead(start_pos, buf+readBytes, to_read, contigI);
    00170
    00171                         readBytes += to_read;
    00172                         remainingBytes -= to_read;
    00173                         if(!success)
    00174                                 break;
    00175                         curSpecI++;
    00176                 }
    00177                 bufLen = readBytes;
    00178                 return true;
    00179         }else{  //read from the specified contig.
    00180                 if(contigI < GetSpecListLength())
    00181                         return GetSpec(contigI)->SeqRead(start, buf, bufLen, ALL_CONTIGS);
    00182                 else
    00183                         Throw_gnEx(SpecIndexOutOfBounds());
    00184         }
    00185         return false;
    00186 }
    00187