Exemplo n.º 1
0
        /// <summary>
        /// We're finished processing a read.  Add it to the read buffer, and flush
        /// old nodes to disk.
        /// </summary>
        public void WriteRead(ref BamAlignment read, bool remapped)
        {
            if (remapped)
            {
                var info = new RemapInfo(read.Position,
                                         read.Position + (int)read.CigarData.GetReferenceSpan() - 1);
                _remappings[string.Format("{0}-{1}", read.Name, read.IsFirstMate() ? 1 : 2)] = info;
            }

            LinkedListNode <ReadsForPosition> node = _readBuffer.First;
            LinkedListNode <ReadsForPosition> nextNode;

            byte[] buffer = BamWriter.SerializeAlignment(ref read);
            while (node != null)
            {
                // Flush reads that are earlier than the earliest possible read we could see in the future (i.e. 2x max shift less than current read).
                // Reasoning: The realign shift could go in two directions. So, for example with max shift of 10, you could receive
                // and buffer reads in an order like this: 100, 100, 110, 115 (originally 110, shifted right to 115),
                // 100 (originally 110, shifted left to 100), 120 (originally 110, shifted right to 120),
                // 101 (originally 110, shifted left to 100), 121, 130, etc. If you had been flushing reads
                // using the max shift only as the threshold, upon hitting the 115 (fourth read) you would have
                // flushed the 100s (because 100 < 115 - 10), even though there still may be 100s coming through.
                // By the time we hit 121, we know that all of the reads we encounter in the future are going to be > 100 (at minimum, the 121 could represent a max-right-shift from 111 and other 111 reads could be max-left-shifted to 101).
                if (node.Value.Position < read.Position - (_maxRealignShift * 2))
                {
                    MinimumRealignmentStartPosition = Math.Max(MinimumRealignmentStartPosition, node.Value.Position);
                    nextNode = node.Next;
                    FlushBufferedRecords(node.Value);
                    _readBuffer.Remove(node);
                    node = nextNode;
                    continue;
                }
                if (node.Value.Position == read.Position)
                {
                    node.Value.Reads.Add(buffer);
                    return;
                }
                if (node.Value.Position > read.Position)
                {
                    ReadsForPosition reads = new ReadsForPosition();
                    reads.Position = read.Position;
                    reads.Reads.Add(buffer);
                    _readBuffer.AddBefore(node, reads);
                    return;
                }
                node = node.Next;
            }
            ReadsForPosition readList = new ReadsForPosition();

            readList.Position = read.Position;
            readList.Reads.Add(buffer);
            _readBuffer.AddLast(readList);
        }
Exemplo n.º 2
0
        private void AdjustMates(string tmpFile, BamWriter writer)
        {
            // Second pass: Adjust flags on mates
            Logger.WriteToLog("Writing reads with corrected mate flags, {0} total remapped reads", _remappings.Count);
            var read = new BamAlignment();

            using (var reader = new BamReader(tmpFile))
            {
                while (true)
                {
                    var result = reader.GetNextAlignment(ref read, false);
                    if (!result)
                    {
                        break;
                    }

                    // Adjust flags as needed:
                    var       mateKey = string.Format("{0}-{1}", read.Name, read.IsFirstMate() ? 2 : 1);
                    RemapInfo info;

                    if (!_remappings.TryGetValue(mateKey, out info))
                    {
                        writer.WriteAlignment(read);
                        continue;
                    }

                    if (info.Start == -1)
                    {
                        read.SetIsMateUnmapped(true);
                        read.SetIsProperPair(false);
                        read.FragmentLength = 0;
                    }
                    else
                    {
                        read.MatePosition = info.Start;
                    }
                    if (read.IsMateMapped() && read.IsProperPair())
                    {
                        int readEnd = read.Position + (int)read.CigarData.GetReferenceSpan() - 1;
                        // todo jg - should FragmentLength be 0 if the reads are mapped to diff chrs
                        read.FragmentLength = (read.Position < info.Start
                            ? info.End - read.Position + 1
                            : info.Start - readEnd - 1);
                    }

                    writer.WriteAlignment(read);
                }
            }
        }