/** ** 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 BclWriter.cpp ** ** \brief Reads BCL files and other associated files (filter, position). ** ** \author Come Raczy **/ #include #include #include #include #include #include #include #include #include "io/BclWriter.hh" #include "common/FastIo.hh" namespace casava { namespace io { namespace cc = casava::common; BclWriter::BclWriter(const fs::path &path, const cc::Compression &compressor, const unsigned int expectedClusters) : outputFilePath_(path.string() + compressor.getFileNameExtension()), os_(compressor), currentCluster_(0) , expectedClusters_(expectedClusters) { open(); } BclWriter::BclWriter(const fs::path &path, const unsigned int expectedClusters) : outputFilePath_(path), os_(cc::CompressionFactory::none()), currentCluster_(0) , expectedClusters_(expectedClusters) { open(); } void BclWriter::open() { using boost::format; if (fs::exists(outputFilePath_)) { BOOST_THROW_EXCEPTION(cc::IoException(errno, "File already exists: " + outputFilePath_.string())); } os_.open(outputFilePath_.string().c_str()); if (!os_) { BOOST_THROW_EXCEPTION(cc::IoException(errno, "Couldn't open BCL file: " + outputFilePath_.string())); } if (!cc::writeUnsignedInteger<4>(os_, expectedClusters_)) { BOOST_THROW_EXCEPTION(casava::common::PreConditionException("Failed to write into: " + outputFilePath_.string())); } } BclWriter::~BclWriter() { } void BclWriter::close() { if(os_.is_open()) { if (expectedClusters_ != currentCluster_) { if (!os_.seekp(0, std::ios_base::beg) || !cc::writeUnsignedInteger<4>(os_, currentCluster_)) { BOOST_THROW_EXCEPTION(cc::IoException(errno, "Failed to write number of clusters into BCL: " + outputFilePath_.string())); } } os_.close(); currentCluster_ = 0; } } void BclWriter::writeBase(const char &base, const char &qual) { static const struct Base2Bits: public std::vector { Base2Bits() : std::vector('t' + 1, '?') { at('A') = 0; at('C') = 1; at('G') = 2; at('T') = 3; at('N') = 0; } } base2Bits; // N is encoded as A but we'll make sure to set the quality to 0 in this case const char translatedBase(base2Bits[static_cast(base)]); if ('?' == translatedBase){ BOOST_THROW_EXCEPTION(cc::InvalidParameterException( (boost::format("Non-ACGT bases not supported in BCL. Given: %c") % base).str())); } const char c = ('N' == base ? 0 : (qual - 64) << 2) | translatedBase; if (!os_.put(c)) { BOOST_THROW_EXCEPTION(cc::IoException(errno, "Failed to write BCL file: %s" + outputFilePath_.string())); } } } // namespace alignment } // namespace casava