public CompactSAMSequence CreateTrimmedSequence(int newLength)
        {
            if (newLength > this.sequenceData.Length || newLength < 1)
            {
                throw new ArgumentOutOfRangeException("length");
            }

            byte[]  newSequenceData  = new byte[newLength];
            sbyte[] newQualityScores = new sbyte[newLength];

            Array.Copy(sequenceData, 0, newSequenceData, 0, newLength);
            Array.Copy(qualityScores, 0, newQualityScores, 0, newLength);

            //now to adjust cigar
            string newCigar = CIGAR;

            if (!CigarUtils.NoInformationCigar(CIGAR))
            {
                var elements = CigarUtils.GetCigarElements(CIGAR);
                int curLen   = 0;
                for (int i = 0; i < elements.Count; i++)
                {
                    var ce = elements [i];
                    var op = ce.Operation;
                    if (op == CigarOperations.HARD_CLIP || op == CigarOperations.DELETION)
                    {
                        continue;
                    }
                    else if (op == CigarOperations.PADDING || op == CigarOperations.SKIPPED)
                    {
                        throw new NotImplementedException();
                    }
                    else if (op == CigarOperations.SOFT_CLIP || op == CigarOperations.INSERTION || CigarOperations.OperationIsMatch(op))
                    {
                        curLen += ce.Length;
                        if (curLen == newLength)
                        {
                            newCigar = CigarUtils.CreateCigarString(elements.Take(i + 1));
                            break;
                        }
                        else if (curLen > newLength)
                        {
                            var dif = curLen - newLength;
                            ce.Length   -= dif;
                            elements [i] = ce;
                            newCigar     = CigarUtils.CreateCigarString(elements.Take(i + 1));
                            break;
                        }
                    }
                }
            }
            var ns = new CompactSAMSequence(this.Alphabet, this.FormatType, newSequenceData, newQualityScores, false);

            ns.Pos   = Pos;
            ns.CIGAR = newCigar;
            return(ns);
        }
        /// <summary>
        /// Unpacks the sequence so that it is aligned to the reference at the given start but ignoring insertions.
        /// Useful for Depth of Coverage;
        /// </summary>
        public void ProcessCountCoverageFromSequence(CompactSAMSequence orgSeq)
        {
            if (orgSeq == null || orgSeq.RName != StaticResources.MT_CHROMOSOME_NAME)
            {
                return;
            }
            string CIGAR = orgSeq.CIGAR;

            if (!CigarUtils.NoInformationCigar(CIGAR))
            {
                int curRef   = orgSeq.Pos - 1;
                var elements = CigarUtils.GetCigarElements(CIGAR);
                foreach (var v in elements)
                {
                    var len = v.Length;
                    switch (v.Operation)
                    {
                    case 'P':                     //padding (Silent deltions from padded reference)
                    case 'N':                     //skipped region from reference
                        throw new Exception("Not built to handle clipping yet");

                    case 'M':                     //match or mismatch
                    case '=':                     //match
                    case 'X':                     //mismatch
                        for (int k = 0; k < len; k++)
                        {
                            if (curRef >= StaticResources.CRS_LENGTH)
                            {
                                Debug.WriteLine("Seq: " + orgSeq.ID + " is aligned past the MT DNA reference genome");
                                break;
                            }
                            depthCounts [curRef] = depthCounts [curRef] + 1.0;
                            curRef++;
                        }
                        break;

                    case 'I':                    //insertion to the reference
                        break;

                    case 'D':                    //Deletion from the reference
                        curRef += len;
                        break;

                    case 'S':                    //soft clipped
                    case 'H':                    //had clipped
                        break;

                    default:
                        throw new FormatException("Unexpected SAM Cigar element found " + v.Operation.ToString());
                    }
                }
            }
        }
        public void TrimSequence(int newLength)
        {
            Count = newLength;
            if (newLength > this.sequenceData.Length || newLength < 1)
            {
                throw new ArgumentOutOfRangeException("length");
            }
            Array.Resize(ref sequenceData, newLength);
            Array.Resize(ref qualityScores, newLength);

            //now to adjust cigar
            string newCigar = CIGAR;

            if (!CigarUtils.NoInformationCigar(CIGAR))
            {
                var elements = CigarUtils.GetCigarElements(CIGAR);
                int curLen   = 0;
                for (int i = 0; i < elements.Count; i++)
                {
                    var ce = elements [i];
                    var op = ce.Operation;
                    if (op == CigarOperations.HARD_CLIP || op == CigarOperations.DELETION)
                    {
                        continue;
                    }
                    else if (op == CigarOperations.PADDING || op == CigarOperations.SKIPPED)
                    {
                        throw new NotImplementedException();
                    }
                    else if (op == CigarOperations.SOFT_CLIP || op == CigarOperations.INSERTION || CigarOperations.OperationIsMatch(op))
                    {
                        curLen += ce.Length;
                        if (curLen == newLength)
                        {
                            newCigar = CigarUtils.CreateCigarString(elements.Take(i + 1));
                            break;
                        }
                        else if (curLen > newLength)
                        {
                            ce.Length   -= curLen - newLength;
                            elements [i] = ce;
                            newCigar     = CigarUtils.CreateCigarString(elements.Take(i + 1));
                            break;
                        }
                    }
                }
            }
            CIGAR = newCigar;
        }
        /// <summary>
        /// Gets the reference sequence alignment length depending on the CIGAR value.
        /// </summary>
        /// <returns>Length of the alignment.</returns>
        private int getRefSeqAlignmentLengthFromCIGAR()
        {
            if (CigarUtils.NoInformationCigar(CIGAR))
            {
                return(0);
            }
            var elements = CigarUtils.GetCigarElements(CIGAR);
            int len      = 0;

            foreach (var v in elements)
            {
                if (CigarUtils.CigarElementis_MDNX_Equal(v.Operation))
                {
                    len += v.Length;
                }
            }
            return(len);
        }