/** ** Copyright (c) 2007-2009 Illumina, Inc. ** ** This software is covered by the "Illumina Genome Analyzer Software ** License Agreement" and the "Illumina Source Code License Agreement", ** and certain third party copyright/licenses, and any user of this ** source file is bound by the terms therein (see accompanying files ** Illumina_Genome_Analyzer_Software_License_Agreement.pdf and ** Illumina_Source_Code_License_Agreement.pdf and third party ** copyright/license notices). ** ** This file is part of the Consensus Assessment of Sequence And VAriation ** (CASAVA) software package. ** ** \file SignalMeansTile.cpp ** ** \brief Implementation of the I/O API for signal means data type ( _all files). ** ** \author Mauricio Varea **/ #include #include #include "common/Exceptions.hh" #include "common/SignalMeansTile.hh" namespace casava { namespace common { SignalMeansTile::SignalMeansTile() : passFilter_(0,0) { } SignalMeansTile::SignalMeansTile(const unsigned int numberOfCycles) : passFilter_(0,0) , baseCalls_(numberOfCycles) { } SignalMeansTile::SignalMeansTile(const SignalMeansTile &ref) : passFilter_(ref.passFilter_) , baseCalls_(ref.baseCalls_) { } SignalMeansTile &SignalMeansTile::operator=(const SignalMeansTile &ref) { if (&ref != this) { passFilter_ = ref.passFilter_; baseCalls_ = ref.baseCalls_; } return *this; } unsigned int SignalMeansTile::read(std::istream &is) { SignalMeans data; while (is >> data) { if (data.isValid()) { baseCalls_.push_back(data); } } return baseCalls_.size(); } void SignalMeansTile::readHeader(std::istream &is) { is.seekg(0,std::ios::beg); std::string line; bool firstLine(true); char c; while(true) { is.get(c); if (is.fail()) { BOOST_THROW_EXCEPTION(CasavaException(EINVAL, "Failed to read first char of a SignalMeans header")); } if ('#' != c) { is.putback(c); break; } std::getline(is,line); if (is.fail()) { BOOST_THROW_EXCEPTION(CasavaException(EINVAL, "Failed to read a line in SignalMeans header")); } if (firstLine) { //e.g. # Clusters: Filtered 13684 Original 15725 unsigned int p1 = line.find("Filtered"); unsigned int p2 = line.find("Original"); std::string original( line.substr(p2 + 9) ); std::string filtered( line.substr(p1 + 9, p2 - p1 - 10) ); passFilter_.first = boost::lexical_cast(filtered); passFilter_.second = boost::lexical_cast(original); firstLine = false; } } if (firstLine) { BOOST_THROW_EXCEPTION(CasavaException(EINVAL, "Wrong format: SignalMeans header should begin with '#'")); } } unsigned int SignalMeansTile::write(std::ostream &os) { for(std::vector::iterator it = baseCalls_.begin(); it != baseCalls_.end(); ++it) { if (it->isValid()) { os << *it; } } return baseCalls_.size(); } void SignalMeansTile::writeHeader(std::ostream &os) { os.seekp(0,std::ios::beg); os << boost::format("# Clusters: Filtered %u Original %u") % passFilter_.first % passFilter_.second << std::endl; os << boost::format("#") << std::endl; os << boost::format("#Lane\tCycle\tAll A\tAll C\tAll G\tAll T\tCall A\tCall C\tCall G\tCall T\tNum A\tNum C\tNum G\tNum T\tNum X") << std::endl; } void SignalMeansTile::clear(const std::list &remove) { // removes the list of elements provided as argument (needs to be sorted) for(std::list::const_reverse_iterator it=remove.rbegin(); it != remove.rend(); ++it) { baseCalls_.erase(baseCalls_.begin() + *it); } // ...and then set the remaining values to '0' for(std::vector::iterator it = baseCalls_.begin(); it != baseCalls_.end(); ++it) { if (it->isValid()) { it->setNumA(0); it->setNumC(0); it->setNumG(0); it->setNumT(0); it->setNumX(0); } } this->setNumFilteredClusters(0); this->setNumOriginalClusters(0); } void SignalMeansTile::incrementallyPopulate(std::string seq) { if ( seq.length() != baseCalls_.size() ) { BOOST_THROW_EXCEPTION(CasavaException(EINVAL, (boost::format("Length of sequence differs from space reserved for Tile's SignalMeans. Received: %u, reserved: %u") % seq.length() % baseCalls_.size() ).str() )); } for(unsigned int cycle=0; cycle < seq.length(); cycle++) { baseCalls_[cycle] += seq[cycle]; } } bool SignalMeansTile::isValid() { bool valid = true; for(unsigned int i=0; i < baseCalls_.size(); i++) { valid &= (baseCalls_[i].isValid() && (i == (baseCalls_[i].getCycle() - 1) )); } return valid; } void SignalMeansTile::makeValid() { for(unsigned int i=0; i < baseCalls_.size(); i++) { baseCalls_[i].setCycle(i+1); } } } // namespace common } // namespace casava