public QPeptide() { Matches = null; RefMatch = null; RefNumberMatch = null; AlreadySearched = false; }
public PeptidePair(QPeptide Pept, int Left, int Right) { Ratio = 0.0; ESIFactor = 1.0; MaxConv = 0.0; Shift = 0.0; Peptide = Pept; if (Pept.Matches[Left] != null) { LeftMatch = new QMatch(Pept.Matches[Left]); } else { LeftMatch = null; } if (Pept.Matches[Right] != null) { //RightMatch - не меняется - поэтому может быть представлен ссылкой в основной экземпляр данных RightMatch = Pept.Matches[Right]; } else { RightMatch = null; } }
public override string ToString() { string comment; QMatch Match; if (Matches == null || RefMatch == null) { Match = new QMatch(); comment = "ERROR: No main peak"; } else { Match = RefMatch; comment = ""; if (ModMass != 0.0) { comment = ModDesk; } } QMatch Refs; if (RefNumberMatch == null) { Refs = new QMatch(); } else { Refs = RefNumberMatch; } string Out = ((ReportString[0] != '1')?"":String.Format("{0:20} \t", (Sequence ?? "NOSEQUENCE"))) + ((ReportString[1] != '1')?"":String.Format("{0:f4}\t", MascotRT)) + ((ReportString[2] != '1')?"":String.Format("{0:f4}\t", Match.ApexRT)) + ((ReportString[3] != '1')?"":String.Format("{0:F6}\t", Match.RTDisp)) + ((ReportString[4] != '1')?"":String.Format("{0}\t", Match.Shift)) + ((ReportString[5] != '1')?"":String.Format("{0}\t", Match.MaxConv)) + ((ReportString[6] != '1')?"":String.Format("{0}\t", Match.RTDisp / Refs.RTDisp)) + ((ReportString[7] != '1')?"":String.Format("{0:f4}\t", Match.LongESICoef)) + ((ReportString[8] != '1')?"":String.Format("{0:f2}\t", Match.Score)) + ((ReportString[9] != '1')?"":String.Format("{0}\t", Refs.Score)) + ((ReportString[10] != '1')?"":String.Format("{0}\t", Math.Log10(Match.Score))) + ((ReportString[11] != '1')?"":String.Format("{0}\t", Math.Log10(Refs.Score))) + ((ReportString[12] != '1')?"":String.Format("{0:f2}\t", Match.ApexScore)) + ((ReportString[13] != '1')?"":String.Format("{0:f5}\t", MascotMZ)) + ((ReportString[14] != '1')?"":String.Format("{0:f5}\t", Match.ApexMZ)) + ((ReportString[15] != '1')?"":String.Format("{0}\t", Charge)) + ((ReportString[16] != '1')?"":String.Format("{0}\t", PI)) + ((ReportString[17] != '1')?"":String.Format("{0}\t", Match.MSMatches == null?0:Match.MSMatches.Count - 2)) + ((ReportString[18] != '1')?"":String.Format("{0}\t", (IPI ?? "NOPROTEIN"))) + ((ReportString[19] != '1')?"":String.Format("{0:f2}\t", MascotScore)) + ((ReportString[20] != '1')?"":String.Format("{0:f5}\t", ModMass)) + ((ReportString[21] != '1')?"":String.Format("{0:f5}\t", Match.IsotopeRatio)) + ((ReportString[22] != '1')?"":String.Format("{0:f5}\t", TheorIsotopeRatio)) + ((ReportString[23] != '1')?"":String.Format("{0}", comment)); // Out = String.Format("{0}\t{1}\t"+Out,RTNumber,MascotScan); return(Out); }
public QMatch(QMatch Match) { ApexRT = Match.ApexRT; ApexScore = Match.ApexScore; ApexMZ = Match.ApexMZ; ApexIndex = Match.ApexIndex; Score = Match.Score; RTDisp = Match.RTDisp; IsotopeRatio = Match.IsotopeRatio; MaxConv = Match.MaxConv; Shift = Match.Shift; LongESICoef = Match.LongESICoef; if (Match.MSMatches != null) { MSMatches = new List <MSMatch>(); MSMatch MS; for (int i = 0; i < Match.MSMatches.Count; i++) { MS = new MSMatch(Match.MSMatches[i]); MSMatches.Add(MS); } } else { MSMatches = null; } }
public static double CalcMaxConv(QMatch Match1, QMatch Match2, ref double Shift) { //с шагом в 1 секунду пробегаем весь диапазон //первый нужно сместить так чтобы последняя точка первого приходилась на первую точку второго double FirstShift = Match2.MSMatches[0].RT - Match1.MSMatches[Match1.MSMatches.Count - 1].RT; double LastShift = Match2.MSMatches[Match2.MSMatches.Count - 1].RT - Match1.MSMatches[0].RT; double ShiftForMax = 0.0; double MaxConv = 0.0; for (double CurrShift = FirstShift; CurrShift <= LastShift; CurrShift += (1.0 / 60.0)) { double Conv = QMatch.Convolution(Match1, Match2, CurrShift); if (Conv > MaxConv) { MaxConv = Conv; ShiftForMax = CurrShift; } } //с шагом в одну десятую секунды FirstShift = ShiftForMax - 1.0 / 60.0; LastShift = ShiftForMax + 1.0 / 60.0; MaxConv = 0.0; for (double CurrShift = FirstShift; CurrShift <= LastShift; CurrShift += (1.0 / 600.0)) { double Conv = QMatch.Convolution(Match1, Match2, CurrShift); if (Conv > MaxConv) { MaxConv = Conv; ShiftForMax = CurrShift; } } //с шагом в одну сотую секунды FirstShift = ShiftForMax - 1.0 / 600.0; LastShift = ShiftForMax + 1.0 / 600.0; MaxConv = 0.0; for (double CurrShift = FirstShift; CurrShift <= LastShift; CurrShift += (1.0 / 6000.0)) { double Conv = QMatch.Convolution(Match1, Match2, CurrShift); if (Conv > MaxConv) { MaxConv = Conv; ShiftForMax = CurrShift; } } Shift = ShiftForMax; return(MaxConv); }
public void CutTails(QMatch Ext) { //упрощенная версия - от апекса double Shift = ApexRT - Ext.ApexRT; //double Shift = -Ext.Shift; int CutOff, i; if (MSMatches == null || Ext.MSMatches == null) { return; } //сортируем //передние хвосты if (MSMatches[0].RT - Shift > Ext.MSMatches[0].RT) { //наш хвост короче for (i = 1; i < Ext.MSMatches.Count; i++) { if (MSMatches[0].RT - Shift < Ext.MSMatches[i].RT) { break; } } if (i < Ext.MSMatches.Count) { //Ext.MSMatches.RemoveRange(0,i-1); ////ноль будет объявлен там же где и ноль у образца //Temp = ((MSMatches[0].RT - Shift) - Ext.MSMatches[i-1].RT)/2; //Ext.MSMatches[i-1].RT = MSMatches[0].RT - Shift; //Ext.MSMatches[i].RT = Ext.MSMatches[i].RT + Temp; CutOff = (Math.Abs(MSMatches[0].RT - Shift - Ext.MSMatches[i].RT) < Math.Abs(MSMatches[0].RT - Shift - Ext.MSMatches[i - 1].RT))?i:i - 1; //Ext.MSMatches.RemoveRange(0,CutOff); - предидущее if (CutOff > 0) { Ext.MSMatches[CutOff - 1].Score = 0.0; Ext.MSMatches.RemoveRange(0, CutOff - 1); } } } else { //их хвост короче for (i = 1; i < MSMatches.Count; i++) { if (Ext.MSMatches[0].RT + Shift < MSMatches[i].RT) { break; } } if (i < MSMatches.Count) { CutOff = (Math.Abs(MSMatches[i].RT - Shift - Ext.MSMatches[0].RT) < Math.Abs(MSMatches[i - 1].RT - Shift - Ext.MSMatches[0].RT))?i:i - 1; //MSMatches.RemoveRange(0,CutOff);- предидущее if (CutOff > 0) { MSMatches[CutOff - 1].Score = 0.0; MSMatches.RemoveRange(0, CutOff - 1); } } } //задние хвосты int IntCount = MSMatches.Count - 1; int ExtCount = Ext.MSMatches.Count - 1; if (MSMatches[IntCount].RT - Shift < Ext.MSMatches[ExtCount].RT) { //наш хвост короче for (i = ExtCount - 1; i >= 0; i--) { if (MSMatches[IntCount].RT - Shift > Ext.MSMatches[i].RT) { break; } } if (i >= 0) { CutOff = (Math.Abs(MSMatches[IntCount].RT - Shift - Ext.MSMatches[i].RT) < Math.Abs(MSMatches[IntCount].RT - Shift - Ext.MSMatches[i + 1].RT))?i:i + 1; //Ext.MSMatches.RemoveRange(CutOff+1, ExtCount-CutOff); - предыдущее if (CutOff < Ext.MSMatches.Count - 1) { Ext.MSMatches[CutOff + 1].Score = 0.0; Ext.MSMatches.RemoveRange(CutOff + 2, ExtCount - CutOff - 1); } } } else { //их хвост короче for (i = IntCount - 1; i >= 0; i--) { if (Ext.MSMatches[ExtCount].RT + Shift > MSMatches[i].RT) { break; } } if (i >= 0) { CutOff = (Math.Abs(MSMatches[i].RT - Shift - Ext.MSMatches[ExtCount].RT) < Math.Abs(MSMatches[i + 1].RT - Shift - Ext.MSMatches[ExtCount].RT))?i:i + 1; //MSMatches.RemoveRange(CutOff+1, IntCount-CutOff);- предыдущее if (CutOff < MSMatches.Count - 1) { MSMatches[CutOff + 1].Score = 0.0; MSMatches.RemoveRange(CutOff + 2, IntCount - CutOff - 1); } } } this.Estimate(IsotopeRatio); Ext.Estimate(Ext.IsotopeRatio); }
public static double Convolution(QMatch Match1, QMatch Match2, double Shift) { QMatch MatchTemp = null; //ставим первой ту что начинается раньше double Shift1 = Shift; double Shift2 = 0.0; if (Match1.MSMatches[0].RT + Shift1 >= Match2.MSMatches[0].RT) { MatchTemp = Match1; Match1 = Match2; Match2 = MatchTemp; Shift2 = Shift; Shift1 = 0.0; } if (Match1.MSMatches[Match1.MSMatches.Count - 1].RT + Shift1 <= Match2.MSMatches[0].RT + Shift2) { return(0.0); } List <Intervs> Ints = new List <Intervs>(); Intervs Interv; int i1 = 0, i2 = 0; double max1 = 0.0, max2 = 0.0; double sum1 = 0.0, sum2 = 0.0; //первый цикл - один QMatch активен //убираем влияние временного коэффициэнта for (i1 = 0; i1 < Match1.MSMatches.Count; i1++) { Match1.MSMatches[i1].Score = Match1.MSMatches[i1].Score / Match1.MSMatches[i1].TimeCoeff; } for (i2 = 0; i2 < Match2.MSMatches.Count; i2++) { Match2.MSMatches[i2].Score = Match2.MSMatches[i2].Score / Match2.MSMatches[i2].TimeCoeff; } i1 = 0; i2 = 0; do { Interv = new Intervs(); Interv.RT = Match1.MSMatches[i1].RT + Shift1; Interv.Value1 = Match1.MSMatches[i1].Score; Interv.Value2 = 0.0; Ints.Add(Interv); max1 = Match1.MSMatches[i1].Score > max1 ? Match1.MSMatches[i1].Score : max1; sum1 += Match1.MSMatches[i1].Score * Match1.MSMatches[i1].TimeCoeff; i1++; }while (Match1.MSMatches[i1].RT + Shift1 < Match2.MSMatches[0].RT + Shift2); //средний цикл - оба активны do { //считаем значения в точках Interv = new Intervs(); if (Match1.MSMatches[i1].RT + Shift1 < Match2.MSMatches[i2].RT + Shift2) { max1 = Match1.MSMatches[i1].Score > max1 ? Match1.MSMatches[i1].Score : max1; sum1 += Match1.MSMatches[i1].Score * Match1.MSMatches[i1].TimeCoeff; Interv.RT = Match1.MSMatches[i1].RT + Shift1; Interv.Value1 = Match1.MSMatches[i1].Score; //аппроксимированные значения double RTRatio = ((Match1.MSMatches[i1].RT + Shift1) - (Match2.MSMatches[i2 - 1].RT + Shift2)) / ((Match2.MSMatches[i2].RT + Shift2) - (Match2.MSMatches[i2 - 1].RT + Shift2)); Interv.Value2 = Match2.MSMatches[i2 - 1].Score + RTRatio * (Match2.MSMatches[i2].Score - Match2.MSMatches[i2 - 1].Score); i1++; if (i1 >= Match1.MSMatches.Count) { break; } } else { max2 = Match2.MSMatches[i2].Score > max2 ? Match2.MSMatches[i2].Score : max2; sum2 += Match2.MSMatches[i2].Score * Match2.MSMatches[i2].TimeCoeff; Interv.RT = Match2.MSMatches[i2].RT + Shift2; Interv.Value2 = Match2.MSMatches[i2].Score; //аппроксимированные значения double RTRatio = ((Match2.MSMatches[i2].RT + Shift2) - (Match1.MSMatches[i1 - 1].RT + Shift1)) / ((Match1.MSMatches[i1].RT + Shift1) - (Match1.MSMatches[i1 - 1].RT + Shift1)); Interv.Value1 = Match1.MSMatches[i1 - 1].Score + RTRatio * (Match1.MSMatches[i1].Score - Match1.MSMatches[i1 - 1].Score); i2++; } Ints.Add(Interv); }while(((Match1.MSMatches[i1 - 1].Score > 0.0) || (max1 == 0.0)) && //мы только что обработали нулевую точку с дальнего конца ((Match2.MSMatches[i2 - 1].Score > 0.0) || (max2 == 0.0))); //пройдена хотя по одной значащей точке в Match1 и Match2 //последний цикл - опять только один активен if (i1 == Match1.MSMatches.Count) { //остался только второй for ( ; i2 < Match2.MSMatches.Count; i2++) { Interv = new Intervs(); Interv.RT = Match2.MSMatches[i2].RT + Shift2; Interv.Value1 = 0.0; Interv.Value2 = Match2.MSMatches[i2].Score; Ints.Add(Interv); max2 = Match2.MSMatches[i2].Score > max2 ? Match2.MSMatches[i2].Score : max2; sum2 += Match2.MSMatches[i2].Score * Match2.MSMatches[i2].TimeCoeff; } } else { //остался только первый for ( ; i1 < Match1.MSMatches.Count; i1++) { Interv = new Intervs(); Interv.RT = Match1.MSMatches[i1].RT + Shift1; Interv.Value1 = Match1.MSMatches[i1].Score; Interv.Value2 = 0.0; Ints.Add(Interv); max1 = Match1.MSMatches[i1].Score > max1 ? Match1.MSMatches[i1].Score : max1; sum1 += Match1.MSMatches[i1].Score * Match1.MSMatches[i1].TimeCoeff; } } //возвращаем временной коэффициэнт for (i1 = 0; i1 < Match1.MSMatches.Count; i1++) { Match1.MSMatches[i1].Score = Match1.MSMatches[i1].Score * Match1.MSMatches[i1].TimeCoeff; } for (i2 = 0; i2 < Match2.MSMatches.Count; i2++) { Match2.MSMatches[i2].Score = Match2.MSMatches[i2].Score * Match2.MSMatches[i2].TimeCoeff; } //Применяем максимум //double Ratio = max2 /max1; double Ratio = sum2 / sum1; for (int i = 0; i < Ints.Count; i++) { Interv = Ints[i]; Interv.Value1 *= Ratio; Ints[i] = Interv; } //вычисление свертки double Union = 0.0, Cross = 0.0; for (int i = 0; i < Ints.Count - 1; i++) { //полные площади double S10 = (Ints[i + 1].RT - Ints[i].RT) * (Ints[i + 1].Value2 + Ints[i].Value2) / 2; double S20 = (Ints[i + 1].RT - Ints[i].RT) * (Ints[i + 1].Value1 + Ints[i].Value1) / 2; double Sign = (Ints[i].Value1 - Ints[i].Value2) * (Ints[i + 1].Value1 - Ints[i + 1].Value2); if (Sign >= 0.0) //не пересекаются { Cross += Math.Min(S10, S20); Union += Math.Max(S10, S20); } else //пересекаются //смысл коэффициэнтов - смотри в тетрадке { double Prop = (Ints[i].Value2 - Ints[i].Value1) / (Ints[i + 1].Value1 - Ints[i + 1].Value2); double l2 = (Ints[i + 1].RT - Ints[i].RT) / (1 + Prop); double l1 = l2 * Prop; //if (Ints[i].Value1 > Ints[i+1].Value1){ double buf = l1; l1=l2; l2 = buf; } double S1 = Math.Abs(Ints[i].Value2 - Ints[i].Value1) * l1 / 2; double S2 = Math.Abs(Ints[i + 1].Value1 - Ints[i + 1].Value2) * l2 / 2; double S0; if (Ints[i].Value1 < Ints[i].Value2) //if (a1>b1) { S0 = S10 - S1; } else { S0 = S20 - S1; } Cross += S0; Union += S0 + S1 + S2; } } return(Cross / Union); }
public QMatch FindBestScore(double MZ, int Charge, double IsoRatio, double MinRT, double MaxRT) { MSMatch First = null, Best = null; QMatch Res = new QMatch(); Res.Clean(); Res.MSMatches = new List <MSMatch>(); double FirstIso = 0.0, SecondIso = 0.0; double BestScore = 0.0, fs = 0.0; int BestIndex = 0; int Scan = 0; double AveRT = (MinRT + MaxRT) / 2; RawFile.ScanNumFromRT(AveRT, ref Scan); Scan = ms2index[Scan]; //отступаем до минимального времени RT в массиве спектров double LowMZ = (MZ * Charge + (float)1.007277) / (Charge + 1); double HighMZ; if (Charge > 1) { HighMZ = (MZ * Charge - 1.007277) / (Charge - 1); } else { HighMZ = 0.0; } while (Scan > 0 && RawSpectra[Scan].RT >= MinRT) { Scan = IndexRev[Scan]; } //цикл поиска лучшего while (Scan != -1 && RawSpectra[Scan].RT <= MaxRT) { if (Settings.Default.Deconvolution) //прихватываем другие зарядовые состояния { First = FindMatchwithCharges(Scan, MZ, Charge, LowMZ, HighMZ); } else { First = FindMatch(Scan, MZ, Charge); } //если не найден сам пик или его первый изотоп - сбрасываем if (First.Score == 0.0 || First.SecondIsotope == 0.0) { Scan = IndexDir[Scan]; continue; } FirstIso = First.FirstIsotope + (First.UpperCharges == null ? 0 : First.UpperCharges.FirstIsotope) + (First.LowerCharges == null ? 0 : First.LowerCharges.FirstIsotope); SecondIso = First.SecondIsotope + (First.UpperCharges == null ? 0 : First.UpperCharges.SecondIsotope) + (First.LowerCharges == null ? 0 : First.LowerCharges.SecondIsotope); fs = SecondIso / FirstIso; double CurrentScore = First.Score + (First.UpperCharges == null ? 0 : First.UpperCharges.Score) + (First.LowerCharges == null ? 0 : First.LowerCharges.Score); //пик может распространяться за границы, но апекс должен быть внутри if (CurrentScore > BestScore && fs > IsoRatio * 0.5 && fs < IsoRatio * 2) { BestScore = CurrentScore; BestIndex = Scan; Best = First; } //переходим к следующему full-ms Scan = IndexDir[Scan]; } if (BestScore == 0.0) { return(null); } //если хоть что-то нашли //добавляем наибольшее LowMZ = (Best.MZ * Charge + (float)1.007277) / (Charge + 1); if (Charge > 1) { HighMZ = (MZ * Charge - 1.007277) / (Charge - 1); } else { HighMZ = 0.0; } Res.ApexRT = Best.RT; Res.MSMatches.Add(Best); //берем сплошную область вокруг Best - вперед for (Scan = IndexDir[BestIndex]; Scan > 0; Scan = IndexDir[Scan]) { if (Settings.Default.Deconvolution) //прихватываем другие зарядовые состояния { First = FindMatchwithCharges(Scan, Best.MZ, Charge, LowMZ, HighMZ); } else { First = FindMatch(Scan, Best.MZ, Charge); } if (First.Score == 0.0 || First.SecondIsotope == 0.0) { Res.MSMatches.Add(First); break; } fs = First.SecondIsotope / First.FirstIsotope; //включаем здесь контроль по соотношению изотопов //if (fs < IsoRatio*0.5 || fs > IsoRatio * 2 ){ // break; //} Res.MSMatches.Add(First); } //берем сплошную область вокруг Best - назад for (Scan = IndexRev[BestIndex]; Scan > 0; Scan = IndexRev[Scan]) { if (Settings.Default.Deconvolution) //прихватываем другие зарядовые состояния { First = FindMatchwithCharges(Scan, Best.MZ, Charge, LowMZ, HighMZ); } else { First = FindMatch(Scan, Best.MZ, Charge); } if (First.Score == 0.0 || First.SecondIsotope == 0.0) { Res.MSMatches.Add(First); break; } fs = First.SecondIsotope / First.FirstIsotope; //включаем здесь контроль по соотношению изотопов //if (fs < IsoRatio*0.5 || fs > IsoRatio * 2 ){ // break; //} Res.MSMatches.Insert(0, First); } Res.Estimate(IsoRatio); Res.CleanUp(); return(Res); }
public void CutTails1(QMatch Ext) { double Shift0 = ApexRT - Ext.ApexRT; double Shift = -Ext.Shift; double Temp; int i; if (MSMatches == null || Ext.MSMatches == null) { return; } //сортируем //передние хвосты if (MSMatches[0].RT - Shift > Ext.MSMatches[0].RT) { //наш хвост короче for (i = 1; i < Ext.MSMatches.Count; i++) { if (MSMatches[0].RT - Shift < Ext.MSMatches[i].RT) { break; } } if (i < Ext.MSMatches.Count) { Ext.MSMatches.RemoveRange(0, i - 1); //ноль будет объявлен там же где и ноль у образца Temp = ((MSMatches[0].RT - Shift) - Ext.MSMatches[0].RT) / 2; Ext.MSMatches[0].RT = MSMatches[0].RT - Shift; Ext.MSMatches[0].Score = 0.0; Ext.MSMatches[1].RT = Ext.MSMatches[1].RT + Temp; // CutOff = (Math.Abs(MSMatches[0].RT - Shift - Ext.MSMatches[i].RT) < Math.Abs(MSMatches[0].RT - Shift - Ext.MSMatches[i-1].RT))?i:i-1; // Ext.MSMatches.RemoveRange(0,CutOff); } } else { //их хвост короче for (i = 1; i < MSMatches.Count; i++) { if (Ext.MSMatches[0].RT + Shift < MSMatches[i].RT) { break; } } if (i < MSMatches.Count) { MSMatches.RemoveRange(0, i - 1); //ноль будет объявлен там же где и ноль у образца Temp = (Ext.MSMatches[0].RT - (MSMatches[0].RT - Shift)) / 2; MSMatches[0].RT = Ext.MSMatches[0].RT + Shift; MSMatches[0].Score = 0.0; MSMatches[1].RT = MSMatches[1].RT + Temp; //CutOff = (Math.Abs(MSMatches[i].RT - Shift - Ext.MSMatches[0].RT) < Math.Abs(MSMatches[i-1].RT - Shift - Ext.MSMatches[0].RT))?i:i-1; //MSMatches.RemoveRange(0,CutOff); } } //задние хвосты int IntCount = MSMatches.Count - 1; int ExtCount = Ext.MSMatches.Count - 1; if (MSMatches[IntCount].RT - Shift < Ext.MSMatches[ExtCount].RT) { //наш хвост короче for (i = ExtCount - 1; i >= 0; i--) { if (MSMatches[IntCount].RT - Shift > Ext.MSMatches[i].RT) { break; } } if (i >= 0) { Ext.MSMatches.RemoveRange(i + 2, Ext.MSMatches.Count - i - 2); //ноль будет объявлен там же где и ноль у образца Temp = ((MSMatches[MSMatches.Count - 1].RT - Shift) - Ext.MSMatches[Ext.MSMatches.Count - 1].RT) / 2; Ext.MSMatches[Ext.MSMatches.Count - 1].RT = MSMatches[MSMatches.Count - 1].RT - Shift; Ext.MSMatches[Ext.MSMatches.Count - 1].Score = 0.0; Ext.MSMatches[Ext.MSMatches.Count - 2].RT = Ext.MSMatches[Ext.MSMatches.Count - 2].RT + Temp; //CutOff = (Math.Abs(MSMatches[IntCount].RT - Shift - Ext.MSMatches[i].RT) < Math.Abs(MSMatches[IntCount].RT - Shift - Ext.MSMatches[i+1].RT))?i:i+1; //Ext.MSMatches.RemoveRange(CutOff+1, ExtCount-CutOff); } } else { //их хвост короче for (i = IntCount - 1; i >= 0; i--) { if (Ext.MSMatches[ExtCount].RT + Shift > MSMatches[i].RT) { break; } } if (i >= 0) { MSMatches.RemoveRange(i + 2, MSMatches.Count - i - 2); //ноль будет объявлен там же где и ноль у образца Temp = (Ext.MSMatches[Ext.MSMatches.Count - 1].RT - (MSMatches[MSMatches.Count - 1].RT - Shift)) / 2; MSMatches[MSMatches.Count - 1].RT = Ext.MSMatches[Ext.MSMatches.Count - 1].RT + Shift; MSMatches[MSMatches.Count - 1].Score = 0.0; MSMatches[MSMatches.Count - 2].RT = MSMatches[MSMatches.Count - 2].RT + Temp; //CutOff = (Math.Abs(MSMatches[i].RT - Shift - Ext.MSMatches[ExtCount].RT) < Math.Abs(MSMatches[i+1].RT - Shift - Ext.MSMatches[ExtCount].RT))?i:i+1; //MSMatches.RemoveRange(CutOff+1, IntCount-CutOff); } } this.Estimate(IsotopeRatio); Ext.Estimate(Ext.IsotopeRatio); }