Source code for MSQuant: PTMscorer.vb, MSQuant/msquant/src/main/massbase/PTMscorer.vb.

Table of contents page.

Home page for MSQuant.

'****************************************************************************
'* Copyright (C) 2005 Peter Mortensen and Matthias Mann                     *
'* This file is part of MSQuant.                                            *
'*                                                                          *
'* MSQuant is distributed under the terms of                                *
'* the GNU General Public License. See src/COPYING.TXT or                   *
'* <http://www.gnu.org/licenses/gpl.txt> for details.                       *
'*                                                                          *
'* MSQuant is free software; you can redistribute it                        *
'* and/or modify it under the terms of the GNU                              *
'* General Public License as published by the Free                          *
'* Software Foundation; either version 2 of the                             *
'* License, or (at your option) any later version.                          *
'*                                                                          *
'* MSQuant is distributed in the hope that it will be                       *
'* useful, but WITHOUT ANY WARRANTY; without even the                       *
'* implied warranty of MERCHANTABILITY or FITNESS FOR                       *
'* A PARTICULAR PURPOSE.  See the GNU General Public                        *
'* License for more details.                                                *
'*                                                                          *
'* You should have received a copy of the GNU General                       *
'* Public License along with MSQuant; if not, write to                      *
'* the Free Software Foundation, Inc., 59 Temple                            *
'* Place, Suite 330, Boston, MA  02111-1307  USA                            *
'*                                                                          *
'* Purpose: Holds class PTMscorer, see below for documentation.             *
'*                                                                          *
'****************************************************************************

'****************************************************************************
'*                               CEBI                                       *
'*                    Software Development Group                            *
'*                         Peter Mortensen                                  *
'*                E-mail: NUKESPAMMERSdrmortensen@get2netZZZZZZ.dk          *
'*                 WWW: http://www.cebi.sdu.dk/                             *
'*                                                                          *
'*  Program for postprocessing of MS-MS search result                       *
'*                                                                          *
'*    FILENAME:   PTMscorer.vb                                              *
'*    TYPE:  VISUAL_BASIC                                                   *
'*                                                                          *
'* CREATED: PM 2005-08-08   Vrs 1.0.                                        *
'* UPDATED: PM 2005-xx-xx                                                   *
'*                                                                          *
'****************************************************************************

Option Strict On
Option Explicit On 

Imports System.Text  'For StringBuilder
'Imports System.Collections.Specialized 'For BitVector32
Imports System.Collections.Generic 'For Dictionary

Imports MolecularSharedStructures 'For modificationCountStructure

'Changed PM_MOD_PREFIX_AND_POSTFIX 2006-06-07
Imports massSpectrometryBase.quantitation 'For QuantitationModes_moreGeneral

Imports SDUPutility 'For SDUPbitHandler


