Esempio n. 1
0
        // writes an alignment
        public void WriteAlignment(BamAlignment al)
        {
            if (!IsOpen)
            {
                throw new IOException(string.Format("ERROR: Tried to write an alignment but the file has not been opened yet."));
            }

            // initialize
            uint nameLen            = (uint)al.Name.Length + 1;
            uint numBases           = (uint)al.Bases.Length;
            uint numCigarOperations = (uint)al.CigarData.Count;
            uint packedCigarLen     = numCigarOperations * 4;
            uint numEncodedBases    = (uint)((numBases / 2.0) + 0.5);
            uint tagDataLen         = (uint)al.TagData.Length;
            uint dataBlockSize      = nameLen + packedCigarLen + numEncodedBases + numBases + tagDataLen;
            uint alignBlockSize     = BamConstants.CoreAlignmentDataLen + dataBlockSize;
            uint blockSize          = alignBlockSize + 4;
            int  offset             = 0;

            // test if we should flush the block
            if ((BlockOffset + blockSize) > MaxBlockSize)
            {
                FlushBlock();
            }

            // redimension the buffer if needed
            if (blockSize > _outputBuffer.Length)
            {
                _outputBuffer = new byte[blockSize + 1024];
            }

            // store the block size
            BinaryIO.AddUIntBytes(ref _outputBuffer, ref offset, alignBlockSize);

            // store the BAM core data
            BinaryIO.AddIntBytes(ref _outputBuffer, ref offset, al.RefID);
            BinaryIO.AddIntBytes(ref _outputBuffer, ref offset, al.Position);
            BinaryIO.AddUIntBytes(ref _outputBuffer, ref offset, (al.Bin << 16) | (al.MapQuality << 8) | nameLen);
            BinaryIO.AddUIntBytes(ref _outputBuffer, ref offset, (al.AlignmentFlag << 16) | numCigarOperations);
            BinaryIO.AddUIntBytes(ref _outputBuffer, ref offset, numBases);
            BinaryIO.AddIntBytes(ref _outputBuffer, ref offset, al.MateRefID);
            BinaryIO.AddIntBytes(ref _outputBuffer, ref offset, al.MatePosition);
            BinaryIO.AddIntBytes(ref _outputBuffer, ref offset, al.FragmentLength);

            // store the alignment name
            BinaryIO.AddNullTerminatedString(ref _outputBuffer, ref offset, al.Name);

            // store the packed CIGAR string and packed bases
            PackCigar(ref offset, ref _outputBuffer, al.CigarData);
            PackBases(ref offset, numEncodedBases, al.Bases);

            // store the base qualities
            Buffer.BlockCopy(al.Qualities, 0, _outputBuffer, offset, al.Qualities.Length);
            offset += al.Qualities.Length;

            // store the tag data
            Buffer.BlockCopy(al.TagData, 0, _outputBuffer, offset, al.TagData.Length);
            offset += al.TagData.Length;

            // write the alignment
            Write(_outputBuffer, blockSize);
        }