/** ** 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 Bcl2FastqRecordConverter.hh ** ** \brief Converts between a composite BCL record and a Fastq record. ** ** \author Roman Petrovski **/ #ifndef CASAVA_DEMULTIPLEX_BCL_2_FASTQ_RECORD_CONVERTER_HH #define CASAVA_DEMULTIPLEX_BCL_2_FASTQ_RECORD_CONVERTER_HH #include #include "io/FastqWriter.hh" #include "demultiplex/CompositeBclReader.hh" #include "demultiplex/MaskQvalsByEamss.hh" namespace casava { namespace demultiplex { /** * @brief Converts CompositeBclReader::RecordType object into FastqWriter::RecordType one. * Tries to reduce the memory management by reusing an object across multiple conversion * calls. Therefore - not thread-safe. */ struct Bcl2FastqRecordConverter { // converts the Illumina BQ offset (64) to the FASTQ BQ offset (33) struct IlluminaToFastqOffset { char operator()(char c) { return c - 31; } }; Bcl2FastqRecordConverter(const std::string &instrumentName, const unsigned int runNumber, const std::string &flowCellId, const unsigned int lane, const unsigned int tile, const unsigned int readNumber, const bool withEamss, const bool unified, const unsigned barcodeCycles) : buffer_(instrumentName, runNumber, flowCellId, lane, tile, std::make_pair(0,0), "", readNumber, false, 0, std::make_pair("", "")) , unifiedFilterControl(unified) , withEamss(withEamss) , maskQvalsByEamss() , barcodeCycles_(barcodeCycles) {} const cio::FastqWriter::RecordType &operator()(const CompositeBclReader::RecordType &bclRecord) const { buffer_.position_.first = static_cast(roundf(1000.0f + 10.0f * bclRecord.position_.first)); buffer_.position_.second = static_cast(roundf(1000.0f + 10.0f * bclRecord.position_.second)); buffer_.barcode_ = bclRecord.cluster_.first.substr(bclRecord.cluster_.first.size() - barcodeCycles_);; buffer_.filter_ = static_cast(0x01 & bclRecord.filter_); buffer_.control_ = static_cast(0xFFFE & (unifiedFilterControl ? bclRecord.filter_ : bclRecord.control_) ); buffer_.cluster_.first = bclRecord.cluster_.first.substr(0, bclRecord.cluster_.first.size() - barcodeCycles_); buffer_.cluster_.second.clear(); const std::string::const_iterator dataCyclesEnd = bclRecord.cluster_.second.begin() + bclRecord.cluster_.second.size() - barcodeCycles_; if (withEamss) { std::copy(bclRecord.cluster_.second.begin(), dataCyclesEnd, std::back_inserter(buffer_.cluster_.second)); maskQvalsByEamss(buffer_.cluster_.second, bclRecord.cluster_.first); std::transform(buffer_.cluster_.second.begin(), buffer_.cluster_.second.end(), buffer_.cluster_.second.begin(), IlluminaToFastqOffset()); } else { std::transform(bclRecord.cluster_.second.begin(), dataCyclesEnd, std::back_inserter(buffer_.cluster_.second), IlluminaToFastqOffset()); } return buffer_; } private: mutable cio::FastqWriter::RecordType buffer_; const bool unifiedFilterControl; const bool withEamss; const MaskQvalsByEamss maskQvalsByEamss; const unsigned barcodeCycles_; }; } // namespce demultiplex } // namespace casava #endif // CASAVA_DEMULTIPLEX_BCL_2_FASTQ_RECORD_CONVERTER_HH