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