'****************************************************************************
'* Copyright (C) 2004 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: XYZ. *
'* *
'****************************************************************************
'****************************************************************************
'* CEBI *
'* Software Development Group *
'* Peter Mortensen *
'* E-mail: NUKESPAMMERSdrmortensen@get2netZZZZZZ.dk *
'* WWW: http://www.cebi.sdu.dk/ *
'* *
'* Program for post-processing of result from search in mass *
'* spectrometric data. *
'* *
'* FILENAME: signal.vb *
'* MAIN_CLASS: signal *
'* STRUCTS_AND_CLASSES: <none> *
'* TYPE: VISUAL_BASIC *
'* *
'* CREATED: PM 2003-03-04 Vrs 1.0. *
'* UPDATED: PM 2003-xx-xx *
'* *
'****************************************************************************
'Future:
' 1. There is so much to look forward to....
' 2.
' 3.
' 4.
Option Strict On
Option Explicit On
Imports System.Text 'For StringBuilder
Imports System.Collections.Generic
'Changed PM_SUPERCHARGE 2003-11-03
'Imports Mascot_Parser.massSpectrometryBase 'For signalStructure
'Imports Mascot_Parser.SDUPutility
Imports massSpectrometryBase 'For signalStructure
Imports SDUPutility
'Why is "Public" needed in order to use it
' in AnalystRawDataFileHandling.vb/returnDataPoints(); last parameter??
Public Module signalModule
'Purpose, 2003-03-30: part of refactoring to make xxxx also work
' for MS spectra (TOF), not just for LC level signal (LC peak detection).
'It is also part of the effort to separate GUI from non-GUI part of the application.
'
'Possible future:
' 1. It could hold the signal state (protect direct access to signals)
' 2. It could hide how to get to raw signals in an MS or MSMS
' spectrum. Hide details of: platform, spectrum type, manufacturer specifics, ...
' 3.
' 4.
'Partly redundant information in SpecQuantStructure, but repeated
'to avoid messing with the existing code.
Public Structure ZZZsignalStructure
Dim Xsig As Double
Dim Ysig As Double 'Something representing signal intensity.
' It is unspecified: it can be the original signal or some
' derived quantitity: maximum signal strength, area (XIC),
' sum of signal strengths in a window, etc.
Dim tagValue As Double 'Some value carried with each point. For
' instance: neutral centroid mass for each signal in a LC signal.
End Structure 'ZZZsignalStructure
'Changed PM_REFACTOR 2004-06-22. Moved from rawDataFileHandling.vb
'****************************************************************************
'd$ <summary>
'd$ Purpose:
'd$ Organises values specifying max/min values for a range of datapoints.
'd$ </summary>
Public Structure dataPointsInfoStructure2
'X range:
Dim minX2 As Double
Dim maxX2 As Double
'Dim minY As Double
'Dim maxY As Double
Dim maximumSignal As signalStructure
Dim minimumSignal As signalStructure
End Structure 'dataPointsInfoStructure2
'Specialised data structure...
Public Structure LCPeakInfoStructure
Dim maxIntensity As Double
Dim calibratedNeutralMass As Double 'May not be needed if we
' are just interested in the relative mass error (ppm).
Dim absRelError_PPM As Double
Dim peakToBackgroundRatio As Double
'Later:
' 1. some mass accuracy measure, e.g. mass accuracy for max signal or some
' average of the best (or all) points within peak.
' 2. xyz
Dim LCpeakTimeCentroid As Double
Dim LCpeakWindowStart As Integer
Dim LCpeakWindowEnd As Integer
Dim LCMaxTime As Double
Dim LCMaxIndex As Integer
'Changed PM_LCPEAK_MSMSEVENT 2004-02-02
Dim MSMSeventInPeak As Boolean
End Structure 'LCPeakInfoStructure
'Changed PM_MANNREDUCTION_LEVEL 2005-09-05
'Currently only used in GUI, but could be used for packing the parameters
'for spectrum reduction.
Public Structure reductionParametersStructure
Dim MannReductionLevel2 As Integer
Dim smartPickingLevel2 As Integer
'Changed PM_USERSET_MS3_MATCHING_TOLERANCE 2007-07-13
Dim smartPickingMassWindow As Double
Dim matchingMassTolerance As Double 'No longer only reduction
' parameters with this field.
End Structure 'reductionParametersStructure
'Changed PM_TYPESAFE 2006-11-01. Changed to generics...
'****************************************************************************
'* SUBROUTINE NAME: SortByRelError *
'd$ <summary> N/A. ...
'd$ Note: descending sort </summary>
Public Class SortByRelError
Implements System.Collections.Generic.IComparer(Of LCPeakInfoStructure)
Public Function Compare( _
ByVal aItem1 As LCPeakInfoStructure, _
ByVal aItem2 As LCPeakInfoStructure) _
As Integer _
Implements _
System.Collections.Generic.IComparer(Of LCPeakInfoStructure).Compare
Dim toReturn As Integer = 0
If aItem1.absRelError_PPM < aItem2.absRelError_PPM Then
toReturn = 1
Else
If aItem1.absRelError_PPM > aItem2.absRelError_PPM Then
toReturn = -1
Else
'Equal....
Dim peter9 As Integer = 9
End If
End If
Return toReturn
End Function 'Compare
End Class 'SortByRelError
'Changed PM_TYPESAFE 2006-11-01. Changed to generics...
'****************************************************************************
'* SUBROUTINE NAME: SortByX *
'd$ <summary> N/A. ...
'd$ Note: ascending sort </summary>
Public Class SortByX
'Implements IComparer(Of LCPeakInfoStructure)
Implements System.Collections.Generic.IComparer(Of LCPeakInfoStructure)
Public Function Compare( _
ByVal aItem1 As LCPeakInfoStructure, _
ByVal aItem2 As LCPeakInfoStructure) _
As Integer _
Implements _
System.Collections.Generic.IComparer(Of LCPeakInfoStructure).Compare
'Implements System.Collections.IComparer.Compare
Dim toReturn As Integer = 0
If aItem1.LCpeakTimeCentroid < aItem2.LCpeakTimeCentroid Then
toReturn = -1
Else
If aItem1.LCpeakTimeCentroid > aItem2.LCpeakTimeCentroid Then
toReturn = 1
Else
'Equal....
Dim peter9 As Integer = 9
End If
End If
Return toReturn
End Function 'Compare
End Class 'SortByX
'Changed PM_DTASC_MEMORY 2004-10-15
'This class exists to reduce the information required to pass in the parameters
'for the recursive function internal_findThePeaks(). It is used for a sort of
'read-on-demand; the information in this class seldomly used (but is needed) and
'is either read-only or global to the purpose of the function.
Public Class peaksInfoStorage
Dim mMaxY As Double
'Changed PM_REFACTOR 2006-10-12
'Dim mSignal As ArrayList
Dim mSignal As Generic.List(Of massSpectrometryBase.signalStructure)
Dim mInAASequence As String
Dim mCalibratedMeasuredMZ As Double
Dim mCharge As Integer
Dim mDumpString As StringBuilder
Dim mMaximumXDistanceForPeakDetection As Double
Dim mMaximumXDistanceForMinima As Double
Dim mMascotCalculatedMW As Double
Dim mMSMSretentionTimeMinutes As Double
Dim mConsiderMSMSevent As Boolean
'Changed PM_TYPESAFE 2006-11-01
'Dim mPeakCandidates As ArrayList
Dim mPeakCandidates As Generic.List(Of LCPeakInfoStructure)
Dim mConsiderSet As Boolean 'For error checking
Dim mFindPeaksMaxSearchLevel As Integer
Dim mActualDeepestSearchLevel As Integer
'****************************************************************************
'* <placeholder for header> *
'****************************************************************************
Public Sub New()
mConsiderSet = False
mDumpString = New StringBuilder
'Changed PM_TYPESAFE 2006-11-01. Lazy instantiate it.
'mPeakCandidates = New ArrayList
mMaxY = -1000000000.0
mSignal = Nothing
mInAASequence = ""
mCalibratedMeasuredMZ = -300.0
mCharge = -2
mMaximumXDistanceForPeakDetection = -300.0
mMaximumXDistanceForMinima = -300.0
mMascotCalculatedMW = -300.0
mMSMSretentionTimeMinutes = -300.0
mActualDeepestSearchLevel = -2
mFindPeaksMaxSearchLevel = -2
End Sub
'****************************************************************************
'* <placeholder for header> *
'****************************************************************************
Public Sub addToDumpString(ByRef aStringToAdd As String)
mDumpString.Append(aStringToAdd)
End Sub
'****************************************************************************
'* <placeholder for header> *
'****************************************************************************
Public Function getDumpString() As String
'Trace.Assert(mDumpString.Length > 0, "PIL ASSERT. Dump string not set....")
Return mDumpString.ToString
End Function 'getDumpString
'****************************************************************************
'* <placeholder for header> *
'****************************************************************************
Public Sub addToPeakCandidates(ByRef aInPeakCandidate As LCPeakInfoStructure)
'Changed PM_TYPESAFE_ANDLAZYINSTANTIATE 2006-11-01
'Lazy instantiate.
If mPeakCandidates Is Nothing Then
mPeakCandidates = New Generic.List(Of LCPeakInfoStructure)
End If
mPeakCandidates.Add(aInPeakCandidate)
End Sub 'addToPeakCandidates
'****************************************************************************
'* <placeholder for header> *
'****************************************************************************
Public Function getPeakCandidates() _
As Generic.List(Of LCPeakInfoStructure)
'Old:
' Return type
' As ArrayList
Return mPeakCandidates 'Note: can be empty...
End Function 'getPeakCandidates
'****************************************************************************
'* <placeholder for header> *
'****************************************************************************
Public Sub setMaxY(ByVal aMaxY As Double)
mMaxY = aMaxY
End Sub 'setMaxY
'****************************************************************************
'* <placeholder for header> *
'****************************************************************************
Public Function getMaxY() As Double
Trace.Assert(mMaxY > -290.0, "PIL ASSERT. <message>.")
Return mMaxY
End Function 'getMaxY
'****************************************************************************
'* <placeholder for header> *
'****************************************************************************
Public Sub setSignal( _
ByRef anInSignal As Generic.List(Of massSpectrometryBase.signalStructure))
'Old:
' ByRef anInSignal As ArrayList
mSignal = anInSignal 'Will this make a copy?? Hopefully not
End Sub 'setSignal
'****************************************************************************
'* <placeholder for header> *
'****************************************************************************
Public Function getSignal() _
As Generic.List(Of massSpectrometryBase.signalStructure)
'Old return type:
' ArrayList
Trace.Assert(Not mSignal Is Nothing, "PIL ASSERT. <message>.")
Return mSignal
End Function 'getSignal
'****************************************************************************
'* <placeholder for header> *
'****************************************************************************
Public Sub setAASequence(ByRef anInAASequence As String)
mInAASequence = anInAASequence
End Sub 'setAASequence
'****************************************************************************
'* <placeholder for header> *
'****************************************************************************
Public Function getAASequence() As String
Trace.Assert(mInAASequence <> "", "PIL ASSERT. <message>.")
Return mInAASequence
End Function 'getAASequence
'****************************************************************************
'* <placeholder for header> *
'****************************************************************************
Public Sub setCalibratedMeasuredMZ(ByVal anCalibratedMeasuredMZ As Double)
mCalibratedMeasuredMZ = anCalibratedMeasuredMZ
End Sub
'****************************************************************************
'* <placeholder for header> *
'****************************************************************************
Public Function getCalibratedMeasuredMZ() As Double
Trace.Assert(mCalibratedMeasuredMZ > -290.0, "PIL ASSERT. <message>.")
Return mCalibratedMeasuredMZ
End Function
'****************************************************************************
'* <placeholder for header> *
'****************************************************************************
Public Sub setCharge(ByVal aCharge As Integer)
mCharge = aCharge
End Sub
'****************************************************************************
'* <placeholder for header> *
'****************************************************************************
Public Function getCharge() As Integer
Trace.Assert(mCharge >= -1, "PIL ASSERT. <message>.")
Return mCharge
End Function
'****************************************************************************
'* <placeholder for header> *
'****************************************************************************
Public Sub setMaximumXDistanceForPeakDetection( _
ByVal anMaximumXDistanceForPeakDetection As Double)
mMaximumXDistanceForPeakDetection = anMaximumXDistanceForPeakDetection
End Sub
'****************************************************************************
'* <placeholder for header> *
'****************************************************************************
Public Sub setMaximumXDistanceForMinima( _
ByVal anMaximumXDistanceForMinima As Double)
mMaximumXDistanceForMinima = anMaximumXDistanceForMinima
End Sub
'****************************************************************************
'* <placeholder for header> *
'****************************************************************************
Public Function getMaximumXDistanceForPeakDetection() As Double
Trace.Assert(mMaximumXDistanceForPeakDetection > -290.0, "PIL ASSERT. <message>.")
Return mMaximumXDistanceForPeakDetection
End Function
'****************************************************************************
'* <placeholder for header> *
'****************************************************************************
Public Function getMaximumXDistanceForMinima() As Double
Trace.Assert(mMaximumXDistanceForMinima > -290.0, "PIL ASSERT. <message>.")
Return mMaximumXDistanceForMinima
End Function
'****************************************************************************
'* <placeholder for header> *
'****************************************************************************
Public Sub setMascotCalculatedMW(ByVal anMascotCalculatedMW As Double)
mMascotCalculatedMW = anMascotCalculatedMW
End Sub
'****************************************************************************
'* <placeholder for header> *
'****************************************************************************
Public Function getMascotCalculatedMW() As Double
Trace.Assert(mMascotCalculatedMW > -290.0, "PIL ASSERT. <message>.")
Return mMascotCalculatedMW
End Function
'****************************************************************************
'* <placeholder for header> *
'****************************************************************************
Public Sub setMSMSretentionTimeMinutes(ByVal aMSMSretentionTimeMinutes As Double)
mMSMSretentionTimeMinutes = aMSMSretentionTimeMinutes
End Sub
'****************************************************************************
'* <placeholder for header> *
'****************************************************************************
Public Function getMSMSretentionTimeMinutes() As Double
Trace.Assert(mMSMSretentionTimeMinutes > -290.0, "PIL ASSERT. <message>.")
Return mMSMSretentionTimeMinutes
End Function
'****************************************************************************
'* <placeholder for header> *
'****************************************************************************
Public Sub setConsiderMSMSevent(ByVal aConsiderMSMSevent As Boolean)
mConsiderSet = True
mConsiderMSMSevent = aConsiderMSMSevent
End Sub
'****************************************************************************
'* <placeholder for header> *
'****************************************************************************
Public Function getConsiderMSMSevent() As Boolean
Trace.Assert(mConsiderSet = True, "PIL ASSERT. <message>.")
Return mConsiderMSMSevent
End Function
'****************************************************************************
'* <placeholder for header> *
'****************************************************************************
Public Sub setFindPeaksMaxSearchLevel(ByVal aFindPeaksMaxSearchLevel As Integer)
mFindPeaksMaxSearchLevel = aFindPeaksMaxSearchLevel
End Sub
'****************************************************************************
'* <placeholder for header> *
'****************************************************************************
Public Function getFindPeaksMaxSearchLevel() As Integer
Trace.Assert(mFindPeaksMaxSearchLevel >= 0, "PIL ASSERT. <message>.")
Return mFindPeaksMaxSearchLevel
End Function
'****************************************************************************
'* <placeholder for header> *
'****************************************************************************
Public Sub setActualDeepestSearchLevel(ByVal aActualDeepestSearchLevel As Integer)
mActualDeepestSearchLevel = aActualDeepestSearchLevel
End Sub
'****************************************************************************
'* <placeholder for header> *
'****************************************************************************
Public Function getActualDeepestSearchLevel() As Integer
Trace.Assert(mActualDeepestSearchLevel >= 0, "PIL ASSERT. <message>.")
Return mActualDeepestSearchLevel
End Function
End Class 'peaksInfoStorage
'Opearations on signals (e.g. LC or MS level), not necesseraly uniformly sampled.
'****************************************************************************
'* <placeholder for header> *
'****************************************************************************
Public Class BSignal
'Changed PM_REFACTOR_FINDPEAK_ 2003-03-30. Moved from QuantWindow.vb.
'Changed PM_LC_PEAKDETECTION 2003-03-20
'Type of aSignal: signalStructure
'****************************************************************************
'* <placeholder for header> *
'****************************************************************************
Public Shared Sub findSignalPeak( _
ByRef aSignal As Generic.List(Of massSpectrometryBase.signalStructure), _
ByVal anStartIndex As Integer, ByVal anEndIndex As Integer, _
ByVal aMaximumXDistanceForPeakDetection As Double, _
ByVal aMaximumXDistanceForMinima As Double, _
ByRef anOutSignalPeakXCentroid As Double, _
ByRef anOutSignalPeakYCentroid As Double, _
ByRef anOutSignalPeakIndexStart As Integer, _
ByRef anOutSignalPeakIndexEnd As Integer, _
ByRef anOutSignalPeakWindowStart As Integer, _
ByRef anOutSignalPeakWindowEnd As Integer, _
ByRef anOutSignalMaxX As Double, ByRef anOutSignalMaxY As Double, _
ByRef anOutSignalMaxIndex As Integer, _
ByRef anOutBackgroundLevel As Double _
)
'Old:
' ByRef aSignal As ArrayList
Dim stoppedByMaxDist_left As Boolean = False
Dim stoppedByMaxDist_right As Boolean = False
If anEndIndex = 81 AndAlso anStartIndex = 0 Then
Dim peter81 As Integer = 81
End If
'Changed PM_IGNORE_ZEROS_IN_LCPROFILE_ 2004-06-18.
Const IDENTICALZERO_THRESHOLD As Double = 0.0011
'Changed PM_REFACTOR_FINNEGAN 2003-07-25
'We can not currently handle empty signals....
Dim sLen As Integer = aSignal.Count
Trace.Assert(sLen > 0, "PIL ASSERT. Empty signal. In findSignalPeak().")
Dim firstX As Double = aSignal(0).Xsig
Dim lastIndex As Integer = sLen - 1
Trace.Assert(sLen > 0, _
"PIL ASSERT: unexpected empty list in findSignalPeak()")
Trace.Assert(anEndIndex >= anStartIndex, _
"PIL ASSERT: anEndIndex >= anStartIndex in findSignalPeak()")
Trace.Assert(anStartIndex >= 0, _
"PIL ASSERT: anStartIndex >= 0 in findSignalPeak()")
'This would also be caught by the run time, but we want to
'put a (hopefully) more understandable message to the user...
Dim endX As Double = _
aSignal(lastIndex).Xsig / 60.0 'LC/minutes dependence...
Trace.Assert(anEndIndex < sLen, _
"PIL ASSERT. Could not find signal peak. The end signal x was specified outside the end of range (" & _
endX & "). Report to a developer near you.")
Dim somePoint As signalStructure
Dim minYpoint As signalStructure
minYpoint.Ysig = 1.0E+20
Dim maxYpoint As signalStructure
maxYpoint.Ysig = -1.0E+20
Dim minYindex As Integer
Dim maxYindex As Integer
Dim index As Integer = 0
Dim maxYtime As Double = -1.0E+20
For Each somePoint In aSignal
'Trace.Assert(somePoint.Ysig > 0.00001, _
' "PIL ASSERT. Bad Y value: (" & _
' somePoint.Ysig & "). Report to a developer near you.")
If index >= anStartIndex And index <= anEndIndex Then
If somePoint.Ysig < minYpoint.Ysig Then
minYpoint = somePoint
minYindex = index
End If
If somePoint.Ysig > maxYpoint.Ysig Then
maxYpoint = somePoint
maxYindex = index
maxYtime = somePoint.Xsig
End If
'index += 1 'Why was it here????
End If
index += 1
Next
Dim minY As Double = minYpoint.Ysig
Dim maxY As Double = maxYpoint.Ysig
anOutSignalMaxX = maxYtime
anOutSignalMaxY = maxY
anOutSignalMaxIndex = maxYindex
Dim ySize As Double = maxY - minY
Dim yThres As Double = ySize * 0.3 'Hardcoded 30 % limit...
Dim yThresAbsU As Double = yThres + minY
'To find the peak we do a LaserOne style inside-out peak detection....
'Changed PM_IGNORE_ZEROS_IN_LCPROFILE_ 2004-06-21
'Dim xStartIndexForCentroid As Integer = maxYindex
'Dim xEndIndexForCentroid As Integer = maxYindex
Dim xStartIndexForCentroid As Integer = maxYindex - 1
Dim xEndIndexForCentroid As Integer = maxYindex + 1
'Changed PM_IGNORE_ZEROS_IN_LCPROFILE_ 2004-06-21
Dim pointsUsed As Integer = 1 'One because we have already the max point...
'Changed PM_IGNORE_ZEROS_IN_LCPROFILE_ 2004-06-18. Condition added...
'Changed PM_IGNORE_ZEROS_IN_LCPROFILE_ 2004-06-21
'Dim peakLeftSideY As Double = -1.0
Dim peakLeftSideY As Double = maxY
'Note: condition relies on boolean shortcircuit...
Dim done_Left As Boolean = False
While Not done_Left
If xStartIndexForCentroid >= anStartIndex Then
Dim curPoint As signalStructure = aSignal(xStartIndexForCentroid)
Dim curY As Double = curPoint.Ysig
Dim curX As Double = curPoint.Xsig
'Changed PM_PEAKFIND_MAXFINDDISTANCE 2004-06-25
Dim xDist As Double = maxYtime - curX 'We don't need Abs(), we
' are sure of the sign...
'Changed PM_SMARTPICKING_FIX 2004-10-27
'Check this first, never look at points too far during
'peak detection.
If xDist <= aMaximumXDistanceForPeakDetection Then
If curY >= yThresAbsU Or _
curY <= IDENTICALZERO_THRESHOLD Then
'Changed PM_IGNORE_ZEROS_IN_LCPROFILE_ 2004-06-18
'Dim curY As Double = DirectCast(aSignal(xStartIndexForCentroid), _
' signalStructure).Ysig
If curY > IDENTICALZERO_THRESHOLD Then
peakLeftSideY = curY
'Changed PM_IGNORE_ZEROS_IN_LCPROFILE_ 2004-06-21
pointsUsed += 1
End If
xStartIndexForCentroid -= 1
Else
done_Left = True
End If
Else
done_Left = True
End If
Else
done_Left = True
stoppedByMaxDist_left = True
End If
End While
xStartIndexForCentroid += 1
'Changed PM_IGNORE_ZEROS_IN_LCPROFILE_ 2004-06-18. Condition added...
'Note: condition relies on boolean shortcircuit...
'Changed PM_IGNORE_ZEROS_IN_LCPROFILE_ 2004-06-23
'Dim peakRightSideY As Double = -1.0
Dim peakRightSideY As Double = maxY
Dim done_Right As Boolean = False
While Not done_Right
If xEndIndexForCentroid <= anEndIndex Then
Dim curPoint As signalStructure = _
aSignal(xEndIndexForCentroid)
Dim curY As Double = curPoint.Ysig
Dim curX As Double = curPoint.Xsig
'Changed PM_PEAKFIND_MAXFINDDISTANCE 2004-06-25
Dim xDist As Double = curX - maxYtime 'We don't need Abs(), we
' are sure of the sign...
'Changed PM_SMARTPICKING_FIX 2004-10-27
'Check this first, never look at points too far during
'peak detection.
If xDist <= aMaximumXDistanceForPeakDetection Then
If curY >= yThresAbsU Or _
curY <= IDENTICALZERO_THRESHOLD Then
'Changed PM_IGNORE_ZEROS_IN_LCPROFILE_ 2004-06-18
'Dim curY As Double = DirectCast(aSignal(xEndIndexForCentroid), _
' signalStructure).Ysig
If curY > IDENTICALZERO_THRESHOLD Then
peakRightSideY = curY
'Changed PM_IGNORE_ZEROS_IN_LCPROFILE_ 2004-06-21
pointsUsed += 1
End If
xEndIndexForCentroid += 1
Else
done_Right = True
End If
Else
done_Right = True
End If
Else
done_Right = True
stoppedByMaxDist_right = True
End If
End While
xEndIndexForCentroid -= 1
Trace.Assert(xEndIndexForCentroid >= xStartIndexForCentroid, _
"PIL ASSERT: xEndIndexForCentroid>=xStartIndexForCentroid. xEndIndexForCentroid: " & _
xEndIndexForCentroid & ". xEndIndexForCentroid: " & xEndIndexForCentroid)
'Changed PM_IGNORE_ZEROS_IN_LCPROFILE_ 2004-06-21
'Dim pointsUsed As Integer = xEndIndexForCentroid - xStartIndexForCentroid + 1
'Find the x og y centroid
Dim weigthedRetSum As Double = 0.0
Dim ySum As Double = 0.0
Dim xWeightSum As Double = 0.0
Dim yWeightSum As Double = 0.0
Dim areaSum As Double = 0.0
Dim prevPoint As signalStructure = aSignal(xStartIndexForCentroid)
' 'Changed PM_NONUNIFORMSAMPLING_LCCENTROID 2003-03-24
' 'Make sure we use the last point
' Dim indexEnd As Integer = xEndIndexForCentroid
' indexEnd += 1 'For using the last point, for forward approximation
' If indexEnd > anEndIndex Then
' indexEnd = anEndIndex
' End If
If pointsUsed >= 2 Then
Dim j As Integer
For j = xStartIndexForCentroid To xEndIndexForCentroid
Dim curSignalPoint As signalStructure = aSignal(j)
'Changed PM_IGNORE_ZEROS_IN_LCPROFILE_ 2004-06-18.
'Ignore points with identical zero as y-value.
If curSignalPoint.Ysig > IDENTICALZERO_THRESHOLD Then
'Old method that assumes constant x sampling:
' Dim wCon As Double = curSignalPoint.Ysig * curSignalPoint.Xsig
' weigthedRetSum += wCon
' ySum += curSignalPoint.Ysig
'Forward approximation
' 'Changed PM_NONUNIFORMSAMPLING_LCCENTROID 2003-03-24
' 'Left point is defined as determining y value (including area).
' Dim area As Double = _
' (curSignalPoint.Xsig - prevPoint.Xsig) * prevPoint.Ysig
' Dim x As Double = (prevPoint.Xsig + curSignalPoint.Xsig) / 2
' Dim y As Double = 0.5 * prevPoint.Ysig
' Dim xw As Double = x * area
' Dim yw As Double = y * area
' xWeightSum += xw
' yWeightSum += yw
' areaSum += area
'Bilinear approximation
Dim yMin As Double
Dim yMax As Double
Dim xFactor As Double
If prevPoint.Ysig < curSignalPoint.Ysig Then
yMin = prevPoint.Ysig
yMax = curSignalPoint.Ysig
xFactor = 2.0 / 3.0
Else
yMin = curSignalPoint.Ysig
yMax = prevPoint.Ysig
xFactor = 1.0 / 3.0
End If
Dim yDiff As Double = yMax - yMin
Dim xDiff As Double = curSignalPoint.Xsig - prevPoint.Xsig
'Rectangular area under the triangle.
Dim area1 As Double = xDiff * yMin
Dim x1 As Double = (prevPoint.Xsig + curSignalPoint.Xsig) / 2
Dim y1 As Double = 0.5 * yMin
Dim xw1 As Double = x1 * area1
Dim yw1 As Double = y1 * area1
xWeightSum += xw1
yWeightSum += yw1
areaSum += area1
'The triangle above the triangle.
Dim area2 As Double = 0.5 * xDiff * yDiff
Dim x2 As Double = xFactor * xDiff + prevPoint.Xsig
Dim y2 As Double = yDiff / 3 + yMin
Dim xw2 As Double = x2 * area2
Dim yw2 As Double = y2 * area2
xWeightSum += xw2
yWeightSum += yw2
areaSum += area2
prevPoint = curSignalPoint
End If
Next j
Trace.Assert(areaSum > 0.0, "PIL ASSERT. areaSum > 0.0. In findSignalPeak().")
'Changed PM_NONUNIFORMSAMPLING_LCCENTROID 2003-03-24
'anOutSignalPeakXCentroid = weigthedRetSum / ySum
'anOutSignalPeakYCentroid = ySum / pointsUsed
anOutSignalPeakXCentroid = xWeightSum / areaSum
anOutSignalPeakYCentroid = yWeightSum / areaSum
Else 'pointsUsed >= 2
'Should mean a single point...
Trace.Assert(pointsUsed = 1, "PIL ASSERT: pointsForCentroid = 1. In findSignalPeak()")
Dim firstSignalPoint As signalStructure = _
aSignal(xStartIndexForCentroid)
anOutSignalPeakXCentroid = firstSignalPoint.Xsig
anOutSignalPeakYCentroid = firstSignalPoint.Ysig
End If
Trace.Assert(anOutSignalPeakXCentroid > -1000000.0 And _
anOutSignalPeakXCentroid < 1000000.0, _
"PIL ASSERT. anOutSignalPeakXCentroid out of range: " & _
anOutSignalPeakXCentroid)
'For FTMS we can get very high values. This value has been
'seen: 2004785.7348632813
Trace.Assert(anOutSignalPeakYCentroid > -1000000000.0 And _
anOutSignalPeakYCentroid < 1000000000.0, _
"PIL ASSERT. anOutSignalPeakYCentroid out of range: " & _
anOutSignalPeakYCentroid)
anOutSignalPeakIndexStart = xStartIndexForCentroid
anOutSignalPeakIndexEnd = xEndIndexForCentroid
'Changed PM_EXTENDED_LCPEAK_TIMEWINDOW 2003-03-24
'Find local minima to the left and right of the
'points used for the centroid.
If True Then 'to the left...
anOutSignalPeakWindowStart = anOutSignalPeakIndexStart
'Dim prevY As Double = DirectCast( _
' aSignal(anOutSignalPeakWindowStart), _
' signalStructure).Ysig
Dim prevY As Double = peakLeftSideY
anOutSignalPeakWindowStart -= 1
Dim stopNow As Boolean = False
While Not stopNow And anOutSignalPeakWindowStart >= anStartIndex
Dim curPoint As signalStructure = _
aSignal(anOutSignalPeakWindowStart)
Dim curY As Double = curPoint.Ysig
'Changed PM_SMARTPICKING_FIX 2004-10-27
Dim curX As Double = curPoint.Xsig
Dim xDist As Double = maxYtime - curX 'We don't need Abs(), we
' are sure of the sign...
'Changed PM_SMARTPICKING_FIX 2004-10-27
If xDist <= aMaximumXDistanceForMinima Then
'Changed PM_IGNORE_ZEROS_IN_LCPROFILE_ 2004-06-18
If curY > IDENTICALZERO_THRESHOLD Then
If curY <= prevY Then
Else
stopNow = True
End If
prevY = curY
End If
Else
stopNow = True
stoppedByMaxDist_left = True
End If
If Not stopNow Then
anOutSignalPeakWindowStart -= 1
End If
End While
anOutSignalPeakWindowStart += 1
'If anOutSignalPeakWindowStart < anStartIndex Then
'anOutSignalPeakWindowStart = anStartIndex
'End If
End If 'To the left
'Those 2 blocks have a lot in common. Can we make it less redundant?
If True Then 'to the right...
anOutSignalPeakWindowEnd = anOutSignalPeakIndexEnd
'Changed PM_IGNORE_ZEROS_IN_LCPROFILE_ 2004-06-18
'Dim prevY As Double = DirectCast( _
' aSignal(anOutSignalPeakWindowEnd), _
' signalStructure).Ysig
Dim prevY As Double = peakRightSideY
anOutSignalPeakWindowEnd += 1
Dim stopNow As Boolean = False
While Not stopNow And anOutSignalPeakWindowEnd <= anEndIndex
Dim curPoint As signalStructure = _
aSignal(anOutSignalPeakWindowEnd)
Dim curY As Double = curPoint.Ysig
'Changed PM_SMARTPICKING_FIX 2004-10-27
Dim curX As Double = curPoint.Xsig
Dim xDist As Double = curX - maxYtime 'We don't need Abs(), we
' are sure of the sign...
'Changed PM_SMARTPICKING_FIX 2004-10-27
If xDist <= aMaximumXDistanceForMinima Then
'Changed PM_IGNORE_ZEROS_IN_LCPROFILE_ 2004-06-18
If curY > IDENTICALZERO_THRESHOLD Then
If curY <= prevY Then
Else
stopNow = True
End If
prevY = curY
End If
Else
stopNow = True
stoppedByMaxDist_right = True
End If
If Not stopNow Then
anOutSignalPeakWindowEnd += 1
End If
End While
anOutSignalPeakWindowEnd -= 1
End If
'Changed PM_BETTER_LCPEAK_DETECTION 2003-10-16
' as the background.
Dim minYinPeakWindow As Double = 1000000000.0
Dim k As Integer
For k = anOutSignalPeakWindowStart To anOutSignalPeakWindowEnd
Dim curY As Double = aSignal(k).Ysig
'Changed PM_LCPEAKDETECT_IGNORE_ZERO_FOR_BACKGROUND 2003-10-21
'If curY < minYinPeakWindow Then
If curY > IDENTICALZERO_THRESHOLD AndAlso _
curY < minYinPeakWindow Then 'IDENTICALZERO_THRESHOLD: ignore
' points zero value. This would give very high ..??
minYinPeakWindow = curY
End If
Next
anOutBackgroundLevel = minYinPeakWindow 'For now: just use the minimum value
Dim stoppedByMax_bothDirs As Boolean = _
stoppedByMaxDist_left And stoppedByMaxDist_right
If stoppedByMax_bothDirs Then
Dim peter9 As Integer = 9
End If
Trace.Assert(anOutSignalPeakWindowStart <= anOutSignalPeakIndexStart, _
"PIL ASSERT: anOutSignalPeakWindowStart <= anOutSignalPeakIndexStart in findSignalPeak()")
Trace.Assert(anOutSignalPeakWindowEnd >= anOutSignalPeakIndexEnd, _
"PIL ASSERT: anOutSignalPeakWindowEnd >= anOutSignalPeakIndexEnd in findSignalPeak()")
'Avoid a single point defining an signal peak...
Trace.Assert(anOutSignalPeakWindowStart < anOutSignalPeakWindowEnd Or _
stoppedByMax_bothDirs, _
"PIL ASSERT: single point signal peak - anOutSignalPeakWindowStart < anOutSignalPeakWindowEnd. In findSignalPeak()")
End Sub 'findSignalPeak()
'****************************************************************************
'* <placeholder for header> *
'****************************************************************************
Public Shared Sub dumpSignalToDisk(ByVal aHeadline As String, _
ByRef anInSignal As Generic.List(Of massSpectrometryBase.signalStructure), _
ByVal aFullPathFileName As String)
Dim toOutputSB As StringBuilder = New StringBuilder(300) 'Instead
' estimate on length of input signal?
'Dim tableHeaders As String = _
' aHeadline & PILInputOutput.LINEEND & PILInputOutput.LINEEND & _
' "Index" & vbTab & "x" & vbTab & "y" & PILInputOutput.LINEEND
toOutputSB.Append(aHeadline)
toOutputSB.Append(PILInputOutput.LINEEND)
toOutputSB.Append(PILInputOutput.LINEEND)
toOutputSB.Append("Index")
toOutputSB.Append(vbTab)
toOutputSB.Append("x")
toOutputSB.Append(vbTab)
toOutputSB.Append("y")
toOutputSB.Append(PILInputOutput.LINEEND)
'Dim str As String = tableHeaders
Dim index As Integer = 0
Dim sPoint As signalStructure
For Each sPoint In anInSignal
'Str &= index & vbTab & _
' sPoint.Xsig & vbTab & sPoint.Ysig & PILInputOutput.LINEEND
toOutputSB.Append(index)
toOutputSB.Append(vbTab)
toOutputSB.Append(sPoint.Xsig)
toOutputSB.Append(vbTab)
toOutputSB.Append(sPoint.Ysig)
toOutputSB.Append(PILInputOutput.LINEEND)
index += 1
Next
PILInputOutput.pushToFile(aFullPathFileName, toOutputSB.ToString)
End Sub 'dumpSignalToDisk
'Changed PM_REFACTOR 2004-06-22
'Changed PM_LCPROFILE_DUMP 2003-11-16
'****************************************************************************
'* SUBROUTINE NAME: findLCProfileProperties *
'd$ <summary>
'd$ Purpose: Find some properties of the LC profile, e.g. max point, XYZ
'd$ Type of elements in anInSignal: signalStructure
'd$
'd$ <see cref="T:VBXMLDoc.CVBXMLDoc" />.
'd$ </summary>
Public Shared Sub findSignalProfileProperties( _
ByRef anInSignal As _
Generic.List(Of massSpectrometryBase.signalStructure), _
ByRef anOutSignalProfileDescriptor As dataPointsInfoStructure2)
'Old:
' ByRef anInSignal As ArrayList
Dim maxYsignal As Double = -1000000000.0
Dim minYsignal As Double = 1000000000.0
Dim lastIndex As Integer = anInSignal.Count - 1
Dim minX As Double = anInSignal.Item(0).Xsig
Dim maxX As Double = anInSignal.Item(lastIndex).Xsig
Dim sPoint As signalStructure
For Each sPoint In anInSignal
Dim curY As Double = sPoint.Ysig
If curY > maxYsignal Then
maxYsignal = curY
anOutSignalProfileDescriptor.maximumSignal = sPoint
End If
If curY < minYsignal Then
minYsignal = curY
anOutSignalProfileDescriptor.minimumSignal = sPoint
End If
'sIndex += 1
Next
anOutSignalProfileDescriptor.minX2 = minX
anOutSignalProfileDescriptor.maxX2 = maxX
End Sub 'findLCProfileProperties
'Changed PM_DTASC_MEMORY 2004-10-15. Refactored out the private part of findThePeaks
' in order to avoid passing constant values in the recursive calls.
'****************************************************************************
'* <placeholder for header> *
'****************************************************************************
Private Shared Sub internal_findThePeaks( _
ByRef anInfo As peaksInfoStorage, _
ByVal anStartIndex As Integer, ByVal anEndIndex As Integer, _
ByVal aSearchLevel As Integer, _
ByRef anInOutDumpFileCounter As Integer _
)
Dim pointsToUse As Integer = anEndIndex - anStartIndex + 1
'Changed PM_CENTROIDEDDATA_PEAKDETECTION 2005-01-21
'Dim minimumNumberOfPoints As Integer = 1
Dim minimumNumberOfPoints As Integer = 0
Dim doFindPeakAtThisLevel As Boolean = True
If pointsToUse <= minimumNumberOfPoints Then 'We don't accept LC ranges with only a single point.
doFindPeakAtThisLevel = False
Else
Dim findPeaksMaxSearchLevel As Integer = _
anInfo.getFindPeaksMaxSearchLevel()
If aSearchLevel > findPeaksMaxSearchLevel Then
doFindPeakAtThisLevel = False
Else
Dim curDeepestSearchLevel As Integer = anInfo.getActualDeepestSearchLevel()
If aSearchLevel > curDeepestSearchLevel Then
anInfo.setActualDeepestSearchLevel(aSearchLevel)
Else
Dim peter9 As Integer = 9
End If
End If
End If
If doFindPeakAtThisLevel Then 'We don't accept LC ranges with only a single point.
Dim outLCpeakTimeCentroid As Double
Dim outLCpeakIntensity As Double
Dim outLCPeakIndexStart As Integer
Dim outLCPeakIndexEnd As Integer
Dim outLCpeakWindowStart As Integer
Dim outLCpeakWindowEnd As Integer
Dim outLCMaxTime As Double
Dim outLCMaxIntensity As Double
Dim LCMaxIndex As Integer
Dim backGround As Double
'Dim inSignal As ArrayList = anInfo.getSignal()
Dim inSignal As _
Generic.List(Of massSpectrometryBase.signalStructure) = _
anInfo.getSignal()
If False Then
'Test only, but should be out-factored - we may want to provide
'a menu command to dump the LC peak profiles.
Dim doDump As Boolean = False 'True Or mDumpFileCounter = 0
Dim maxY As Double = anInfo.getMaxY()
If maxY > 210000 Then 'Thats for
' Finnegan FTMS, typical high intensity value.
doDump = True
Else
Dim peter21 As Integer = 21
End If
If aSearchLevel > 0 Then 'Only once...
doDump = False
Else
'Only needed for testing..
'Dim msMea As Double = mPept.calibratedMeasuredMass
'Dim msMascot As Double = mPept.MascotCalculatedMW
'Dim absErr As Double = msMea - msMascot
'Dim relErr As Double = 1000000.0 * absErr / msMascot
'If Math.Abs(relErr) > 7.5 Then
' Dim peter20 As Integer = 20
'Else
' doDump = False 'Don't dump unless rel error is high....
' Dim peter03 As Integer = 3
'End If
End If
'Only needed for testing..
''doDump = True 'Active: temp!!!!!!!!!!!!!!!!!!
'If mPept.AASequence = "LGVLGFFSTGDQHAR" Then
' doDump = True
'End If
'Changed PM_DUMP_PERFORMANCE_MARKER 2004-06-25
doDump = False 'Activate for use in DTA SuperCharge - dumping
' makes peakdetection extremely slow. Perhaps the
' limit 210000 above should be parameter, to be set by
' clients?
''doDump = True 'Test only!!!!!!!!!!!!!
If doDump Then
'mDumpFileCounter
'mPept.AASequence
'mPept.calibratedMeasuredMZ
'mPept.charge
'mStr
Dim AASequence As String = anInfo.getAASequence()
Dim calibratedMeasuredMZ As Double = _
anInfo.getCalibratedMeasuredMZ()
Dim charge As Integer = anInfo.getCharge()
Dim str As String = _
dumpLCprofile(inSignal, _
anStartIndex, anEndIndex, _
anInOutDumpFileCounter, aSearchLevel, _
AASequence, calibratedMeasuredMZ, charge)
'Function name is a misnomer in this case...
anInfo.addToDumpString(str)
anInOutDumpFileCounter += 1
End If
End If
'Changed PM_OPTIMISATION 2004-12-17
'Only get the signal once!
'Dim someSignal As ArrayList = anInfo.getSignal()
Dim maximumXDistanceForPeakDetection As Double = _
anInfo.getMaximumXDistanceForPeakDetection()
Dim maximumXDistanceForMinima As Double = _
anInfo.getMaximumXDistanceForMinima()
BSignal.findSignalPeak( _
inSignal, anStartIndex, anEndIndex, _
maximumXDistanceForPeakDetection, maximumXDistanceForMinima, _
outLCpeakTimeCentroid, outLCpeakIntensity, _
outLCPeakIndexStart, outLCPeakIndexEnd, _
outLCpeakWindowStart, outLCpeakWindowEnd, _
outLCMaxTime, outLCMaxIntensity, LCMaxIndex, _
backGround)
Dim LCpointForMax As signalStructure = inSignal(LCMaxIndex)
Dim leftLCpoint As signalStructure = inSignal(outLCpeakWindowStart)
Dim rightLCpoint As signalStructure = inSignal(outLCpeakWindowEnd)
Dim calibratedCentroidMass As Double = LCpointForMax.tagValue
'mPept.MascotCalculatedMW
Dim theoMass As Double = anInfo.getMascotCalculatedMW()
'mPept.measuredMW
'mPept.neutralMScentroidForLCMax
'mPept.calibratedMeasuredMass
Dim relError As Double = _
1000000.0 * (calibratedCentroidMass - theoMass) / theoMass
Dim absRelError As Double = Math.Abs(relError)
If backGround < 1.0 Then 'Avoid division by zero
backGround = 1
End If
Dim peakToBackgroundRatio As Double = _
outLCMaxIntensity / backGround
'Changed PM_LCPEAK_MSMSEVENT 2004-02-02
Dim MSMSeventInPeak As Boolean = False
Dim MSMSretentionTimeSecs As Double = _
60.0 * anInfo.getMSMSretentionTimeMinutes()
If anInfo.getConsiderMSMSevent() Then
If MSMSretentionTimeSecs >= leftLCpoint.Xsig AndAlso _
MSMSretentionTimeSecs <= rightLCpoint.Xsig Then
MSMSeventInPeak = True
End If
End If
Dim LCPeakInfo As LCPeakInfoStructure
LCPeakInfo.maxIntensity = outLCMaxIntensity
LCPeakInfo.calibratedNeutralMass = calibratedCentroidMass
LCPeakInfo.absRelError_PPM = absRelError
LCPeakInfo.peakToBackgroundRatio = peakToBackgroundRatio
'Copy these fields. Needed by clients.
LCPeakInfo.LCpeakTimeCentroid = outLCpeakTimeCentroid
LCPeakInfo.LCpeakWindowStart = outLCpeakWindowStart
LCPeakInfo.LCpeakWindowEnd = outLCpeakWindowEnd
LCPeakInfo.LCMaxTime = outLCMaxTime
LCPeakInfo.LCMaxIndex = LCMaxIndex
LCPeakInfo.MSMSeventInPeak = MSMSeventInPeak
'mLCPeakCandidates.Add(LCPeakInfo) 'Note: this is for the
anInfo.addToPeakCandidates(LCPeakInfo) 'Note: this is for the
' peak in the middle interval.
'To the left.
Dim startIndex_left As Integer = anStartIndex
Dim endIndex_left As Integer = outLCpeakWindowStart - 1
internal_findThePeaks(anInfo, startIndex_left, endIndex_left, _
aSearchLevel + 1, _
anInOutDumpFileCounter) 'Recursive!
'To the right.
Dim startIndex_right As Integer = outLCpeakWindowEnd + 1
Dim endIndex_right As Integer = anEndIndex
internal_findThePeaks(anInfo, startIndex_right, endIndex_right, _
aSearchLevel + 1, _
anInOutDumpFileCounter) 'Recursive!
End If
End Sub 'internal_findThePeaks
'****************************************************************************
'* SUBROUTINE NAME: findThePeaksNonEx *
'd$ <summary>
'd$ Purpose: Wrapper for findThePeaks() - few parameters.
'd$ It also sorts the output peak list by X value, e.g. mass.
'd$ Type of elements in anInSignal: signalStructure
'd$ <see cref="T:VBXMLDoc.CVBXMLDoc" />.
'd$ </summary>
' Later:
' Provide wrapper to this function
Public Shared Sub findThePeaksNonEx( _
ByRef anInSignal As Generic.List(Of massSpectrometryBase.signalStructure), _
ByRef anInOutPeakCandidates As Generic.List(Of LCPeakInfoStructure), _
ByVal anInMaximumXDistanceForPeakDetection As Double, _
ByVal anInMaximumXDistanceForMinima As Double, _
ByVal anInFindPeaksMaxSearchLevel As Integer, _
ByRef anInOutActualDeepestSearchLevel As Integer)
'Old:
' ByRef anInSignal As ArrayList
' ByRef anInOutPeakCandidates As ArrayList
Dim considerMSMSevent As Boolean = False
Dim dumpCounter As Integer = 0
Dim dumpStr As String = ""
Dim doNotTriggerDump As Double = 111.1
Dim lastIndex As Integer = anInSignal.Count - 1
findThePeaks( _
anInSignal, _
0, _
lastIndex, _
considerMSMSevent, _
-10.0, _
doNotTriggerDump, _
anInOutPeakCandidates, _
dumpCounter, _
"XYZ", _
-5.0, _
-10.0, _
-1, _
dumpStr, _
anInMaximumXDistanceForPeakDetection, _
anInMaximumXDistanceForMinima, _
anInFindPeaksMaxSearchLevel, _
anInOutActualDeepestSearchLevel, _
1000000.0, _
0.5)
Dim comp As New SortByX()
anInOutPeakCandidates.Sort(comp)
End Sub 'findThePeaksNonEx
'Changed PM_REFACTOR 2004-06-22. Moved from FindLCpeaks.vb
'Later: remove any reference to LC stuff...
'Changed PM_BETTER_LCPEAK_DETECTION 2003-10-16
'
'Changed PM_DTASC_MEMORY 2004-10-15
' ByVal anAASequence -> ByRef anAASequence
'
'****************************************************************************
'* SUBROUTINE NAME: findThePeaks *
'd$ <summary>
'd$ Purpose: Find a candidate list of peaks. This is done by
'd$ subdiving the interval XYZ.
'd$ Type of elements in anInSignal: signalStructure
'd$ <see cref="T:VBXMLDoc.CVBXMLDoc" />.
'd$ </summary>
' Later:
' Provide wrapper to this function
Public Shared Sub findThePeaks( _
ByRef anInSignal As _
Generic.List(Of massSpectrometryBase.signalStructure), _
ByVal anStartIndex As Integer, _
ByVal anEndIndex As Integer, _
ByVal aConsiderMSMSevent As Boolean, _
ByVal aMSMSretentionTimeMinutes As Double, _
ByVal aMaxY As Double, _
ByRef anInOutPeakCandidates As Generic.List(Of LCPeakInfoStructure), _
ByRef anInOutDumpFileCounter As Integer, _
ByRef anInAASequence As String, _
ByVal anCalibratedMeasuredMZ As Double, _
ByVal aMascotCalculatedMW As Double, _
ByVal aCharge As Integer, _
ByRef anInOutDumpString As String, _
ByVal anInMaximumXDistanceForPeakDetection As Double, _
ByVal anInMaximumXDistanceForMinima As Double, _
ByVal anInFindPeaksMaxSearchLevel As Integer, _
ByRef anInOutActualDeepestSearchLevel As Integer, _
ByVal aSegmentSize As Double, _
ByVal aSegmentBoundaryValue As Double)
'Old:
' ByRef anInSignal As ArrayList
' ByRef anInOutPeakCandidates As ArrayList
Dim info As peaksInfoStorage = New peaksInfoStorage
info.setSignal(anInSignal)
info.setMaxY(aMaxY)
info.setAASequence(anInAASequence)
info.setCalibratedMeasuredMZ(anCalibratedMeasuredMZ)
info.setCharge(aCharge)
info.setMaximumXDistanceForPeakDetection(anInMaximumXDistanceForPeakDetection)
info.setMaximumXDistanceForMinima(anInMaximumXDistanceForMinima)
info.setMascotCalculatedMW(aMascotCalculatedMW)
info.setMSMSretentionTimeMinutes(aMSMSretentionTimeMinutes)
info.setConsiderMSMSevent(aConsiderMSMSevent)
'Changed PM_OPTIMISATION 2004-12-17
info.setFindPeaksMaxSearchLevel(anInFindPeaksMaxSearchLevel) 'Re-enable.....
info.setActualDeepestSearchLevel(0)
'Old.
'internal_findThePeaks( _
' info, anStartIndex, anEndIndex, 0, anInOutDumpFileCounter)
'aSegments
Dim firstIndex As Integer = 0
Dim lastIndex As Integer = anInSignal.Count - 1
Dim firstSegmentLowerBound As Double
Dim maxX As Double
If True Then
Dim firstPoint As signalStructure = anInSignal(firstIndex)
Dim lastPoint As signalStructure = anInSignal(lastIndex)
Dim minX As Double = firstPoint.Xsig
maxX = lastPoint.Xsig
firstSegmentLowerBound = aSegmentBoundaryValue
'Find beginning af first segment.
Dim done As Boolean = False
While firstSegmentLowerBound > minX
firstSegmentLowerBound -= aSegmentSize
End While
'Binary search could be used here...
End If
Dim segmentLowerBound As Double = firstSegmentLowerBound
Dim segmentUpperBound As Double = segmentLowerBound + aSegmentSize
Dim startIndex As Integer = firstIndex
Dim segmentCount As Integer = 0
Dim sp As signalStructure
Dim index As Integer = startIndex
For Each sp In anInSignal
Dim Xval As Double = sp.Xsig
Dim atLastIndex As Boolean = index = lastIndex
If Xval > segmentUpperBound Or atLastIndex Then
segmentCount += 1
Dim endIndex As Integer = index - 1
If atLastIndex Then
endIndex = index
End If
internal_findThePeaks( _
info, startIndex, endIndex, 0, anInOutDumpFileCounter)
startIndex = index
segmentLowerBound += aSegmentSize
segmentUpperBound = segmentLowerBound + aSegmentSize
End If
index += 1
Next
anInOutPeakCandidates = info.getPeakCandidates()
anInOutDumpString = info.getDumpString()
'Changed PM_OPTIMISATION 2004-12-17
anInOutActualDeepestSearchLevel = info.getActualDeepestSearchLevel()
End Sub 'findThePeaks
'Changed PM_REFACTOR 2004-03-16
'****************************************************************************
'* SUBROUTINE NAME: dumpLCprofile *
'd$ <summary>
'd$ Purpose: helper function for LC profiles....
'd$
'd$
'd$ Type of elements in anInSignal: signalStructure
'd$ <see cref="T:VBXMLDoc.CVBXMLDoc" />.
'd$ </summary>
Public Shared Function dumpLCprofile( _
ByRef anInSignal As Generic.List(Of massSpectrometryBase.signalStructure), _
ByVal anStartIndex As Integer, ByVal anEndIndex As Integer, _
ByVal anInIDnumber As Integer, _
ByVal aSearchLevel As Integer, _
ByVal aPeptideSequence As String, _
ByVal aCalibMCR As Double, _
ByVal aCharge As Integer _
) _
As String
'Old:
' ByRef anInSignal As ArrayList
Dim firstPoint As signalStructure = anInSignal(anStartIndex)
Dim lastPoint As signalStructure = anInSignal(anEndIndex)
Dim points As Integer = anInSignal.Count
Dim str As String = _
"LC profile (lower) dump " & anInIDnumber & "." & vbCr & vbLf & _
points & " points" & vbCr & vbLf & _
"Level: " & vbTab & aSearchLevel & vbCr & vbLf & _
"Indices: " & vbTab & "[" & vbTab & anStartIndex & vbTab & ";" & _
vbTab & anEndIndex & vbTab & "]" & vbCr & vbLf & _
"Mass range: " & vbTab & "[" & vbTab & firstPoint.Xsig & vbTab & ";" & _
vbTab & lastPoint.Xsig & vbTab & "] Da" & vbCr & vbLf & _
"Sequence: " & vbTab & aPeptideSequence & vbCr & vbLf & _
"Calibrated measured MCR: " & vbTab & aCalibMCR & vbCr & vbLf & _
"Charge: " & vbTab & aCharge & vbCr & vbLf & _
vbCr & vbLf
str &= "Index" & vbTab & _
"Cycle" & vbTab & _
"LC time [secs]" & vbTab & _
"LC signal" & vbTab & _
"Calibrated neutral MS centroid mass" & vbTab & _
vbCr & vbLf
Dim sIndex As Integer = 0
Dim sPoint As signalStructure
For Each sPoint In anInSignal
If sIndex >= anStartIndex AndAlso sIndex <= anEndIndex Then
str &= _
sIndex & vbTab & _
sPoint.tagValue2 & vbTab & _
sPoint.Xsig & vbTab & _
sPoint.Ysig & vbTab & _
sPoint.tagValue & vbTab & _
vbCr & vbLf
End If
sIndex += 1
Next
str &= "END_OF_DUMP" & vbCr & vbLf & _
"============================================" & vbCr & vbLf
Return str
End Function 'dumpLCprofile
'Changed PM_REFACTOR 2005-01-05
'Moved to here from DTASC' peakutil.vb.
'****************************************************************************
'* <placeholder for header> *
'* Type is: signalStructure *
'****************************************************************************
Public Shared Sub filterSignalByMassRange( _
ByRef anInSignal As Generic.List(Of massSpectrometryBase.signalStructure), _
ByVal aStartMass As Double, ByVal anEndMass As Double, _
ByRef anOutSignal As Generic.List(Of massSpectrometryBase.signalStructure), _
ByRef anOutMaxY As Double)
'Old:
' ByRef anInSignal As ArrayList
' ByRef anOutSignal As ArrayList
'anOutMaxY: we don't use dataPointsInfoStructure2 as it would drag in
' too many fields.
anOutMaxY = -1.0E+20
'Type of aSignal: signalStructure
'anOutSignal = New ArrayList
anOutSignal = New Generic.List(Of massSpectrometryBase.signalStructure)
If True Then
Dim someSignal As signalStructure
For Each someSignal In anInSignal
Dim someMass As Double = someSignal.Xsig
If someMass >= aStartMass AndAlso someMass <= anEndMass Then
anOutSignal.Add(someSignal)
If someSignal.Ysig > anOutMaxY Then
anOutMaxY = someSignal.Ysig
End If
End If
Next
End If
End Sub 'filterSignalByMassRange
'****************************************************************************
'* SUBROUTINE NAME: convertListTo_signalStructureList *
'd$ <summary>
'd$ Purpose: convert a list of LCPeakInfoStructure to list
'd$ of signalStructure.
'd$ <see cref="T:VBXMLDoc.CVBXMLDoc" />.
'd$ </summary>
Public Shared Function convertListTo_signalStructureList( _
ByRef anInList As Generic.List(Of LCPeakInfoStructure)) _
As Generic.List(Of massSpectrometryBase.signalStructure)
'Old return type:
' ArrayList
' ByRef anInList As ArrayList
Dim inputSize As Integer = anInList.Count
'Dim outList As ArrayList = New ArrayList
Dim outList As _
Generic.List(Of massSpectrometryBase.signalStructure) = _
New Generic.List(Of massSpectrometryBase.signalStructure)(inputSize)
' Output size is exactly the same as the input size.
Dim someSignal As LCPeakInfoStructure
For Each someSignal In anInList
Dim someNewItem As signalStructure
someNewItem.Xsig = someSignal.LCMaxTime
someNewItem.Ysig = someSignal.maxIntensity
outList.Add(someNewItem)
Next
Trace.Assert(outList.Count = inputSize, _
"PIL ASSERT. convertListTo_signalStructureList is not the " & _
"excepted, in convertListTo_signalStructureList().")
Return outList
End Function 'convertListTo_signalStructureList
'Changed PM_MS3SCORING_ISOTOPE_ELIMINATION 2005-01-21
'****************************************************************************
'* SUBROUTINE NAME: simpleIsotopeElimination *
'd$ <summary>
'd$
'd$ Purpose: elimination of isotope peaks using very simple rules: C13
'd$ peaks are eliminated if there is a lower (low mass fragments
'd$ assumed). The input is assumed to be reduced (peaklist), not
'd$ raw data.
'd$ Note: designed for fragment spectra as isotope patterns are
'd$ assumed to be low mass (not multiple charged at the lower
'd$ mass-to-charge ratio).
'd$
'd$ Real type in lists: LCPeakInfoStructure
'd$ <see cref="T:VBXMLDoc.CVBXMLDoc" />.
'd$ </summary>
Public Shared Function simpleIsotopeElimination( _
ByRef anInList As Generic.List(Of LCPeakInfoStructure)) _
As Generic.List(Of LCPeakInfoStructure)
'Changed PM_TYPESAFE 2006-11-01
'Old:
' ByRef anInList As ArrayList
'
' Return type:
' ArrayList
'Changed PM_TYPESAFE 2006-11-
'Dim toReturn As ArrayList = New ArrayList
Dim inputSize As Integer = anInList.Count
Dim toReturn As Generic.List(Of LCPeakInfoStructure) = _
New Generic.List(Of LCPeakInfoStructure)(inputSize)
' Capacity: it will be smaller than the input, but it is probably
' better than multiple resizes.
Dim len As Integer = anInList.Count
Dim lastIndex As Integer = len - 1
Dim include(lastIndex) As Boolean
Dim tolerance As Double = 0.22
Dim peptideUniDistance As Double = 1.00234565
Dim diffLow As Double = peptideUniDistance - tolerance
Dim diffHigh As Double = peptideUniDistance + tolerance
Dim eliminatedCount As Integer = 0
Dim index As Integer = 0
Dim someSignal As LCPeakInfoStructure
For Each someSignal In anInList
'someNewItem.Xsig = someSignal.LCMaxTime
'someNewItem.Ysig = someSignal.maxIntensity
include(index) = True
'Search back to see if there were any peak at the expected distance with a higher intensity.
Dim mass As Double = someSignal.LCMaxTime
'Dim massLow As Double = mass - diffHigh
'Dim massHigh As Double = mass - diffLow
Dim sIndex As Integer = index - 1
Dim done As Boolean = False
While (Not done)
If sIndex >= 0 Then
Dim massPrev As Double = _
anInList(sIndex).LCMaxTime
Dim massDiff As Double = mass - massPrev
If massDiff > diffHigh Then
'We are past the mass window. Stop.
done = True
Else
If massDiff >= diffLow AndAlso massDiff <= diffHigh Then
Dim y As Double = someSignal.maxIntensity
'Some peak in the window.
Dim prevY As Double = _
anInList(sIndex).maxIntensity
Dim intensityRatio As Double = y / prevY
If intensityRatio < 1.0 Then 'First condition: previous peak
' must be higher. Implicit we assume there are only low
' mass single charged ions.
If intensityRatio > 0.1 AndAlso intensityRatio < 0.8 Then
include(index) = False
eliminatedCount += 1
End If
End If
End If
End If
Else
done = True 'Outside array bounds.
End If
sIndex -= 1
End While
index += 1
Next
'Read-out
index = 0
For Each someSignal In anInList
If include(index) Then
toReturn.Add(someSignal)
End If
index += 1
Next
Return toReturn
End Function 'simpleIsotopeElimination
'****************************************************************************
'* <placeholder for header> *
'* *
'* Given a centroided peak list or raw data, we give back a list *
'* of the four *
'* highest intensity peaks per hundred Da (storing only the indices). *
'* Right now we can have four values for the first and last interval *
'* even if it is very small. Need to fix. *
'* *
'****************************************************************************
Public Shared Sub reducePeakList2( _
ByRef anInSignal As Generic.List(Of massSpectrometryBase.signalStructure), _
ByRef anOutPeakLst() As Integer, _
ByRef anOutEffectiveDataPoints As Generic.List(Of LCPeakInfoStructure), _
ByVal aMaxSearchLevel As Integer, _
ByVal aMassWindow As Double, _
ByVal aKeepCount As Integer, _
ByVal aCatchDistance As Double)
'Old:
' ByRef anInSignal As ArrayList
' ByRef anOutEffectiveDataPoints As ArrayList
'
' ByRef aDataPtInfoStr_toDelete As dataPointsInfoStructure2, _
'Find peaks in the MS spectrum.
'Changed PM_USERSET_MS3_MATCHING_TOLERANCE 2007-07-13
'Dim massWindow As Double = 100.0
Dim massWindow As Double = aMassWindow
'Changed PM_TYPESAFE 2006-11-01
'anOutEffectiveDataPoints = New ArrayList
anOutEffectiveDataPoints = New Generic.List(Of LCPeakInfoStructure)
If True Then
'Changed PM_TYPESAFE 2006-11-01
'Dim initialPeakList As ArrayList = Nothing 'Keep compiler happy.
Dim initialPeakList As Generic.List(Of LCPeakInfoStructure) = _
Nothing 'Keep compiler happy.
'Changed PM_CODEMARKER_0.3DA_CATCHDISTANCE 2006-11-22
'Dim catchDistance As Double = 0.03 'Bigger peaks will not...
Dim catchDistance As Double = 0.3 'Bigger peaks will not
' svallow smaller ones, even if the data is already centroided.
'Changed PM_USERSET_MS3_MATCHING_TOLERANCE 2007-07-13
catchDistance = aCatchDistance
'Changed PM_MS3SCORING_LOWER_CATCHDISTANCE 2005-01-21
'Dim catchDistanceForExtension As Double = 1.1
Dim catchDistanceForExtension As Double = 0.4
'Dim findPeaksMaxSearchLevel As Integer = 99 now a parameter..
Dim actualDeepestSearchLevel As Integer
BSignal.findThePeaksNonEx( _
anInSignal, _
initialPeakList, _
catchDistance, catchDistanceForExtension, _
aMaxSearchLevel, actualDeepestSearchLevel)
'Changed PM_MS3SCORING_ISOTOPE_ELIMINATION 2005-01-21
anOutEffectiveDataPoints = _
BSignal.simpleIsotopeElimination(initialPeakList)
End If
Dim lastIndex2 As Integer = anOutEffectiveDataPoints.Count - 1
Dim outSize As Integer = 0
Dim low100 As Double = 0
Dim high100 As Double = -100
If lastIndex2 >= 0 Then 'It can be -1 if the spectrum
' is empty. This can be the case if XCalibur 2.0 is
' installed and an older LTQ-FT file is open.....
Dim minX As Double = _
anOutEffectiveDataPoints(0).LCpeakTimeCentroid
Dim maxX As Double = _
anOutEffectiveDataPoints(lastIndex2).LCpeakTimeCentroid
'Changed PM_MS3SCORING_USEPEAKS 2004-10-27
'Dim low100 As Double = 100 * Math.Floor(aDataPtInfoStr.minX2 / 100.0)
'Dim high100 As Double = 100 * Math.Ceiling(aDataPtInfoStr.maxX2 / 100.0)
low100 = massWindow * Math.Floor(minX / massWindow)
high100 = massWindow * Math.Ceiling(maxX / massWindow)
outSize = _
CInt(Math.Round(aKeepCount * (high100 - low100) / massWindow))
End If
ReDim anOutPeakLst(outSize) 'Up to
' four peaks per massWindow Da.
Dim j As Integer 'Indices for the signal structures
' in this massWindow Da range.
Dim theLowMass As Double = 0.0
Dim iHighMass As Integer = 0
Dim iLowMass As Integer = 0
Dim numIons As Integer = 0
Dim lastIndexArr As Integer = aKeepCount - 1
Dim tempArr(lastIndexArr) As Integer 'Keep the indices
' within massWindow Da range.
For theLowMass = low100 To high100 Step massWindow
'Changed PM_MANNREDUCTION_LEVEL 2005-09-05
'tempArr(0) = -1
'tempArr(1) = -1
'tempArr(2) = -1
'tempArr(3) = -1
Dim i As Integer
For i = 0 To lastIndexArr Step 1
tempArr(i) = -1
Next i
'Set the index for the higher mass.
Dim upperMassInInterval As Double = theLowMass + massWindow
'Changed PM_MS3SCORING_USEPEAKS 2004-10-27
'While iHighMass < inSignArr.Count AndAlso _
' DirectCast(inSignArr(iHighMass), signalStructure).Xsig <= _
' upperMassInInterval
While iHighMass < anOutEffectiveDataPoints.Count AndAlso _
anOutEffectiveDataPoints(iHighMass).LCpeakTimeCentroid <= _
upperMassInInterval
iHighMass += 1
End While
'Run through the array four times, determining the
'highest remaining value each time.
'Should be fast enough and we don't need to do complicated
'array sorts.
Dim k As Integer
Dim lastIndex As Integer = iHighMass - 1
For k = 0 To lastIndexArr
Dim highSignVal As Double = Double.MinValue
For j = iLowMass To lastIndex
Dim y As Double = _
anOutEffectiveDataPoints(j).maxIntensity
'Changed PM_MANNREDUCTION_LEVEL 2005-09-05
Dim allDifferent As Boolean = True
For i = 0 To lastIndexArr Step 1
If tempArr(i) = j Then
allDifferent = False
End If
Next i
'
'If y > highSignVal AndAlso _
' tempArr(0) <> j AndAlso _
' tempArr(1) <> j AndAlso _
' tempArr(2) <> j AndAlso _
' tempArr(3) <> j Then
If y > highSignVal AndAlso _
allDifferent Then
highSignVal = y
tempArr(k) = j
End If
Next j
Next k
iLowMass = iHighMass 'Rachet up the lower index to iHighMass which
'is already in the next massWindow.
'Now append the values in tempArr to outPeakLst.
For k = 0 To lastIndexArr
If tempArr(k) <> -1 Then
anOutPeakLst(numIons) = tempArr(k)
numIons += 1
End If
Next
Next 'next theLowMass
ReDim Preserve anOutPeakLst(numIons - 1)
Array.Sort(anOutPeakLst) 'It is sufficient to sort the indices.
End Sub 'reducePeakList
End Class 'BSignal
End Module 'signalModule
Generated by script codePublish.pl at 2008-09-23T11:59:18.