'****************************************************************************
'd$ <summary>
'd$   Purpose: Namespace for lower layers of mass spectrometric
'd$            applications: raw data file handling, descriptive statistics,
'd$            fragment masses, digestion, file associations, etc.
'd$   <see cref="T:VBXMLDoc.CVBXMLDoc" />.
'd$   <isUnitTest></isUnitTest>
'd$   <applicationname>test_rawDataFileHandling</applicationname>
'd$   <author>Peter Mortensen</author>
'd$   <seealso>http://www.cebi.sdu.dk/</seealso>
'd$   <codetype>PLATFORM independent</codetype>
'd$ </summary>
Namespace massSpectrometryBase

    'Structures that clients will use to represent one or more PTMs.

    'Changed PM_REFACTOR 2006-12-17
    'Structure onePTMStructure moved to MSQuantCommon2.vb in order
    'to be visible from clsMolShrStruct.vb. Is this the right 
    'way to do it?

    'Changed PM_REFACTOR 2006-12-17
    'Structure onePTMcombinationStructure moved to MSQuantCommon2.vb in order
    'to be visible from clsMolShrStruct.vb.

    'All these structures may not need to be Public...

    Public Structure AApositionInfoStructure
        Dim forwardIonMassDiff As Double
        Dim backwardIonMassDiff As Double
    End Structure 'AApositionInfoStruct


    Public Structure combItemStructure

        Dim pattern4_old As Integer 'Used as a bit vector. We do
        '  this to be able to do bitwise AND/OR (not possible
        '  with array of Booleans).
        '  Note: we are limited to 31 modified AAs. But our
        '        current brute-force approach becomes too slow before
        '        we reach this limit...


        Dim pattern4() As Integer 'Each integer represents which 
        '  PTM positions are active (for a combination).


        'Changed PM_MARKER 2006-07-02
        'Use AND masks to test for individual bits???

        'The array types used before could keep track, but now
        'we need to do it ourselves. Should we create a utility class
        'for this purpose? Such a class could also contain the AND masks
        'for getting the value of individual bits.
        Dim patternLen As Integer

        Dim trues As Integer
    End Structure 'combItemStructure


    'Changed PM_PTMBUG 2006-07-03
    Public Structure modCountCheckStructure
        Dim bitVector7 As Integer 'To mask out bits in a combination
        Dim targetCount As Integer

        Dim modAAs As String 'Copied from the fields AA
        '  of a quantModificationStructure.
    End Structure 'modCountCheckStructure


    'Not yet, we use a hash, (AA, count), for the moment.
    ''Do we already something like this somewhere else?
    'Public Structure AAcombStructure
    'End Structure


    '****************************************************************************
    '*  SUBROUTINE NAME:   PTMcomb_SortByScore_usingIndex                       *
    'd$ <summary> N/A. ...  
    'd$      Note: xyz                    </summary>
    Class PTMcomb_SortByScore_usingIndex
        'Implements IComparer
        Implements System.Collections.Generic.IComparer(Of Integer)

        Dim mCombinations2 As List(Of onePTMcombinationStructure)

        '****************************************************************************
        '*    <placeholder for header>                                              *
        '****************************************************************************
        Sub New(ByVal aCombinations2 As List(Of onePTMcombinationStructure))
            'Type of aCombinations is onePTMcombinationStructure.

            mCombinations2 = aCombinations2
        End Sub 'New


        '****************************************************************************
        '*    <placeholder for header>                                              *
        '****************************************************************************
        Function Compare( _
          ByVal aItem1 As Integer, _
          ByVal aItem2 As Integer) _
          As Integer _
          Implements _
            System.Collections.Generic.IComparer(Of Integer).Compare

            Dim comb1 As onePTMcombinationStructure = mCombinations2(aItem1)
            Dim comb2 As onePTMcombinationStructure = mCombinations2(aItem2)

            'Note: descending sort
            Dim toReturn As Integer = 0
            If comb1.score < comb2.score Then
                toReturn = 1
            Else
                If comb1.score > comb2.score Then
                    toReturn = -1
                Else
                    'Equal.... 
                    Dim peter9 As Integer = 9
                End If
            End If
            Return toReturn
        End Function 'Compare
    End Class 'PTMcomb_SortByScore_usingIndex


    'Changed PM_PHOSPHO_SCORING 2005-08-07
    '****************************************************************************
    '*    Class PTMscorer.                                                      *
    '*                                                                          *
    '*    Purpose:  Scoring of spectrum with information about position of      *
    '*              post translational modifications (e.g phosphorylation)  -   *
    '*              and associated utility functions.                           *
    '*                                                                          *
    '****************************************************************************
    Public Class PTMscorer

        'Changed PM_BROADER_PTMSCORE 2007-03-27
        Private Structure singleModStackItemStructure

            'Dim curCount As Integer
            Dim bitHandler As SDUPbitHandler 'Has min, max and current state.

            Dim startState As Boolean 'Marker that bitHandler has just been 
            '  initialised.
            Dim curBitVector As Integer
        End Structure 'singleModStackItemStructure


        'Changed PM_BROADER_PTMSCORE 2007-03-27
        'Cached information about a modification in a form suitable.
        'It also contains peptide dependent fields, e.g. AND masks.
        Private Structure positionRefStructure
            Dim posIndex As Integer 'Index into mPTMpositions2, the
            '  list modification sites in the peptide.

            'Dim maxMods As Integer 'Usually 1, but can be 3 for methylation.
        End Structure 'positionRefStructure


        'Changed PM_BROADER_PTMSCORE 2007-03-27
        Private Structure internalModsStructure
            Dim posRefs As List(Of positionRefStructure)

            Dim modID2 As Integer
            Dim name2 As String 'For info/reference only.

            Dim countFromMascot As Integer

            'This is not needed at all. Multiple modifications are always
            'handled by having separate modifications. E.g. 3 different
            'modifications for 1xMethylation, 2xMethylation and 3xMethylation.
            'Dim maxModsPerPosition As Integer 'Usually 1, but can be 3 for methylation.
        End Structure 'internalModsStructure


        Private mPeptideSeq As String
        Private mPepSize As Integer

        'Changed PM_PHOSPHO_SCORING_USERSEL 2006-01-05
        Private mModificationCount As Integer


        'Changed PM_MARKER_PTM 2007-03-26
        'Old.
        Private mPTMpositions_old As ArrayList

        'Changed PM_TYPESAFE 2007-04-03
        'Private mCombs As ArrayList 'Real type is combItemStructure
        Private mCombs2 As List(Of combItemStructure)

        Private mMaxPTMs As Integer

        'Changed PM_REFACTOR 2007-04-02
        'Private mCurIonDiffs As ArrayList 'Real type is ionSetStructure
        Private mCurIonDiffs2 As List(Of ionSetStruct)

        Private mReadIndex As Integer
        Private mReadDirectionForward As Boolean
        Private mLastReadIndex As Integer


        'Changed PM_BROADER_PTMSCORE 2007-03-16
        Private mQuantitationModes As QuantitationModes_moreGeneral
        'Derived
        Private mSILACmods As Dictionary(Of Integer, Boolean)
        Private mModifications As List(Of modificationCountStruct)

        'Changed PM_BROADER_PTMSCORE 2007-03-23
        Private mAAs As Dictionary(Of String, Integer)
        Private mPTMpositions2 As List(Of PTMinfoStructure)
        'Private mBitHandler As SDUPbitHandler

        'Note: this is for caching of modification information that is
        '      independent. It can also be seen as another way to
        '      represent modifications, using hashes.
        '
        'Do we need extra information besides the mass differences? In
        'that case the value of the first level hash would be a
        'structure instead of another hash.
        '
        'First level:  key is modID. 
        'Second level: key is amino acid letter. Value is mass difference.
        Private mModInfo As Dictionary(Of Integer, Dictionary(Of String, Double))

        Private mPositionMassDiffs() As Double


        '****************************************************************************
        '*  SUBROUTINE NAME:   New                                                  *
        'd$ <summary>Constructor</summary>
        Public Sub New( _
          ByRef anInQuantitationModes As QuantitationModes_moreGeneral, _
          ByVal anInQuantModeCode As Integer)

            MyBase.New() 'Is this necessary? Yes!

            'InitializeComponent()    Is this necessary??

            'Changed PM_BROADER_PTMSCORE 2007-03-16
            If True Then
                mQuantitationModes = anInQuantitationModes

                'Immediately derive 
                mSILACmods = _
                  anInQuantitationModes.modificationIDsForQuantitationMode( _
                    anInQuantModeCode)
            End If

            mMaxPTMs = 0 'We lazy instantiate mCombs2. mCombs2 is also rewritten
            '  if a peptide have more sites than the current number. 
            mCombs2 = Nothing 'Lazy instantiation...

            If True Then
                Dim int1 As Integer = 477
                Dim int2 As Integer = 120
                Dim int3 As Integer = int1 And int2 'It works!!! int3
                '  is 88, corresponding to bitwise "and"....

                Trace.Assert(int3 = 88, "PIL ASSERT. <message>.") 'Perhaps this
                '  should be in a general section (e.g. application object)
                '  and only checked at program startup?
            End If

            ''Changed PM_BROADER_PTMSCORE 2007-03-29
            'mBitHandler = New SDUPbitHandler

            ReDim mPositionMassDiffs(1) 'To avoid having to check for Nothing
            '  for every use.
        End Sub 'New()


        'Changed PM_BROADER_PTMSCORE 2007-03-23
        '  Is this functionality somewhere else???
        '****************************************************************************
        '*    <placeholder for header>                                              *
        '****************************************************************************
        Private Shared Function peptideInventory( _
          ByRef anInPeptideSequence As String) _
          As Dictionary(Of String, Integer)

            Dim toReturn As Dictionary(Of String, Integer) = _
              New Dictionary(Of String, Integer)

            Dim slen As Integer = anInPeptideSequence.Length()
            If True Then 'Speculate that most modifications will affect the entire
                '  peptide (non-terminal modifications). Construct hash with the
                '  amino acid content for the peptide sequence.

                Dim lastIndex As Integer = slen - 1
                Dim j As Integer
                For j = 0 To lastIndex Step 1
                    Dim AA As String = anInPeptideSequence(j)

                    Dim someValue As Integer
                    If toReturn.TryGetValue(AA, someValue) Then
                        'Exists. Update count.
                        Dim newCount As Integer = someValue + 1
                        toReturn(AA) = newCount
                    Else
                        toReturn.Add(AA, 1)
                    End If
                Next j
            End If

            Return toReturn
        End Function 'peptideInventory


        'Changed PM_BROADER_PTMSCORE 2007-03-23
        'Changed PM_TERMMOD_MARKER 2007-09-10. This function is not called from anywhere!
        '****************************************************************************
        '*    <placeholder for header>                                              *
        '****************************************************************************
        Private Function deriveAffectedAAs2( _
          ByRef anInPeptideSequence As String, _
          ByRef anInModifications As List(Of modificationCountStruct)) _
          As Dictionary(Of String, Integer)

            'Not yet...
            Trace.Assert(False, "Stop!", _
              "PIL ASSERT. Internal/development assert for stopping execution......")

            'Changed PM_TERMMOD_MARKER 2007-09-10
            'Find set of amino acids that are affected by the current 
            'modification(s). This includes observing position 
            'restrictions for terminal modifications.

            Dim toReturn As Dictionary(Of String, Integer) = Nothing
            'Dim slen As Integer = anInPeptideSequence.Length()

            Dim slen As Integer = anInPeptideSequence.Length()
            Dim AAs As Dictionary(Of String, Integer) = _
              PTMscorer.peptideInventory(anInPeptideSequence)

            Dim allModsAllPositions As Boolean = True
            Dim someMod As modificationCountStruct
            For Each someMod In anInModifications 'Note: list does not contain SILAC
                '  modifications.

                If toReturn Is Nothing Then 'Lazy instantiation.
                    toReturn = New Dictionary(Of String, Integer)
                End If

                Dim modID As Integer = someMod.quantModificationID
                Dim modCount As Integer = someMod.count3

                Dim modInfo As _
                  quantModificationStructure = _
                    mQuantitationModes.getModification(modID)

                Dim allPositions As Boolean
                Dim startPos As Integer
                Dim endPos As Integer
                Dim maxMods As Integer
                'Convert from peptide region specification to actual 
                'indices into the peptide sequence.
                PILpeptide.findPositionsEtc( _
                  modInfo.startPosition, modInfo.endPosition, slen, _
                  allPositions, startPos, endPos, maxMods)

                If allPositions Then
                    'We do not have to go through the peptide sequence as we have
                    'cached the peptide's amino acids in a hash. 
                Else
                    'Note: as we have to observe position restrictions we can
                    '      not just make.
                    allModsAllPositions = False
                End If

                Dim peter2 As Integer = 2
            Next 'Through modifications.

            Return toReturn
        End Function 'deriveAffectedAAs


        '****************************************************************************
        '*    <placeholder for header>                                              *
        '****************************************************************************
        Private Function findAffectedAAs( _
          ByRef anInModifications As List(Of modificationCountStruct), _
          ByRef anInPeptideSequence As String) _
          As Dictionary(Of String, Integer)

            'Changed PM_TERMMOD 2007-09-10. As modifications can now affect a
            '  subset of the peptide sequence we can cut down on the number of
            '  affected amino acids. This is particular important for terminal
            '  modifications that affects all amino acids, but only one amino acid 
            '  for a particular peptide.

            'Assume client has checked it.
            Trace.Assert(Not anInModifications Is Nothing, _
              "PIL ASSERT. anInModifications is nothing. In findAffectedAAs().")
            Trace.Assert(anInModifications.Count() > 0, _
              "PIL ASSERT. anInModifications has a length of zero. " & _
              "In findAffectedAAs().")

            Dim toReturn As Dictionary(Of String, Integer) = _
              New Dictionary(Of String, Integer)

            Dim pepLen As Integer = anInPeptideSequence.Length()


            Dim someMod As modificationCountStruct
            For Each someMod In anInModifications

                Dim modInfo As quantModificationStructure = _
                  mQuantitationModes.getModification(someMod.quantModificationID)

                'Changed PM_TERMMOD 2007-09-10
                Dim allPositions As Boolean
                Dim startPos As Integer
                Dim endPos As Integer
                Dim maxMods As Integer
                PILpeptide.findPositionsEtc( _
                  modInfo.startPosition, modInfo.endPosition, pepLen, _
                  allPositions, startPos, endPos, maxMods)

                Dim someAAset As AAsetStruct
                For Each someAAset In modInfo.affectedAAs

                    Dim lastIndex As Integer = someAAset.AAs.Length() - 1
                    Dim j As Integer

                    For j = 0 To lastIndex
                        Dim AA As String = someAAset.AAs(j)

                        'Changed PM_TERMMOD 2007-09-10
                        'Only use the amino acid if it is actually in the peptide
                        'sequence and if in the subset of the peptide that is
                        'specified.
                        Dim AAisActive As Boolean = False
                        Dim k As Integer
                        For k = startPos To endPos

                            If AA = anInPeptideSequence(k) Then
                                AAisActive = True
                                Exit For
                            End If
                        Next 'Through subset of peptide sequence.

                        'Changed PM_TERMMOD 2007-09-10
                        If AAisActive Then
                            Dim aminoAcidCount As Integer = 0
                            If toReturn.TryGetValue(AA, aminoAcidCount) Then
                                Dim peter3 As Integer = 3
                                'No update of count. We don't need it.
                            Else
                                toReturn.Add(AA, 1)
                            End If
                        Else
                            Dim peter2 As Integer = 2
                        End If

                    Next j
                Next 'Through affectedAAs
            Next 'Through modifications.

            Return toReturn
        End Function 'findAffectedAAs


        'Changed PM_BROADER_PTMSCORE 2007-03-26
        '****************************************************************************
        '*    <placeholder for header>                                              *
        '****************************************************************************
        Private Sub filterOutSILACandOthers( _
          ByRef anInModifications As List(Of modificationCountStruct), _
          ByVal aPeptideLength As Integer, _
          ByRef anOutFilteredMods As List(Of modificationCountStruct))

            '  Filter out the SILAC modifications from the passed list of 
            '  modifications. mSILACmods was set in the constructor.
            '  
            '  Also filter out those modifications where all possible sites 
            '  are modified.
            '  
            '  In fact we do not need to score terminal modifications at 
            '  all (or any modification that only affects a single 
            '  position).

            anOutFilteredMods = Nothing 'Just in case.

            Dim nonSILACmods As List(Of modificationCountStruct) = _
              Nothing 'Lazy instantiation. We also use it as a flag.

            Dim someMod As modificationCountStruct
            For Each someMod In anInModifications

                Dim modID As Integer = someMod.quantModificationID
                Dim MascotCount As Integer = someMod.count3
                Dim useModification As Boolean = True

                Dim someValue As Boolean
                If Not mSILACmods.TryGetValue(modID, someValue) Then

                    'Not SILAC modification...

                    'Find out if there is only one possibility:
                    '  1. The number indicated by Mascot is equal to
                    '     the number of possible sites.

                    Dim modInfo As _
                      quantModificationStructure = _
                        mQuantitationModes.getModification(modID)
                    Dim allPositions As Boolean
                    Dim startPos As Integer
                    Dim endPos As Integer
                    Dim maxMods As Integer
                    PILpeptide.findPositionsEtc( _
                      modInfo.startPosition, modInfo.endPosition, aPeptideLength, _
                      allPositions, startPos, endPos, maxMods)

                    Dim modCount As Integer = 0

                    Dim someAAset As AAsetStruct
                    For Each someAAset In modInfo.affectedAAs

                        Dim lastIndex As Integer = someAAset.AAs.Length() - 1
                        Dim j As Integer
                        For j = 0 To lastIndex Step 1
                            Dim AA As String = someAAset.AAs(j)

                            If allPositions Then
                                'Relatively easy: add up counts using the cached
                                'information in a hash about the peptide sequence.

                                Dim aminoAcidCount As Integer = 0
                                If mAAs.TryGetValue(AA, aminoAcidCount) Then
                                    Dim peter3 As Integer = 3
                                End If

                                modCount += aminoAcidCount * maxMods
                            Else

                                'Changed PM_TERMMOD 2007-09-10
                                'Note: we don't need to implement it as we want
                                '      a PTM score in any case.
                                Dim peter2 As Integer = 2

                                ''Implement later.
                                'Trace.Assert(False, "Stop!", _
                                '  "PIL ASSERT. Internal/development assert for stopping execution......")

                            End If
                        Next j
                    Next 'Through affectedAAs

                    Dim onlyOnePossibility As Boolean = _
                      MascotCount = modCount


                    If onlyOnePossibility Then

                        'Changed PM_PTMSCORE_ALL_MODIFIED 2007-08-03
                        'useModification = False   disabled now. Users wanted
                        'it - a PTM score even if there is only one possibility.
                    Else
                        Dim peter2 As Integer = 2
                    End If

                Else
                    useModification = False 'SILAC modification...
                End If

                If useModification Then
                    If nonSILACmods Is Nothing Then
                        'Lazy instantiation.
                        nonSILACmods = New List(Of modificationCountStruct)
                    End If
                    nonSILACmods.Add(someMod)
                End If
            Next 'Through modifications for peptide.

            anOutFilteredMods = nonSILACmods
        End Sub 'filterOutSILACandOthers


        'Changed PM_BROADER_PTMSCORE 2007-03-27
        '****************************************************************************
        '*    <placeholder for header>                                              *
        '****************************************************************************
        Private Shared Function collapseAAs( _
          ByRef anInAffectedAAs As List( _
          Of massSpectrometryBase.quantitation.AAsetStruct)) _
          As String


            'Future: the collapsed set is now actually cached in the
            '        modification, field "INTERNAL_collapsedAAset".

            Dim toReturn As String = Nothing

            If anInAffectedAAs.Count() = 1 Then
                toReturn = anInAffectedAAs(0).AAs
            Else
                Dim AASB As StringBuilder = New StringBuilder(10)
                Dim someItem As AAsetStruct
                For Each someItem In anInAffectedAAs
                    AASB.Append(someItem.AAs)
                Next
                toReturn = AASB.ToString()
            End If

            Return toReturn
        End Function 'collapseAAs


        'Changed PM_BROADER_PTMSCORE 2007-03-30
        '****************************************************************************
        '*    <placeholder for header>                                              *
        '****************************************************************************
        Private Sub updateModificationInformation( _
          ByRef anInModifications As List(Of modificationCountStruct))

            'Note: all this is not specific to PTM scoring. It could be in a
            '      more general place.

            'Cached in this class:
            '  1st level hash with
            '  modification code/ID as key.
            '  Value is something with
            '  a second level hash;
            '  key is AA, value is
            '  mass.

            'Lazy instantiation
            If mModInfo Is Nothing Then
                mModInfo = _
                  New Dictionary(Of Integer, Dictionary(Of String, Double))(15)
            End If

            Dim someItem As modificationCountStruct
            For Each someItem In anInModifications

                Dim modID As Integer = someItem.quantModificationID

                Dim massHash As Dictionary(Of String, Double) = Nothing
                If mModInfo.TryGetValue(modID, massHash) Then
                    'Already cached. Nothing to do.
                    Dim peter2 As Integer = 2
                Else
                    Dim modi As _
                      quantModificationStructure = _
                        mQuantitationModes.getModification(modID)

                    massHash = New Dictionary(Of String, Double)(5)

                    Dim someItem2 As AAsetStruct
                    For Each someItem2 In modi.affectedAAs
                        Dim lastIndex As Integer = _
                          someItem2.AAs.Length() - 1
                        Dim j As Integer
                        For j = 0 To lastIndex
                            Dim AA As String = someItem2.AAs(j)
                            massHash.Add(AA, someItem2.diffFromBase3)

                            'Changed PM_TERMMOD_FRAGMENTMASS_TROUBLE_MARKER 2007-09-14
                            'May have to be much more complex, terminal mods, etc.
                        Next j

                    Next 'Through AA sets.
                    mModInfo.Add(modID, massHash)
                End If
            Next 'Through modifications
        End Sub 'updateModificationInformation


        'Changed PM_BROADER_PTMSCORE 2007-03-30
        '****************************************************************************
        '*    <placeholder for header>                                              *
        '****************************************************************************
        Private Sub findPositionMassDifferences( _
          ByRef anInStack As List(Of singleModStackItemStructure), _
          ByRef anInModsInfo As List(Of internalModsStructure), _
          ByRef anInOutPositionMassDiff() As Double, _
          ByRef anOutPTMposRefsArray As Integer() _
          )

            Dim vecSize As Integer = mPTMpositions2.Count()
            Dim lastPTMpos As Integer = vecSize - 1

            'Parallel list to mPTMpositions2.
            ReDim anInOutPositionMassDiff(lastPTMpos) 'Rely on setting all
            '  items to 0.0...
            '
            'We could also check if the old size is the same as the new and manually
            'reset the values to 0.0. This may save some memory garbage (?).

            Dim maxStackLastIndex As Integer = anInModsInfo.Count() - 1

            'Changed PM_BROADER_PTMSCORE 2007-04-03
            ReDim anOutPTMposRefsArray(maxStackLastIndex)

            Dim j As Integer
            For j = 0 To maxStackLastIndex

                Dim someMod2 As internalModsStructure = anInModsInfo(j)

                Dim someItem6 As singleModStackItemStructure = anInStack(j)
                Dim bitVector2 As Integer = someItem6.curBitVector

                Trace.Assert(bitVector2 >= 0, _
                  "PIL ASSERT. curBitVector is not initialised.")

                Dim PTMpositionsBitVector As Integer = 0


                Dim bitCount As Integer = someMod2.posRefs.Count()
                Dim lastIndex As Integer = bitCount - 1
                Dim k As Integer
                For k = 0 To lastIndex
                    Dim ANDmask As Integer = SDUPbitHandler.bitNumber2mask(k)
                    Dim active As Integer = bitVector2 And ANDmask

                    Dim posInfo As positionRefStructure = someMod2.posRefs(k)
                    Dim globalIndex As Integer = posInfo.posIndex

                    'Note: inverted, we assume the
                    '  client HAS applied the
                    '  modifications to ALL residues.
                    If active = 0 Then

                        Dim AA As String = mPTMpositions2(globalIndex).AA2

                        'Two level hash lookup.
                        Dim mass As Double = mModInfo(someMod2.modID2)(AA)

                        'Later: mass adjustment for
                        ' MS3/neutral loss.

                        '"-" because it is inverted - see above.
                        anInOutPositionMassDiff(globalIndex) -= mass
                    Else
                        'Changed PM_BROADER_PTMSCORE 2007-04-03
                        'As a sort of compression: use a bit vector to 
                        'represent which items in the PTM position vector
                        'are active (for the current combination)
                        Dim shiftedOne As Integer = _
                          SDUPbitHandler.bitNumber2mask(globalIndex)

                        'Set the corresponding bit.
                        PTMpositionsBitVector = _
                          PTMpositionsBitVector Or shiftedOne
                    End If
                Next k 'Through bit vector for
                '  current combination.

                'Changed PM_BROADER_PTMSCORE 2007-04-03
                anOutPTMposRefsArray(j) = PTMpositionsBitVector

                Dim peter5 As Integer = 5
            Next j 'Through modifications (for current
            '  combination - for particular locations of
            '  modifications in peptide sequence).
        End Sub 'findPositionMassDifferences


        'Changed PM_BROADER_PTMSCORE 2007-03-30
        '****************************************************************************
        '*    <placeholder for header>                                              *
        '****************************************************************************
        Private Sub adjustFragmentMasses( _
          ByRef anInPositionMassDiff() As Double, _
          ByVal anInForwardDirection As Boolean, _
          ByRef anOutIonDiffs() As Double, _
          ByVal aPepSize As Integer _
          )
            'anInPositionMassDiff: is only for the affected locations, e.g. 5
            'anOutIonDiffs: one for each AA in the peptide, e.g. 16.

            'Pass as parameter instead and have a static/shared function??
            Dim posVecSize As Integer = mPTMpositions2.Count()

            Dim posMassDiffs As Integer = anInPositionMassDiff.Length()
            Dim lastPosMassDiffsIndex As Integer = posMassDiffs - 1
            Trace.Assert(posVecSize = posMassDiffs, _
              "PIL ASSERT. Length of anInPositionMassDiff is not consistent...: " & _
              posMassDiffs & ".")

            Dim lastPepPos As Integer = aPepSize - 1

            Dim stepValue As Integer = 1
            Dim startIndex As Integer = 0
            Dim endIndex As Integer = lastPepPos
            Dim startPosIndex As Integer = 0
            If Not anInForwardDirection Then

                'Backward ion series... E.g. y-ions.
                stepValue = -1
                startIndex = lastPepPos
                endIndex = 0
                startPosIndex = lastPosMassDiffsIndex
            End If

            ReDim anOutIonDiffs(lastPepPos)
            Dim accumulativeMass As Double = 0.0
            Dim posIndex As Integer = startPosIndex
            Dim j As Integer
            For j = startIndex To endIndex Step stepValue

                'We could cache the value of the lookup below instead of
                'doing it for every peptide position...
                '
                If j = mPTMpositions2(posIndex).AAindex Then
                    'We are at a position in the peptide with
                    'a mass difference due to a modification.
                    Dim massDiff As Double = anInPositionMassDiff(posIndex)
                    accumulativeMass += massDiff

                    posIndex += stepValue
                    If posIndex < 0 Then
                        posIndex = 0
                    End If
                    If posIndex > lastPosMassDiffsIndex Then
                        posIndex = lastPosMassDiffsIndex
                    End If
                End If
                anOutIonDiffs(j) = accumulativeMass
            Next j
        End Sub 'adjustFragmentMasses


        'Changed PM_BROADER_PTMSCORE 2007-03-16
        '****************************************************************************
        '*    <placeholder for header>                                              *
        '****************************************************************************
        Public Function setPeptideAndModifications( _
          ByRef anInPeptideSequence As String, _
          ByRef anInModifications As List(Of modificationCountStruct), _
          ByVal anInMaxCombinations As Double, _
          ByVal aIsMS3spectrum As Boolean, _
          ByRef anOutPTMcombinations As Integer _
          ) _
          As Boolean
            'Return value: TRUE if it is OK to PTM score.
            '
            'aIsMS3spectrum does not seem to be used!!

            Dim toReturn As Boolean = True

            mPeptideSeq = anInPeptideSequence
            mPepSize = anInPeptideSequence.Length()
            mModifications = Nothing

            mAAs = PTMscorer.peptideInventory(anInPeptideSequence)
            Dim slen As Integer = anInPeptideSequence.Length()

            'No scoring if there are not any modifications...
            If anInModifications Is Nothing Then
                toReturn = False
            Else
                toReturn = anInModifications.Count > 0
            End If

            If toReturn Then
                updateModificationInformation(anInModifications) 'For cached information 
                '  about modifications that is independent of a particular peptide.

                filterOutSILACandOthers(anInModifications, slen, mModifications)

                If mModifications Is Nothing Then 'E.g. if only one possibility
                    '  for each modification.
                    toReturn = False
                Else
                    If mModifications.Count() = 0 Then
                        toReturn = False
                    Else
                        'We could sort it here, ascending after count from
                        '  Mascot - to limit the number of iterations on the
                        '  first level - this will quickly bring down the 
                        '  number of iterations on subsequent levels.
                        '
                        'We could sort indices instead of actually sorting the list.
                        Dim peter3 As Integer = 3
                    End If
                End If
            End If 'Peptide has modifications.

            If toReturn Then
                'Go through the filtered modifications, mModifications.

                If True Then
                    '  Reduce the number of bits to represent positions 
                    '  in the sequence. This is important as we are 
                    '  limited to 31 bits.
                    '
                    '  The strategy used here is to find the set of affected
                    '  amino acids and then use this subset for selecting
                    '  the sites in the peptide that we will represent by 
                    '  bit vectors.
                    '
                    '  Note: as we only have amino acid content we will have some
                    '        extra positions, but that is OK as long as we reduce 
                    '        the number of bits.
                    '
                    '        Sample: DFRLKR with a C-terminal modifications will
                    '                give 2 positions, mask 001001.

                    'Strategy: find affected subset of amino acids and then
                    '          use the positions according to those.
                    '
                    'Use some character type instead of String ? (to ease
                    'memory load).
                    Dim affectedAAs As Dictionary(Of String, Integer) = _
                      findAffectedAAs(mModifications, anInPeptideSequence)
                    Dim peter3 As Integer = 3

                    mPTMpositions2 = New List(Of PTMinfoStructure) 'Will
                    '  get rid of the old one...

                    mCombs2 = New List(Of combItemStructure) 'This will
                    '  also drop the old definitions....

                    Dim lastPepIndex As Integer = slen - 1
                    Dim j As Integer
                    For j = 0 To lastPepIndex Step 1
                        Dim AA As String = anInPeptideSequence.Substring(j, 1)

                        Dim someCount As Integer
                        If affectedAAs.TryGetValue(AA, someCount) Then

                            Dim someItem As PTMinfoStructure
                            someItem.AAindex = j
                            someItem.AA2 = AA

                            'Note: we can not really set basicMassDiff and modID 
                            '      as more than one modification may act on the 
                            '      same position/amino acid.

                            mPTMpositions2.Add(someItem)
                        End If
                    Next j 'Through peptide sequence.
                End If 'Block

                Dim positions As Integer = mPTMpositions2.Count

                Dim modsInfo As List(Of internalModsStructure) = _
                  Nothing

                'Changed PM_LIMIT_PTMCOMBINATIONS 2008-01-15
                Dim totalCombinations As Double = 1.0 'Actually product of
                '  ***permutations***.
                If True Then
                    modsInfo = New List(Of internalModsStructure)

                    'Prepare list of modifications suitable for PTM scoring.

                    Dim someMod As modificationCountStruct
                    For Each someMod In mModifications

                        'Changed PM_TERMMOD 2007-09-10.
                        'Dim posRefs As List(Of positionRefStructure) = _
                        '  New List(Of positionRefStructure)
                        Dim posRefs As List(Of positionRefStructure) = _
                          Nothing 'Lazy instantitation.

                        Dim modID As Integer = someMod.quantModificationID
                        Dim modCount As Integer = someMod.count3

                        'Last lookup! - hopefully.
                        Dim modInfo As _
                          quantModificationStructure = _
                            mQuantitationModes.getModification(modID)

                        'Note: we could now use this cached field
                        '      instead of calling the function: INTERNAL_collapsedAAset.
                        '
                        Dim allAAsForMod As String = collapseAAs(modInfo.affectedAAs)

                        Dim allPositions As Boolean
                        Dim startPos As Integer
                        Dim endPos As Integer
                        Dim maxMods As Integer
                        PILpeptide.findPositionsEtc( _
                          modInfo.startPosition, modInfo.endPosition, slen, _
                          allPositions, startPos, endPos, maxMods)

                        'For current modification:
                        '  build list of references to all the affected
                        '  peptide positions.

                        Dim lastIndex As Integer = mPTMpositions2.Count() - 1
                        Dim j As Integer
                        For j = 0 To lastIndex
                            Dim someItem2 As PTMinfoStructure = _
                              mPTMpositions2(j)

                            Dim pepIndex As Integer = someItem2.AAindex
                            If pepIndex >= startPos AndAlso _
                               pepIndex <= endPos Then
                                Dim idx As Integer = _
                                  allAAsForMod.IndexOf(someItem2.AA2)
                                If idx >= 0 Then
                                    'The current amino acid is affected 
                                    'by the current modification.

                                    Dim newItem As positionRefStructure
                                    newItem.posIndex = j 'Store a reference
                                    '  to the list of PTMinfoStructure's.

                                    'Changed PM_TERMMOD 2007-09-10
                                    If posRefs Is Nothing Then
                                        'Lazy instantitation
                                        posRefs = New List(Of positionRefStructure)
                                    End If

                                    posRefs.Add(newItem)
                                Else
                                    Dim peter3 As Integer = 3
                                End If
                            Else
                                'Outside range in peptide sequence...
                                Dim peter7 As Integer = 7
                            End If
                        Next j 'Through all modification positions in the peptide.

                        'Changed PM_TERMMOD 2007-09-10
                        If Not posRefs Is Nothing Then
                            Dim someModInfo As internalModsStructure
                            someModInfo.modID2 = modID
                            someModInfo.posRefs = posRefs
                            someModInfo.name2 = modInfo.modificationName
                            someModInfo.countFromMascot = modCount
                            'someModInfo.maxModsPerPosition = maxMods

                            Dim N As Integer = posRefs.Count()
                            Dim K As Integer = modCount
                            Dim combinations As Double = _
                              SDUPstatistics.NoverK(N, K) 'Actually
                            '  permutations, not combinations.
                            totalCombinations *= combinations

                            modsInfo.Add(someModInfo)
                        Else
                            'This can happen if a terminal modification does
                            'not include all amino acids and the peptide's 
                            'terminal amino acid is not one of them.
                            Dim peter2 As Integer = 2
                        End If
                    Next 'Through modifications

                    'Changed PM_LIMIT_PTMCOMBINATIONS 2008-01-15
                    If totalCombinations > anInMaxCombinations Then

                        'Changed PM_LIMIT_PTMCOMBINATIONS_REAL 2008-05-21. Conversion
                        'to integer fails if above 2147483647...
                        If totalCombinations < 2000000000.0 Then
                            anOutPTMcombinations = CInt(totalCombinations)
                        Else
                            anOutPTMcombinations = 999999999
                        End If

                        toReturn = False
                    End If

                End If 'Block.

                'Now we have found the number of possible sites and can thus
                'reduce the length of the bit vector(s) to represent the
                'different combinations.

                'To go through the combinations we don't go through the 
                'peptide sequence, switching on or off at positions in the 
                'peptide sequence (this does not work when several 
                'modifications can work on the same position). Instead we go 
                'through each modification in turn. For each combination for 
                'a modification we then go through the next modification's
                'combinations. And so on - recursively.

                'Changed PM_LIMIT_PTMCOMBINATIONS 2008-01-15
                If toReturn Then 'Is false if too many combinations - we 
                    '  terminate if there are going to be too many (takes
                    '  too long time and may risk out of memory).

                    '  Main loop in this class... Find and store (?)
                    '  the different combinations.

                    'Note: traversing the different combinations is more
                    '      suited for a recursive solution. But we are 
                    '      afraid of the memory/performance implications.

                    'Changed PM_REFACTOR 2008-01-15. Moved in here.
                    mCurIonDiffs2 = New List(Of ionSetStruct)
                    Dim curID As Integer = 1 'Note: we are currently dependent on
                    '  starting from 1...


                    Dim maxStackSize As Integer = modsInfo.Count()
                    Dim maxStackLastIndex As Integer = maxStackSize - 1

                    Dim stack As List(Of singleModStackItemStructure) = _
                      New List(Of singleModStackItemStructure)(maxStackSize)
                    Dim sp As Integer = 0

                    Dim done2 As Boolean = False
                    While Not done2

                        'Physical insert.
                        If sp >= stack.Count() Then
                            Dim someItem2 As singleModStackItemStructure
                            someItem2.bitHandler = New SDUPbitHandler
                            someItem2.startState = True
                            someItem2.curBitVector = -1
                            stack.Add(someItem2)
                        End If

                        If stack(sp).startState Then
                            Dim someMod2 As internalModsStructure = modsInfo(sp)

                            Dim someItem3 As singleModStackItemStructure = _
                              stack(sp)
                            someItem3.startState = False
                            someItem3.curBitVector = -1
                            someItem3.bitHandler.setup( _
                              someMod2.countFromMascot, _
                              someMod2.posRefs.Count())
                            stack(sp) = someItem3
                        Else
                            Dim someItem4 As singleModStackItemStructure = _
                              stack(sp)
                            Dim bitVector As Integer

                            'Note: getBitVector() returns the next combination.
                            If stack(sp).bitHandler.getBitVector(bitVector) Then
                                someItem4.curBitVector = bitVector
                                stack(sp) = someItem4

                                If sp = maxStackLastIndex Then
                                    'The stack is full. It now represents one
                                    'combination - the set of modifications, each
                                    'modification in particular position(s) in the
                                    'peptide sequence.

                                    'Go through each modification in turn and compute
                                    'an accumulative mass difference vector.

                                    Dim anOutPTMposRefsArray(0) As Integer

                                    Me.findPositionMassDifferences( _
                                      stack, modsInfo, _
                                      mPositionMassDiffs, anOutPTMposRefsArray)

                                    If True Then
                                        Dim someItem As combItemStructure
                                        someItem.patternLen = -1
                                        someItem.pattern4 = anOutPTMposRefsArray
                                        someItem.trues = 1
                                        someItem.pattern4_old = -1
                                        mCombs2.Add(someItem)
                                    End If

                                    Dim someIonSet As ionSetStruct
                                    someIonSet.forwardIonDiffs = Nothing
                                    someIonSet.backwardIonDiffs = Nothing
                                    someIonSet.compVectorIndex = curID - 1
                                    someIonSet.ID = curID
                                    curID += 1

                                    Me.adjustFragmentMasses( _
                                       mPositionMassDiffs, _
                                       True, _
                                       someIonSet.forwardIonDiffs, _
                                       mPepSize)

                                    Me.adjustFragmentMasses( _
                                       mPositionMassDiffs, _
                                       False, _
                                       someIonSet.backwardIonDiffs, _
                                       mPepSize)

                                    mCurIonDiffs2.Add(someIonSet)

                                    'For the current combination(s) we
                                    'now have the mass adjustment for each
                                    'modification affected position in the
                                    'peptide. Convert it into mass
                                    'difference for forward and backward
                                    'ion series (e.g. b and y series).

                                    Dim peter6 As Integer = 6
                                Else
                                    sp += 1
                                End If 'Stack full or not.
                            Else
                                'End of combinations for current modification. Pop
                                'off top stack item (effectively).
                                someItem4.startState = True 'We have to invalidate
                                '  as we are not physically creating new items.
                                stack(sp) = someItem4
                                sp -= 1

                                If sp < 0 Then
                                    done2 = True
                                End If
                            End If 'Next bitvector. Or end-of-bitvectors.
                        End If 'Start state or not.
                    End While

                    'Changed PM_PTMSCORE_STATS 2007-08-03
                    anOutPTMcombinations = mCurIonDiffs2.Count()
                Else
                    Dim peter2 As Integer = 2 'Too many combinations.
                End If 'Block, main loop of this class..
            End If 'OK to score.

            Return toReturn
        End Function 'setPeptideAndModifications


        'Changed PM_BROADER_PTMSCORE 2007-03-16
        '****************************************************************************
        '*    <placeholder for header>                                              *
        '****************************************************************************
        Public Sub XXXXXsetPeptide2()

            Trace.Assert(False, "Stop!", _
              "PIL ASSERT. Internal/development assert for stopping execution......")

            Trace.Assert( _
              Not mModifications Is Nothing, _
              "PIL ASSERT. Internal code error. mModifications is Nothing. " & _
              "This indicates a client error.")

            If True Then 'Derive data structures from modifications that
                '  are suitable for finding all combinations to score for.

                Dim someMod As modificationCountStruct
                For Each someMod In mModifications
                    Dim modID As Integer = someMod.quantModificationID
                    Dim modInfo As _
                      quantModificationStructure = _
                        mQuantitationModes.getModification(modID)

                    Dim peter2 As Integer = 2
                Next 'Through modifications.
            End If

            'More to be added.
            Trace.Assert( _
              False, "Stop!", _
              "PIL ASSERT. Internal/development assert for stopping execution......")
        End Sub 'setPeptide2


        '****************************************************************************
        '*    <placeholder for header>                                              *
        '****************************************************************************
        Private Sub finalComb( _
          ByVal aCombItem As combItemStructure, _
          ByRef anInOutListToAddTo As List(Of combItemStructure))

            Dim len As Integer = aCombItem.patternLen
            Dim lastIndex As Integer = len - 1
            Dim count As Integer = _
              SDUPbitHandler.onesCount(aCombItem.pattern4_old, len)
            Dim leadingFalseToAdd As Integer = mMaxPTMs - len
            Dim firstIndex As Integer = lastIndex + 1
            aCombItem.patternLen = mMaxPTMs
            Dim lastIndex2 As Integer = mMaxPTMs - 1
            Dim j As Integer
            For j = firstIndex To lastIndex2 Step 1
                setBitToFalse(aCombItem.pattern4_old, j)
            Next j
            aCombItem.trues = count
            anInOutListToAddTo.Add(aCombItem)
        End Sub 'finalComb


        'Changed PM_REFACTOR 2006-07-03
        '****************************************************************************
        '*    <placeholder for header>                                              *
        '*    aBitNumber is zero-based.                                             *
        '****************************************************************************
        Private Shared Sub setBitToFalse( _
          ByRef anInOutBitVector As Integer, ByVal aBitNumber As Integer)

            Dim ANDmask As Integer = SDUPbitHandler.bitNumber2mask(aBitNumber)
            Dim invertedMask As Integer = Not ANDmask

            anInOutBitVector = anInOutBitVector And invertedMask
        End Sub 'setBitToFalse


        'Changed PM_REFACTOR 2006-07-03
        '****************************************************************************
        '*    <placeholder for header>                                              *
        '*    aBitNumber is zero-based.                                             *
        '****************************************************************************
        Private Shared Sub setBitToTrue( _
          ByRef anInOutBitVector As Integer, ByVal aBitNumber As Integer)

            Dim ORmask As Integer = SDUPbitHandler.bitNumber2mask(aBitNumber)
            anInOutBitVector = anInOutBitVector Or ORmask 'Set the required bit...
        End Sub 'setBitToTrue


        'Changed PM_PHOSPHO_SCORING_NOLIMIT 2005-10-13
        '****************************************************************************
        '*    <placeholder for header>                                              *
        '****************************************************************************
        Private Sub prepareCombinationTable_old( _
          ByVal aPTMs As Integer, _
          ByVal anInRequiredOnesCount As Integer, _
          ByRef anInOutCountsFromMascot As ArrayList)

            'Alternatives:
            '  1. Class BitArray. Presumably unlimited number of bits. Reference
            '     type.
            '  2. "And" operator on integers. Limited to 32.
            '  3. Class BitVector32. Value type. "BitVector32 is more efficient 
            '     than BitArray for Boolean values and small integers that are
            '     used internally".
            '     There is no bitwise AND/OR operations, but this could be done using
            '     integers. BitVector32 could then be used to get individual bits.
            ' 
            ' '2' is probably OK wrt. the number of bits, in 1. it is easier
            '     to count the number of ones.

            'set depends on each peptide's modification set and counts.

            mMaxPTMs = aPTMs 'Note: must be set before call of 

            'Changed PM_TYPESAFE 2007-04-03
            'mCombs = New ArrayList
            mCombs2 = New List(Of combItemStructure) 'This will
            '  also drop the old definitions....

            Dim someItem As combItemStructure
            Dim combinations As Integer = CInt(Math.Pow(2, aPTMs))
            Dim lastCombinationNumber As Integer = combinations - 1

            Dim j As Integer
            For j = 0 To lastCombinationNumber
                Dim useCombination As Boolean = False

                If True Then
                    'Note: a format specification for binary does not
                    'exist, only hexadecimal. But we can expand the
                    'hexadecimal output to binary by a 16 entry lookup table.
                    'But first we check if the current combinations have
                    'the number of modified positions that we know
                    'from Mascot.

                    Dim barr4 As Integer = j

                    'Truncate
                    Dim lastIndex2 As Integer = 31 - 1 '31 because of a bug
                    '  for the highest significant bit.

                    Dim i As Integer
                    Dim indexForHighestOne As Integer = 0
                    For i = lastIndex2 To 0 Step -1
                        Dim ANDmask As Integer = SDUPbitHandler.bitNumber2mask(i)
                        If (barr4 And ANDmask) > 0 Then
                            indexForHighestOne = i
                            Exit For
                        End If
                    Next i

                    Dim significantBits As Integer = indexForHighestOne + 1
                    someItem.patternLen = significantBits

                    Dim oCount As Integer = _
                      SDUPbitHandler.onesCount(barr4, significantBits)

                    '1. Refactor field .pattern to use type BitArray
                    '   or BitVector32.
                    '
                    '2. Use "barr" below, instead of binStr, etc. 
                    '   "barr" can be assigned directly to field "pattern"
                    '   when the refactoring has taken place.

                    Dim totalOnesCount As Integer = oCount

                    If totalOnesCount = anInRequiredOnesCount Then
                        useCombination = True
                    End If

                    'Also check the individual modification count for
                    'each modification.
                    If useCombination Then

                        Dim lastIndex As Integer = _
                          anInOutCountsFromMascot.Count - 1
                        Dim n As Integer
                        For n = 0 To lastIndex Step 1
                            Dim someItem2 As modCountCheckStructure = _
                              DirectCast(anInOutCountsFromMascot(n), _
                                modCountCheckStructure)

                            'Mask out all the other modifications.
                            Dim maskedOutBitVector As Integer = _
                              someItem2.bitVector7 And barr4

                            Dim countForCurrentModification As Integer = _
                              SDUPbitHandler.onesCount( _
                                maskedOutBitVector, significantBits)

                            If someItem2.targetCount <> _
                               countForCurrentModification Then

                                useCombination = False
                                Exit For 'No need to continue.
                            Else
                                Dim peter2 As Integer = 2 'At least
                                '  one modification have the right count.
                            End If
                        Next n
                    End If

                    'Always accept the unmodified.
                    If totalOnesCount = 0 Then
                        useCombination = True
                    End If
                End If

                If useCombination Then
                    someItem.pattern4_old = j
                    someItem.pattern4 = Nothing 'Keep compiler happy.
                    Me.finalComb(someItem, mCombs2)
                Else
                    Dim peter2 As Integer = 2 'Not the required number of ones.
                End If
            Next j 'Next combination candidate. Note: we don't use all of them, 
            '  only the ones where the total modification count fits and all 
            '  of the individual modification counts for each modification.
        End Sub 'prepareCombinationTable_old


        'This function could be anywhere....
        '****************************************************************************
        '*    <placeholder for header>                                              *
        '****************************************************************************
        Private Function letterDistribution( _
          ByRef aStr As String) _
          As Hashtable

            Dim toReturn As Hashtable = New Hashtable
            If True Then
                Dim lastIndex As Integer = aStr.Length - 1
                Dim j As Integer
                For j = 0 To lastIndex Step 1
                    Dim AA As String = aStr.Substring(j)

                    'Would be so much more compact in Perl!
                    If toReturn.Contains(AA) Then 'What is the
                        Dim oldCount As Integer = CInt(toReturn(AA))
                        toReturn(AA) = oldCount + 1
                    Else
                        toReturn.Add(AA, 1)
                    End If
                Next j
            End If

            Return toReturn
        End Function 'letterDistribution


        'Changed PM_REFACTOR 2006-05-08
        '****************************************************************************
        '*    <placeholder for header>                                              *
        '****************************************************************************
        Private Shared Sub adjustFragmentMasses_old( _
          ByRef anInPTMpositions As ArrayList, _
          ByRef anInCombVector4 As Integer, _
          ByVal anInForwardDirection As Boolean, _
          ByVal aNeutralLosses As Integer, _
          ByVal anInPhos98corr As Double, _
          ByVal anInLastPepIndex As Integer, _
          ByRef anOutIonDiffs() As Double _
          )
            'anInPTMpositions: real type is: PTMinfoStructure.
            Dim lowerMassLimit As Double = 56.0 'Slightly less than G/Gly.
            '  Copied from Public Sub CalcFragIons()....

            Dim positions As Integer = anInPTMpositions.Count
            Dim lastIndex3 As Integer = positions - 1

            Dim startIndex1 As Integer = 0 'Better name?
            Dim endIndex1 As Integer = lastIndex3 'Better name?
            Dim stepValue1 As Integer = 1

            If Not anInForwardDirection Then
                'That's backward...

                startIndex1 = lastIndex3
                endIndex1 = 0
                stepValue1 = -1
            End If

            Dim i As Integer
            For i = startIndex1 To endIndex1 Step stepValue1
                Dim PTM As PTMinfoStructure = _
                  DirectCast(anInPTMpositions(i), PTMinfoStructure)

                Dim startIndex2 As Integer = PTM.AAindex 'Better name?
                Dim endIndex2 As Integer = anInLastPepIndex  'Better name?
                If Not anInForwardDirection Then
                    'That's backward...
                    startIndex2 = 0
                    endIndex2 = PTM.AAindex
                End If

                'Changed PM_BAD_MS3_MASSES 2006-05-08. Temporary
                'solution, apply the extra modification mass
                'correction to phospho AAs only.
                'The symptom was:
                '  "Impossible low mass for amino 
                '   acid "M" in peptide MGRSRSPATAK 
                '   (position 1): 50.065771705 Da 
                '   (limit: 56 Da). b-ion series."
                '
                Dim diff2 As Double = anInPhos98corr 'Default: phospho corr.
                If Not (PTM.AA2 = "S" Or PTM.AA2 = "T" Or PTM.AA2 = "Y") Then
                    diff2 = 0.0 'Not a phospho site.
                Else
                    Dim peter6 As Integer = 6 'phospho site.
                End If

                Dim k As Integer

                Dim ANDmask As Integer = SDUPbitHandler.bitNumber2mask(i)
                Dim val As Integer = ANDmask And anInCombVector4
                Dim combValue4 As Boolean = Not (val > 0) ' "not" is
                '  used because we assume the client HAS applied
                '  the modifications to ALL residues.

                Dim applyMassCorr As Boolean = False
                Dim massCorr As Double = -7.777E+18

                If combValue4 Then
                    'Going back to non-modified.
                    applyMassCorr = True
                    massCorr = PTM.basicMassDiff
                Else
                    'Modified, but the original mass computed by the
                    'client is not the correct one. We must adjust such
                    'that it corresponds to what is in the spectrum.
                    'E.g.: a phosphorylated amino acid is 80 Da heavier 
                    '      if the modification is intact, but if the 
                    '      precursor has lost the modification before 
                    '      fragmentation then the residue mass in the 
                    '      fragment spectrum is 18 Da less the 
                    '      unmodified residue, required to substract 
                    '      98 Da to get the correct fragment residue
                    '      mass.

                    'Extra large adjustment...
                    If aNeutralLosses > 0 Then
                        'For sites that are phosphorylated in the
                        'physical world. These looses 98 Da, end
                        'mass is -18 Da compared to unmodified residue.

                        applyMassCorr = True
                        massCorr = diff2
                    End If
                End If 'Else part, is modified

                If applyMassCorr Then
                    'Apply mass diff from current and all the way
                    'to the end (forward) or to the beginning (backward).
                    Dim prevMass As Double = 0.0
                    For k = startIndex2 To endIndex2 Step 1
                        Dim oldMass As Double = anOutIonDiffs(k)
                        Dim newMass As Double = oldMass - massCorr
                        anOutIonDiffs(k) = newMass

                        prevMass = newMass
                    Next k 'Through mass diff vector
                End If 'Apply mass correction
            Next 'Through PTM sites
        End Sub 'adjustFragmentMasses_old


        '****************************************************************************
        '*    <placeholder for header>                                              *
        '****************************************************************************
        Public Sub setPeptide_old( _
          ByRef anInPeptideSequence As String, _
          ByRef anInModifiedAAs As String, _
          ByVal aModificationCount As Integer, _
          ByVal aNeutralLosses As Integer, _
          ByRef anInBasicMassDifferencesAndOthers As Hashtable, _
          ByRef anInOutCountsFromMascot As ArrayList _
          )

            'Type of anInOutCountsFromMascot is: modCountCheckStructure.

            mPeptideSeq = anInPeptideSequence
            mModificationCount = aModificationCount

            Dim diff2a As Double
            If True Then
                'Still only for phosphorylation.
                Dim basicMassDiff2 As Double = _
                  MSQuantCommon2.PHOSPHORYLATION_DIFF_98
                diff2a = basicMassDiff2 * aNeutralLosses
            End If

            Dim pepLen As Integer = anInPeptideSequence.Length
            Dim lastPepIndex As Integer = pepLen - 1

            'Parameter anModCount: -1 for undertermined??

            mPTMpositions_old = New ArrayList 'Real type is: PTMinfoStructure

            'Find the residues that can be modified.
            If True Then
                Dim bitNumber As Integer = 0
                Dim j As Integer
                For j = 0 To lastPepIndex Step 1
                    Dim AA As String = anInPeptideSequence.Substring(j, 1)

                    If anInModifiedAAs.IndexOf(AA) >= 0 Then

                        Dim someItem As PTMinfoStructure
                        someItem.AAindex = j
                        someItem.AA2 = AA

                        'Changed PM_MOD_PREFIX_AND_POSTFIX 2006-06-07

                        'This lookup assumes there is only one modification for an
                        'amino acid.

                        'Changed PM_CODEMARKER 2006-08-21. Problem here....

                        'Changed PM_PTM_BROKEN20060713 2006-08-24
                        Trace.Assert( _
                          anInBasicMassDifferencesAndOthers.ContainsKey(AA), _
                          "PIL ASSERT. Key """ & AA & _
                          """ does not exist in " & _
                          "hash ""anInBasicMassDifferencesAndOthers"".")

                        Dim mod2 As quantModificationStructure = _
                          DirectCast(anInBasicMassDifferencesAndOthers(AA), _
                            quantModificationStructure)

                        'Note: this is for the old PTM score...
                        someItem.basicMassDiff = _
                          mod2.affectedAAs(0).diffFromBase3 'For now: use 
                        '  the first item. Then it does not work for N15. But it is 
                        '  a fixed modification anyway that we do not need to score.
                        '
                        '  Proper implementation:
                        '    compute mass diff based on current AA (variable "AA") 
                        '    and the list in affectedAAs.

                        'Changed PM_MOD_PREFIX_AND_POSTFIX 2006-06-07
                        someItem.modID = mod2.quantModificationID

                        mPTMpositions_old.Add(someItem)

                        'Iterate through the list for each AA in the
                        'peptide sequence. Could be more efficient.

                        Dim lastIndex As Integer = _
                          anInOutCountsFromMascot.Count - 1
                        Dim k As Integer
                        For k = 0 To lastIndex Step 1
                            Dim someItem2 As modCountCheckStructure = _
                              DirectCast( _
                                anInOutCountsFromMascot(k), _
                                  modCountCheckStructure)
                            If someItem2.modAAs.IndexOf(AA) >= 0 Then
                                Dim ORmask As Integer = _
                                  SDUPbitHandler.bitNumber2mask(bitNumber)
                                someItem2.bitVector7 = _
                                  someItem2.bitVector7 Or ORmask
                                'Write-back, in-place. We can continue
                                'the iteration.
                                anInOutCountsFromMascot(k) = someItem2
                            End If
                        Next k

                        bitNumber += 1
                    End If
                Next j
            End If

            Dim positions As Integer = mPTMpositions_old.Count
            Me.prepareCombinationTable_old( _
              positions, aModificationCount, anInOutCountsFromMascot)

            '  Test a case: aModificationCount must be 2...

            'Find mass difference vectors, one vector per combination.
            If True Then
                mCurIonDiffs2 = New List(Of ionSetStruct)

                Dim curID As Integer = 1 'Note: we are currently dependent on
                '  starting from 1...

                Dim lastIndex2 As Integer = mCombs2.Count() - 1

                Dim j As Integer
                For j = 0 To lastIndex2 Step 1
                    'Changed PM_ZERO_PHOSPHO_JA 2005-09-07.
                    'Also consider the combination where all PTM groups
                    'have fallen off.

                    Dim numTrues As Integer = mCombs2(j).trues

                    'The number of iterations/comparisons could be
                    'optimised, e.g. using mCombs sorted by field 'trues'.
                    If aModificationCount = numTrues Or _
                       numTrues = 0 Then

                        Dim combVector4 As Integer = mCombs2(j).pattern4_old

                        Dim someIonSet As ionSetStruct
                        someIonSet.compVectorIndex = j

                        someIonSet.ID = curID
                        curID += 1

                        'Rely on setting to 0.0...
                        ReDim someIonSet.backwardIonDiffs(lastPepIndex)
                        ReDim someIonSet.forwardIonDiffs(lastPepIndex)

                        'Forward ions
                        If True Then
                            PTMscorer.adjustFragmentMasses_old( _
                              mPTMpositions_old, _
                              combVector4, _
                              True, _
                              aNeutralLosses, _
                              diff2a, _
                              lastPepIndex, _
                              someIonSet.forwardIonDiffs)
                        End If

                        'Backward ions
                        If True Then
                            PTMscorer.adjustFragmentMasses_old( _
                              mPTMpositions_old, _
                              combVector4, _
                              False, _
                              aNeutralLosses, _
                              diff2a, _
                              lastPepIndex, _
                              someIonSet.backwardIonDiffs)
                        End If 'Backward ions

                        mCurIonDiffs2.Add(someIonSet)
                    End If 'Number of modifications matches
                Next j 'Through all combinations
            End If 'Block, find diff vectors
        End Sub 'setPeptide_old


        '****************************************************************************
        '*    <placeholder for header>                                              *
        '****************************************************************************
        Public Sub resetReadCombinations()
            mReadIndex = 0
            mReadDirectionForward = True
        End Sub 'resetReadCombinations


        '****************************************************************************
        '*    <placeholder for header>                                              *
        '****************************************************************************
        Public Function readNextCombination( _
          ByRef anOutCombination As ionSetStruct) _
          As Boolean

            Dim toReturn As Boolean = False

            If mReadDirectionForward = False Then
                mReadIndex += 2 'Now at the next read position
            End If

            Dim len As Integer = mCurIonDiffs2.Count
            If mReadIndex < len Then
                anOutCombination = mCurIonDiffs2(mReadIndex)
                mLastReadIndex = mReadIndex
                mReadIndex += 1
                toReturn = True
            End If
            mReadDirectionForward = True
            Return toReturn
        End Function 'readNextCombination


        '****************************************************************************
        '*    <placeholder for header>                                              *
        '****************************************************************************
        Public Function readPrevCombination( _
          ByRef anOutCombination As ionSetStruct) _
          As Boolean

            Dim toReturn As Boolean = False

            If mReadDirectionForward = True Then
                mReadIndex -= 1 'Now at the last read position
            End If
            mReadIndex -= 1

            Dim len As Integer = mCurIonDiffs2.Count()
            If mReadIndex >= 0 Then
                toReturn = True
            Else
                'Automatic wrap-around in this case....
                mReadIndex = len - 1
                toReturn = True
            End If

            anOutCombination = mCurIonDiffs2(mReadIndex)
            mLastReadIndex = mReadIndex

            mReadDirectionForward = False
            Return toReturn
        End Function 'readPrevCombination


        'Changed PM_PHOSPHO_SCORING_EXPORT 2005-10-13
        '****************************************************************************
        '*    <placeholder for header>                                              *
        '****************************************************************************
        Public Sub fillInExternalStructures( _
          ByVal aBestComb As ionSetStruct, _
          ByRef anInOutPublicStructure As onePTMcombinationStructure)

            'Note: only fills in ***one*** combination.

            anInOutPublicStructure.score = aBestComb.score
            anInOutPublicStructure.positions2 = New List(Of PTMinfoStructure)

            'This is effectively filtering a list of PTMinfoStructure, 
            'keeping only those that are modified.
            If True Then
                Dim combIdx As Integer = aBestComb.compVectorIndex

                Dim combVector4 As Integer = mCombs2(combIdx).pattern4_old

                'Changed PM_BROADER_PTMSCORE 2007-04-03
                If combVector4 >= 0 Then
                    'Old way.
                    Dim positions As Integer = mPTMpositions_old.Count

                    Dim lastIndex3 As Integer = positions - 1
                    Dim i As Integer
                    For i = 0 To lastIndex3
                        Dim PTM As PTMinfoStructure = _
                          DirectCast(mPTMpositions_old(i), PTMinfoStructure)

                        Dim ANDmask As Integer = SDUPbitHandler.bitNumber2mask(i)
                        Dim combValue As Boolean = (combVector4 And ANDmask) > 0

                        If combValue Then
                            'Not added for the no modifications case, 
                            'combVector4 = 0. Is this what we intend?

                            anInOutPublicStructure.positions2.Add(PTM)
                        End If
                    Next
                Else
                    'New way.
                    Dim PTMposRefsArray() As Integer = mCombs2(combIdx).pattern4
                    Dim mods As Integer = PTMposRefsArray.Length()
                    Dim modsLastIndex As Integer = mods - 1

                    Dim positions4 As Integer = mPTMpositions2.Count()
                    Dim lastIndex4 As Integer = positions4 - 1
                    Dim i As Integer
                    For i = 0 To lastIndex4
                        Dim PTM As PTMinfoStructure = mPTMpositions2(i)
                        Dim ANDmask As Integer = _
                          SDUPbitHandler.bitNumber2mask(i)

                        Dim j As Integer
                        For j = 0 To modsLastIndex
                            Dim bitVector As Integer = PTMposRefsArray(j)

                            Dim active As Integer = bitVector And ANDmask
                            If active > 0 Then

                                'Use chance to put in modification ID.
                                Dim modID As Integer = _
                                  mModifications(j).quantModificationID
                                PTM.modID = modID

                                anInOutPublicStructure.positions2.Add(PTM)
                            End If
                        Next j
                    Next i
                End If 'Else, new way.

            End If
        End Sub 'fillInExternalStructures


        '****************************************************************************
        '*    <placeholder for header>                                              *
        '****************************************************************************
        Public Shared Sub formatSomeCombinations( _
          ByRef anInPeptideSeq As String, _
          ByRef aPTMlist2 As List(Of onePTMStructure), _
          ByVal aOnlyTheBest As Boolean, _
          ByRef anInQuantitationModesObject As QuantitationModes_moreGeneral, _
          ByRef anInOutBuf As StringBuilder, _
          ByRef anOutHighestScore As Double _
          )
            anOutHighestScore = 0.0

            'Hard coded limit for now.
            'Changed PM_LIMIT_PTM_OUTPUT_TO_20 2006-06-07
            'Dim MAX_COMBINATIONS As Integer = 10
            'Dim MAX_COMBINATIONS As Integer = 20
            Dim MAX_COMBINATIONS As Integer = 50

            Dim lastIndexCombs As Integer = MAX_COMBINATIONS - 1

            'Datastructure to decide whether to output a low scoring combination
            'or not. Note: some low scoring ones may still be output. This
            'depends on the order of the PTM combinations... It is mostly for
            'practical reasons (size of export) rather than excluding all
            'low scoring combinations.
            Dim highestScores(lastIndexCombs) As Double

            Dim lowestScoreIndex As Integer = -1
            Dim lowestScore As Double = 1.0E+18 'This is the score 
            '  we will be using as threshold.
            Dim fillIndex As Integer = 0

            'For now: imply that scores are output if only showing the best
            Dim outScore As Boolean = Not aOnlyTheBest
            outScore = True

            If Not aPTMlist2 Is Nothing Then

                Dim combList2 As List(Of PTMinfoStructure) = Nothing

                'Changed PM_PTMSCORE_TROUBLE 2008-05-23
                Dim lowestScoreForASSERTmsg As Double = 5555.5
                Dim highestScoreForASSERTmsg As Double = -5555.5

                If aOnlyTheBest = False Then
                    Dim peter8 As Integer = 8
                End If

                Dim onePTM As onePTMStructure = aPTMlist2(0)

                Dim scoreASSERTfired As Boolean = False
                Dim lastIndex As Integer = onePTM.combinations2.Count - 1
                Dim j As Integer
                For j = 0 To lastIndex

                    'Moved up here to use new "checked" field, instead of the
                    'convention of the last item being the best.
                    Dim someComb As onePTMcombinationStructure = _
                      onePTM.combinations2(j)
                    Dim score As Double = someComb.score

                    'Changed PM_PTMSCORE_TROUBLE 2008-05-23
                    Dim scoreWithinExpectedRange As Boolean = _
                      score > -0.00001 AndAlso score < 1000.0

                    'Convert Infinity or -Infinity into a large negative number. But
                    'not too large to disturb our max/min finding (as it will
                    'create an exception below)   1.0E+19
                    If score > -1000000000000.0 AndAlso score < 1000000000000.0 Then
                        Dim peter2 As Integer = 2 'Within range
                    Else
                        score = -1000000000000.0
                    End If

                    If score < lowestScoreForASSERTmsg Then
                        lowestScoreForASSERTmsg = score
                    End If
                    If score > highestScoreForASSERTmsg Then
                        highestScoreForASSERTmsg = score
                    End If

                    Trace.Assert( _
                      scoreASSERTfired Or scoreWithinExpectedRange, _
                      "PIL ASSERT. PTM score, " & score & _
                      ", is outside range ]-0.00001; 1000.0[.")

                    'Changed PM_PTMSCORE_TROUBLE 2008-05-23
                    'Limit number of ASSERTs...
                    If Not scoreWithinExpectedRange Then
                        scoreASSERTfired = True
                    End If

                    Dim doOutput As Boolean = True

                    'Note: aOnlyTheBest is false for column "PTM info" in 
                    '      export/save and thus the checked state will be ingored
                    '      in that case.
                    If aOnlyTheBest AndAlso someComb.checked7 = False Then
                        doOutput = False
                    Else
                        Dim peter3 As Integer = 3
                    End If

                    If doOutput Then
                        If fillIndex < MAX_COMBINATIONS Then
                            'We still have empty slots to fill in.

                            If score < lowestScore Then
                                lowestScore = score
                                lowestScoreIndex = fillIndex
                            End If

                            highestScores(fillIndex) = score
                            fillIndex += 1
                        Else
                            If score < lowestScore Then
                                doOutput = False 'Outcommented: test only!!!!!!!!

                                Dim peter8 As Integer = 8
                            Else
                                'Changed PM_PTMSCORE_TROUBLE 2008-05-23
                                'The current item has a higher score than one or 
                                'more of the items in our list. Put it into the 
                                'slot where current lowest score is. After the 
                                'insertion find the slot with the (new) lowest score.
                                Trace.Assert(lowestScoreIndex >= 0, _
                                  "PIL ASSERT. lowestScoreIndex is out of range (" & _
                                  lowestScoreIndex & _
                                  "). This is probably because one or more PTM scores " & _
                                  "were infinity or -infinity. Likely PTM score range for " & _
                                  "this peptide, " & anInPeptideSeq & ", is [" & _
                                  lowestScoreForASSERTmsg.ToString() & ";" & _
                                  highestScoreForASSERTmsg.ToString() & "].")

                                highestScores(lowestScoreIndex) = score

                                lowestScore = 1.0E+19
                                Dim n As Integer
                                For n = 0 To lastIndexCombs Step 1
                                    Dim sc As Double = highestScores(n)
                                    If sc < lowestScore Then
                                        lowestScore = sc
                                        lowestScoreIndex = n
                                    End If
                                Next n
                            End If
                        End If
                    End If

                    If doOutput Then
                        combList2 = someComb.positions2

                        'Changed PM_MISLEADING_EXPORT_PTMSCORE 2006-03-01
                        If score > anOutHighestScore Then
                            anOutHighestScore = score
                        End If

                        If outScore Then
                            anInOutBuf.Append(someComb.score.ToString("F2"))
                            anInOutBuf.Append(" ")
                        End If

                        PTMscorer.formatOneCombination( _
                          anInPeptideSeq, combList2, _
                          anInQuantitationModesObject, _
                          anInOutBuf)
                        anInOutBuf.Append(",")
                    End If
                Next j
            End If
        End Sub 'formatSomeCombinations


        '****************************************************************************
        '*    <placeholder for header>                                              *
        '****************************************************************************
        Public Shared Sub formatOneCombination( _
          ByRef anInPeptideSeq As String, _
          ByRef anInPTMpositions2 As List(Of PTMinfoStructure), _
          ByRef anInQuantitationModesObject As QuantitationModes_moreGeneral, _
          ByRef anInOutBuf As StringBuilder _
          )
            'Old:
            '  ByVal anInCombVector4 As Integer, _

            'Changed PM_BROADER_PTMSCORE_SELFCHECK 2007-04-04
            Dim useSelfCheck As Boolean = True 'True: only for testing versions!!!!
            '  Users may use uppercase characters in prefix and
            '  postfix for a modification.

            If Not anInPTMpositions2 Is Nothing Then

                'Changed PM_BROADER_PTMSCORE_SELFCHECK 2007-04-04
                'For memory efficiency when self check is off.
                Dim seqPartSB As StringBuilder = anInOutBuf
                If useSelfCheck Then
                    seqPartSB = New StringBuilder
                End If

                Dim strSB2 As StringBuilder = New StringBuilder

                Dim pepLen As Integer = anInPeptideSeq.Length

                Dim preFixes As String = Nothing
                Dim PTM_AA As String = ""
                Dim postFixes As String = Nothing

                Dim positions As Integer = anInPTMpositions2.Count
                Dim lastPTMindex As Integer = positions - 1
                Dim i As Integer
                Dim startCopyPos As Integer = 0
                Dim curPTMpos As Integer = -1 'In case there are no modifications.
                For i = 0 To lastPTMindex

                    Dim lastItem As Boolean = i = lastPTMindex
                    Dim PTM As PTMinfoStructure = anInPTMpositions2(i)
                    Dim combValue As Boolean = True

                    ' If anInCombVector4 >= 0 Then
                    ' 
                    '     'Not really used....
                    '     Dim ANDmask As Integer = SDUPbitHandler.bitNumber2mask(i)
                    '     combValue = (anInCombVector4 And ANDmask) > 0
                    ' End If

                    If combValue Then
                        curPTMpos = PTM.AAindex

                        'For breakpoints only.
                        If curPTMpos = 0 Then
                            Dim peter10 As Integer = 10
                        End If

                        If True Then
                            Dim modID As Integer = PTM.modID
                            Dim mod2 As quantModificationStructure = _
                              anInQuantitationModesObject.getModification(modID)
                            Dim ptmAA As String = _
                              anInPeptideSeq.Substring(curPTMpos, 1)

                            Dim copyLen As Integer = curPTMpos - startCopyPos

                            If copyLen >= 0 Then 'Will be -1 if at same position.

                                'Output cached strings
                                If PTM_AA <> "" Then
                                    seqPartSB.Append(preFixes)
                                    seqPartSB.Append(PTM_AA)
                                    seqPartSB.Append(postFixes)
                                End If

                                Dim prev As String = _
                                  anInPeptideSeq.Substring(startCopyPos, copyLen)
                                seqPartSB.Append(prev)

                                PTM_AA = ptmAA
                                preFixes = mod2.shortPrefix
                                postFixes = mod2.shortPostfix
                            Else
                                If mod2.shortPrefix.Length() > 0 Then
                                    preFixes &= "," & mod2.shortPrefix
                                End If
                                If mod2.shortPostfix.Length() > 0 Then
                                    postFixes &= "," & mod2.shortPostfix
                                End If
                            End If

                            startCopyPos = curPTMpos + 1
                        End If

                        'Affected ions
                        If True Then
                            Dim bIon As Integer = curPTMpos + 1
                            strSB2.Append("b")
                            strSB2.Append(bIon)

                            Dim yIon As Integer = pepLen - curPTMpos
                            strSB2.Append("/y")
                            strSB2.Append(yIon)
                            strSB2.Append(" ")
                        End If
                    End If
                Next i 'Through PTM positions (in the peptide).

                'Changed PM_BROADER_PTMSCORE 2007-04-03
                If PTM_AA <> "" Then

                    seqPartSB.Append(preFixes)
                    seqPartSB.Append(PTM_AA)
                    seqPartSB.Append(postFixes)
                End If

                Dim rest2 As String = anInPeptideSeq.Substring(curPTMpos + 1)
                seqPartSB.Append(rest2)

                'Dim seqPartSB As StringBuilder = anInOutBuf
                If useSelfCheck Then
                    Dim seqPart As String = seqPartSB.ToString()

                    Dim strippedOutputLen As Integer = 0
                    Dim lastIndex As Integer = seqPart.Length() - 1
                    Dim j As Integer
                    For j = 0 To lastIndex Step 1
                        Dim formattedCH As String = seqPart(j)

                        'Changed PM_BROADER_PTMSCORE_DASHPROBLEM 2007-04-16.
                        'Extra.
                        If formattedCH >= "A" AndAlso _
                           formattedCH <= "Z" AndAlso _
                           formattedCH <> "-" Then
                            strippedOutputLen += 1
                        End If
                    Next j

                    Trace.Assert(strippedOutputLen = pepLen, _
                      "PIL ASSERT. Peptide " & anInPeptideSeq & _
                      " may not have been formatted correctly: " & seqPart & _
                      ". Some amino acid letters may have been left out. " & _
                      "The most probable reason is that prefix and postfix strings for " & _
                      "the modification are not allowed to contain ***uppercase*** letters.")

                    anInOutBuf.Append(seqPartSB)
                End If

                anInOutBuf.Append(" ")
                anInOutBuf.Append(strSB2) 'Ions corresponding to affected
                '  positions, e.g. b7/y4 b2/y9
            End If
        End Sub 'formatOneCombination


        'Not currently used....
        ' '****************************************************************************
        ' '*    <placeholder for header>                                              *
        ' '****************************************************************************
        ' Public Function reportStrForCurrent() As String
        ' 
        '     Dim strSB As StringBuilder = New StringBuilder
        '     'Dim strSB2 As StringBuilder = New StringBuilder
        ' 
        '     'Dim curCmbination As ionSetStructure = _
        '     '  DirectCast(mCurIonDiffs(mReadIndex - 1), ionSetStructure)
        '     Dim curCmbination As ionSetStructure = _
        '       DirectCast(mCurIonDiffs(mLastReadIndex), ionSetStructure)
        ' 
        '     Dim combIdx As Integer = curCmbination.compVectorIndex
        '     Dim combVector As Boolean() = _
        '       DirectCast(mCombs(combIdx), combItemStructure).pattern
        ' 
        '     'Changed PM_REFACTOR 2005-10-17
        '     PTMscorer.formatOneCombination(mPeptideSeq, mPTMpositions, combVector, strSB)
        ' 
        '     Return strSB.ToString
        ' End Function 'reportStrForCurrent


        'Changed PM_PHOSPHO_SCORING 2005-09-08
        '****************************************************************************
        '*    <placeholder for header>                                              *
        '****************************************************************************
        Public Sub setScoreForCurrent(ByVal aScore As Double)

            Dim curItem As ionSetStruct = mCurIonDiffs2(mLastReadIndex)
            curItem.score = aScore
            mCurIonDiffs2(mLastReadIndex) = curItem
        End Sub 'setScoreForCurrent


        'Changed PM_PHOSPHO_SCORING_EXPORT 2005-10-13
        'Utility function to handle Nothing for the peptide field "PTMs".
        '****************************************************************************
        '*    <placeholder for header>                                              *
        '****************************************************************************
        Public Shared Function getPTMscore2(ByVal aPTMs As ArrayList) As Double
            Dim toReturn As Double = 0.0
            If Not aPTMs Is Nothing Then
                Trace.Assert(aPTMs.Count = 1, _
                  "PIL ASSERT. More than one PTM: " & aPTMs.Count)

                Dim onePTM As onePTMStructure = _
                  DirectCast(aPTMs(0), onePTMStructure)

                Dim lastIndex As Integer = onePTM.combinations2.Count - 1
                Dim bestComb As onePTMcombinationStructure = _
                  onePTM.combinations2(lastIndex)
                '  Assume the list is sorted by score, highest score first.
                toReturn = bestComb.score
            End If
            Return toReturn
        End Function 'getPTMscore


        '****************************************************************************
        '*    <placeholder for header>                                              *
        '****************************************************************************
        Public Shared Sub formatPTMinfo( _
          ByVal aPTMs As ArrayList, ByRef anInOutBuf As StringBuilder)

            If Not aPTMs Is Nothing Then
                Trace.Assert(aPTMs.Count = 1, _
                  "PIL ASSERT. More than one PTM: " & aPTMs.Count)

                Dim onePTM As onePTMStructure = DirectCast(aPTMs(0), onePTMStructure)
                Dim bestComb As onePTMcombinationStructure = _
                  onePTM.combinations2(0)
                '  Assume the list is sorted by score, highest score first.
            End If
        End Sub 'formatPTMinfo


        '****************************************************************************
        '*    <placeholder for header>                                              *
        '****************************************************************************
        Private Shared Sub seriesInVector( _
          ByRef anOutSortedIndex2 As List(Of Integer), _
          ByVal aSize As Integer)

            anOutSortedIndex2 = New List(Of Integer)(aSize)
            Dim lastIndex As Integer = aSize - 1
            Dim j As Integer
            For j = 0 To lastIndex Step 1
                anOutSortedIndex2.Add(j)
            Next j
        End Sub 'seriesInVector


        'Changed PM_PHOSPHO_SCORING_USERSEL 2005-12-22
        '****************************************************************************
        '*    <placeholder for header>                                              *
        '****************************************************************************
        Public Shared Sub sortCombinationsByScoreUsingIndex( _
          ByRef aCombinations2 As List(Of onePTMcombinationStructure), _
          ByRef anOutSortedIndex2 As List(Of Integer))

            Dim cSize As Integer = aCombinations2.Count
            PTMscorer.seriesInVector(anOutSortedIndex2, cSize)
            anOutSortedIndex2.Sort(New PTMcomb_SortByScore_usingIndex(aCombinations2))
        End Sub 'sortUsingIndex


        'Changed PM_PHOSPHO_SCORING_USERSEL 2006-01-05
        '****************************************************************************
        '*    <placeholder for header>                                              *
        '****************************************************************************
        Public Function getModificationCount() As Integer
            Return mModificationCount
        End Function


        '****************************************************************************
        '*    <placeholder for header>                                              *
        '****************************************************************************
        Public Function getCombinationByIndex(ByVal anIndex As Integer) _
          As ionSetStruct

            Dim lastIndex As Integer = mCurIonDiffs2.Count() - 1
            Trace.Assert(anIndex <= lastIndex, _
              "PIL ASSERT. Index, " & anIndex & _
              ", is past the last index of mCurIonDiffs, " & lastIndex & _
              ". In getCombinationByIndex(), class PTMscorer.")

            Return mCurIonDiffs2(anIndex)
        End Function 'readNextCombination


        'This function could be anywhere. It is not parcular to PTM scoring.
        '****************************************************************************
        '*    <placeholder for header>                                              *
        '****************************************************************************
        Public Shared Function AAstats(ByRef anInPeptideSequence As String) _
          As Hashtable

            Dim toReturn As Hashtable = New Hashtable

            'Is this necessary? It makes it easier for the client.
            toReturn.Add("A", 0)
            toReturn.Add("C", 0)
            toReturn.Add("D", 0)
            toReturn.Add("E", 0)
            toReturn.Add("F", 0)
            toReturn.Add("G", 0)
            toReturn.Add("H", 0)
            toReturn.Add("I", 0)
            toReturn.Add("K", 0)
            toReturn.Add("L", 0)
            toReturn.Add("M", 0)
            toReturn.Add("N", 0)
            toReturn.Add("P", 0)
            toReturn.Add("Q", 0)
            toReturn.Add("R", 0)
            toReturn.Add("S", 0)
            toReturn.Add("T", 0)
            toReturn.Add("V", 0)
            toReturn.Add("W", 0)
            toReturn.Add("Y", 0)

            'Changed PM_SNIPS_OUJ_RKN 2006-11-29
            toReturn.Add("U", 0)
            toReturn.Add("O", 0)
            toReturn.Add("J", 0)

            Dim lastIndex As Integer = anInPeptideSequence.Length - 1
            Dim j As Integer
            For j = 0 To lastIndex Step 1
                Dim AA As String = anInPeptideSequence.Substring(j, 1)

                Dim oldValue As Integer = CInt(toReturn(AA))
                Dim newValue As Integer = oldValue + 1
                toReturn(AA) = newValue
            Next j

            Return toReturn
        End Function 'AAstats

    End Class 'PTMscorer

End Namespace 'massSpectrometryBase, class PTMscorer



    

    

Generated by script codePublish.pl at 2008-09-23T11:59:18.