'****************************************************************************
'* Copyright (C) 2007 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: 1. Encapsulates knowledge of how to recalibrate masses. *
'* *
'* 2. Can compute recalibration in the appropriate *
'* domain, e.g. frequency for LTQ-FT. *
'* *
'* 3. Encapsulates calibration constants and how to use *
'* them - so clients need not and should not know *
'* how to convert between calibrated and uncalibrated. *
'* *
'* *
'* *
'* *
'****************************************************************************
'****************************************************************************
'* 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: SDUPrecalibrator.vb *
'* TYPE: VISUAL_BASIC *
'* *
'* CREATED: PM 2007-10-24 Vrs 1.0. *
'* UPDATED: PM 2007-xx-xx *
'* *
'****************************************************************************
'Future:
' 1.
Option Strict On
Option Explicit On
Imports System.Text 'For StringBuilder
Imports System.Collections.Generic 'For Dictionary
Imports SimmoTech.Utils.Serialization 'For SerializationReader and SerializationWriter.
Imports SDUPutility 'For SDUPstatistics
'Changed PM_REFACTOR 2007-11-07
Imports MolecularSharedStructures 'For ProteinHitStructure and for PeptideHitStructure.
Imports massSpectrometryBase 'For peptideFilterStructure
Imports utilityStatic 'For numbersClose
'Changed PM_RECALIB_OUTLIERDETECTION 2007-12-12
'****************************************************************************
'* SUBROUTINE NAME: doublesList_Sort_usingIndex *
'* *
'* Note: this class is completely general (application and domain *
'* independent) and should be in a general place... *
'* *
'd$ <summary> N/A. ...
'd$ Note: xyz </summary>
Class doublesList_Sort_usingIndex
Implements System.Collections.Generic.IComparer(Of Integer)
Dim mDoubles As List(Of Double)
'****************************************************************************
'* <placeholder for header> *
'****************************************************************************
Sub New(ByRef aDoubles As List(Of Double))
'Type of aCombinations is onePTMcombinationStructure.
mDoubles = aDoubles
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 val1 As Double = mDoubles(aItem1)
Dim val2 As Double = mDoubles(aItem2)
'Note: ascending sort
Dim toReturn As Integer = 0
If val1 > val2 Then
toReturn = 1
Else
If val1 < val2 Then
toReturn = -1
Else
'Equal....
Dim peter9 As Integer = 9
End If
End If
Return toReturn
End Function 'Compare
End Class 'doublesList_Sort_usingIndex
'****************************************************************************
'* <placeholder for header> *
'****************************************************************************
Public Class SDUPrecalibrator
Const MAX_DATAPOINTS2 As Integer = 300
Const LASTIDX As Integer = MAX_DATAPOINTS2 - 1
Public Const ALL_TAGCODE As Integer = 41650
Public Enum recalibDomainEnum 'Note: the order of enumerators is
' independent of the order in the Tools/Options dialog. That
' dependence is expressed in constants LISTINDEX_XYZ, etc.
enumRecalibDomainMass = 383
enumRecalibDomainFreq2 'LTQ-FT. MCR is inversely
' proportional to frequency.
enumRecalibDomainTOFtime 'TOF: QSTAR, Qtof
enumRecalibDomainSqrtFreq 'Orbi. MCR is inversely
' proportional to the square-root of frequency.
'
' From <http://en.wikipedia.org/wiki/Orbitrap>:
'
' "The frequency of these harmonic oscillations is
' independent of the ion velocity and is inversely
' proportional to the square root of the MCR."
'
' "Like FTICR-MS the orbitrap resolving power is
' proportional to the number of harmonic oscillations of the
' ions, as a result the resolving power is inversely
' proportional to the square root of MCR and proportional to
' acquisition time."
End Enum 'QuantMSTypesEnum
'Changed PM_RECALIB_REALITY_CHECK 2008-03-26
Public Structure recalibLimitsStructure
'Linear calibration constants, but in some
'domain (mass/frequency/time).
Dim startSlope As Double
Dim endSlope As Double
Dim startOffset As Double
Dim endOffset As Double
Dim startDatapoints As Integer
Dim endDatapoints As Integer
'Changed PM_SAVE_ALLRECALIB_MB4 2008-11-24
'****************************************************************************
'* For recalibLimitsStructure. *
'****************************************************************************
Public Shared Function readFromStream2( _
ByRef anInReader As SerializationReader, _
ByVal aMBfileVersion As Integer) _
As recalibLimitsStructure
Dim toReturn As recalibLimitsStructure
toReturn.startSlope = anInReader.ReadDouble()
toReturn.endSlope = anInReader.ReadDouble()
toReturn.startOffset = anInReader.ReadDouble()
toReturn.endOffset = anInReader.ReadDouble()
toReturn.startDatapoints = anInReader.ReadInt32()
toReturn.endDatapoints = anInReader.ReadInt32()
Return toReturn
End Function 'readFromStream2(). For recalibLimitsStructure.
'Changed PM_SAVE_ALLRECALIB_MB4 2008-11-24
'****************************************************************************
'* For SDUPrecalibrator. *
'****************************************************************************
Public Sub addToStream2( _
ByRef anInOutWriter As SerializationWriter, _
ByVal aMBfileVersion As Integer)
'aMBfileVersion: e.g. 300 for MB3, 400 for MB4.
'SERMARK23. A marker. Keep it.
'Assume client has checked file version...
Trace.Assert(aMBfileVersion >= AppConstants.SAVEDFILEVERSION_MB4, _
"Unexpected file version: " & aMBfileVersion)
anInOutWriter.Write(startSlope)
anInOutWriter.Write(endSlope)
anInOutWriter.Write(startOffset)
anInOutWriter.Write(endOffset)
anInOutWriter.Write(startDatapoints)
anInOutWriter.Write(endDatapoints)
End Sub 'addToStream2(). For recalibLimitsStructure.
End Structure 'recalibLimitsStructure
'Changed PM_PERFILE_RECALIBRATION 2007-11-14. Moved most
'members to this structure.
Private Structure calibValuesStructure
'Linear calibration constants in some domain (frequency,
'square-root mass, etc.)
'
'Values are valid: from uncalibrated to calibrated;
'
' calib = mSlope * uncalib + mOffset
'
Dim slope As Double
Dim offset As Double
'Changed PM_DOMAINS_RECALIBRATION 2007-11-05
'The values can be MCR, MCR freq, MCR time. Depending in
'which domain the recalibration is done in (e.g. frequency
'domain for LTQ-FT).
Dim measValues() As Double
Dim calcValues() As Double
'For computing MCR errors after recalibration has been done. It
'is the only reason for remembering those values.
Dim measValues_MCR() As Double
Dim calcValues_MCR() As Double
Dim tags2() As String 'What is this? Is client defined. Is
' only used for the recalibration report. Sample
' item: "AAEAGGAEEQYGFLTTPTK_2_Q6175_Hit1_IPI00008868.3".
'
' Client is ourselfes!, feedCalibratorWithPeptides(),
' file SDUPrecalibrator.vb.
Dim idx2 As Integer
Dim absPPMErrBeforeSum As Double 'Note: is always
' the input (MCR) domain. As it is computed directly
' from the input.
Dim recalibReport As StringBuilder
'Is used to insure that the entire mass range is
'used in the recalibration
Dim excludeHash As Dictionary(Of Integer, Double) 'Key is
' nominal ***neutral*** mass. Value is highest
' peptide score for that mass.
'Changed PM_EXCLUDEDSTATS_RECALIBRATION 2007-11-16
Dim consideredPoints As Integer 'For statistics only.
' A value much higher than 300 indicates that the
' protein contains a lot of peptides.
'Changed PM_PERFILE_RECALIBRATION 2007-11-19
Dim reachedMaxForRecalib As Boolean 'E.g. used 300 peptides
' for current raw file or for all.
'Changed PM_SAVE_ALLRECALIB_MB4 2008-11-24
'****************************************************************************
'* For calibValuesStructure. *
'****************************************************************************
Public Shared Function readFromStream2( _
ByRef anInReader As SerializationReader, _
ByVal aMBfileVersion As Integer) _
As calibValuesStructure
Dim toReturn As calibValuesStructure
Dim slope As Double = anInReader.ReadDouble()
toReturn.offset = anInReader.ReadDouble()
Trace.Assert( _
slope > 0.1 AndAlso slope < 10.0, _
"PIL ASSERT. In deserialisation of calibValuesStructure; ." & _
" slope has an unreasonable value: " & _
slope & ".")
toReturn.slope = slope
'Keep compiler happy.
toReturn.calcValues = Nothing
toReturn.calcValues_MCR = Nothing
toReturn.excludeHash = Nothing
toReturn.measValues = Nothing
toReturn.measValues_MCR = Nothing
toReturn.recalibReport = Nothing
toReturn.tags2 = Nothing
Return toReturn
End Function 'readFromStream2(). For calibValuesStructure.
'Changed PM_SAVE_ALLRECALIB_MB4 2008-11-24
'****************************************************************************
'* For calibValuesStructure. *
'****************************************************************************
Public Sub addToStream2( _
ByRef anInOutWriter As SerializationWriter, _
ByVal aMBfileVersion As Integer)
'aMBfileVersion: e.g. 300 for MB3, 400 for MB4.
'SERMARK24. A marker. Keep it.
'Assume client has checked file version...
anInOutWriter.Write(slope)
anInOutWriter.Write(offset)
'What about the other values, e.g. list of (x,y) used
'for recalibration?
End Sub 'addToStream2(). For calibValuesStructure.
End Structure 'calibValuesStructure
'Changed PM_PERFILE_RECALIBRATION 2007-11-14
Private mCalibs As Dictionary(Of Integer, calibValuesStructure)
'Changed PM_PERFILE_RECALIBRATION 2007-11-19
Private mReachedLimitCount As Integer 'Current number of raw files/all files that
' has received the maximum number of peptides for recalibration.
'Changed PM_REFACTOR 2007-11-14
'Private mSlope As Double
'Private mOffset As Double
'Private mMeasValues() As Double
'Private mCalcValues() As Double
'Private mMeasValues_MCR() As Double
'Private mCalcValues_MCR() As Double
'Private mTags2() As String
'Private mIdx2 As Integer
'Private mAbsPPMErrBeforeSum3 As Double
'Private mRecalibReport As StringBuilder
'Private mExcludeHash As Dictionary(Of Integer, Double)
Private mComputedRecalibration As Boolean
Private mAccuracyStatsStr_all As String 'For now: global - independent
' of e.g. raw files recalibration. This implies that the calibration
' error is almost identical for the different raw files.
Private mRecalibMsgStr_all As String
'Changed PM_DOMAINS_RECALIBRATION 2007-11-05
Private mDomainType As recalibDomainEnum
Private mDomainStr As String 'Used in reporting (to clients, for reports).
'Later: mDomainUnitsStr, for use near ""Recalibration report. "
Private mFTlinearCalib As Double
Private mFTquadraticCalib As Double
Private mFTextraCalib As Double
'Changed PM_ORBI_AWARE_RECALIB 2008-02-14
Private mOrbiLinearCalib As Double
Private mOrbiQuadraticCalib As Double
'Changed PM_RECALIB_REALITY_CHECK 2008-03-27
Private mRecalibLimits As recalibLimitsStructure
'****************************************************************************
'* <placeholder for header> *
'****************************************************************************
Public Sub New( _
ByVal aDomainType As recalibDomainEnum, _
ByVal aRecalibLimits As recalibLimitsStructure)
mRecalibLimits.startDatapoints = -1
'Changed PM_RECALIB_REALITY_CHECK 2008-03-27
mRecalibLimits = aRecalibLimits
Trace.Assert(mRecalibLimits.startDatapoints > 0, _
"PIL ASSERT. mRecalibLimits.startDatapoints is zero or less.")
'Hardcoded for now! But they really should be correct. Even if the
'error is small. It usually works because we transform back and
'forth with the ***same*** constants and thus the important
'thing is the major non-linear transformation (square).
mFTlinearCalib = 107411.977 ' 107412.00
mFTquadraticCalib = -475.49 ' -433.121
mFTextraCalib = 0.0
'Changed PM_ORBI_AWARE_RECALIB 2008-02-15
'mOrbiLinearCalib = 47518908.357
mOrbiLinearCalib = Math.Sqrt(47518908.357) 'To fit the form.
mOrbiQuadraticCalib = -16477771.902
mOrbiQuadraticCalib = 0.0 'For now. We don't yet know the structure
' for mOrbiQuadraticCalib.
' 'Changed PM_REFACTOR 2007-11-14
' mCommonForAll.slope = 1.0
' mCommonForAll.offset = 0.0
'
' mCommonForAll.measValues = Nothing 'To be explicit.
' mComputedRecalibration = False
' mCommonForAll.excludeHash = New Dictionary(Of Integer, Double)
'mCommonForAll = emptyCalibValues()
'Changed PM_PERFILE_RECALIBRATION 2007-11-14
mCalibs = New Dictionary(Of Integer, calibValuesStructure)
mReachedLimitCount = 0
Dim allCalib As calibValuesStructure = emptyCalibValues()
mCalibs.Add(ALL_TAGCODE, allCalib)
Me.newDomainType(aDomainType)
'Changed PM_ORBI_AWARE_RECALIB 2008-02-15
Me.selfTest_Calib()
End Sub 'Constructor.
'Changed PM_SAVE_ALLRECALIB_MB4 2008-11-21.
'****************************************************************************
'* For SDUPrecalibrator. *
'****************************************************************************
Public Shared Function readFromStream2( _
ByRef anInReader As SerializationReader, _
ByVal aMBfileVersion As Integer) _
As SDUPrecalibrator
Dim toReturn As SDUPrecalibrator = Nothing
'Allow us to read in old format (by not reading anything here).
If aMBfileVersion >= AppConstants.SAVEDFILEVERSION_MB4 Then
Dim recalibDomain As recalibDomainEnum = _
DirectCast(anInReader.ReadInt32(), recalibDomainEnum)
Dim recalibLimits As recalibLimitsStructure = _
recalibLimitsStructure.readFromStream2(anInReader, aMBfileVersion)
toReturn = New SDUPrecalibrator(recalibDomain, recalibLimits)
toReturn.mComputedRecalibration = True 'Playing with the
' internals... Not a whole lot of encapsulation here... Should
' we instead use setLinearCalibrationConstants()? It could set
' the slope and offset (but only those).
If True Then 'Block. Reading hash.
Dim items As Integer = anInReader.ReadOptimizedInt32()
If (items > 0) Then
'Set capacity for toReturn.mCalibs ?
Dim lastIndex As Integer = items - 1
Dim j As Integer
For j = 0 To lastIndex
Dim curKey As Integer = anInReader.ReadInt32()
Dim curValue As calibValuesStructure = _
calibValuesStructure.readFromStream2( _
anInReader, aMBfileVersion)
'Direct...
If toReturn.mCalibs.ContainsKey(curKey) Then
toReturn.mCalibs(curKey) = curValue
Else
toReturn.mCalibs.Add(curKey, curValue)
End If
Next j
Else
'What to do?
Dim peter2 As Integer = 2
End If
End If
Else
Dim peter2 As Integer = 2 'MB3. We will return Nothing. Hopyfully
' the client can cope.
End If
Return toReturn
End Function 'readFromStream2(). For SDUPrecalibrator.
'Changed PM_SAVE_ALLRECALIB_MB4 2008-11-21.
'****************************************************************************
'* For SDUPrecalibrator. *
'****************************************************************************
Public Sub addToStream2( _
ByRef anInOutWriter As SerializationWriter, _
ByVal aMBfileVersion As Integer)
'aMBfileVersion: e.g. 300 for MB3, 400 for MB4.
'SERMARK22. A marker. Keep it.
'Allow us to save in old format (by not saving anything here).
If aMBfileVersion >= AppConstants.SAVEDFILEVERSION_MB4 Then
anInOutWriter.Write(mDomainType)
'Do we really need this?
mRecalibLimits.addToStream2(anInOutWriter, aMBfileVersion)
'Dump what we have... (presumably there is a one-to-one correspondence
'to a raw file - except the for-all tag).
If True Then 'Block. Writing hash.
If Not mCalibs Is Nothing Then 'Not really needed.
Dim items As Integer = mCalibs.Count()
anInOutWriter.WriteOptimized(items)
Dim hashEnumerator2 As Dictionary( _
Of Integer, calibValuesStructure).Enumerator = _
mCalibs.GetEnumerator()
While hashEnumerator2.MoveNext()
Dim curKey As Integer = hashEnumerator2.Current.Key
Dim curValue As calibValuesStructure = _
hashEnumerator2.Current.Value
anInOutWriter.Write(curKey)
curValue.addToStream2(anInOutWriter, aMBfileVersion)
End While 'Hash iteration.
Else
Dim items As Integer = 0
'Encode nothing as zero length.
anInOutWriter.WriteOptimized(items)
End If
End If 'Block. Writing hash.
End If 'MB4 or later.
End Sub 'addToStream2(). For SDUPrecalibrator.
'****************************************************************************
'* <placeholder for header> *
'****************************************************************************
Private Function emptyCalibValues() _
As calibValuesStructure
Dim toReturn As calibValuesStructure
'Identity calibration. So it works if recalibration was not
'attempted or if there was not enough data points for proper
'values of calibration constants.
toReturn.slope = 1.0
toReturn.offset = 0.0
toReturn.idx2 = 0 'Required (for lazy instantiation )
toReturn.reachedMaxForRecalib = False 'Required. Or at least to
' be explicit.
toReturn.measValues = Nothing 'To be explicit.
toReturn.excludeHash = New Dictionary(Of Integer, Double)
'Keep compiler happy
toReturn.calcValues = Nothing
toReturn.calcValues_MCR = Nothing
toReturn.measValues_MCR = Nothing
toReturn.recalibReport = Nothing
toReturn.tags2 = Nothing
Return toReturn
End Function 'emptyCalibValues()
'****************************************************************************
'* <placeholder for header> *
'****************************************************************************
Private Sub newDomainType(ByVal aNewDomainType As recalibDomainEnum)
'Result is used for reporting (to clients, for reports).
'Default, same as the only option/way until 2007-10.
'mDomainType = recalibDomainEnum.enumRecalibDomainMass
mDomainType = aNewDomainType
mDomainStr = ""
Select Case mDomainType
Case recalibDomainEnum.enumRecalibDomainMass
mDomainStr = "MCR"
Case recalibDomainEnum.enumRecalibDomainFreq2
mDomainStr = "frequency (FT)"
Case recalibDomainEnum.enumRecalibDomainTOFtime
'Not yet...
'Changed PM_ORBI_AWARE_RECALIB 2008-02-14
Case recalibDomainEnum.enumRecalibDomainSqrtFreq
mDomainStr = "frequency (Orbitrap)" 'This is also frequency, but
' the transformation is different.
Case Else
Trace.Assert(False, _
"PIL ASSERT. Select Case never fall-through")
End Select
End Sub 'newDomainType()
'****************************************************************************
'* <placeholder for header> *
'* Used when loading from a saved parse. *
'****************************************************************************
Public Sub setLinearCalibrationConstants( _
ByVal aSlope As Double, ByVal anOffset As Double, _
ByVal aTag As Integer)
'Recalib domain type as well? mDomainType.
Trace.Assert( _
aSlope > 0.1 AndAlso aSlope < 10.0, _
"PIL ASSERT. In setLinearCalibrationConstants(); ." & _
" recalibSlope has an unreasonable value: " & _
aSlope & ".")
'Changed PM_PERFILE_RECALIBRATION 2007-11-14
'mCommonForAll.slope = aSlope
'mCommonForAll.offset = anOffset
Dim someCalibValues As calibValuesStructure = emptyCalibValues()
If mCalibs.TryGetValue( _
aTag, someCalibValues) Then
Else
'Values set below. Should we do an Add() or does
'the below work????
Dim peter2 As Integer = 2 'For breakpoints.
End If
someCalibValues.slope = aSlope
someCalibValues.offset = anOffset
mCalibs(aTag) = someCalibValues
mComputedRecalibration = True 'Do not attempt to compute
' recalibration with data that we may not have...
End Sub 'setLinearCalibrationConstants()
'Changed PM_REFACTOR 2008-03-03
'****************************************************************************
'* <placeholder for header> *
'****************************************************************************
Private Sub handleNotFoundCalibSet( _
ByVal aTag As Integer, ByRef anOutCalibValues As calibValuesStructure)
'Changed PM_BUG_TOO_FEW_PEPTIDES_FOR_RAWFILE 2008-03-03
''Values set below. Should we do an Add() or does
''the below work????
'This usually happens when there are no peptides
'representing a raw file.
'
'Now: silently fail; add the misisng entry and set values so as
' to effectively disabled recalibration.
Dim someCalibValues As calibValuesStructure = emptyCalibValues()
'Already set, but be explicit.
someCalibValues.slope = 1.0
someCalibValues.offset = 0.0
'What else to set???? When loading from mb3 we only set those
'two fields, but what about reports, etc.??
mCalibs.Add(aTag, someCalibValues)
anOutCalibValues = someCalibValues
End Sub 'handleNotFoundCalibSet()
'****************************************************************************
'* <placeholder for header> *
'****************************************************************************
Public Sub getLinearCalibrationConstants( _
ByRef anOutSlope As Double, ByRef anOutOffset As Double, _
ByVal aTag As Integer)
'Changed PM_PERFILE_RECALIBRATION 2007-11-14
'anOutSlope = mCommonForAll.slope
'anOutOffset = mCommonForAll.offset
Dim someCalibValues As calibValuesStructure = emptyCalibValues()
If mCalibs.TryGetValue( _
aTag, someCalibValues) Then
'Slope less than 1.0 for sample FT data? Yes, because
'it is reverse when the recalibration domain is
'frequency.
anOutSlope = someCalibValues.slope
anOutOffset = someCalibValues.offset
Else
'Changed PM_REFACTOR 2008-03-03
''Values set below. Should we do an Add() or does
''the below work????
Me.handleNotFoundCalibSet(aTag, someCalibValues)
End If
End Sub 'getLinearCalibrationConstants()
'****************************************************************************
'* <placeholder for header> *
'****************************************************************************
Public Function calibrationIsDefined() _
As Boolean
'Changed PM_PERFILE_RECALIBRATION 2007-11-14
'Dim isDefined As Boolean = mCommonForAll.slope >= 0.2
Dim calibValues_All As calibValuesStructure = mCalibs(ALL_TAGCODE)
Dim isDefined As Boolean = calibValues_All.slope >= 0.2 'Note:
' this (perhaps) contradicts with some of the asserts?
If Not isDefined Then
Dim peter2 As Integer = 2 'Does this ever happen?
End If
Return isDefined
End Function 'calibrationIsDefined()
'****************************************************************************
'* <placeholder for header> *
'****************************************************************************
Private Sub checkRecalibration()
If Not mComputedRecalibration Then
computeRecalibration()
End If
End Sub 'checkRecalibration()
'****************************************************************************
'* <placeholder for header> *
'****************************************************************************
Public Function getAccuracyStatsStr() _
As String
checkRecalibration()
Return mAccuracyStatsStr_all
End Function 'getAccuracyStatsStr
'****************************************************************************
'* <placeholder for header> *
'****************************************************************************
Public Function getRecalibReport() _
As StringBuilder
checkRecalibration()
'Changed PM_PERFILE_RECALIBRATION 2007-11-14
'Dim report As StringBuilder = mCommonForAll.recalibReport
Dim calibValues_All As calibValuesStructure = mCalibs(ALL_TAGCODE)
Dim report As StringBuilder = calibValues_All.recalibReport
Return report
End Function 'getAccuracyStatsStr
'****************************************************************************
'* <placeholder for header> *
'****************************************************************************
Public Function getRecalibMsgStr() _
As String
checkRecalibration()
Return mRecalibMsgStr_all
End Function 'getAccuracyStatsStr
'****************************************************************************
'* <placeholder for header> *
'****************************************************************************
Private Function FTmass2freq(ByVal aMass As Double) _
As Double
Dim A As Double = aMass
Dim B As Double = -mFTlinearCalib
Dim C As Double = -mFTquadraticCalib
' mFTextraCalib
Dim sd As Double = Math.Sqrt(B * B - 4 * A * C)
Dim freq1 As Double = (-B - sd) / (2 * A) 'E.g. + 4.03 Hz.
Dim freq2 As Double = (-B + sd) / (2 * A) 'E.g. + 263.4 kHz
Return freq2 'The second solution is the correct one.
End Function 'FTmass2freq
'****************************************************************************
'* <placeholder for header> *
'****************************************************************************
Private Function FTfreq2mass(ByVal aFreq As Double) _
As Double
Dim toReturn As Double = _
mFTlinearCalib / aFreq + _
mFTquadraticCalib / (aFreq * aFreq)
Return toReturn
End Function 'FTfreq2mass
'Changed PM_ORBI_AWARE_RECALIB 2008-02-14
'****************************************************************************
'* <placeholder for header> *
'****************************************************************************
Private Function OrbiMass2freq(ByVal aMass As Double) _
As Double
'Is all this correct???? How is the C parameter defined for Orbitrap??
Dim A As Double = aMass
Dim B As Double = -mOrbiLinearCalib
Dim C As Double = -mOrbiQuadraticCalib
'Is it true that it is in freq^2 ????
Dim sd As Double = Math.Sqrt(B * B - 4 * A * C)
Dim freq1 As Double = (-B - sd) / (2 * A) 'E.g. + 0.3467 kHz * kHz.
Dim freq2 As Double = (-B + sd) / (2 * A) 'E.g. + 81050.199 kHz * kHz.
'The second solution is the correct one.
Dim realFreq As Double = freq2 * freq2 'What unit??
Return realFreq '
End Function 'OrbiMass2freq
'Changed PM_ORBI_AWARE_RECALIB 2008-02-14
'****************************************************************************
'* <placeholder for header> *
'****************************************************************************
Private Function OrbiFreq2mass(ByVal aFreq As Double) _
As Double
'Is the second term correct???.
Dim toReturn As Double = _
mOrbiLinearCalib / Math.Sqrt(aFreq) + _
mOrbiQuadraticCalib / aFreq
If False Then 'For debugging only.
Dim freq2 As Double = OrbiMass2freq(toReturn)
Dim peter2 As Integer = 2
End If
Return toReturn
End Function 'OrbiFreq2mass
'Changed PM_PERFILE_RECALIBRATION 2007-11-16
'The function we use internally so we can pass any hash. It is required
'from within the hash iteration in computeRecalibration().
'****************************************************************************
'* <placeholder for header> *
'* Used when loading from a saved parse. *
'****************************************************************************
Private Function uncalib2calib_internal( _
ByVal anUncalibrated As Double, _
ByVal aSlope As Double, _
ByVal anOffset As Double _
) _
As Double
Dim toReturn As Double = 0.0
Trace.Assert(aSlope > 0.8, _
"PIL ASSERT. Calibration constant out of range: " & _
aSlope & _
". It is expected to be close to 1.0.")
Trace.Assert(aSlope < 1.2, _
"PIL ASSERT. Calibration constant out of range: " & _
aSlope & _
". It is expected to be close to 1.0.")
Dim calibrated As Double = -1.444E-25
Select Case mDomainType
Case recalibDomainEnum.enumRecalibDomainMass
calibrated = anOffset + aSlope * anUncalibrated
Case recalibDomainEnum.enumRecalibDomainFreq2
Dim freqUncalib As Double = Me.FTmass2freq(anUncalibrated)
Dim calibFrequency As Double = anOffset + aSlope * freqUncalib
calibrated = Me.FTfreq2mass(calibFrequency)
Case recalibDomainEnum.enumRecalibDomainTOFtime
'Not yet...
'Changed PM_ORBI_AWARE_RECALIB 2008-02-14
Case recalibDomainEnum.enumRecalibDomainSqrtFreq
Dim freqUncalib As Double = Me.OrbiMass2freq(anUncalibrated)
Dim calibFrequency As Double = anOffset + aSlope * freqUncalib
calibrated = Me.OrbiFreq2mass(calibFrequency)
Case Else
Trace.Assert(False, _
"PIL ASSERT. Select Case never fall-through")
End Select
toReturn = calibrated
Return toReturn
End Function 'uncalib2calib_internal
'****************************************************************************
'* Used when loading from a saved parse. *
'* *
'* Note: should not be used internally from member functions. *
'* *
'* *
'****************************************************************************
Public Function uncalib2calib( _
ByVal anUncalibrated As Double, _
ByVal aTag As Integer) _
As Double
checkRecalibration()
'Changed PM_PERFILE_RECALIBRATION 2007-11-14
''Changed PM_REFACTOR 2007-11-14
'Dim slope As Double = mCommonForAll.slope
'Dim offset As Double = mCommonForAll.offset
Dim someCalibValues As calibValuesStructure = _
emptyCalibValues() 'Keep compiler happy.
If mCalibs.TryGetValue( _
aTag, someCalibValues) Then
'Set below...
Dim peter2 As Integer = 2
Else
'Changed PM_REFACTOR 2008-03-03
''Values set below. Should we do an Add() or does
''the below work????
Me.handleNotFoundCalibSet(aTag, someCalibValues)
End If
Dim slope As Double = someCalibValues.slope
Dim offset As Double = someCalibValues.offset
Dim toReturn As Double = _
uncalib2calib_internal(anUncalibrated, slope, offset)
Return toReturn
End Function 'uncalib2calib
'****************************************************************************
'* <placeholder for header> *
'****************************************************************************
Public Function calib2uncalib( _
ByVal aCalibrated As Double, _
ByVal aTag As Integer) _
As Double
Dim toReturn As Double = 0.0
checkRecalibration()
'Dim slope As Double = mCommonForAll.slope
'Dim offset As Double = mCommonForAll.offset
Dim someCalibValues As calibValuesStructure = emptyCalibValues()
If mCalibs.TryGetValue( _
aTag, someCalibValues) Then
'Set below...
Dim peter2 As Integer = 2
Else
'Changed PM_REFACTOR 2008-03-03
''Values set below. Should we do an Add() or does
''the below work????
Me.handleNotFoundCalibSet(aTag, someCalibValues)
End If
Dim slope As Double = someCalibValues.slope
Dim offset As Double = someCalibValues.offset
Trace.Assert(slope > 0.8, _
"PIL ASSERT. Calibration constant out of range: " & _
slope & _
". It is expected to be close to 1.0.")
Trace.Assert(slope < 1.2, _
"PIL ASSERT. Calibration constant out of range: " & _
slope & _
". It is expected to be close to 1.0.")
Dim uncalibrated As Double = -3.3E+23
Select Case mDomainType
Case recalibDomainEnum.enumRecalibDomainMass
uncalibrated = (aCalibrated - offset) / slope
Case recalibDomainEnum.enumRecalibDomainFreq2
Dim freqCalib As Double = Me.FTmass2freq(aCalibrated)
Dim uncalibFrequency As Double = (freqCalib - offset) / slope
uncalibrated = Me.FTfreq2mass(uncalibFrequency)
Case recalibDomainEnum.enumRecalibDomainTOFtime
'Not yet...
Case recalibDomainEnum.enumRecalibDomainSqrtFreq
Dim freqCalib As Double = Me.OrbiMass2freq(aCalibrated)
Dim uncalibFrequency As Double = (freqCalib - offset) / slope
uncalibrated = Me.OrbiFreq2mass(uncalibFrequency)
Case Else
Trace.Assert(False, _
"PIL ASSERT. Select Case never fall-through")
End Select
toReturn = uncalibrated
Return toReturn
End Function 'calib2uncalib
'****************************************************************************
'* <placeholder for header> *
'****************************************************************************
Public Function addPoint( _
ByVal anUncalibrated2 As Double, ByVal aTrueValue2 As Double, _
ByVal aScore As Double, _
ByVal aTag3 As Integer, _
ByRef anInTagStr As String, _
ByRef anOutUsedForRecalibration As Boolean) _
As Boolean
Dim toReturn As Boolean = False 'Value if not all raw file
' recalibrations have received datapoints of the
' maximum of 300.
'Changed PM_PEPTIDEFIELD_USEDFORRECALIBRATION 2008-11-25
anOutUsedForRecalibration = False
'Changed PM_PERFILE_RECALIBRATION 2007-11-16
Dim keyLen As Integer = 2
If ALL_TAGCODE = aTag3 Then 'Avoid double add.
keyLen = 1
End If
Dim onlyOne As Boolean = keyLen = 1
Dim lastIndex As Integer = keyLen - 1
Dim keys(lastIndex) As Integer
keys(0) = ALL_TAGCODE
If Not onlyOne Then
keys(1) = aTag3
End If
Dim j As Integer
For j = 0 To lastIndex
Dim tag As Integer = keys(j)
Dim isAll As Boolean = _
tag = ALL_TAGCODE
'Changed PM_PERFILE_RECALIBRATION 2007-11-14
'Dim usedAll As Boolean = mCommonForAll.idx2 > LASTIDX
Dim calibValues As calibValuesStructure = emptyCalibValues()
If mCalibs.TryGetValue(tag, calibValues) Then
'We got it!
Dim peter2 As Integer = 2
Else
'Needed??
'mCalibs.Add()
Dim peter2 As Integer = 2
End If
Dim usedAll2 As Boolean = calibValues.idx2 > LASTIDX
If usedAll2 Then
'Nothing more to add (for current raw file or for all).
If Not isAll Then
Dim peter2 As Integer = 2 'For breakpoints.
End If
'Changed PM_PERFILE_RECALIBRATION 2007-11-19. Did NOT work.
' Stopped when the ***first*** raw file or all reached
' the limit of 300.
''Changed PM_PERFILE_RECALIBRATION 2007-11-16
''toReturn = True
'If onlyOne Or Not isAll Then
' toReturn = True 'The return value is for current
' raw file and not all.
'End If
If Not calibValues.reachedMaxForRecalib Then 'Only once, just
' when we reach the limit, e.g. 300.
calibValues.reachedMaxForRecalib = True
'Note: this is not bulletproof. It will fail if the
' first 300 peptides are from the same raw file.
' But there is no way around it unless we look at
' all peptides or perhaps another higher number
' of peptides than 300 before we cut off completely.
mReachedLimitCount += 1
Dim currentRawFilesAndAll As Integer = mCalibs.Count()
If mReachedLimitCount = currentRawFilesAndAll Then
toReturn = True
End If
Trace.Assert(mReachedLimitCount <= currentRawFilesAndAll, _
"PIL ASSERT. mReachedLimitCount is too high...: " & _
mReachedLimitCount)
mCalibs(tag) = calibValues 'Write back. Needed
' for reachedMaxForRecalib. But is only done
' once.
End If
Else
''Changed PM_REFACTOR 2007-11-14
'Dim calibValues As calibValuesStructure = mCommonForAll
'Lazy instantiation.
If calibValues.measValues Is Nothing Then
ReDim calibValues.measValues(LASTIDX)
ReDim calibValues.calcValues(LASTIDX)
ReDim calibValues.measValues_MCR(LASTIDX)
ReDim calibValues.calcValues_MCR(LASTIDX)
ReDim calibValues.tags2(LASTIDX)
calibValues.idx2 = 0
calibValues.absPPMErrBeforeSum = 0.0
mComputedRecalibration = False
'Changed PM_RECALIBRATION_TROUBLE 2007-05-16
calibValues.excludeHash = _
New Dictionary(Of Integer, Double) 'Key is
' nominal ***neutral*** mass. Value is highest
' peptide score for that mass.
End If
'Dim idxMax As Integer = LASTIDX
'Changed PM_EXCLUDEDSTATS_RECALIBRATION 2007-11-16
calibValues.consideredPoints += 1
Dim peptOK2 As Boolean = True
Dim nominalCalcMCR As Integer = CInt(anUncalibrated2) 'Note: it
' ***is*** the MCR that should be used (not mass). MCR is
' the domain for measurements - that should be recalibrated.
'Use of mExcludeHash: we don't want any observed mass to be
'represented more than once. This is to insure the
'entire mass range is used in the recalibration.
'Otherwise the top protein with a very high
'number of peptides could result in only a
'few (low) masses to be used and thus
'extrapolation for most masses (very
'bad).
'
Dim oldScore As Double
If calibValues.excludeHash.TryGetValue( _
nominalCalcMCR, oldScore) Then
If aScore > oldScore Then
'Note: we will not undo using the lower scoring
'peptide. Thus the peptides used for recalibration
'depends on the order in which there are presented.
'We change this so peptides are presented in
'descending order after score (for each protein).
calibValues.excludeHash(nominalCalcMCR) = aScore
' Replace with the new higher score.
'
' In this way we record the highest scoring for each
' nominal mass - used above for deciding wether to use
' a candidate mass or not depending on its score.
Else
peptOK2 = False 'Lower score than some other
' peptide (for the same nominal mass): ignore current
' point.
End If
Else
'New entry. First time we see this nominal mass.
calibValues.excludeHash(nominalCalcMCR) = aScore
End If
If peptOK2 Then
'Changed PM_PEPTIDEFIELD_USEDFORRECALIBRATION 2008-11-25
anOutUsedForRecalibration = True
Dim domainMeasured As Double = -3.3E+23
Dim domainCalc As Double = -3.3E+23
Select Case mDomainType
Case recalibDomainEnum.enumRecalibDomainMass
'Same domain...
domainMeasured = anUncalibrated2
domainCalc = aTrueValue2
Case recalibDomainEnum.enumRecalibDomainFreq2
'Transform to frequency domain. That is where the
'recalibration will take place. A constant frequency
'shift is a good first approximation for space charge.
'
'A more advanced scheme would use the precursor
'intensity and find a maximum in a 2D performance
'landscape.
'
domainMeasured = Me.FTmass2freq(anUncalibrated2)
domainCalc = Me.FTmass2freq(aTrueValue2)
Case recalibDomainEnum.enumRecalibDomainTOFtime
'Not yet...
Case recalibDomainEnum.enumRecalibDomainSqrtFreq
'Transform to frequency domain. That is where the
'recalibration will take place. How are the
'errors for Orbitrap???.
' '
domainMeasured = Me.OrbiMass2freq(anUncalibrated2)
domainCalc = Me.OrbiMass2freq(aTrueValue2)
Case Else
Trace.Assert(False, _
"PIL ASSERT. Select Case never fall-through")
End Select
'Changed PM_REFACTOR 2007-11-14
'Dim idx As Integer = mIdx2
Dim idx As Integer = calibValues.idx2
calibValues.measValues(idx) = domainMeasured
calibValues.calcValues(idx) = domainCalc
'Record for use in computing MCR error after recalibration.
calibValues.measValues_MCR(idx) = anUncalibrated2
calibValues.calcValues_MCR(idx) = aTrueValue2
'Changed PM_RECALIB_REPORT 2005-07-29
calibValues.tags2(idx) = anInTagStr
'Note: MCR domain. Values are OK.
Dim errorBefore As Double = aTrueValue2 - anUncalibrated2
Dim absErrorBefore As Double = Math.Abs(errorBefore)
Dim absPPMErrBefore As Double = _
absErrorBefore / aTrueValue2 * 1000000.0
calibValues.absPPMErrBeforeSum += absPPMErrBefore 'Note:
' always for input domain (MCR).
calibValues.idx2 += 1
End If
'Changed PM_PERFILE_RECALIBRATION 2007-11-16
''Changed PM_REFACTOR 2007-11-14
'mCommonForAll = calibValues
mCalibs(tag) = calibValues 'Write back.
End If 'Not used all (e.g. 300 points).
Next j 'Particular file or all.
Return toReturn
End Function 'addPoint
'****************************************************************************
'* <placeholder for header> *
'****************************************************************************
Private Sub computeRecalibration()
If Not mComputedRecalibration Then
mComputedRecalibration = True
'Build a new hash as changing mCalibs during iteration
'will result in an exception.
Dim tempCalibs As Dictionary(Of Integer, calibValuesStructure) = _
New Dictionary(Of Integer, calibValuesStructure)
Dim hashEnumerator2 As Dictionary( _
Of Integer, calibValuesStructure).Enumerator = _
mCalibs.GetEnumerator()
'Loop over the raw files and all (ALL_TAGCODE). Everything is
'already in mCalibs.
While hashEnumerator2.MoveNext()
Dim curTag As Integer = hashEnumerator2.Current.Key
'Changed PM_PERFILE_RECALIBRATION 2007-11-16
''Changed PM_REFACTOR 2007-11-14
'Dim calibValues As calibValuesStructure = mCommonForAll
Dim calibValues As calibValuesStructure = _
hashEnumerator2.Current.Value 'Values for a particular
' raw file (or for all).
Dim numbDataPts_all As Integer = calibValues.idx2 'This happens
' to be the case with the way we update idx2.
'Changed PM_RECALIB_REALITY_CHECK 2008-03-27
'If numbDataPts_all < 4 Then
Dim minPts As Integer = mRecalibLimits.startDatapoints
Dim maxPts As Integer = mRecalibLimits.endDatapoints
If numbDataPts_all < minPts OrElse _
numbDataPts_all > maxPts _
Then
calibValues.slope = 1.0
calibValues.offset = 0.0
'Changed PM_CALIBRATION_TROUBLE 2003-08-14
MsgBox( _
AppConstants.LONG_APP & _
" is very dissatisfied with the number of " & _
"peptides to use for calibration ( " & _
numbDataPts_all.ToString & _
") - outside [" & minPts & ";" & maxPts & "]. " & _
"The calibration constants have been " & _
"set to 1.0 and 0.0. " & _
"It means that effectively re-calibration is not used.")
Else
'Number of datapoints for recalibration OK.
Dim lastDataIndex_all As Integer = numbDataPts_all - 1
ReDim Preserve calibValues.measValues(lastDataIndex_all)
ReDim Preserve calibValues.calcValues(lastDataIndex_all)
ReDim Preserve calibValues.measValues_MCR(lastDataIndex_all)
ReDim Preserve calibValues.calcValues_MCR(lastDataIndex_all)
ReDim Preserve calibValues.tags2(lastDataIndex_all)
Dim slope7 As Double = 1.0 'Initial guess. If there
' is no systematic error then it is a good guess.
Dim offset7 As Double = 0.0
'Changed PM_RECALIB_OUTLIERDETECTION 2007-12-12
'Now several steps to find the recalibration constants,
'effectively outlier detection, even if it is very big
'it will not affect the recalibration at all.
Dim recalibIteration As Integer
For recalibIteration = 1 To 5 'For now: a fixed number of
' iterations.
' Other possibilities includes stop if change
' parameters are sufficiently small or if mass
' range is sufficiently large (or a combination
' of these conditions).
Dim useErrors(lastDataIndex_all) As Boolean
'Changed PM_RECALIB_OUTLIERDETECTION 2007-12-12
If True Then 'Find errors with current parameters, find
' which ones are in the best half and use those for
' finding new parameters.
'
' With systematic errors we risk using only a part
' of the mass range in the first step. But in the
' next step we will extrapolate into the unused
' regions and in the third step points from those
' regions will also be used in recalibration.
Dim errors As List(Of Double) = _
New List(Of Double)(numbDataPts_all)
Dim errKeys As List(Of Integer) = _
New List(Of Integer)(numbDataPts_all)
Dim lastIndex As Integer = lastDataIndex_all
Dim j As Integer
For j = 0 To lastIndex
Dim meas As Double = calibValues.measValues(j)
Dim predicted As Double = slope7 * meas + offset7
Dim calc As Double = calibValues.calcValues(j)
Dim predError As Double = calc - predicted 'Unit
' depends on domain, Mass/Frequency, etc.
errors.Add(predError)
errKeys.Add(j)
Next j
'Sort mass errors (predicted vs. observed) -
'actually sorting keys. The
'middle value is the index for the median.
errKeys.Sort(New doublesList_Sort_usingIndex(errors))
'Best half is from first quarter to third quarter.
Dim startIndex As Integer = lastDataIndex_all \ 4
Dim endIndex As Integer = (lastDataIndex_all * 3) \ 4
'Build inclusion list for regression, for it to use
'only.
If True Then
Dim lastIndex2 As Integer = lastDataIndex_all
Dim n As Integer
For n = 0 To lastIndex2 'Through sorted keys.
Dim val1 As Boolean = False
If n >= startIndex AndAlso n <= endIndex Then
val1 = True
End If
Dim someIndex As Integer = errKeys(n)
useErrors(someIndex) = val1
Next n
End If
End If
If True Then
Dim yErrorsDomain(lastDataIndex_all) As Double
Dim minAbsErr2 As Double
Dim maxAbsErr2 As Double
Dim medianAbsErr2 As Double
Dim minXUsed As Double
Dim maxXUsed As Double
'Note: this is not necessarily in the MCR domain. It
' could be in the frequency domain.
SDUPstatistics.linearRegression( _
calibValues.measValues, _
calibValues.calcValues, _
slope7, offset7, _
yErrorsDomain, _
minAbsErr2, maxAbsErr2, medianAbsErr2, _
useErrors, _
minXUsed, maxXUsed)
'Changed PM_MARKER_OUTLIERDETECTION 2007-12-07
'For breakpoints.
Select Case recalibIteration
Case 1
Dim peter1 As Integer = 1
Case 2
Dim peter2 As Integer = 2
Case 3
Dim peter3 As Integer = 3
Case 4
Dim peter4 As Integer = 4
End Select
End If 'Block.
Next recalibIteration
'Changed PM_RECALIB_REALITY_CHECK 2008-03-27
If slope7 < mRecalibLimits.startSlope OrElse _
slope7 > mRecalibLimits.endSlope OrElse _
offset7 < mRecalibLimits.startOffset OrElse _
offset7 > mRecalibLimits.endOffset _
Then
slope7 = 1.0
offset7 = 0.0
Else
Dim peter2 As Integer = 2 'Within allowed range.
End If
'Assign recalibration constants.
calibValues.slope = slope7 'Sample value: 0.9999297083806169
calibValues.offset = offset7 'Sample value: 0.030780173
If True Then
'No longer required: premature write-back. Instead
'we pass the necessary values directly
'to uncalib2calib_internal() below.
Dim slope6 As Double = calibValues.slope
Dim offset6 As Double = calibValues.offset
'We can not use yErrorsDomain directly. We have to
'compute predicted (calibrated) values.
Dim yErrorsMCR_all(lastDataIndex_all) As Double
Dim lastIndex3 As Integer = lastDataIndex_all
Dim j As Integer
For j = 0 To lastIndex3
Dim MCRuncalib As Double = _
calibValues.measValues_MCR(j)
Dim MCRcalibMeas As Double = _
Me.uncalib2calib_internal( _
MCRuncalib, slope6, offset6)
Dim trueMCRvalue As Double = _
calibValues.calcValues_MCR(j)
Dim MCRcalibError As Double = _
MCRcalibMeas - trueMCRvalue
yErrorsMCR_all(j) = MCRcalibError
Next j
'yErrors are domain errors (e.g. frequency error) and not
'what we want to report... We need to apply calibration
'manually, using uncalib2calib() on mMeasValues.
SDUPstatistics.convertToRelativeError( _
yErrorsMCR_all, calibValues.calcValues_MCR)
Dim aveAbsPPMErrAfter_all As Double = _
SDUPstatistics.absAverage(yErrorsMCR_all)
'Note: OK value as it is computed from input
' domain (MCR) values.
'
'Note 2: use of mCommonForAll is deliberate...
'
Dim aveAbsPPMErrBefore_all As Double = _
calibValues.absPPMErrBeforeSum / numbDataPts_all
'Note 1: "mass" is only acceptable instead of "MCR"
' because the relative error is almost
' ***identical*** for the two.
'
mAccuracyStatsStr_all = _
"Average absolute mass accuracy improved from " & _
vbCrLf & _
aveAbsPPMErrBefore_all.ToString("0.##") & " ppm to " & _
aveAbsPPMErrAfter_all.ToString("0.##") & " ppm. "
'Get rid of the MCR arrays (what about mMeasValues and
'mCalcValues?):
calibValues.measValues_MCR = Nothing
calibValues.calcValues_MCR = Nothing
End If
'Changed PM_RECALIB_REPORT 2005-07-28
If True Then
calibValues.recalibReport = _
New System.Text.StringBuilder(4000)
'Should also dump MCR values? In that case observed
'the get rid of them just above...
'Note: units are incorrect for other domains than MCR...
SDUPstatistics.dumpXandYandYerrors( _
"Recalibration report. Done in the " & _
mDomainStr & " domain. ", _
calibValues.measValues, slope7, offset7, _
calibValues.calcValues, calibValues.tags2, _
"[Th]", "[Th]", _
calibValues.recalibReport)
End If
End If 'Enough data points for recalibration.
'Changed PM_RECALIBCONSTANTS_EXTRADECIMALS 2007-11-07. 3 extra...
Dim calValuesStr_all As String = _
"For " & mDomainStr & " domain. " & _
"Slope=" & calibValues.slope.ToString("0.0000000000") & _
", offset=" & calibValues.offset.ToString("0.0000000000") & "."
'mRecalibMsgStr_all is overwritten many times...
'Dim recalibMsgStr As String = Nothing
If numbDataPts_all < 20 Then
mRecalibMsgStr_all = _
"Only " & numbDataPts_all.ToString & _
" peptides to recalibrate on. " & _
calValuesStr_all
Else
mRecalibMsgStr_all = _
numbDataPts_all.ToString & _
" peptides were used for recalibration. " & _
calValuesStr_all
End If
'Changed PM_PERFILE_RECALIBRATION 2007-11-16
''Changed PM_REFACTOR 2007-11-14
'mCommonForAll = calibValues
tempCalibs(curTag) = calibValues 'Write back.
End While 'Hash iteration.
'Changed PM_PERFILE_RECALIBRATION 2007-11-16
mCalibs = tempCalibs 'Replace with new, containing the calibration
' constants. This is required as we can not change the hash
' during the read-only iteration.
Else
Dim peter2 As Integer = 2 'Already computed.
End If
'Algorithm from numerical recipes in C.
'void fit(float x[], float y[], int ndata, float sig[], int mwt, float *a,
' float *b, float *siga, float *sigb, float *chi2, float *q)
'{
' float gammq(float a, float x);
' int i;
' float wt,t,sxoss,sx=0.0,sy=0.0,st2=0.0,ss,sigdat;
'
' *b=0.0;
' if (mwt) {
' ss=0.0;
' for (i=1;i<=ndata;i++) {
' wt=1.0/SQR(sig[i]);
' ss += wt;
' sx += x[i]*wt;
' sy += y[i]*wt;
' }
' } else {
' for (i=1;i<=ndata;i++) {
' sx += x[i];
' sy += y[i];
' }
' ss=ndata;
' }
' sxoss=sx/ss;
' if (mwt) {
' for (i=1;i<=ndata;i++) {
' t=(x[i]-sxoss)/sig[i];
' st2 += t*t;
' *b += t*y[i]/sig[i];
'
'}
' } else {
' for (i=1;i<=ndata;i++) {
' t=x[i]-sxoss;
' st2 += t*t;
' *b += t*y[i];
' }
' }
' *b /= st2;
' *a=(sy-sx*(*b))/ss;
' *siga=sqrt((1.0+sx*sx/(ss*st2))/ss);
' *sigb=sqrt(1.0/st2);
' *chi2=0.0;
' *q=1.0;
' if (mwt == 0) {
' for (i=1;i<=ndata;i++)
' *chi2 += SQR(y[i]-(*a)-(*b)*x[i]);
' sigdat=sqrt((*chi2)/(ndata-2));
' *siga *= sigdat;
' *sigb *= sigdat;
' } else {
' for (i=1;i<=ndata;i++)
' *chi2 += SQR((y[i]-(*a)-(*b)*x[i])/sig[i]);
' if (ndata>2) *q=gammq(0.5*(ndata-2),0.5*(*chi2));
'
'}
'}
End Sub 'computeRecalibration
'Changed PM_REFACTOR 2007-11-07. Moved to here from frmProteinList.vb
'****************************************************************************
'* <placeholder for header> *
'****************************************************************************
Public Shared Sub feedCalibratorWithPeptides( _
ByRef aProteinsSubset_dataStructureIndices2 As Generic.List(Of Integer), _
ByRef anInParsedProts As Generic.List(Of ProteinHitStructure), _
ByRef anInRecalibPeptideFilter As peptideFilterStructure, _
ByRef anInOutRecalibrator As SDUPrecalibrator)
'Go through our data structure and find peptides with a score as
'defined by the recalibration peptide filter and record
'obs and meas peptide MCR.
Dim pept2 As PeptideHitStructure = PeptideHitStructure.blankPeptide()
' Keep compiler happy.
Dim bailOut As Boolean = False 'To stop iteration when the
' maximum number of peptides for recalibration have been used. This
' is to save unnecessary iteration through ***all*** the peptides.
'Changed PM_RECALIB_AFTERPARSE 2007-11-07
Dim useAllProteins As Boolean = _
aProteinsSubset_dataStructureIndices2 Is Nothing
Dim len As Integer
If useAllProteins Then
len = anInParsedProts.Count()
Else
len = aProteinsSubset_dataStructureIndices2.Count()
End If
'Changed PM_MEMORY_EFFICIENCY 2008-12-03
Dim scratchSB As StringBuilder = New StringBuilder(128)
Dim proteinIndex As Integer
Dim lastIndex As Integer = len - 1
Dim i As Integer
For i = 0 To lastIndex
If useAllProteins Then
proteinIndex = i
Else
proteinIndex = aProteinsSubset_dataStructureIndices2(i)
End If
'Changed PM_PEPTIDEFIELD_USEDFORRECALIBRATION 2008-11-25
Dim peptideFieldsUpdated As Boolean = False
Dim prot2 As ProteinHitStructure = anInParsedProts(proteinIndex)
'Changed PM_RECALIB_FILTER 2007-09-04
''Changed PM_REFACTOR 2006-03-16
'Dim pepIter As peptideListIterator = _
' New peptideListIterator(prot.peptides)
Dim pepIter As peptideListIterator = _
New peptideListIterator( _
prot2.peptides, anInRecalibPeptideFilter)
Dim peptideToken As Integer
While _
Not bailOut AndAlso _
Not pepIter.nextPeptide(pept2, peptideToken)
'Changed PM_MASCOTSCORE_ASDOUBLE 2008-11-25. No
'longer implicit conversion from integer to
'double...
Dim score As Double = pept2.MascotScore2
'Changed PM_REFACTOR 2007-10-24. Limitation of number
' of peptides is now in the new recalibrator class.
''Changed PM_RECALIB_FILTER 2007-09-04
''If Not (score < MINIMUM_SCORE Or _
'' pept2.rank > 1 Or idx >= idxMax) Then
'If Not (pept2.rank > 1 Or idx2 >= idxMax) Then
If Not (pept2.rank > 1) Then
Dim measuredMCR As Double = pept2.measuredMCR
Dim charge As Integer = _
CInt(pept2.measuredMass / measuredMCR + 0.2)
Dim seq As String = pept2.AASequence
Dim monoMass As Double = _
MMaaSequence.monoMass(seq, "Carbamidomethyl (C)")
'Dim calMCR As Double = _
' (monoMass + charge * MSconstants.PROTON_MASS) / charge
Dim calMCR As Double = _
PILmassCalc.chargeTransform(monoMass, 0, charge)
Dim massDiff As Double = measuredMCR - calMCR
Dim absMassDiff As Double = Math.Abs(massDiff)
'Will this not fail if peptide is highly charged?????
'Shouldn't we use neutral mass difference instead
'of MCR difference????
If absMassDiff > 0.2 Then
'Changed PM_REFACTOR 2008-05-20
'Changed PM_RECALIB_MODIFIEDPEPTIDES 2004-12-13
'Modified peptide, use the Mascot supplied value instead.
'calMCR = _
' (pept2.MascotCalculatedMass + _
' charge * MSconstants.PROTON_MASS) / _
' charge
calMCR = _
PILmassCalc.chargeTransform( _
pept2.MascotCalculatedMass, 0, charge)
Else
'Use the value that we have calculated above.
If absMassDiff > 0.1 Then
Dim peter1 As Integer = 1 'Same nominal mass, but
' huge mass difference.
End If
End If
'Changed PM_CODEMARKER_CALIBPEPTIDES 2008-11-21.
'Changed PM_PERFILE_RECALIBRATION 2007-11-16
Dim tag As Integer = pept2.rawFileID
'Why do we need to include protein (effectively
'considering each protein's peptides independently)?.
'Why not only use a single version of a peptide instead
'potentially have the same peptide from the same
'raw data several times?
'
'Changed PM_MEMORY_EFFICIENCY 2008-12-03
'Dim tagStr2 As String = _
' pept2.AASequence & "_" & pept2.charge & _
' "_Q" & pept2.queryNumber & _
' "_Hit" & prot2.hitNumber & "_" & prot2.accNum
scratchSB.Length = 0
scratchSB.Append(pept2.AASequence)
scratchSB.Append("_")
scratchSB.Append(pept2.charge)
scratchSB.Append("_Q")
scratchSB.Append(pept2.queryNumber)
scratchSB.Append("_Hit")
scratchSB.Append(prot2.hitNumber)
scratchSB.Append("_")
scratchSB.Append(prot2.accNum)
Dim tagStr2 As String = scratchSB.ToString
'Changed PM_REFACTOR 2007-10-24
Dim usedForRecalibration As Boolean
Dim usedAllValues1 As Boolean = _
anInOutRecalibrator.addPoint( _
measuredMCR, calMCR, score, tag, tagStr2, _
usedForRecalibration)
'Changed PM_PEPTIDEFIELD_USEDFORRECALIBRATION 2008-11-25
'Condition: optimisation to avoid unnecessary write-backs.
If usedForRecalibration <> pept2.usedForRecalibration Then
pept2.usedForRecalibration = usedForRecalibration
'We must write-back no matter what as the user may
'do recalibration at any time using any protein subset.
'An optimisation would be to get information about max
'peptides reached, etc.
prot2.peptides.updatePeptideByToken(peptideToken, pept2)
' Write-back
peptideFieldsUpdated = True 'Flag, for avoiding
' unnecessary updates.
Else
Dim peter2 As Integer = 2
End If
'Trouble here. If the peptide filter is such
' that a raw file is not represented by any peptide then
' the entry in the calibrator is missing and we will
' fail when applying the recalibration to all peptides.
'
' Update:
If usedAllValues1 Then
'For CPU/memory efficiency.
bailOut = True
End If
Else
Dim peter9 As Integer = 9
End If
End While 'Through peptides.
'Changed PM_PEPTIDEFIELD_USEDFORRECALIBRATION 2008-11-25
If peptideFieldsUpdated Then
anInParsedProts(proteinIndex) = prot2 'Write back.
Else
Dim peter2 As Integer = 2 'For breakpoints. No peptides
' changed state...
End If
'Changed PM_REFACTOR 2007-10-24
If bailOut Then
Exit For
End If
Next 'Through proteins
End Sub 'feedCalibratorWithPeptides()
'Changed PM_REFACTOR 2007-11-07. Converted to shared, with new paramters.
'Changed PM_CACHE_CALIBRATED_MASSES 2003-04-16
'****************************************************************************
'* <placeholder for header> *
'****************************************************************************
Public Shared Sub setCalibratedValues( _
ByRef anInOutParsedProts As Generic.List(Of ProteinHitStructure), _
ByRef anInRecalibrator As SDUPrecalibrator, _
ByVal aProtDefaultValidationScoreThr As Double, _
ByVal aValidationFilter As peptideFilterStructure, _
ByVal aScoreForApeptGroup As Double, _
ByVal aScoreForBpeptGroup As Double, _
ByVal aScoreForCpeptGroup As Double _
)
'Old:
' ByVal aPeptideMaximumRelativeError_PPM As Double
'Note: aValidationFilter is not ***used*** as a full peptide
' filter - uniquely highest scoring is not
' supported. Is this what we want or is it a
' bug??
'Changed PM_REFACTOR 2007-11-07. Now on client side. Preparation for
'post-parse recalibration.
'Dim validationFilter As peptideFilterStructure = _
' mOptions.peptideFilters(peptideFilterEnum.enumValidationParse)
'Changed PM_REFACTOR 2007-10-24. Now in class SDUPrecalibrator.
''Changed PM_CALIBRATION_TROUBLE 2003-08-14. Change to output value
'' of calibration constant.
''The calibrated and raw mass values are expected to be close:
'Trace.Assert(mB > 0.8, _
' "PIL ASSERT. Calibration constant out of range: " & mB & _
' ". It is expected to be close to 1.0.")
'Trace.Assert(mB < 1.2, _
' "PIL ASSERT. Calibration constant out of range: " & mB & _
' ". It is expected to be close to 1.0.")
'Why don't we use a peptide filter in iterating through the peptides below???
'Is it because there is a "permanent" filter in effect?
'
'Unnecessary operations and incorrect results may be the result. E.g.
'protein score if option "Only highest scoring uniquely modified" is
'in effect.
'
'Client side:
' Dim parsePeptideFilter As peptideFilterStructure = _
' mParseOptions.peptideFilters(peptideFilterEnum.enumParsing2)
'
Dim i As Integer
Dim protein As ProteinHitStructure
Dim highestAbsoluteError As Double = -10.0
'Changed PM_VALIDATION_AS_PEPTFILTER 2007-09-05
'Dim excludedPeptides As Integer = 0
Dim preValidatedPeptides As Integer = 0
Dim lastProteinIndex As Integer = anInOutParsedProts.Count - 1
For i = 0 To lastProteinIndex
'This relies on the fact that this structure is in sync with
'the table (i.e. no sorting).
'Todo: use has table like for the peptides
protein = anInOutParsedProts(i)
'Just in case. Don't rely on what may have been done earlier.
protein.numPeptsInA = 0
protein.numPeptsInB = 0
protein.numPeptsInC = 0
protein.scoreInABC = 0
protein.peptsInABC = 0
'Changed PM_PROTEINVAL_REQUIRES_PEPTIDEVALS 2007-08-31
Dim verifiedPeptidesForProtein As Integer = 0
If True Then 'Possible protein condition here, for checked status (?).
Dim proteinHighestAbsoluteError As Double = -10.0
'Dim lastPeptideIndex As Integer = theProt.pepts.Count - 1
'Dim j As Integer
Dim pept As PeptideHitStructure = _
PeptideHitStructure.blankPeptide() 'Keep compiler happy.
Dim pepIter As peptideListIterator = _
New peptideListIterator(protein.peptides)
While Not pepIter.nextPeptide(pept)
'Changed PM_PERFILE_RECALIBRATION 2007-11-16
Dim tag As Integer = pept.rawFileID
'Changed PM_REFACTOR 2007-10-24
'Dim calibratedMCR As Double = mA + mB * pept.measuredMCR
Dim calibratedMCR As Double = _
anInRecalibrator.uncalib2calib(pept.measuredMCR, tag)
' Note: this is per file. Currently no way to use
' the value for all if there is not enough
' data points for recalibration for one or
' more raw files.
'Changed PM_REFACTOR 2008-05-20
'Note: calibrated.
'Dim measMass As Double = _
' (calibratedMCR - MSconstants.PROTON_MASS) * pept.charge
Dim measMass As Double = _
PILmassCalc.chargeTransform(calibratedMCR, pept.charge, 0)
'Note: calibrated.
Dim deltaPPM As Double = _
(pept.MascotCalculatedMass - measMass) / _
pept.MascotCalculatedMass * _
1000000.0
pept.calibratedMeasuredMCR = calibratedMCR
pept.calibratedMeasuredMass = measMass
pept.relativeErrorForPeptideMass_PPM = deltaPPM
'Changed PM_PRESELECTEDVALIDATED_CONDITIONS 2004-06-21
'What about inserted peptides??????
Dim absRelativeError As Double = Math.Abs(deltaPPM)
'Changed PM_VALIDATION_AFTER_RECALIBRATION 2007-09-24. Now
' done on mass diff ***after*** recalibration.
If True Then 'Peptide validation.
Dim valueToSet As Boolean = False
'Changed PM_VALIDATION_AS_PEPTFILTER 2007-09-05
'Dim OKtoValidate As Boolean = _
' score >= mParseOptions.peptDefaultValidationScoreThr
Dim dummy1 As Boolean
Dim dummy2 As Boolean
Dim OKtoValidate As Boolean = _
Not PILpeptides.simpleFilteredOut( _
pept, aValidationFilter, dummy1, dummy2)
'Problem with uniquely highest scoring?
If OKtoValidate Then
valueToSet = True
'Changed PM_PROTEINVAL_REQUIRES_PEPTIDEVALS 2007-08-31
verifiedPeptidesForProtein += 1
Else
Dim peter1 As Integer = 1 'Not validated....
End If
pept.verified = valueToSet
End If 'Peptide validation.
If pept.verified Then
preValidatedPeptides += 1
'Changed PM_VALIDATION_AS_PEPTFILTER 2007-09-05. Not
' needed, already done during parsing.
'If absRelativeError > aPeptideMaximumRelativeError_PPM Then
' pept.verified = False
' excludedPeptides += 1
'End If
If absRelativeError > proteinHighestAbsoluteError Then
proteinHighestAbsoluteError = absRelativeError
End If
End If
'Changed PM_HIGHESTUNIQUELY_BADVALUES 2008-02-29. Moved
' from MascotResultParser.vb.
'Changed PM_PROTEINSCORE_BUG 2007-02-20
'Moved down here so we are sure we don't add up scores
'for peptides, etc. that are not going to be added.
If True Then
'Rounding problem here??
'Changed PM_MASCOTSCORE_ASDOUBLE 2008-11-25. No
'longer implicit conversion from integer to
'double...
Dim score As Double = pept.MascotScore2
score += 0.0001 'Margin for the "="
'Note: order of if evaluation is important. We
' find frequencies in 3 different score ranges.
'
If score >= aScoreForApeptGroup Then 'The
'highest scoring peptides.
protein.numPeptsInA += 1
Else
If score >= aScoreForBpeptGroup Then
protein.numPeptsInB += 1
Else
If score >= aScoreForCpeptGroup Then
protein.numPeptsInC += 1
Else
Dim peter2 As Integer = 2 'Low scoring
' peptide.
End If
End If
End If
'For protein score. Is sum of peptide scores, except
'for the lowest scoring ones.
If score >= aScoreForCpeptGroup Then
'Changed PM_MASCOTSCORE_ASDOUBLE 2008-11-25. No
'longer implicit conversion from integer to
'double...
protein.scoreInABC += pept.MascotScore2
protein.peptsInABC += 1
End If
End If 'Score stuff
pepIter.updateCurrentPeptide(pept)
End While 'Through peptides.
'Changed PM_VALIDATION_AFTER_RECALIBRATION 2007-09-24
If True Then
Dim valueToSet As Boolean = False
'Possible rounding problem when we use double.
Dim protScore As Double = protein.scoreInABC
protScore += 0.0001 'Margin for the "=" below.
If protScore >= _
aProtDefaultValidationScoreThr Then
'Changed PM_PROTEINVAL_REQUIRES_PEPTIDEVALS 2007-08-31.
' Added this extra requirement.
If verifiedPeptidesForProtein > 0 Then
valueToSet = True
Else
Dim peter2 As Integer = 2 'Enough peptides except
' for very low scoring ones, but none of them
' were validated.
End If
Else
Dim peter60 As Integer = 60 'Sum of peptide
' scores (above some low threshold) not high enough.
End If
protein.proteinHasBeenChecked = valueToSet
End If
anInOutParsedProts(i) = protein 'write-back. All the changed
' peptide values..
If proteinHighestAbsoluteError > highestAbsoluteError Then
highestAbsoluteError = proteinHighestAbsoluteError
End If
End If
Next 'Through proteins.
'Changed PM_VALIDATION_AS_PEPTFILTER 2007-09-05. Disabled these
' statistics for now. But it would be nice to have them back.
'
' 'Changed PM_PRESELECTEDVALIDATED_CONDITIONS 2004-06-21
' If excludedPeptides > 0 Then
' Dim excludePercentage As Double = _
' (100.0 * excludedPeptides) / preValidatedPeptides
' Dim excludedPeptidesStatsStr As String = _
' "Worst absolute error was " & _
' highestAbsoluteError.ToString("0.00") & " ppm. " & _
' excludedPeptides & " peptides out of " & preValidatedPeptides & _
' " (" & excludePercentage.ToString("0.0") & _
' " %) were un-validated because the error was " & _
' "greater than " & aPeptideMaximumRelativeError_PPM.ToString("0.00") & _
' " ppm. " & _
' ""
'
' 'Changed PM_REPORTS 2006-08-21
' 'MsgBox(excludedPeptidesStatsStr)
' mParseReport.AddItem2(1020, 0, excludedPeptidesStatsStr)
' End If
End Sub 'setCalibratedValuesForAllPeptides()
'Moved to her from PILstatistics2.vb.
'****************************************************************************
'* This function is here because it is related to the linear *
'* regression function in this class. *
'* *
'* Should we include offset as well?? *
'****************************************************************************
Public Shared Function identityCalibration( _
ByRef anInCalibration As SDUPrecalibrator) _
As Boolean
'Changed PM_REFACTOR 2007-10-29
' Old:
' ByVal aSlope As Double
'For now. For all raw files. This function is currently only
'used to display some messages about no calibration.
Dim tag As Integer = SDUPrecalibrator.ALL_TAGCODE
'Changed PM_REFACTOR 2007-10-30
'Adaption for now. But: make part of SDUPrecalibrator??
Dim slope As Double
Dim offset As Double
anInCalibration.getLinearCalibrationConstants(slope, offset, tag)
'Changed PM_REFACTOR 2007-10-30
'Dim absDiffIdent As Double = Math.Abs(1.0 - aSlope)
Dim absDiffIdent As Double = Math.Abs(1.0 - slope)
Return absDiffIdent < 0.000000000001
End Function 'identityCalibration
'Changed PM_ORBI_AWARE_RECALIB 2008-02-15
'****************************************************************************
'* Purpose: run-time self-test. *
'* *
'* This should perhaps also (or only) be in a unit test. *
'* *
'****************************************************************************
Private Sub selfTest_Calib()
Dim trialMCR As Double = 587.12
If True Then 'Orbitrap
'Expected to be about 137.85 kHz. The actual value change
'if the constants are changed (e.g. if set to values actually in
'a RAW file.)
Dim orbiFreq2 As Double = Me.OrbiMass2freq(trialMCR)
' Is xx.x for 587.12 Th.
'No matter what we should always get back to exactly the same value.
Dim orbiBackMCR As Double = Me.OrbiFreq2mass(orbiFreq2)
Trace.Assert(numbersClose(trialMCR, orbiBackMCR, 0.00001), _
"PIL ASSERT. Inconsistent Orbitrap calibration transformation, " & _
"between MCR domain and frequency domain (1/f). ")
End If
If True Then 'LTQ-FT
'Expected to be about 182.9428 kHz. The actual value change
'if the constants are changed (e.g. if set to values actually in
'a RAW file.)
Dim FTfreq2 As Double = Me.FTmass2freq(trialMCR)
'No matter what we should always get back to exactly the same value.
Dim FTbackMCR As Double = Me.FTfreq2mass(FTfreq2)
Trace.Assert(numbersClose(trialMCR, FTbackMCR, 0.00001), _
"PIL ASSERT. Inconsistent LTQ-FT calibration transformation, " & _
"between MCR domain and frequency domain (1/f^0.5).")
End If
End Sub 'selfTest_Calib
'Changed PM_RECALIB_REALITY_CHECK 2008-03-26
'****************************************************************************
'* <placeholder for header> *
'****************************************************************************
Public Shared Function defaultRecalibLimits() _
As recalibLimitsStructure
Dim toReturn As recalibLimitsStructure
'toReturn.startDatapoints = 10
toReturn.startDatapoints = 20
toReturn.endDatapoints = 999999
'toReturn.startSlope = 0.8
'toReturn.endSlope = 1.2
'toReturn.startSlope = 0.99
'toReturn.endSlope = 1.01
Dim dSlopeDiff As Double = 0.01
toReturn.startSlope = 1.0 - dSlopeDiff
toReturn.endSlope = 1.0 + dSlopeDiff
'toReturn.startOffset = -0.1
'toReturn.endOffset = 0.1
'toReturn.startOffset = -0.01
'toReturn.endOffset = 0.01
Dim dOffset As Double = 0.03
toReturn.startOffset = -dOffset
toReturn.endOffset = dOffset
Return toReturn
End Function 'defaultRecalibLimits
'Changed PM_RECALIB_REALITY_CHECK 2008-03-26
'****************************************************************************
'* <placeholder for header> *
'****************************************************************************
Public Shared Function recalibLimitsShortSummary( _
ByVal aRecalibLimits As recalibLimitsStructure) _
As String
Dim toReturn As String = Nothing
Dim tol As Double = 0.0000000001 'Damn VB. Written as 1e-10.
Dim defaults As recalibLimitsStructure = defaultRecalibLimits()
Dim summSB As StringBuilder = New StringBuilder(80)
If defaults.startDatapoints <> aRecalibLimits.startDatapoints OrElse _
defaults.endDatapoints <> aRecalibLimits.endDatapoints Then
summSB.Append(aRecalibLimits.startDatapoints)
summSB.Append("-")
summSB.Append(aRecalibLimits.endDatapoints)
summSB.Append("pts")
summSB.Append(",")
End If
If Not numbersClose( _
defaults.startSlope, _
aRecalibLimits.startSlope, _
tol) OrElse _
Not numbersClose( _
defaults.endSlope, _
aRecalibLimits.endSlope, _
tol) Then
'Later:
' Numbers can be very close to 1.0. Recompute as relative
' change from 1.0 (in ppm).
summSB.Append("sl")
summSB.Append(aRecalibLimits.startSlope)
summSB.Append("-")
summSB.Append(aRecalibLimits.endSlope)
summSB.Append(",")
End If
If Not numbersClose( _
defaults.startOffset, _
aRecalibLimits.startOffset, _
tol) OrElse _
Not numbersClose( _
defaults.endOffset, _
aRecalibLimits.endOffset, _
tol) Then
summSB.Append("off")
summSB.Append(aRecalibLimits.startOffset)
summSB.Append("-")
summSB.Append(aRecalibLimits.endOffset)
'summSB.Append(",")
End If
toReturn = summSB.ToString()
Return toReturn
End Function 'recalibLimitsShortSummary
End Class 'SDUPrecalibrator
Generated by script codePublish.pl at 2009-01-05T15:20:59.