//****************************************************************************
//* Copyright (C) 2006 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: encapsulation of a list of peptides. E.g. no *
//* direct indexing so we can apply filters, do *
//* caching, change representation, do sorting by *
//* sorting keys, lazy sort, parallel structures for *
//* caching information such that PeptideHitStructure *
//* does not need to have so many fields, etc. *
//* *
//* Note: some redundancy here as purpose is *
//* repeated in header for Class PILpeptides (but *
//* the justification is that it is far down in the *
//* file...). *
//* *
//****************************************************************************
//****************************************************************************
//* 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: PILpeptides.cs *
//* TYPE: VISUAL_BASIC *
//* *
//* CREATED: PM 2008-10-30 Vrs 1.0. Translated from VB.NET, *
// file PILpeptides.vb, 2006-03-15 *
//* UPDATED: PM 2008-xx-xx *
//* *
//****************************************************************************
//Future:
// 1. Some filter for the "verified" field. Such that client don't have to
// check it.
//
// 2. Let this class handle things that are now in MascotResultParser.vb,
// sum score (scoreInABC), counts in .
// Perhaps extend/rename peptideCount() to return all these values (?).
using System.Text; //For StringBuilder
using System.Collections.Generic; //For Dictionary. And List.
using System.Diagnostics; //For Trace. And its Assert.
//Changed PM_FAST_SERIALISATION 2006-12-15
using System.Runtime.Serialization;
//For SerializationInfo and StreamingContext.
//Changed PM_FAST_SERIALISATION 2006-12-15
using SimmoTech.Utils.Serialization;
//For SerializationWriter
//using utilityStatic; //For numbersClose Not possible to use for classes in C#...
//using MolecularSharedStructures;
//****************************************************************************
//d$ <summary>
//d$ Purpose: Namespace for lower layers of mass spectrometric
//d$ applications: raw data file handling, descriptive statistics,
//d$ fragment masses, digestion, file associations, etc.
//d$ <see cref="T:VBXMLDoc.CVBXMLDoc" />.
//d$ <isUnitTest></isUnitTest>
//d$ <applicationname>test_rawDataFileHandling</applicationname>
//d$ <author>Peter Mortensen</author>
//d$ <seealso>http://www.cebi.sdu.dk/</seealso>
//d$ <codetype>PLATFORM independent</codetype>
//d$ </summary>
namespace massSpectrometryBase
{
//Should client specify a list of keys instead?
public enum peptideSortOrderEnum
{
enumSequenceThenScore = 313
//Asc and descending, respectively.
} //peptideSortOrderEnum
//Changed PM_SILACDISH_UNIQUELY_HIGHEST_SCORING 2008-10-02
//Various option if
public struct highestScoringParametersStructure
{
public bool differentCharge;
public bool differentRawFile;
public bool differentModificationSet;
public bool differentModificationCounts2;
//Changed PM_SILAC_AWARE_PEPTIDEFILTERDIALOG 2008-10-08
//List of modifications to exclude for use in ,
//differentModificationSet typically the SILAC modifications (for
//the current quantitation mode).
//Nothing means that the exclude filer is not in effect.
public Dictionary<int, int> differentModification_excludedMods2;
//Note: not a simple list. This is to comply with how this
// is done in the rest of the program... The value is
// the modification count, but we don't use it here.
public bool differentSILACdish;
//Utility function. Shouls it be here?
public static List<int> hash2list(Dictionary<int, int> anInHash)
{
List<int> toReturn = null;
if (anInHash != null)
{
toReturn = new List<int>();
Dictionary<int, int>.Enumerator hashEnumerator2 =
anInHash.GetEnumerator();
while (hashEnumerator2.MoveNext())
{
int curKey = hashEnumerator2.Current.Key;
int curValue = hashEnumerator2.Current.Value;
toReturn.Add(curKey);
} //Hash iteration.
}
else
{
int peter2 = 2;
}
return toReturn;
} //hash2list()
public static Dictionary<int, int> list2hash(List<int> anInList)
{
Dictionary<int, int> toReturn = null;
if (anInList != null)
{
toReturn = new Dictionary<int, int>();
//int someModID = 0;
foreach (int someModID in anInList)
{
toReturn.Add(someModID, 1);
} //Through anInList
}
else
{
int peter2 = 2;
}
return toReturn;
} //list2hash()
} //highestScoringParametersStructure
// [Serializable()]
public struct peptideFilterStructure //: ISerializable
{
//Changed PM_SAVEMB4_QUESTIONS 2008-06-30
//Why do we save this structure to the MB3/MB4 file??? Will it
//save some temporary filters for exporting??. Is it
//because we physically parse in more peptides than is shown?
//
//Answer: we ***don't*** save all (only the first 5 fields...) and
// we just set the lists and hashes to Nothing/null
// when the MB3/MB4 file is read.
//
//But the question remains: why do we do this at all? Effectively
//we may not - it is because the filters in the client(s) are
//overwritten from the outside and it does not matter what is
//read in?
//Note: if fields are added readFromStream2() and
// addToStream2() should be updated!!!
//Changed PM_FAST_SERIALISATION 2006-12-15
public int chargeMin; //Inclusive
public int chargeMax; //Inclusive
public int seqLengthMin; //Inclusive
public int seqLengthMax; //Inclusive
public double massMin; //Inclusive
public double massMax; //Inclusive
//Changed PM_SILACDISH_UNIQUELY_HIGHEST_SCORING 2008-10-02. Replaced
// with something slightly different!
//Dim highestScoringUniquelyModified As Boolean
public bool onlyHighestScoring;
public highestScoringParametersStructure highestScoringParameters;
//Changed PM_EXCLUDE_MODFILTER 2008-06-30
//'Changed PM_PEPTIDEFILTER_GENERALISED 2007-08-24. Moved to here.
//Dim pepModFilter3 As List(Of Integer)
public List<int> pepIncludeModFilter3;
public List<int> pepExcludeModFilter;
//Changed PM_MARKER_FOR_MB4 2008-06-30. -for pepExcludeModFilter. Do
// we need/do we actually save this?
//Helper field - for easy/fast lookup. Derived
//from field peptideModificationFilter2.
public Dictionary<int, int> includeModHash_INTERNAL2;
//Changed PM_EXCLUDE_MODFILTER 2008-06-30
public Dictionary<int, int> excludeModHash_INTERNAL;
//Changed PM_HIGHESTSCORINGUNIQUELYMODIFIED_BUG 2007-10-05. Now
// per iterator.
public Dictionary<string, int> exHash2_INTERNAL;
//Changed PM_PEPTIDEFILTER_GENERALISED 2007-08-25
public double scoreMin; //Inclusive
public double scoreMax2; //Inclusive
public bool verifiedOnly;
public bool quantifiedOnly;
//Changed PM_PEPTIDEFILTER_GENERALISED 2007-08-27
//Some tag the client can use, e.g. to
public int tag1; // mark as permanent filter - depends on the
// iterator constructor used.
//Some tag the client can use, e.g. marked for
public int tag2; //deletion or no filter.
//Changed PM_MASSACC_PEPFILTER 2007-09-05
//Inclusive. Relative; unit [ppm]
public double massAccuracyMin;
//Inclusive. Relative; unit [ppm]
public double massAccuracyMax;
//Changed PM_RAWFILE_PEPFILTER 2007-11-16
//Negative value is taken as meaning no filter.
public int rawFileID;
//Changed PM_FAST_SERIALISATION_READ 2007-01-01
//****************************************************************************
//* For peptideFilterSpecificationStructure. *
//****************************************************************************
public static peptideFilterStructure readFromStream2(
ref SerializationReader anInReader, int aMBfileVersion)
{
//Changed PM_PEPTIDEFILTER_GENERALISED 2007-08-29. To get
// proper defaults. Otherwise e.g. the score range would
// be empty, [0; 0].
//Dim toReturn As peptideFilterSpecificationStructure
peptideFilterStructure toReturn =
peptideFilterStructure.noPepFilter();
toReturn.chargeMin = anInReader.ReadInt32();
int chargeMax = anInReader.ReadInt32();
Trace.Assert(
chargeMax >= 0 && chargeMax <= 29,
"PIL ASSERT. Deserialisation, chargeMax is out of range." +
chargeMax + ".");
toReturn.chargeMax = chargeMax;
toReturn.seqLengthMin = anInReader.ReadInt32();
toReturn.seqLengthMax = anInReader.ReadInt32();
//Changed PM_SILACDISH_UNIQUELY_HIGHEST_SCORING 2008-10-02.
// Equivalent. But why do we store the peptide filter as all?
// See comments in the beginning of this structure...
//toReturn.highestScoringUniquelyModified = anInReader.ReadBoolean()
toReturn.onlyHighestScoring = anInReader.ReadBoolean();
{
//Changed PM_REFACTOR 2008-10-30. Generated by VB to C#
//converted. Disable it for now to stay faithful to
//the original.
//highestScoringParametersStructure hsPars = default(highestScoringParametersStructure);
highestScoringParametersStructure hsPars;
//For notational convenience.
hsPars.differentCharge = false;
hsPars.differentRawFile = false;
hsPars.differentModificationSet = true;
hsPars.differentModificationCounts2 = true;
//Changed PM_SILAC_AWARE_PEPTIDEFILTERDIALOG 2008-10-08
hsPars.differentModification_excludedMods2 = null;
hsPars.differentSILACdish = false;
toReturn.highestScoringParameters = hsPars;
} //Block.
toReturn.pepIncludeModFilter3 = null;
//Changed PM_EXCLUDE_MODFILTER 2008-06-30
toReturn.pepExcludeModFilter = null;
return toReturn;
} //readFromStream2(). For peptideFilterStructure.
//Changed PM_FAST_SERIALISATION_AVOID_DOTNET 2006-12-19
//****************************************************************************
//* For peptideFilterSpecificationStructure. *
//****************************************************************************
public void addToStream2(
ref SerializationWriter anInOutWriter, int aMBfileVersion)
{
//aVersion: e.g. 300 for MB3, 400 for MB4.
//SERMARK13. A marker. Keep it.
anInOutWriter.Write(chargeMin);
anInOutWriter.Write(chargeMax);
anInOutWriter.Write(seqLengthMin);
anInOutWriter.Write(seqLengthMax);
//Changed PM_SILACDISH_UNIQUELY_HIGHEST_SCORING 2008-10-02
//anInOutWriter.Write(highestScoringUniquelyModified)
anInOutWriter.Write(onlyHighestScoring);
} //addToStream2(). For peptideFilterStructure.
//****************************************************************************
//* <placeholder for header> *
//****************************************************************************
public static List<int> deepCopyModList(ref List<int> anInModList)
{
List<int> toReturn = null;
if (anInModList != null)
{
int inLen = anInModList.Count;
Trace.Assert(
inLen > 0,
"PIL ASSERT. Mod list is empty (but not Nothing).");
toReturn = new List<int>();
//int modID = 0;
foreach (int modID in anInModList)
{
toReturn.Add(modID);
}
}
else
{
//If input is Nothing then we also return Nothing.
int peter2 = 2;
}
return toReturn;
} //deepCopyModList()
//****************************************************************************
//* <placeholder for header> *
//****************************************************************************
public peptideFilterStructure deepCopy2()
{
peptideFilterStructure toReturn = this;
toReturn.includeModHash_INTERNAL2 = null;
//Changed PM_EXCLUDE_MODFILTER 2008-06-30
toReturn.excludeModHash_INTERNAL = null;
//Changed PM_HIGHESTSCORINGUNIQUELYMODIFIED_BUG 2007-10-05
toReturn.exHash2_INTERNAL = null;
//Changed PM_EXCLUDE_MODFILTER 2008-06-30
//toReturn.pepModFilter3 = _
// peptideFilterStructure.deepCopyModList(Me.pepModFilter3)
toReturn.pepIncludeModFilter3 =
peptideFilterStructure.deepCopyModList(
ref this.pepIncludeModFilter3);
toReturn.pepExcludeModFilter =
peptideFilterStructure.deepCopyModList(
ref this.pepExcludeModFilter);
return toReturn;
} //deepCopy2()
//Changed PM_REFACTOR 2007-08-27. From defaultOptions().
// It also needed from QuantWindow.vb.
//
//Should this be a constructor instead?
//****************************************************************************
//* <placeholder for header> *
//****************************************************************************
public static peptideFilterStructure noPepFilter()
{
//Changed PM_PEPTIDEFILTER_GENERALISED 2007-08-24
//.peptideFilterSpecification.chargeMin = 1
//.peptideFilterSpecification.chargeMax = 20
//.peptideFilterSpecification.seqLengthMin = 1
//.peptideFilterSpecification.seqLengthMax = 99
//.peptideFilterSpecification.highestScoringUniquelyModified = _
// False
//Changed PM_REFACTOR 2008-10-30. Generated by VB to C#
//converted. Disable it for now to stay faithful to
//the original.
//peptideFilterStructure somePeptideFilter =
// default(peptideFilterStructure);
//peptideFilterStructure somePeptideFilter;
peptideFilterStructure somePeptideFilter =
default(peptideFilterStructure); //Use it after all.
somePeptideFilter.chargeMin = 1;
somePeptideFilter.chargeMax = 20;
somePeptideFilter.seqLengthMin = 1;
somePeptideFilter.seqLengthMax = 99;
//Changed PM_PEPTIDEFILTER_GENERALISED 2007-08-28
somePeptideFilter.massMin = 0.0;
somePeptideFilter.massMax = 8888.0;
//Changed PM_SILACDISH_UNIQUELY_HIGHEST_SCORING 2008-10-02
//somePeptideFilter.highestScoringUniquelyModified = False
somePeptideFilter.onlyHighestScoring = false;
//Changed PM_REFACTOR 2008-10-30. Generated by VB to C#
//converted. Disable it for now to stay faithful to
//the original.
//highestScoringParametersStructure pars =
// default(highestScoringParametersStructure);
highestScoringParametersStructure pars;
pars.differentCharge = false;
pars.differentRawFile = false;
pars.differentModificationSet = true;
pars.differentModificationCounts2 = true;
//Count was actually considered in the old...
pars.differentModification_excludedMods2 = null;
pars.differentSILACdish = false;
somePeptideFilter.highestScoringParameters = pars;
//Changed PM_EXCLUDE_MODFILTER 2008-06-30
//'Changed PM_PEPTIDEFILTER_GENERALISED 2007-08-29
//'somePeptideFilter.peptideModificationFilter2 = _
//' New List(Of Integer) 'Empty, but existing...
//somePeptideFilter.pepModFilter3 = Nothing
somePeptideFilter.pepIncludeModFilter3 = null;
somePeptideFilter.pepExcludeModFilter = null;
//Changed PM_PEPTIDEFILTER_GENERALISED 2007-08-29
somePeptideFilter.includeModHash_INTERNAL2 = null; //Just in case.
//Changed PM_EXCLUDE_MODFILTER 2008-06-30
somePeptideFilter.excludeModHash_INTERNAL = null; //Just in case.
//Changed PM_HIGHESTSCORINGUNIQUELYMODIFIED_BUG 2007-10-05
somePeptideFilter.exHash2_INTERNAL = null; //Just in case.
//Changed PM_PEPTIDEFILTER_GENERALISED 2007-08-25
somePeptideFilter.scoreMin = 1;
somePeptideFilter.scoreMax2 = 200.0;
//Changed PM_MASSACC_PEPFILTER 2007-09-05
somePeptideFilter.massAccuracyMin = -99999.0;
somePeptideFilter.massAccuracyMax = 99999.0;
//Changed PM_PEPTIDEFILTER_GENERALISED 2007-08-27
somePeptideFilter.tag1 = 0;
//No permanent filter, at least not yet.
somePeptideFilter.tag2 = PILpeptides.NOFILTER_CODE2;
//Changed PM_RAWFILE_PEPFILTER 2007-11-16
somePeptideFilter.rawFileID = -10000;
//No filter; all...
return somePeptideFilter;
} //noFilter()
//Changed PM_REFACTOR 2007-08-29
//****************************************************************************
//* <placeholder for header> *
//****************************************************************************
public static Dictionary<int, int> hashForModFilter(
List<int> anInModList)
{
Dictionary<int, int> toReturn = new Dictionary<int, int>();
if (anInModList != null)
{
//int modID = 0;
foreach (int modID in anInModList)
{
toReturn.Add(modID, 1);
}
}
else
{
//Input was Nothing. We return an empty hash. That is fine.
int peter2 = 2;
}
return toReturn;
} //hashForModFilter()
//****************************************************************************
//* <placeholder for header> *
//****************************************************************************
public static bool anyModsInFilter(
List<modificationCountStruct> anInModsInPeptide,
Dictionary<int, int> anInLookupHash)
{
bool toReturn = true;
Trace.Assert(
(anInLookupHash != null),
"PIL ASSERT. anInLookupHash Is Nothing....");
//Changed PM_REFACTOR 2006-10-22
//Dim mods As ArrayList = pept.modHits
List<modificationCountStruct> mods2 = anInModsInPeptide;
bool anyModsInPeptide = (mods2 != null) && mods2.Count > 0;
//Note: relies on short-circuit
// boolean logic - this order must be preserved!
if (anyModsInPeptide)
{
int lastIndex = mods2.Count - 1;
int j = 0;
bool matchedID = false;
for (j = 0; j <= lastIndex; j++)
{
modificationCountStruct curMod = mods2[j];
if (anInLookupHash.ContainsKey(curMod.quantModificationID))
{
matchedID = true;
break; // TODO: might not be correct. Was : Exit For
}
}
if (!matchedID)
{
toReturn = false;
}
else
{
int peter8 = 8;
}
}
else
{
//No modifications for peptide. As we have a filter then
//the peptide must be excluded....
toReturn = false;
} //Any mods (in peptide).
return toReturn;
} //anyModsInFilter()
} //peptideFilterSpecificationStructure()
//****************************************************************************
//* CLASS NAME: peptideListIterator *
//d$ <summary>
//d$ Purpose: syntactic sugar to ease clients use of PILpeptides
//d$
//d$
//d$
//d$ <see cref="T:VBXMLDoc.CVBXMLDoc" />.
//d$ <applicationname>xyz</applicationname>
//d$ <author>Peter Mortensen</author>
//d$ <seealso>http://www.cebi.sdu.dk/</seealso>
//d$ <codetype>PLATFORM independent</codetype>
//d$ </summary>
public class peptideListIterator
{
PILpeptides mPeptideList;
//Makes more than one iterator at a time possible.
int mIteratorToken;
//Zero-based. Used for a service for the client.
int mIndex;
//May not be needed.
//'Using this will result in more copies. Perhaps PILpeptides should
//'handle this?
//Dim mCurrentPeptide As PeptideHitStructure
//****************************************************************************
//* <placeholder for header> *
//* *
//* Note: uses whatever peptide filter is already set in *
//* the peptide list (if any). *
//* *
//****************************************************************************
public peptideListIterator(PILpeptides aPeptideList)
{
//Changed PM_PEPTIDEFILTER_GENERALISED 2007-08-27
peptideFilterStructure filter = peptideFilterStructure.noPepFilter();
//Using this constructor means the ***permanent*** filter will be
//used (that was set previously - could even have been set during a
//previous session of this program (saved with MB3))
filter.tag1 = PILpeptides.MARK_PERMANENT_FILTER2;
//The permanent filter
// may or may not have been set (by call
// to setPermanentPeptideFilter()). If it has not
// been set then it defaults to no filter.
//
//In any case all other fields of 'filter' will be ignored. We only
//use tag1 to signal to the other class that some already stored filter
//in the peptide list (in that other class) should be used.
this.init(ref aPeptideList, filter);
} //Constructor. One of two.
//Changed PM_PEPTIDEFILTER_GENERALISED 2007-08-26
//****************************************************************************
//* <placeholder for header> *
//* Constructor for letting the client specify a per-iterator peptide *
//* filter, e.g. exporting peptides based on a user defined *
//* peptide filter. *
//* *
//****************************************************************************
public peptideListIterator(
PILpeptides aPeptideList, peptideFilterStructure aFilter)
{
//Using this constructor means some ***user supplied*** filter will
//be used. E.g. at export time.
//Changed PM_PEPTIDECOUNT_BUG 2007-09-04
aFilter.tag1 = 0;
//Meaning: not permanent.
//If Not aFilter.pepModFilter3 Is Nothing Then
// aFilter.tag2 = 0 'Clears "no filter"
//End If
aFilter.tag2 = 0;
//Clears "no filter"
this.init(ref aPeptideList, aFilter);
} //Constructor. One of two.
//Changed PM_REFACTOR 2007-08-26. To be shared by the two
// constructor, one of which is new of this date.
//****************************************************************************
//* <placeholder for header> *
//****************************************************************************
private void init(
ref PILpeptides aPeptideList, peptideFilterStructure aFilter)
{
Trace.Assert(
(aPeptideList != null), "PIL ASSERT. aPeptideList is Nothing...");
mPeptideList = aPeptideList;
mIteratorToken = mPeptideList.newIteratorToken(aFilter);
mIndex = -1;
//mCurrentPeptide.queryNumber = -1
mPeptideList.resetRead(mIteratorToken);
} //init()
//Changed PM_PEPTIDEFILTER_GENERALISED 2007-08-27
//Used only for serialisation?
//****************************************************************************
//* <placeholder for header> *
//****************************************************************************
public int getIterToken()
{
return mIteratorToken;
} //getIterToken()
//****************************************************************************
//* <placeholder for header> *
//****************************************************************************
public bool nextPeptide(out PeptideHitStructure aOutPeptide)
{
mIndex += 1;
int someIteratorToken = 0;
bool toReturn =
mPeptideList.nextPeptide(
mIteratorToken, out aOutPeptide, out someIteratorToken);
//mCurrentPeptide = aOutPeptide
if (toReturn == true)
{
//Later: tell mPeptideList to get rid of the iterator.
int peter1 = 1;
}
return toReturn;
} //nextPeptide()
//****************************************************************************
//* <placeholder for header> *
//****************************************************************************
public bool nextPeptide(
out PeptideHitStructure aOutPeptide, out int anOutPeptideToken)
{
mIndex += 1;
bool toReturn =
mPeptideList.nextPeptide(
mIteratorToken, out aOutPeptide, out anOutPeptideToken);
//mCurrentPeptide = aOutPeptide
if (toReturn == true)
{
//Later: tell mPeptideList to get rid of the iterator.
int peter1 = 1;
}
return toReturn;
} //nextPeptide()
//****************************************************************************
//* <placeholder for header> *
//****************************************************************************
public void currentPeptide(ref PeptideHitStructure aOutPeptide)
{
//What if we are past the collection? Or not started yet?
//Trace.Assert(mCurrentPeptide.queryNumber >= 0, _
// "PIL ASSERT. Current peptide is undefined.")
//aOutPeptide = mCurrentPeptide
mPeptideList.currentPeptide(mIteratorToken, out aOutPeptide);
} //currentPeptide()
//****************************************************************************
//* <placeholder for header> *
//****************************************************************************
public void updateCurrentPeptide(PeptideHitStructure anInPeptide)
{
//What if we are past the collection? Or not started yet?
//Trace.Assert(mCurrentPeptide.queryNumber >= 0, _
// "PIL ASSERT. Current peptide is undefined.")
//aOutPeptide = mCurrentPeptide
mPeptideList.updateCurrentPeptide(mIteratorToken, anInPeptide);
} //updateCurrentPeptide()
} //class peptideListIterator
//****************************************************************************
//* CLASS NAME: PILpeptides *
//d$ <summary>
//d$ Purpose: encapsulation of a list of peptides. E.g. no direct indexing
//d$ so we can apply filters, do caching, change representation,
//d$ do sorting by sorting keys, lazy sort, parallel structures
//d$ for caching information such that PeptideHitStructure does
//d$ not need to have so many fields, etc.
//d$
//d$ <see cref="T:VBXMLDoc.CVBXMLDoc" />.
//d$ <applicationname>xyz</applicationname>
//d$ <author>Peter Mortensen</author>
//d$ <seealso>http://www.cebi.sdu.dk/</seealso>
//d$ <codetype>PLATFORM independent</codetype>
//d$ </summary>
//[Serializable()]
public class PILpeptides //: ISerializable
{
//Note: if fields are added readFromStream2() and
// addToStream2() should be updated!!!
//Changed PM_FAST_SERIALISATION 2006-12-15
//Changed PM_MASCOTSCORE_ASDOUBLE 2008-11-25
////Note: Integer for now. Follows PeptideHitStructure/MascotScore
//public const int FIXED_SCORE_FOR_INSERTED_PEPTIDES = 99;
public const double FIXED_SCORE_FOR_INSERTED_PEPTIDES2 = 99.0;
//Changed PM_PEPTIDEFILTER_GENERALISED 2007-08-27
public const int MARK_PERMANENT_FILTER2 = -359;
//Changed PM_ZAP_PEPTIDES 2006-10-25
public const int NOFILTER_CODE2 = -1;
public const int MARKEDFORDELETION_CODE2 = -2;
//Not yet...
//Private Structure peptideDerivedFieldsStructure
// Dim includedInFilter As Boolean 'Note: this is for the base filter. Other
// 'filters may be applied on top, but this is somewhere else as there
// 'may be many filters at the same time. Perhaps that should be placed
// 'in peptideListIterator?
//End Structure 'peptideDerivedFieldsStructure
//[Serializable()]
private struct iteratorStructure
{
//No ID needed. Only known of admin of a list of these.
public int readIndex;
public int lastReadIndex;
//A convenient place to
public peptideSortOrderEnum sortOrder;
// store this information.
//Also a convenient place..
public int lastIndex;
//Reference to some
public List<int> sortedKeys2;
// sorted keys.
//Changed PM_PEPTIDEFILTER_GENERALISED 2007-08-27
public peptideFilterStructure filter;
//Changed PM_PEPTIDEFILTER_GENERALISED 2007-08-28
//Now per-iterator
public int effectiveNumberOfPeptides;
// count.
} //iteratorStructure
//Changed PM_REFACTOR 2006-11-08. Not used...
// 'Used with mExcludeHash
// Private Structure reducedPeptide1Structure2
// 'No ID needed. Only known of admin of a list of these
//
// Dim readIndex As Integer
// Dim lastReadIndex As Integer
//
// Dim sortOrder As peptideSortOrderEnum 'A convenient place to
// ' store this information.
//
// Dim lastIndex As Integer 'Also a convenient place..
//
// Dim xxxsortedKeys As ArrayList 'Reference to some sorted keys.
//
// 'Future:
// ' 1. Filters
// End Structure 'reducedPeptide1Structure
//****************************************************************************
//* CLASS NAME: SortBySequenceThenScore_usingIndex *
//d$ <summary> N/A. ...
//d$ Note: xyz </summary>
private class SortBySequenceThenScore_usingIndex :
System.Collections.Generic.IComparer<int>
{
//Changed PM_TYPESAFE 2006-10-25
//Dim mPeptideList As ArrayList
List<PeptideHitStructure> mPeptideList3;
//For debugging/statistics/performance evaluation only.
int mCompareCalls;
int mNonEqualCompareCalls;
//****************************************************************************
//* <placeholder for header> *
//****************************************************************************
public SortBySequenceThenScore_usingIndex(
List<PeptideHitStructure> aPeptideList)
{
//Type of aPeptideList is PeptideHitStructure.
mPeptideList3 = aPeptideList;
mCompareCalls = 0;
mNonEqualCompareCalls = 0;
} //Constructor.
//****************************************************************************
//* <placeholder for header> *
//****************************************************************************
public int Compare(int aItem1, int aItem2)
{
int toReturn = 0; //Default: equal.
mCompareCalls += 1;
//We can save some just comparing the indexes. But why are
//we called this way??? The caller should know the two items
//are equal, at least for integer.
if (aItem1 != aItem2)
{
PeptideHitStructure pept1 = mPeptideList3[aItem1];
PeptideHitStructure pept2 = mPeptideList3[aItem2];
mNonEqualCompareCalls += 1;
//Changed PM_REFACTOR 2008-10-31
//if (pept1.AASequence < pept2.AASequence)
//{
// toReturn = -1;
//}
//else
//{
// if (pept1.AASequence > pept2.AASequence)
// {
// toReturn = 1;
// }
// else
// {
// <>
// }
//}
//Use a culture insensitive option to CompareTo() to speed things
//up?
//Or is it only for String.Compare()? Does not seem to exist...
//
//Ref:
// <http://stackoverflow.com/questions/44288/differences-in-string-compare-methods-in-c>
int compareResult =
pept1.AASequence.CompareTo(pept2.AASequence);
if (compareResult != 0)
{
toReturn = compareResult; //Ascending sort for sequence.
}
else
{
//Same sequence, use second key: charge
if (pept1.charge < pept2.charge)
{
toReturn = -1;
}
else
{
if (pept1.charge > pept2.charge)
{
toReturn = 1;
}
else
{
//Third key, score, to accomodate entering of the highest
// scoring peptides into the Quantiation window.
//
//Note 1: descending sort
//Note 2: the inserted peptides, currently score 99, are
// considered to have the lowest score.
double scoreTol = 0.1;
double lowScore = 0.01;
//Changed PM_MASCOTSCORE_ASDOUBLE 2008-11-25. No
//longer implicit conversion from integer to
//double...
double effectiveScore1 = pept1.MascotScore2;
if (utilityStatic.numbersClose(
effectiveScore1,
FIXED_SCORE_FOR_INSERTED_PEPTIDES2,
scoreTol))
{
effectiveScore1 = lowScore;
}
//Changed PM_MASCOTSCORE_ASDOUBLE 2008-11-25. No
//longer implicit conversion from integer to
//double...
double effectiveScore2 = pept2.MascotScore2;
if (utilityStatic.numbersClose(
effectiveScore2,
FIXED_SCORE_FOR_INSERTED_PEPTIDES2,
scoreTol))
{
effectiveScore2 = lowScore;
}
if (effectiveScore1 < effectiveScore2)
{
toReturn = 1;
//Note: descending sort
}
else
{
//Changed PM_SORTBUG 2006-03-17
//If effectiveScore1 < effectiveScore2 Then
if (effectiveScore1 > effectiveScore2)
{
toReturn = -1;
//Note: descending sort
}
else
{
//Fourth key: mass
if (pept1.MascotCalculatedMass < pept2.MascotCalculatedMass)
{
toReturn = -1;
}
else
{
if (pept1.MascotCalculatedMass > pept2.MascotCalculatedMass)
{
toReturn = 1;
}
else
{
//Also exacly same mass, use fifth key. This will
//happen for inserted peptides.
if (pept1.rawFileID < pept2.rawFileID)
{
toReturn = -1;
}
else
{
if (pept1.rawFileID > pept2.rawFileID)
{
toReturn = 1;
}
else
{
//Sixth key: to have a defined sort order for
// double entries (duplication of data
// for a spectrum, in the Mascot input file.)
if (pept1.queryNumber < pept2.queryNumber)
{
toReturn = -1;
}
else
{
if (pept1.queryNumber > pept2.queryNumber)
{
toReturn = 1;
}
else
{
//All 6 keys equal....
int peter9 = 9;
}
}
}
}
}
}
}
}
}
} //Same sequence, use second key: charge
} //Sequence compare
// 'Note: ascending sort
// If pept1.AASequence < pept2.AASequence Then
// toReturn = -1
// Else
// If pept1.AASequence > pept2.AASequence Then
// toReturn = 1
// Else
// 'Equal primary keys.... Use secondary key
// Dim peter9 As Integer = 9
//
// 'Note: descending sort
// If pept1.MascotScore < pept2.MascotScore Then
// toReturn = 1
// Else
// If pept1.MascotScore > pept2.MascotScore Then
// toReturn = -1
// Else
// 'Equal....
// Dim peter10 As Integer = 10
// End If
// End If
// End If
// End If
}
else
{
int peter2 = 2; //Indexes equal.
}
return toReturn;
} //Compare()
} //SortBySequenceThenScore_usingIndex()
//This is what we are protecting!
//'Changed PM_TYPESAFE 2006-10-25
//Dim mPeptides As ArrayList 'Item type is PeptideHitStructure
private List<PeptideHitStructure> mPeptides2;
//Note: this
private int mEffectiveNumberOfPeptides;
// is only for the permanent filter.
//Not yet....
//'Parallel structure to PeptideHitStructure.
//Dim mDerivedPeptideFieldsList As ArrayList 'Item type
//' is : peptideDerivedFieldsStructure
private peptideSortOrderEnum mSortDefaultOrder;
private int mIteratorTokenGeneration;
private int mPeptideTokenBase;
//Changed PM_TYPESAFE 2006-11-08
//Dim mIteratorInfo As Hashtable '(iteratorID, interatorInfo)
//Key: iteratorID
private Dictionary<int, iteratorStructure> mIteratorInfo2;
//For caching lists of sorted keys.
private Dictionary<peptideSortOrderEnum, List<int>> mSortedKeysSet2;
private peptideFilterStructure mPermanentFilter2;
//Changed PM_HIGHESTSCORINGUNIQUELYMODIFIED_BUG 2007-10-05. Now
// per iterator.
//'Changed PM_TYPESAFE 2006-11-09
// ''Changed PM_PEPTIDEFILTER_HIGHESTSCORING 2006-05-19
//'Dim mExcludeHash As Hashtable 'Related to
// '' field highestScoringUniquelyModified in mPermanentFilter.
//Private mExcludeHash2 As Dictionary(Of String, Integer)
//Changed PM_HIGHESTSCORINGUNIQUELYMODIFIED_BUG 2007-10-05
//Used when building
bool mBuildingExcludeHash;
// a data structure when highestScoringUniquelyModified is
// in effect.
//Changed PM_MEMORY_EFFICIENCY 2007-02-19
private int mEstimatedCapacity;
//****************************************************************************
//* Constructor for PILpeptides *
//****************************************************************************
public PILpeptides(int anAnticipatedMaximumNumberOfPeptides)
{
//Changed PM_MEMORY_EFFICIENCY 2007-02-19
mEstimatedCapacity = anAnticipatedMaximumNumberOfPeptides;
mIteratorTokenGeneration = 311;
mPeptideTokenBase = 1993;
mPeptides2 = null; //Lazy instantiation
mIteratorInfo2 = null; //Lazy instantiation
mSortedKeysSet2 = null; //Lazy instantiation
//Changed PM_PEPTIDEFILTER_GENERALISED 2007-08-27. Probably OK to
//set the single field, but we want isolate it...
// 'Changed PM_ZAP_PEPTIDES 2006-10-25
// 'mPermanentFilter.chargeMin = -1 'Flag for no filter
// mPermanentFilter.chargeMin = NOFILTER_CODE 'Flag for no filter
//
// mPermanentFilter.highestScoringUniquelyModified = False 'Default
// ' is no filter.
mPermanentFilter2 = peptideFilterStructure.noPepFilter();
//Changed PM_HIGHESTSCORINGUNIQUELYMODIFIED_BUG 2007-10-05
//'Changed PM_PEPTIDEFILTER_HIGHESTSCORING 2006-05-19
//mExcludeHash2 = Nothing 'Lazy instantiation
mEffectiveNumberOfPeptides = -1;
//Flag for undefined
mBuildingExcludeHash = false;
//Changed PM_ASSERT_ZAPPED_PROTEINS 2006-03-23
mSortDefaultOrder = peptideSortOrderEnum.enumSequenceThenScore;
//Changed PM_COMBINED_INDEXOUTOFRANGE_EXCEPTION 2006-03-27
this.peptidelistChanged();
} //Constructor. For PILpeptides.
//Changed PM_FAST_SERIALISATION 2006-12-30
//****************************************************************************
//* For PILpeptides. *
//****************************************************************************
public static PILpeptides readFromStream2(
ref SerializationReader anInReader, int aMBfileVersion)
{
PILpeptides toReturn = new PILpeptides(0);
//Changed PM_FAST_SERIALISATION_READ 2007-01-01
//List
{
int items = anInReader.ReadOptimizedInt32();
toReturn.mPeptides2 = new List<PeptideHitStructure>(items);
int lastIndex = items - 1;
int j = 0;
for (j = 0; j <= lastIndex; j++)
{
toReturn.mPeptides2.Add(
PeptideHitStructure.readFromStream2(
ref anInReader, aMBfileVersion));
}
} //Block. Reading list.
toReturn.mEffectiveNumberOfPeptides = anInReader.ReadInt32();
toReturn.mSortDefaultOrder =
(peptideSortOrderEnum)anInReader.ReadInt32();
toReturn.mIteratorTokenGeneration = anInReader.ReadInt32();
toReturn.mPeptideTokenBase = anInReader.ReadInt32();
toReturn.mPermanentFilter2 =
peptideFilterStructure.readFromStream2(
ref anInReader, aMBfileVersion);
return toReturn;
} //readFromStream2(). For PILpeptides.
//Changed PM_FAST_SERIALISATION_AVOID_DOTNET 2006-12-19
//****************************************************************************
//* For PILpeptides. *
//****************************************************************************
public void addToStream2(
ref SerializationWriter anInOutWriter, int aMBfileVersion)
{
//aVersion: e.g. 300 for MB3, 400 for MB4.
//SERMARK14. A marker. Keep it.
//Not needed anymore.
//'Changed PM_FAST_SERIALISATION 2006-12-18
//Me.purgeHiddenPeptides()
//Changed PM_FAST_SERIALISATION 2006-12-19. Avoid invoking
// the .NET serialisation (BinaryFormatter).
//writer.Write(mPeptides2) 'List(Of PeptideHitStructure)
//
//Note: we use the public interface even though we have access to
//the datastructure. In this way we get rid of the peptides marked
//for deletion. Those outside the current filter will not be
//saved either (is that what we want).
{
int physicalSize = mPeptides2.Count;
peptideListIterator pepIter = new peptideListIterator(this);
//Changed PM_PEPTIDEFILTER_GENERALISED 2007-08-27
int token = pepIter.getIterToken();
//Note: size depends on which filter is applied. In this case
// we use the permanent filter (created by the first type
// of constructor used above).
int logicalSize = peptideCount2(token);
//This may still create a lot of memory garbage - by the
//current implementation.
//This is our own encoding.
anInOutWriter.WriteOptimized(logicalSize);
int count = 0;
//Changed PM_REFACTOR_OUT_IS_YOUR_FRIEND 2008-10-30
//PeptideHitStructure pept =
// PeptideHitStructure.blankPeptide(); //Keep compiler happy.
PeptideHitStructure pept;
while (!pepIter.nextPeptide(out pept))
{
pept.addToStream2(ref anInOutWriter, aMBfileVersion);
count += 1;
}
Trace.Assert(
logicalSize == count,
"PIL ASSERT. logicalSize ( " + logicalSize +
") is not the same as count (" + count + ").");
int purged = physicalSize - logicalSize;
//For breakpoints.
if (purged >= 1)
{
int peter1 = 1;
}
if (purged >= 2)
{
int peter2 = 2;
}
if (purged >= 3)
{
int peter3 = 3;
}
if (purged >= 4)
{
int peter4 = 4;
}
} //Block.
//Do we need to store all of these??? E.g. there will
//be iterator structures active when we start.
anInOutWriter.Write(mEffectiveNumberOfPeptides);
//Changed PM_REFACTOR_MARKER 2008-10-30. Is 4-byte integer
//the right cast? Yes, the old read (VB version) above was 32 bit.
anInOutWriter.Write((int)mSortDefaultOrder);
anInOutWriter.Write(mIteratorTokenGeneration);
anInOutWriter.Write(mPeptideTokenBase);
//writer.Write(mIteratorInfo2) left out.
//writer.Write(mSortedKeysSet2) left out, created on demand.
//Changed PM_FAST_SERIALISATION_AVOID_DOTNET 2006-12-19. Call
//serialisation directly.
//'writer.Write(mPermanentFilter) 'peptideFilterSpecificationStructure
//anInOutWriter.WriteObject(mPermanentFilter) 'Is this the right
//' way. Should there not be a function for Structures???
mPermanentFilter2.addToStream2(ref anInOutWriter, aMBfileVersion);
//writer.Write(mExcludeHash2) left out. Created on demand.
} //addToStream2(). For PILpeptides.
//Changed PM_FAST_SERIALISATION 2006-12-18
//****************************************************************************
//* <placeholder for header> *
//****************************************************************************
private void purgeHiddenPeptides()
{
//We may not need this function after all; the elimination is now
//done on the client side in serialisation.
Trace.Assert(
false, "Stop!",
"PIL ASSERT. Internal/development assert for stopping execution......");
//For now: use the public interface. This may create a lot of
//memory garbage. But we must somehow physically delete the entries
//as the serialisation run on a Generics list, without any control
//of which elements are serialised ().
//
//In order to prevent unnecessary operations it would also be
//nice if we could check if it is already done. We could use a flag;
//will aldo need to be updated if the condition is invalidated, e.g.
//a peptide.
int physicalSize = mPeptides2.Count;
peptideListIterator pepIter = new peptideListIterator(this);
int token = pepIter.getIterToken();
int logicalSize = peptideCount2(token);
//This may still create
// a lot of memory garbage - by current implementation.
if (physicalSize > logicalSize)
{
List<PeptideHitStructure> newPeptideList =
new List<PeptideHitStructure>();
//Changed PM_REFACTOR_OUT_IS_YOUR_FRIEND 2008-10-30
//PeptideHitStructure pept = PeptideHitStructure.blankPeptide();
PeptideHitStructure pept;
//Keep compiler happy.
while (!pepIter.nextPeptide(out pept))
{
newPeptideList.Add(pept);
}
int oldSize = physicalSize;
int newSize = newPeptideList.Count;
int purged = oldSize - newSize;
mPeptides2 = null;
//Just to be clear we are getting rid of the old
// list.
mPeptides2 = newPeptideList;
this.peptidelistChanged();
//Existing sorted keys are invalidated as
}
// some items were deleted.
else
{
int peter2 = 2;
//No items to leave out.
}
} //purgeHiddenPeptides()
//Changed PM_COMBINED_INDEXOUTOFRANGE_EXCEPTION 2006-03-27
//****************************************************************************
//* <placeholder for header> *
//****************************************************************************
public void peptidelistChanged()
{
mEffectiveNumberOfPeptides = -1;
//Flag for undefined
mSortedKeysSet2 = null;
//Sort order must be found again (for the
// new list)/lazy instantiation.
mIteratorInfo2 = null;
//The list is invalidated so we might as
// well get rid of any tokens.
if (mSortedKeysSet2 != null)
{
int peter2 = 2;
}
if (mIteratorInfo2 != null)
{
int peter3 = 3;
}
} //peptidelistChanged()
//****************************************************************************
//* <placeholder for header> *
//****************************************************************************
public void setPermanentPeptideFilter(
peptideFilterStructure anInPermanentPeptideFilter)
{
mPermanentFilter2 = anInPermanentPeptideFilter;
mPermanentFilter2.tag2 = 0;
//Calling this function clears "no filter".
mEffectiveNumberOfPeptides = -1;
//Flag that we should find effective
// number of peptides (but we lazy find it - just before the
// number is needed).
} //setPermanentPeptideFilter()
//****************************************************************************
//* <placeholder for header> *
//****************************************************************************
public void setDefaultSortOrder(peptideSortOrderEnum aSortOrder)
{
mSortDefaultOrder = aSortOrder;
} //setDefaultSortOrder()
//****************************************************************************
//* <placeholder for header> *
//****************************************************************************
public int newIteratorToken(peptideFilterStructure aFilter)
{
int toReturn = mIteratorTokenGeneration;
mIteratorTokenGeneration += 1;
//Changed PM_REFACTOR 2008-10-30. Generated by VB to C# converted.
//Disable it for now to stay faithful to the original.
//iteratorStructure info = default(iteratorStructure);
//iteratorStructure info;
iteratorStructure info = default(iteratorStructure); //Use it after all.
info.readIndex = 0;
info.lastReadIndex = -99;
//Changed PM_PEPTIDEFILTER_GENERALISED 2007-08-29. Needed because
//of recent changes and some client side call sequences. mPeptides2
//is nothing if no peptide was added to a protein during parsing.
//Dim len As Integer = mPeptides2.Count
int len = 0;
if (mPeptides2 != null)
{
len = mPeptides2.Count;
}
else
{
int peter2 = 2;
//Is Nothing...
}
int lastIndex = len - 1;
info.lastIndex = lastIndex;
info.sortOrder = mSortDefaultOrder;
info.sortedKeys2 = null;
//Lazy instantiation of the sorted indexes.
//Changed PM_PEPTIDEFILTER_GENERALISED 2007-08-28
info.filter = aFilter;
//The assignments to Nothing below
// mimics a deep copy (but we don't need to actually copy - unless
// we could somehow save on creating a hash each time for the same
// peptide filter?).
//Changed PM_PEPTIDEFILTER_GENERALISED 2007-08-29
info.filter.includeModHash_INTERNAL2 = null;
//Lazy instantiate - only
// just before it is needed.
//Changed PM_EXCLUDE_MODFILTER 2008-06-30
info.filter.excludeModHash_INTERNAL = null;
//Lazy instantiate - only
// just before it is needed.
//Changed PM_HIGHESTSCORINGUNIQUELYMODIFIED_BUG 2007-10-05
info.filter.exHash2_INTERNAL = null;
//Lazy instantiate - only just
// before it is needed.
if (mIteratorInfo2 == null)
{
//Lazy instantiation - for the list of iterators itself.
mIteratorInfo2 = new Dictionary<int, iteratorStructure>();
}
if (!mIteratorInfo2.ContainsKey(toReturn))
{
mIteratorInfo2.Add(toReturn, info);
}
else
{
//This should never happen!
Trace.Assert(false, "PIL ASSERT. Non-unique key for peptide list iterator.");
}
return toReturn;
} //newIteratorToken()
//****************************************************************************
//* Helper function to avoid suppress compiler warnings. *
//****************************************************************************
private iteratorStructure emptyIterator2()
{
//No longer needed due to use of out keyword?
//Changed PM_REFACTOR 2008-10-30. Generated by VB to C# converted.
//Disable it for now to stay faithful to the original.
//iteratorStructure toReturn = default(iteratorStructure);
//iteratorStructure toReturn;
iteratorStructure toReturn = default(iteratorStructure); //Use
// it after all.
//Reference members.
//Note: compiler gets confused if these lines are
// in a "If True" block...
toReturn.sortedKeys2 = null;
toReturn.filter.exHash2_INTERNAL = null;
toReturn.filter.includeModHash_INTERNAL2 = null;
//Changed PM_EXCLUDE_MODFILTER 2008-06-30
toReturn.filter.excludeModHash_INTERNAL = null;
//Changed PM_EXCLUDE_MODFILTER 2008-06-30
//toReturn.filter.pepModFilter3 = Nothing
toReturn.filter.pepIncludeModFilter3 = null;
toReturn.filter.pepExcludeModFilter = null;
//Other members. Not strictly needed as we don'y presume to
//initialise everything (but that is what the name of
//the function suggests).
toReturn.readIndex = -1;
//Invalid value. Assume clients are only
// tired of compiler warnings and wants to overwrite...
return toReturn;
} //emptyIterator2()
//****************************************************************************
//* <placeholder for header> *
//****************************************************************************
public void resetRead(int anIteratorToken)
{
Trace.Assert(
(mIteratorInfo2 != null), "PIL ASSERT. mIteratorInfo is Nothing.");
////Changed PM_REFACTOR 2007-12-12
////Dim value As iteratorStructure
//value.sortedKeys2 = Nothing 'Keep compiler happy.
//iteratorStructure value = emptyIterator();
////Keep compiler happy.
iteratorStructure value;
if (mIteratorInfo2.TryGetValue(anIteratorToken, out value))
{
if (value.readIndex > 0)
{
value.readIndex = 0;
mIteratorInfo2[anIteratorToken] = value;
}
else
{
//Already at zero, no need to do anything.
}
}
else
{
//This should never happen!
Trace.Assert(
false,
"PIL ASSERT. Key does not exist for peptide list iterator.");
}
} //resetRead()
//****************************************************************************
//* <placeholder for header> *
//****************************************************************************
private List<int> getSortedKeys(peptideSortOrderEnum aSortOrder)
{
//Note: this gives the order of the ***physical*** list.
//
// This is ***independent*** of any filter that
// applies to the list.
List<int> toReturn = null;
if (mSortedKeysSet2 == null)
{
//Lazy instantiation. Empty, ready to store one keylist per
//kind of sort order.
mSortedKeysSet2 = new Dictionary<peptideSortOrderEnum, List<int>>();
}
//Do we already have the list of sorted keys?
List<int> possibleSortedKeys; // = null;
if (mSortedKeysSet2.TryGetValue(aSortOrder, out possibleSortedKeys))
{
//Changed PM_UNNECESSARY_OPERATION 2008-10-30
//toReturn = mSortedKeysSet2(aSortOrder);
toReturn = possibleSortedKeys;
}
else
{
//Lazy sort... We do not sort until we really have to. That is
//until this function is called, e.g. through nextPeptide().
//Sorted keys do not exist for this sort order. Create them.
int len = mPeptides2.Count;
int lastIndex = len - 1;
//ReDim toReturn(lastIndex)
//Changed PM_TYPESAFE 2006-11-08
//toReturn = New ArrayList(len)
toReturn = new List<int>(len);
//Create keys
int j = 0;
for (j = 0; j <= lastIndex; j += 1)
{
toReturn.Add(j);
}
//Sort the keys.
switch (aSortOrder)
{
case peptideSortOrderEnum.enumSequenceThenScore:
SortBySequenceThenScore_usingIndex sortObject =
new SortBySequenceThenScore_usingIndex( mPeptides2);
toReturn.Sort( sortObject);
break;
default:
Trace.Assert(
false,
"PIL ASSERT. Select Case never fall-through");
break;
}
mSortedKeysSet2.Add(aSortOrder, toReturn);
}
return toReturn;
} //getSortedKeys()
//Changed PM_REFACTOR 2006-10-22
//****************************************************************************
//* <placeholder for header> *
//****************************************************************************
public static int hashValueForModification(
List<modificationCountStruct> anInMods2,
Dictionary<int, int> anInExcludeModsList,
bool aConsiderModCounts)
{
//About anInExcludeModsList:
// 1. could be SILAC modification.
// 2. we ignore the value, it is the SILAC dish number (zero based) and
// is used by client in other places, but not here...
int toReturn = 0;
//Attempt to make unique integer for modification set
//for the current peptide. Note: is not 100% foolproof...
if (anInMods2 != null)
{
int mult = 2;
int hashValue = 0;
//Changed PM_REFACTOR 2008-10-30. Generated by VB to C# converted.
//Disable it for now to stay faithful to the original.
//modificationCountStruct someMod = default(modificationCountStruct);
foreach (modificationCountStruct someMod in anInMods2)
{
int modID = someMod.quantModificationID;
//Changed PM_TOOMANY_QUANT_PEPTIDES_BUG 2008-09-10
bool acceptMod =
anInExcludeModsList == null ||
!anInExcludeModsList.ContainsKey(modID);
//Note: depends
// on boolean short-circuit...
if (acceptMod)
{
//Changed PM_SILACDISH_UNIQUELY_HIGHEST_SCORING 2008-10-02
int modCountToUse = 1;
if (aConsiderModCounts)
{
modCountToUse = someMod.count3;
}
else
{
int peter2 = 2;
}
//For breakpoints
if (modCountToUse > 1)
{
int peter2 = 2;
}
int value = mult * modCountToUse * modID;
hashValue += value;
mult *= 2;
}
else
{
int peter3 = 3;
}
}
toReturn = hashValue;
}
else
{
//No mods....
int peter8 = 8;
}
return toReturn;
} //hashValueForModificaiton()
//****************************************************************************
//* <placeholder for header> *
//****************************************************************************
private void buildKeyForHighestScoring(
string anInSeq,
highestScoringParametersStructure anInKeyBuildOptions,
int aCharge,
int aFileID,
List<modificationCountStruct> anInMods2,
int aSILACdish,
ref StringBuilder anInOutKeySB)
{
//Old name of this function:
// highestScoringUniqueModKey()
//Old:
// ByRef anInMods As ArrayList
if (anInOutKeySB.Length > 0)
{
anInOutKeySB.Length = 0;
//Clear it....
}
anInOutKeySB.Append(anInSeq);
//Changed PM_SILACDISH_UNIQUELY_HIGHEST_SCORING 2008-10-02. Below
// are the new options.
if (anInKeyBuildOptions.differentCharge)
{
anInOutKeySB.Append("_");
anInOutKeySB.Append(aCharge.ToString());
}
if (anInKeyBuildOptions.differentRawFile)
{
anInOutKeySB.Append("_");
anInOutKeySB.Append(aFileID);
}
//Changed PM_SILACDISH_UNIQUELY_HIGHEST_SCORING 2008-10-02
//Now optional. Before it was the option and always on ("Only highest
//scoring uniquely modified").
if (anInKeyBuildOptions.differentModificationSet)
{
anInOutKeySB.Append("_");
//Changed PM_REFACTOR 2006-10-22. Moved to separate function in
//order to use it from elsewhere.
bool considerModificationCounts =
anInKeyBuildOptions.differentModificationCounts2;
int hashValue =
hashValueForModification(
anInMods2,
anInKeyBuildOptions.differentModification_excludedMods2,
considerModificationCounts);
anInOutKeySB.Append(hashValue.ToString());
}
if (anInKeyBuildOptions.differentSILACdish)
{
anInOutKeySB.Append("_");
anInOutKeySB.Append(aSILACdish);
}
} //buildKeyForHighestScoring()
//Dim inModfilter As Boolean = _
//Changed PM_REFACTOR 2008-06-30. Separate function. To make adding
// functionality for exclude modification filter almost trivial.
//****************************************************************************
//* <placeholder for header> *
//****************************************************************************
private static bool isInModFilter(
List<int> anInPeptideModFilter,
ref Dictionary<int, int> anInOutModificationHash,
bool anInValueIfNotSpecified,
List<massSpectrometryBase.modificationCountStruct> anInModHits,
out bool anOutUpdateModHash)
{
//Changed PM_PEPTIDEFILTER_GENERALISED 2007-08-29
bool toReturn = anInValueIfNotSpecified;
//Default if no mod filter specified.
//Changed PM_CSHARP_DETECTED_PROBLEM 2008-10-30
anOutUpdateModHash = false;
List<int> modFilter = anInPeptideModFilter;
bool includeModFilterExists = (modFilter != null);
//Note: depends on short-circuit boolean. Order must be preserved.
bool modFilterInEffect = includeModFilterExists && modFilter.Count > 0;
int filterCount = 0;
if (includeModFilterExists)
{
filterCount = modFilter.Count;
//Require Nothing if not really in effect.
Trace.Assert(
filterCount > 0,
"PIL ASSERT. Field pepModFilter3 is empty (but not Nothing).");
}
//Any mod filter specified?
if (modFilterInEffect)
{
if (anInOutModificationHash == null)
{
//Lazy instantiation.
//
anInOutModificationHash =
peptideFilterStructure.hashForModFilter(modFilter);
//Changed PM_REFACTOR 2007-09-05
//If permanentFilter Then
// mPermanentFilter2.modHash_INTERNAL = _
// effectiveFilter.modHash_INTERNAL 'Update the source...
//Else
// value.filter.modHash_INTERNAL = _
// effectiveFilter.modHash_INTERNAL
// 'Note: write-back for per-iterator is done at
// ' the end of the loop.
//End If
anOutUpdateModHash = true;
}
//Block. For ASSERT only.
{
int count1 = filterCount;
int count2 = anInOutModificationHash.Count;
//Changed PM_PEPTIDECOUNT_BUG 2007-09-04
Trace.Assert(count1 == count2, "PIL ASSERT. " + "Count for field peptideModificationFilter2 " + ", " + count1 + ", is not consistent with count for " + "field modHash_INTERNAL, " + count2 + ".");
} //Block.
toReturn =
peptideFilterStructure.anyModsInFilter(
anInModHits, anInOutModificationHash);
}
else
{
int peter2 = 2;
//No mod filter specified.
} //Any mod-filter.
return toReturn;
} //isInModFilter()
//Changed PM_REFACTOR 2007-09-05
//****************************************************************************
//* <placeholder for header> *
//****************************************************************************
public static bool simpleFilteredOut(
PeptideHitStructure anInPeptide,
peptideFilterStructure anInOutFilter,
out bool anOutUpdateIncludeModHash,
out bool anOutUpdateExcludeModHash)
{
//Note: the modhash field in anInOutFilter may be set in this function.
bool toReturn = true;
//Changed PM_EXCLUDE_MODFILTER 2008-06-30
//anOutUpdateModHash = False
anOutUpdateIncludeModHash = false;
anOutUpdateExcludeModHash = false;
int ch = anInPeptide.charge;
int slen = anInPeptide.AASequence.Length;
bool peptideMarkedForDeletion = ch == MARKEDFORDELETION_CODE2;
//For breakpoints.
if (peptideMarkedForDeletion)
{
int peter2 = 2;
}
else
{
int peter3 = 3;
}
//Changed PM_MASCOTSCORE_ASDOUBLE 2008-11-25
////Changed PM_PEPTIDEFILTER_GENERALISED 2007-08-26
//int score = anInPeptide.MascotScore;
double score2 = anInPeptide.MascotScore2;
//Changed PM_PEPTIDEFILTER_GENERALISED 2007-08-28
//Should we use this value? Mass or MCR? Observed
//or theoretical.
double mass = anInPeptide.MascotCalculatedMass;
//Changed PM_VALIDATION_AFTER_RECALIBRATION 2007-09-24
//Dim measureMassToUse As Double = anInPeptide.measuredMass
double measuresMassToUse = anInPeptide.calibratedMeasuredMass;
if (measuresMassToUse < 10.0)
{
measuresMassToUse = mass;
//Do not consider mass accuracy.
}
else
{
int peter2 = 2;
}
//'Is this defined during parse???
//Dim massAccuracyRelative As Double = _
// (anInPeptide.measuredMass - mass) / mass * 1000000.0
double massAccuracyRelative = (measuresMassToUse - mass) / mass * 1000000.0;
bool quantified = PILpeptides.isQuantified(ref anInPeptide);
bool verified = anInPeptide.verified;
//??? Should
// it be some other field? "Checked" ?
bool inIncludeModfilter =
isInModFilter(
anInOutFilter.pepIncludeModFilter3,
ref anInOutFilter.includeModHash_INTERNAL2,
true,
anInPeptide.modHits2,
out anOutUpdateIncludeModHash);
bool inExcludeModfilter =
isInModFilter(
anInOutFilter.pepExcludeModFilter,
ref anInOutFilter.excludeModHash_INTERNAL,
false,
anInPeptide.modHits2,
out anOutUpdateExcludeModHash);
//Changed PM_MASSACC_PEPFILTER 2007-09-05. Added to
// filter: massAccuracyMin and massAccuracyMax.
//Changed PM_RAWFILE_PEPFILTER 2007-11-16
bool inRawFileFilter = true;
int filterID = anInOutFilter.rawFileID;
bool activeRawFilterFilter = filterID >= 0;
if (activeRawFilterFilter)
{
inRawFileFilter =
filterID == anInPeptide.rawFileID;
}
//Changed PM_SHORTCIRCUIT_BOOL 2008-11-04. The original VB source
//used "Or" and not "OrElse".
//
//Should we reorder so the most likely conditions to be true are
//listed first?
//Changed PM_MASCOTSCORE_ASDOUBLE 2008-11-25. For score
//comparison: no longer integer to double comparison (implicit
//integer to double conversion).
toReturn =
(ch < anInOutFilter.chargeMin ||
ch > anInOutFilter.chargeMax)
||
(slen < anInOutFilter.seqLengthMin ||
slen > anInOutFilter.seqLengthMax)
||
(score2 < anInOutFilter.scoreMin ||
score2 > anInOutFilter.scoreMax2)
||
(mass < anInOutFilter.massMin ||
mass > anInOutFilter.massMax)
||
(anInOutFilter.quantifiedOnly && !quantified)
||
(anInOutFilter.verifiedOnly && !verified)
||
peptideMarkedForDeletion
||
!inIncludeModfilter
||
inExcludeModfilter
||
(massAccuracyRelative < anInOutFilter.massAccuracyMin ||
massAccuracyRelative > anInOutFilter.massAccuracyMax)
||
!inRawFileFilter
||
false;
return toReturn;
} //simpleFilteredOut()
//****************************************************************************
//* <placeholder for header> *
//****************************************************************************
public bool nextPeptide(
int anIteratorToken,
out PeptideHitStructure aOutPeptide,
out int anOutPeptideToken)
{
//Future: detect that resetRead() was called.
bool toReturn2 = false; //Not at EOF
anOutPeptideToken = -1;
//Changed PM_KEEP_COMPILER_HAPPY 2008-10-30
//Keep compiler happy. This function is slower now as a result...
aOutPeptide = default(PeptideHitStructure);
bool filteredOut = true;
//True: at least one time through
// the loop below.
StringBuilder keySB = null;
if (mIteratorInfo2.ContainsKey(anIteratorToken))
{
//Changed PM_PEPTIDEFILTER_GENERALISED 2007-08-27
iteratorStructure value = mIteratorInfo2[anIteratorToken];
//Changed PM_REFACTOR 2008-10-30. Generated by VB to C# converted.
//Disable it for now to stay faithful to the original.
//peptideFilterStructure effectiveFilter =
// default(peptideFilterStructure);
peptideFilterStructure effectiveFilter;
bool permanentFilter =
value.filter.tag1 == PILpeptides.MARK_PERMANENT_FILTER2;
if (permanentFilter)
{
effectiveFilter = mPermanentFilter2;
}
else
{
effectiveFilter = value.filter;
}
//Changed PM_PEPTIDEFILTER_HIGHESTSCORING 2006-05-19
//Highest scoring.
//Changed PM_SILACDISH_UNIQUELY_HIGHEST_SCORING 2008-10-02
//'If mPermanentFilter.highestScoringUniquelyModified Then
//If effectiveFilter.highestScoringUniquelyModified Then
if (effectiveFilter.onlyHighestScoring)
{
//Changed PM_PEPTIDEFILTER_HIGHESTSCORING 2006-05-19
//Changed PM_MARKER_FAIL 2007-08-27
//This will certainly fail (as there is no hash for
// each iterator, but only one per peptide list instance).
//
//Possible scenario 1:
// If "highestScoringUniquelyModified"
// is turned off during export for an unsaved parse (that is
// before they physically excluded by save/load) with this
// option on. Then too many peptides will be exported.
// On the other hand: Will the old state from parsing be
// remembered and thus work anyway?
//
// A partial solution could be to physically exclude
// peptides from the protein list already during parsing.
//
//Possible scenario 2:
// If "highestScoringUniquelyModified" is turned off at parse
// time and on during an export perhaps this state will be
// remembered and reopening a protein validation window will
// display fewer peptides and all subsequently exports will
// also contain too few peptides ?
//Changed PM_HIGHESTSCORINGUNIQUELYMODIFIED_BUG 2007-10-05
//If mExcludeHash2 Is Nothing Then 'Lazy instantiation
if (!mBuildingExcludeHash)
{
//First time we need to find the highest
//scoring uniquely modified peptide in a
//protein's list.
//
//We wait until now to find the best scoring ones.
//Changed PM_HIGHESTSCORINGUNIQUELYMODIFIED_BUG 2007-10-05
//mExcludeHash2 = New Dictionary(Of String, Integer)
//effectiveFilter.excludeHash_INTERNAL = _
// New Dictionary(Of String, Integer)
mBuildingExcludeHash = true;
//Changed PM_PEPTIDEFILTER_GENERALISED 2007-08-27. Use of
//the other constructor.
//Dim pepIter As peptideListIterator = _
// New peptideListIterator(Me)
peptideListIterator pepIter =
new peptideListIterator(this, effectiveFilter);
int peptideToken = 0;
Dictionary<string, int> exHash2 =
new Dictionary<string, int>();
// Temporary, used when building
// up the hash. We can not change mExcludeHash2 until
// we are done with all peptides; our recursive call
// would not work.
keySB = new StringBuilder();
//Changed PM_REFACTOR_OUT_IS_YOUR_FRIEND 2008-10-30
//PeptideHitStructure somePeptide =
// helper.blankPeptide(); //Keep compiler happy.
PeptideHitStructure somePeptide;
//Recursive call of nextPeptide() !!. This for finding the
//highest scoring uniquely modified peptides. The (zero)
// size mExcludeHash2 element (but existing) is the flag.
while (
!pepIter.nextPeptide(
out somePeptide, out peptideToken))
{
//Why do we have this call in two places?
this.buildKeyForHighestScoring(
somePeptide.AASequence,
effectiveFilter.highestScoringParameters,
somePeptide.charge,
somePeptide.rawFileID,
somePeptide.modHits2,
somePeptide.SILACdishIndex,
ref keySB);
string key = keySB.ToString();
int exVal; // = 0;
if (exHash2.TryGetValue(key, out exVal))
{
int tokenForOld = exVal;
double oldScore2 =
this.peptideScoreByToken(tokenForOld);
//Changed PM_MASCOTSCORE_ASDOUBLE 2008-11-25.
//Was integer to double comparison...
if (somePeptide.MascotScore2 > oldScore2)
{
//Higher score. Update hash.
exHash2[key] = peptideToken;
}
else
{
//Lower scoring. Ignore it.
int peter8 = 8;
}
}
else
{
exHash2.Add(key, peptideToken);
//Store the physical
// index... Are tokens stable enough???
}
}
//Changed PM_HIGHESTSCORINGUNIQUELYMODIFIED_BUG 2007-10-05
//mExcludeHash2 = exHash2
effectiveFilter.exHash2_INTERNAL = exHash2;
//Only now
// can we set it (?).
mBuildingExcludeHash = false;
//
//Is it written back??? Yes, apparently always in the
//loop below. Unless at EOF, but then it is not required.
//Write-back. We need to remember the hash for
//all subsequent calls to this function.
if (permanentFilter)
{
mPermanentFilter2 = effectiveFilter;
}
else
{
value.filter = effectiveFilter;
mIteratorInfo2[anIteratorToken] = value;
}
} //if, Building up hash for option highestScoringUniquelyModified.
}
else
{
int peter2 = 2;
//Not highestScoringUniquelyModified...
}
//To end loop either the peptide must
while (filteredOut)
{
// be within the filter or at EOF. This way
// we jump to the next peptide within the filter.
//Changed PM_PEPTIDEFILTER_GENERALISED 2007-08-27. Moved to
// beginning of this function.
//Dim value As iteratorStructure = mIteratorInfo2(anIteratorToken)
int index = value.readIndex;
if (index <= value.lastIndex)
{
if (value.sortedKeys2 == null)
{
value.sortedKeys2 = this.getSortedKeys(value.sortOrder);
int lastIndexSortedKeys = value.sortedKeys2.Count - 1;
int readLastIndex = value.lastIndex;
Trace.Assert(
readLastIndex == lastIndexSortedKeys,
"PIL ASSERT. Sorted keys are too short.... " +
" Sorted keys last index: " + lastIndexSortedKeys +
". Peptide list last index: " + readLastIndex + ".");
}
int peptIndex = value.sortedKeys2[index];
anOutPeptideToken = peptIndex + mPeptideTokenBase;
aOutPeptide = mPeptides2[peptIndex];
//Changed PM_REFACTOR 2007-09-05
//Apply peptide filter on-the-fly.
bool updateIncludeModHash = false;
bool updateExcludeModHash = false;
filteredOut =
simpleFilteredOut(
aOutPeptide,
effectiveFilter,
out updateIncludeModHash,
out updateExcludeModHash);
if (updateIncludeModHash)
{
if (permanentFilter)
{
mPermanentFilter2.includeModHash_INTERNAL2 =
effectiveFilter.includeModHash_INTERNAL2;
//Update
}
// the source...
else
{
value.filter.includeModHash_INTERNAL2 =
effectiveFilter.includeModHash_INTERNAL2;
//Note: write-back for per-iterator is done at
// the end of the loop.
}
}
//Changed PM_EXCLUDE_MODFILTER 2008-06-30
if (updateExcludeModHash)
{
if (permanentFilter)
{
mPermanentFilter2.excludeModHash_INTERNAL =
effectiveFilter.excludeModHash_INTERNAL;
//Update
}
// the source...
else
{
value.filter.excludeModHash_INTERNAL =
effectiveFilter.excludeModHash_INTERNAL;
//Note: write-back for per-iterator is done at
// the end of the loop.
}
}
//ZZZZ peptides
if (!filteredOut)
{
filteredOut =
aOutPeptide.AASequence ==
peptideConstants.SEQUENCE_BADPEPTIDE;
//For breakpoints
if (filteredOut)
{
int peter1 = 1;
}
else
{
int peter2 = 2;
}
}
//Override...
//Assumes the significant values
if (effectiveFilter.tag2 < 0)
{
//are negative...
//Changed PM_ZAP_PEPTIDES 2006-10-25
switch (effectiveFilter.tag2)
{
case NOFILTER_CODE2:
//Override.
filteredOut = false;
break;
//Now handled above.
//Case MARKEDFORDELETION_CODE2
// filteredOut = True
default:
//We do not accept any other negative
//value.
Trace.Assert(false, "PIL ASSERT. Select Case never fall-through");
break;
}
}
//Filtering enabled.
bool considerHighestScoringUniquelyModified =
!filteredOut && effectiveFilter.onlyHighestScoring;
//effectiveFilter.highestScoringUniquelyModified old...
if (considerHighestScoringUniquelyModified)
{
//Changed PM_HIGHESTSCORINGUNIQUELYMODIFIED_BUG 2007-10-05
//If mExcludeHash2.Count = 0 Then
if (mBuildingExcludeHash)
{
//The hash is being built up: do nothing
int peter3 = 3;
}
else
{
//Hash is ready to use!
if (keySB == null)
{
keySB = new StringBuilder();
}
//Why do we have this call in two places?
this.buildKeyForHighestScoring(
aOutPeptide.AASequence,
effectiveFilter.highestScoringParameters,
aOutPeptide.charge,
aOutPeptide.rawFileID,
aOutPeptide.modHits2,
aOutPeptide.SILACdishIndex,
ref keySB);
string key2 = keySB.ToString();
int value2; // = 0;
//Changed PM_HIGHESTSCORINGUNIQUELYMODIFIED_BUG 2007-10-05
//If mExcludeHash2.TryGetValue(key2, value2) Then
if (effectiveFilter.exHash2_INTERNAL.TryGetValue(
key2, out value2))
{
int tokenForPeptideToKeep = value2;
if (anOutPeptideToken != tokenForPeptideToKeep)
{
filteredOut = true;
//Changed PM_HIGHESTSCORINGUNIQUELYMODIFIED_BUG 2007-10-04
//Fix this problem by physically marking
//the peptide so temporary peptide filters
//used later (e.g. for recalibration
//visualisation) will not see it.
if (permanentFilter)
{
PeptideHitStructure.invalidatePeptide(
ref aOutPeptide);
//Write-back.
mPeptides2[peptIndex] = aOutPeptide;
}
}
//But what if the option is set in a
//non-permanent filter???? mExcludeHash2
//is for the entire instance, not
//per iterator.
else
{
int peter8 = 8;
//Current is
// highest scoring uniquely modified
// in a protein.
}
}
else
{
Trace.Assert(false, "PIL ASSERT. mExcludeHash2 does " + "not contain key." + key2);
//We have a key for every peptide for now,
//even non-modified ones.
}
}
//User enabled filtering out of lower
// scoring peptides.
}
//Not filtered out (already).
//For breakpoints
if (filteredOut)
{
int peter1 = 1;
}
else
{
int peter2 = 2;
}
//Prepare for next call
{
value.lastReadIndex = value.readIndex;
value.readIndex += 1;
mIteratorInfo2[anIteratorToken] = value;
//Write back. Do
// we really need to do it this way?
} //Block.
}
else
{
//At EOF
toReturn2 = true;
//At EOF
filteredOut = false;
}
} //filtered out.
}
else
{
//This should never happen!
Trace.Assert(
false,
"PIL ASSERT. Key, " + anIteratorToken +
", does not exist for peptide list iterator.");
}
//Changed PM_MARKER_PEPITERATOR_CLEANUP 2007-09-04
//We should probably clean up at this point. E.g.:
//If toReturn = False Then
// mIteratorInfo2.Remove(anIteratorToken)
//End If
return toReturn2;
} //nextPeptide()
//****************************************************************************
//* <placeholder for header> *
//****************************************************************************
public void currentPeptide(
int anIteratorToken, out PeptideHitStructure aOutPeptide)
{
//Future: detect that resetRead() was called.
Trace.Assert(
false, "Stop!",
"PIL ASSERT. Internal/development assert for stopping execution......");
aOutPeptide = default(PeptideHitStructure); //Make compiler happy.
} //currentPeptide()
//****************************************************************************
//* <placeholder for header> *
//****************************************************************************
public void updateCurrentPeptide(
int anIteratorToken, PeptideHitStructure anInPeptide)
{
//Future: detect that resetRead() was called.
////Changed PM_REFACTOR 2007-12-12
////Dim value As iteratorStructure
////value.sortedKeys2 = Nothing 'Keep compiler happy.
//iteratorStructure value = emptyIterator();
////Keep compiler happy.
iteratorStructure value;
if (mIteratorInfo2.TryGetValue(anIteratorToken, out value))
{
int index = value.lastReadIndex;
int peptIndex = value.sortedKeys2[index];
mPeptides2[peptIndex] = anInPeptide;
}
else
{
//This should never happen!
Trace.Assert(false, "PIL ASSERT. Key does not exist for peptide list iterator.");
}
} //updateCurrentPeptide()
//****************************************************************************
//* <placeholder for header> *
//****************************************************************************
public void addPeptide(PeptideHitStructure anInPeptide)
{
bool addIt = true;
//Permanent filter set by client?
if (mPermanentFilter2.tag2 >= 0)
{
bool dummy1 = false;
bool dummy2 = false;
bool filteredOut =
simpleFilteredOut(
anInPeptide, mPermanentFilter2, out dummy1, out dummy2);
if (filteredOut)
{
addIt = false;
}
else
{
int peter3 = 3;
//OK to add.
}
}
else
{
int peter2 = 2;
//Permanent filter not set.
}
//Do not add it if (the simple) permanent filter says it will
//never be used.
if (addIt)
{
if (mPeptides2 == null)
{
//Lazy instantiation
mPeptides2 =
new List<PeptideHitStructure>(mEstimatedCapacity);
}
//Changed PM_MEMORY_EFFICIENCY 2007-02-19. Capacity...
else
{
int peter2 = 2;
}
mPeptides2.Add(anInPeptide);
//Changed PM_COMBINED_INDEXOUTOFRANGE_EXCEPTION 2006-03-27
this.peptidelistChanged();
//E.g. existing sorted keys are invalidated. This can happen
//for correlated files where peptides are inserted later.
}
else
{
int peter4 = 4;
//Not added...
}
} //addPeptide()
//****************************************************************************
//* <placeholder for header> *
//****************************************************************************
public void peptideByToken(
int aPeptideToken, out PeptideHitStructure aOutPeptide)
{
int peptIndex = aPeptideToken - mPeptideTokenBase;
int lastIndex = mPeptides2.Count - 1;
if (peptIndex >= 0 && peptIndex <= lastIndex)
{
aOutPeptide = mPeptides2[peptIndex];
}
else
{
//Token is probably not given by this class. Leave the return
//peptide undefined. Should we set some fields??
aOutPeptide = default(PeptideHitStructure);
}
} //peptideByToken()
//Convenience function for clients
//****************************************************************************
//* <placeholder for header> *
//****************************************************************************
public double peptideScoreByToken(int aPeptideToken)
{
PeptideHitStructure pept = PeptideHitStructure.blankPeptide();
//Keep compiler happy.
this.peptideByToken(aPeptideToken, out pept);
//Changed PM_MASCOTSCORE_ASDOUBLE 2008-11-25. No longer implicit
//integer to double conversion...
return pept.MascotScore2;
} //peptideScoreByToken()
//****************************************************************************
//* <placeholder for header> *
//****************************************************************************
public void updatePeptideByToken(
int aPeptideToken, PeptideHitStructure anInPeptide)
{
int peptIndex = aPeptideToken - mPeptideTokenBase;
mPeptides2[peptIndex] = anInPeptide;
//Could this not fail
// if one of the fields for sorting has been changed by
// the client??.
} //updatePeptideByToken()
//****************************************************************************
//* <placeholder for header> *
//****************************************************************************
public int peptideCount2(int anIteratorToken)
{
//Changed PM_PEPTIDEFILTER_GENERALISED 2007-08-27
//Count depends on the filter! - per iterator...
//Note: the returned value is not necessarily the physical number
// of peptides as we may be hiding some, e.g. ZZZZ peptides.
//
//Uses default filter (or current filter?).
int toReturn = 0;
bool doContinue = true;
if (mPeptides2 != null)
{
toReturn = mPeptides2.Count;
//Default, if not applying
}
//peptide filter(s).
else
{
doContinue = false;
//This can happen if no peptides
// were added.
}
if (doContinue)
{
//Changed PM_PEPTIDEFILTER_GENERALISED 2007-08-27
iteratorStructure value = mIteratorInfo2[anIteratorToken];
//Changed PM_REFACTOR 2008-10-30. Generated by VB to C# converted.
//Disable it for now to stay faithful to the original.
//peptideFilterStructure effectiveFilter = default(peptideFilterStructure);
peptideFilterStructure effectiveFilter;
bool permanentFilter =
value.filter.tag1 == PILpeptides.MARK_PERMANENT_FILTER2;
if (permanentFilter)
{
effectiveFilter = mPermanentFilter2;
}
else
{
effectiveFilter = value.filter;
}
if (effectiveFilter.tag2 >= 0)
{
//That is: a peptide filter is in effect (permanent or not).
int effectiveNumberOfPeptides = 0;
if (permanentFilter)
{
effectiveNumberOfPeptides = mEffectiveNumberOfPeptides;
}
else
{
effectiveNumberOfPeptides = value.effectiveNumberOfPeptides;
}
//If mEffectiveNumberOfPeptides < 0 Then
if (effectiveNumberOfPeptides < 0)
{
//Find the effective number of peptides given the
//current peptide filter...
int count = 0;
//Changed PM_PEPTIDEFILTER_GENERALISED 2007-08-28
//Dim pepIter As peptideListIterator = _
// New peptideListIterator(Me)
//Changed PM_REFACTOR 2008-10-30. Generated by VB to C# converted.
//Disable it for now to stay faithful to the original.
//peptideListIterator pepIter = default(peptideListIterator);
peptideListIterator pepIter;
if (permanentFilter)
{
pepIter = new peptideListIterator(this);
}
else
{
pepIter = new peptideListIterator(this, value.filter);
}
PeptideHitStructure pept; // = helper.blankPeptide();
while (!pepIter.nextPeptide(out pept))
{
count += 1;
}
//Should this be in the if clause below?.
value.effectiveNumberOfPeptides = count;
mIteratorInfo2[anIteratorToken] = value;
if (permanentFilter)
{
mEffectiveNumberOfPeptides = count;
}
else
{
int peter2 = 2;
}
effectiveNumberOfPeptides = count;
}
else
{
//Already computed. Just use the cached value.
int peter2 = 2;
//For breakpoints.
}
//Changed PM_PEPTIDEFILTER_GENERALISED 2007-08-28
//toReturn = mEffectiveNumberOfPeptides
toReturn = effectiveNumberOfPeptides;
}
else
{
int peter2 = 2;
//No filter...
}
} //If continue.
//Changed PM_PEPTIDEFILTER_GENERALISED 2007-08-29
Trace.Assert(
toReturn >= 0,
"PIL ASSERT. Negative value of peptide count: " + toReturn + ".");
return toReturn;
} //peptideCount2()
//Changed PM_ZAP_PEPTIDES 2006-10-25
//****************************************************************************
//* <placeholder for header> *
//****************************************************************************
public void zapPeptides_queryRange(int aQueryStart, int aQueryEnd)
{
//Note: for now we only mark it for deletion. Later
// we should also physically delete, e.g. if
// more than 10 percent of the peptides have been
// marked for deletion.
//We could use nextPeptide() instead...
int lastIndex = mPeptides2.Count - 1;
int j = 0;
//Linear search... Hopefully there are not too many peptides.
for (j = 0; j <= lastIndex; j += 1)
{
PeptideHitStructure pept = mPeptides2[j];
int query = pept.queryNumber;
if (query >= aQueryStart && query <= aQueryEnd)
{
pept.charge = MARKEDFORDELETION_CODE2;
//We mark the
// peptide for deletion by assigning a non-valid
// valid to one of the peptide's fields.
mPeptides2[j] = pept;
}
else
{
int peter2 = 2;
}
}
this.peptidelistChanged();
//E.g. existing sorted keys are invalidated. This
// can happen for correlated files where peptides are inserted later.
} //zapPeptides_queryRange()
//Changed PM_REFACTOR 2007-08-26
//Should this function be here???? It is related to a
//single peptide, not a list of them...
//****************************************************************************
//* <placeholder for header> *
//****************************************************************************
public static bool isQuantified(ref PeptideHitStructure anInPept)
{
bool quantified = false;
if (anInPept.LCprofilesProperties != null)
{
int effectiveIndex = -1;
int count = anInPept.LCprofilesProperties.Count;
if (count >= 2)
{
effectiveIndex = 1;
//Second dish/heavy isotope.
}
else
{
//Changed PM_EXPORT_BUG_QUANTIFIED_NO_ISOTOPE 2007-01-08
if (count == 1)
{
//No isotope.
effectiveIndex = 0;
}
else
{
//This should never happen...
Trace.Assert(
false, "Stop!",
"PIL ASSERT. " +
"Internal/development assert for stopping execution......");
}
}
LCprofilesPropertiesStructure dish1props =
anInPept.LCprofilesProperties[effectiveIndex];
quantified =
dish1props.averageOfRatios2 > 1E-08 &&
anInPept.useForQuantitation;
}
else
{
int peter9 = 9;
//Has not been quantified....
}
return quantified;
} //isQuantified()
} //class PILpeptides
} //massSpectrometryBase
Generated by script codePublish.pl at 2009-01-05T15:20:59.