public static void CalibrationTestLowRes()
        {
            CalibrationTask calibrationTask = new CalibrationTask();

            EngineLayer.CommonParameters CommonParameters = new EngineLayer.CommonParameters
                                                                (dissociationType: MassSpectrometry.DissociationType.LowCID,
                                                                scoreCutoff: 1);

            string outputFolder = Path.Combine(TestContext.CurrentContext.TestDirectory, @"TestCalibrationLow");
            string myFile       = Path.Combine(TestContext.CurrentContext.TestDirectory, @"TestData\sliced_b6.mzML");
            string myDatabase   = Path.Combine(TestContext.CurrentContext.TestDirectory, @"TestData\LowResSnip_B6_mouse_11700_117500pruned.xml");

            Directory.CreateDirectory(outputFolder);

            calibrationTask.RunTask(outputFolder, new List <DbForTask> {
                new DbForTask(myDatabase, false)
            }, new List <string> {
                myFile
            }, "test");
            Assert.That(File.Exists(Path.Combine(outputFolder, @"sliced_b6-calib.mzML")));
            Assert.That(File.Exists(Path.Combine(outputFolder, @"sliced_b6-calib.toml")));
            var lines      = File.ReadAllLines(Path.Combine(outputFolder, @"sliced_b6-calib.toml"));
            var tolerance  = Regex.Match(lines[0], @"\d+\.\d*").Value;
            var tolerance1 = Regex.Match(lines[1], @"\d+\.\d*").Value;

            Assert.That(double.TryParse(tolerance, out double tol) == true);
            Assert.That(double.TryParse(tolerance1, out double tol1) == true);
            Assert.That(lines[0].Contains("PrecursorMassTolerance"));
            Assert.That(lines[1].Contains("ProductMassTolerance"));
            Directory.Delete(outputFolder, true);
            Directory.Delete(Path.Combine(TestContext.CurrentContext.TestDirectory, @"Task Settings"), true);
        }
Exemple #2
0
 public ProteinScoringAndFdrEngine(List <ProteinGroup> proteinGroups, List <PeptideSpectralMatch> newPsms, bool noOneHitWonders, bool treatModPeptidesAsDifferentPeptides, bool mergeIndistinguishableProteinGroups, CommonParameters commonParameters, List <string> nestedIds) : base(commonParameters, nestedIds)
 {
     NewPsms         = newPsms;
     ProteinGroups   = proteinGroups;
     NoOneHitWonders = noOneHitWonders;
     TreatModPeptidesAsDifferentPeptides = treatModPeptidesAsDifferentPeptides;
     MergeIndistinguishableProteinGroups = mergeIndistinguishableProteinGroups;
 }
        public static IsotopicEnvelope[] GetNeutralExperimentalFragments(MsDataScan scan, CommonParameters commonParam)
        {
            int minZ = 1;
            int maxZ = 10;

            var neutralExperimentalFragmentMasses = scan.MassSpectrum.Deconvolute(scan.MassSpectrum.Range,
                                                                                  minZ, maxZ, commonParam.DeconvolutionMassTolerance.Value, commonParam.DeconvolutionIntensityRatio).ToList();

            if (commonParam.AssumeOrphanPeaksAreZ1Fragments)
            {
                HashSet <double> alreadyClaimedMzs = new HashSet <double>(neutralExperimentalFragmentMasses
                                                                          .SelectMany(p => p.peaks.Select(v => ClassExtensions.RoundedDouble(v.mz).Value)));

                for (int i = 0; i < scan.MassSpectrum.XArray.Length; i++)
                {
                    double mz        = scan.MassSpectrum.XArray[i];
                    double intensity = scan.MassSpectrum.YArray[i];

                    if (!alreadyClaimedMzs.Contains(ClassExtensions.RoundedDouble(mz).Value))
                    {
                        neutralExperimentalFragmentMasses.Add(new IsotopicEnvelope(
                                                                  new List <(double mz, double intensity)> {
                            (mz, intensity)
                        },
                                                                  mz.ToMass(1), 1, intensity, 0, 0));
                    }
                }
            }

            return(neutralExperimentalFragmentMasses.OrderBy(p => p.monoisotopicMass).ToArray());
        }
        public Ms2ScanWithSpecificMass(MsDataScan mzLibScan, double precursorMonoisotopicPeakMz, int precursorCharge, string fullFilePath, CommonParameters commonParam, IsotopicEnvelope[] neutralExperimentalFragments = null)
        {
            PrecursorMonoisotopicPeakMz = precursorMonoisotopicPeakMz;
            PrecursorCharge             = precursorCharge;
            PrecursorMass = PrecursorMonoisotopicPeakMz.ToMass(precursorCharge);
            FullFilePath  = fullFilePath;
            ChildScans    = new List <Ms2ScanWithSpecificMass>();
            NativeId      = mzLibScan.NativeId;

            TheScan = mzLibScan;

            ExperimentalFragments = neutralExperimentalFragments ?? GetNeutralExperimentalFragments(mzLibScan, commonParam);

            if (ExperimentalFragments.Any())
            {
                DeconvolutedMonoisotopicMasses = ExperimentalFragments.Select(p => p.monoisotopicMass).ToArray();
            }
            else
            {
                DeconvolutedMonoisotopicMasses = new double[0];
            }
        }
Exemple #5
0
        public ProteinParsimonyEngine(List <PeptideSpectralMatch> allPsms, bool modPeptidesAreDifferent, CommonParameters commonParameters, List <string> nestedIds) : base(commonParameters, nestedIds)
        {
            _treatModPeptidesAsDifferentPeptides = modPeptidesAreDifferent;

            if (!allPsms.Any())
            {
                _fdrFilteredPsms = new List <PeptideSpectralMatch>();
            }

            // parsimony will only use non-ambiguous, high-confidence PSMs
            // KEEP decoys and contaminants for use in parsimony!
            if (modPeptidesAreDifferent)
            {
                _fdrFilteredPsms = allPsms.Where(p => p.FullSequence != null && p.FdrInfo.QValue <= FdrCutoffForParsimony && p.FdrInfo.QValueNotch <= FdrCutoffForParsimony).ToList();
            }
            else
            {
                _fdrFilteredPsms = allPsms.Where(p => p.BaseSequence != null && p.FdrInfo.QValue <= FdrCutoffForParsimony && p.FdrInfo.QValueNotch <= FdrCutoffForParsimony).ToList();
            }

            // if PSM is a decoy, add only decoy sequences; same for contaminants
            // peptides to use in parsimony = peptides observed in high-confidence PSMs
            _fdrFilteredPeptides = new HashSet <PeptideWithSetModifications>();

            foreach (var psm in _fdrFilteredPsms)
            {
                if (psm.IsDecoy)
                {
                    foreach (var peptide in psm.BestMatchingPeptides.Select(p => p.Peptide).Where(p => p.Protein.IsDecoy))
                    {
                        _fdrFilteredPeptides.Add(peptide);
                    }
                }
                else if (psm.IsContaminant)
                {
                    foreach (var peptide in psm.BestMatchingPeptides.Select(p => p.Peptide).Where(p => p.Protein.IsContaminant))
                    {
                        _fdrFilteredPeptides.Add(peptide);
                    }
                }
                else // PSM is target
                {
                    foreach (var peptide in psm.BestMatchingPeptides.Select(p => p.Peptide).Where(p => !p.Protein.IsDecoy && !p.Protein.IsContaminant))
                    {
                        _fdrFilteredPeptides.Add(peptide);
                    }
                }
            }

            // we're storing all PSMs (not just FDR-filtered ones) here because we will remove some protein associations
            // from low-confidence PSMs if they can be explained by a parsimonious protein
            _allPsms = allPsms;
        }
Exemple #6
0
        /// <summary>
        /// Calculates the spectral angle, as described by Prosit ( https://www.nature.com/articles/s41592-019-0426-7 ).
        /// </summary>
        public static double CalculateNormalizedSpectralAngle(List <MatchedFragmentIon> theoreticalLibraryIons, MsDataScan scan, CommonParameters commonParameters)
        {
            double mzCutoff             = 300;
            int    fragmentNumberCutoff = 3;

            // if the spectrum has no peaks
            if (scan.MassSpectrum.XArray.Length == 0)
            {
                return(0);
            }

            Dictionary <MatchedFragmentIon, MatchedFragmentIon> matchedIons = new Dictionary <MatchedFragmentIon, MatchedFragmentIon>();

            // search for each theoretical ion
            for (int i = 0; i < theoreticalLibraryIons.Count; i++)
            {
                var libraryIon = theoreticalLibraryIons[i];

                // see https://www.nature.com/articles/s41592-019-0426-7
                // "All non-zero fragment ions (m/z > 300, ion >3, no neutral loss fragment ions) were considered for spectral angle calculation"
                if (libraryIon.Mz <= mzCutoff || libraryIon.NeutralTheoreticalProduct.FragmentNumber <= fragmentNumberCutoff)
                {
                    continue;
                }

                // get the closest peak in the spectrum to the library peak
                var    closestPeakIndex = scan.MassSpectrum.GetClosestPeakIndex(libraryIon.Mz);
                double mz = scan.MassSpectrum.XArray[closestPeakIndex];
                double experimentalIntensity = scan.MassSpectrum.YArray[closestPeakIndex];

                // is the mass error acceptable?
                if (commonParameters.ProductMassTolerance.Within(mz.ToMass(libraryIon.Charge), libraryIon.Mz.ToMass(libraryIon.Charge)))
                {
                    var test = new Product(libraryIon.NeutralTheoreticalProduct.ProductType, libraryIon.NeutralTheoreticalProduct.Terminus,
                                           libraryIon.NeutralTheoreticalProduct.NeutralMass, libraryIon.NeutralTheoreticalProduct.FragmentNumber,
                                           libraryIon.NeutralTheoreticalProduct.AminoAcidPosition, libraryIon.NeutralTheoreticalProduct.NeutralLoss);
                    matchedIons.Add(libraryIon, new MatchedFragmentIon(ref test, mz, experimentalIntensity, libraryIon.Charge));
                }
            }

            // L2 norm
            double expNormalizer   = Math.Sqrt(matchedIons.Sum(p => Math.Pow(p.Value.Intensity, 2)));
            double theorNormalizer = Math.Sqrt(theoreticalLibraryIons.Sum(p => Math.Pow(p.Intensity, 2)));

            double dotProduct = 0;

            foreach (var libraryIon in theoreticalLibraryIons)
            {
                if (matchedIons.TryGetValue(libraryIon, out var experIon))
                {
                    dotProduct += (libraryIon.Intensity / theorNormalizer) * (experIon.Intensity / expNormalizer);
                }
            }

            double normalizedSpectralAngle = 1 - (2 * Math.Acos(dotProduct) / Math.PI);

            return(normalizedSpectralAngle);
        }
Exemple #7
0
 public SequencesToActualProteinPeptidesEngine(List <PeptideSpectralMatch> allPsms, List <Protein> proteinList, List <ModificationWithMass> fixedModifications, List <ModificationWithMass> variableModifications, List <ProductType> ionTypes, IEnumerable <DigestionParams> collectionOfDigestionParams, bool reportAllAmbiguity, CommonParameters commonParameters, List <string> nestedIds) : base(commonParameters, nestedIds)
 {
     Proteins                    = proteinList;
     AllPsms                     = allPsms;
     FixedModifications          = fixedModifications;
     VariableModifications       = variableModifications;
     TerminusType                = ProductTypeMethods.IdentifyTerminusType(ionTypes);
     CollectionOfDigestionParams = collectionOfDigestionParams;
     ReportAllAmbiguity          = reportAllAmbiguity;
 }
 public ProteinParsimonyEngine(List <PeptideSpectralMatch> allPsms, bool modPeptidesAreDifferent, CommonParameters commonParameters, List <(string fileName, CommonParameters fileSpecificParameters)> fileSpecificParameters, List <string> nestedIds) : base(commonParameters, fileSpecificParameters, nestedIds)
Exemple #9
0
        public static void CalculateSpectralAngles(SpectralLibrary spectralLibrary, PeptideSpectralMatch[] peptideSpectralMatches,
                                                   Ms2ScanWithSpecificMass[] arrayOfSortedMs2Scans, CommonParameters commonParameters)
        {
            foreach (PeptideSpectralMatch psm in peptideSpectralMatches.Where(p => p != null))
            {
                Ms2ScanWithSpecificMass scan = arrayOfSortedMs2Scans[psm.ScanIndex];

                //TODO: spectral angle could be used to disambiguate PSMs. right now for ambiguous PSMs, the spectral angle for only one peptide option is saved
                foreach (var peptide in psm.PeptidesToMatchingFragments)
                {
                    if (spectralLibrary == null || !spectralLibrary.TryGetSpectrum(peptide.Key.FullSequence, scan.PrecursorCharge, out var librarySpectrum))
                    {
                        continue;
                    }

                    double spectralAngle = CalculateNormalizedSpectralAngle(librarySpectrum.MatchedFragmentIons, scan.TheScan, commonParameters);

                    psm.SpectralAngle = spectralAngle;
                }
            }
        }
Exemple #10
0
        public static List <MatchedFragmentIon> MatchFragmentIons(MzSpectrum spectrum, List <TheoreticalFragmentIon> theoreticalFragmentIons, CommonParameters commonParameters)
        {
            var matchedFragmentIons = new List <MatchedFragmentIon>();
            var alreadyCountedMzs   = new HashSet <double>();

            // if the spectrum has no peaks
            if (spectrum.Size == 0)
            {
                return(matchedFragmentIons);
            }

            //search for ions in the spectrum
            foreach (var tIon in theoreticalFragmentIons)
            {
                // unknown fragment mass; this only happens rarely for sequences with unknown amino acids
                if (double.IsNaN(tIon.Mass))
                {
                    continue;
                }

                // get the closest peak in the spectrum to the theoretical peak
                int matchedPeakIndex = spectrum.GetClosestPeakIndex(tIon.Mz).Value;

                double mz        = spectrum.XArray[matchedPeakIndex];
                double intensity = spectrum.YArray[matchedPeakIndex];

                // is the mass error acceptable and has it been counted already?
                if (commonParameters.ProductMassTolerance.Within(mz.ToMass(tIon.Charge), tIon.Mass) && !alreadyCountedMzs.Contains(mz))
                {
                    matchedFragmentIons.Add(new MatchedFragmentIon(tIon, mz, intensity));
                    alreadyCountedMzs.Add(mz);
                }
            }

            return(matchedFragmentIons);
        }
Exemple #11
0
 protected MetaMorpheusEngine(CommonParameters commonParameters, List <string> nestedIds)
 {
     this.commonParameters = commonParameters;
     this.nestedIds        = nestedIds;
 }
Exemple #12
0
        public static void CalculateSpectralAngles(SpectralLibrary spectralLibrary, PeptideSpectralMatch[] psms,
                                                   Ms2ScanWithSpecificMass[] arrayOfSortedMs2Scans, CommonParameters commonParameters)
        {
            if (spectralLibrary != null)
            {
                // one lock for each MS2 scan; a scan can only be accessed by one thread at a time
                var myLocks = new object[psms.Length];
                for (int i = 0; i < myLocks.Length; i++)
                {
                    myLocks[i] = new object();
                }

                int   maxThreadsPerFile = commonParameters.MaxThreadsToUsePerFile;
                int[] threads           = Enumerable.Range(0, maxThreadsPerFile).ToArray();
                Parallel.ForEach(threads, (i) =>
                {
                    // Stop loop if canceled
                    if (GlobalVariables.StopLoops)
                    {
                        return;
                    }
                    for (; i < psms.Length; i += maxThreadsPerFile)
                    {
                        lock (myLocks[i])
                        {
                            if (psms[i] != null)
                            {
                                Ms2ScanWithSpecificMass scan = arrayOfSortedMs2Scans[psms[i].ScanIndex];
                                List <(int, PeptideWithSetModifications)> pwsms = new();
                                List <double> pwsmSpectralAngles = new();
                                foreach (var(Notch, Peptide) in psms[i].BestMatchingPeptides)
                                {
                                    //if peptide is target, directly look for the target's spectrum in the spectral library
                                    if (!Peptide.Protein.IsDecoy && spectralLibrary.TryGetSpectrum(Peptide.FullSequence, scan.PrecursorCharge, out var librarySpectrum))
                                    {
                                        SpectralSimilarity s = new SpectralSimilarity(scan.TheScan.MassSpectrum, librarySpectrum.XArray, librarySpectrum.YArray, SpectralSimilarity.SpectrumNormalizationScheme.squareRootSpectrumSum, commonParameters.ProductMassTolerance.Value, false);
                                        if (s.SpectralContrastAngle().HasValue)
                                        {
                                            pwsms.Add((Notch, Peptide));
                                            pwsmSpectralAngles.Add((double)s.SpectralContrastAngle());
                                        }
                                    }

                                    //if peptide is decoy, look for the decoy's corresponding target's spectrum in the spectral library and generate decoy spectrum by function GetDecoyLibrarySpectrumFromTargetByRevers
                                    else if (Peptide.Protein.IsDecoy && spectralLibrary.TryGetSpectrum(Peptide.PeptideDescription, scan.PrecursorCharge, out var targetlibrarySpectrum))
                                    {
                                        var decoyPeptideTheorProducts = new List <Product>();
                                        Peptide.Fragment(commonParameters.DissociationType, commonParameters.DigestionParams.FragmentationTerminus, decoyPeptideTheorProducts);
                                        var decoylibrarySpectrum = GetDecoyLibrarySpectrumFromTargetByReverse(targetlibrarySpectrum, decoyPeptideTheorProducts);
                                        SpectralSimilarity s     = new SpectralSimilarity(scan.TheScan.MassSpectrum, decoylibrarySpectrum.Select(x => x.Mz).ToArray(), decoylibrarySpectrum.Select(x => x.Intensity).ToArray(), SpectralSimilarity.SpectrumNormalizationScheme.squareRootSpectrumSum, commonParameters.ProductMassTolerance.Value, false);
                                        if (s.SpectralContrastAngle().HasValue)
                                        {
                                            pwsms.Add((Notch, Peptide));
                                            pwsmSpectralAngles.Add((double)s.SpectralContrastAngle());
                                        }
                                    }
                                }
                                if (pwsmSpectralAngles.Count > 0 && !pwsmSpectralAngles.Max().Equals(null))
                                {
                                    psms[i].SpectralAngle = pwsmSpectralAngles.Max();
                                }
                                else
                                {
                                    psms[i].SpectralAngle = -1;
                                }
                            }
                        }
 public ProteinParsimonyEngine(Dictionary <CompactPeptideBase, HashSet <PeptideWithSetModifications> > compactPeptideToProteinPeptideMatching, bool modPeptidesAreDifferent, CommonParameters commonParameters, List <string> nestedIds) : base(commonParameters, nestedIds)
 {
     TreatModPeptidesAsDifferentPeptides    = modPeptidesAreDifferent;
     CompactPeptideToProteinPeptideMatching = compactPeptideToProteinPeptideMatching;
     ListOfDigestionParams = new HashSet <DigestionParams>(compactPeptideToProteinPeptideMatching.Values.SelectMany(p => p.Select(v => v.DigestionParams)));
 }
Exemple #14
0
        public static List <MatchedFragmentIon> MatchFragmentIons(Ms2ScanWithSpecificMass scan, List <Product> theoreticalProducts, CommonParameters commonParameters)
        {
            var matchedFragmentIons = new List <MatchedFragmentIon>();

            // if the spectrum has no peaks
            if (!scan.ExperimentalFragments.Any())
            {
                return(matchedFragmentIons);
            }

            if (scan.TheScan.MassSpectrum.XcorrProcessed)
            {
                foreach (Product product in theoreticalProducts)
                {
                    // unknown fragment mass; this only happens rarely for sequences with unknown amino acids
                    if (double.IsNaN(product.NeutralMass))
                    {
                        continue;
                    }

                    double theoreticalFragmentMz = Math.Round(product.NeutralMass.ToMz(1) / 1.0005079, 0) * 1.0005079;
                    var    closestMzIndex        = scan.TheScan.MassSpectrum.GetClosestPeakIndex(theoreticalFragmentMz).Value;

                    if (commonParameters.ProductMassTolerance.Within(scan.TheScan.MassSpectrum.XArray[closestMzIndex], theoreticalFragmentMz))
                    {
                        matchedFragmentIons.Add(new MatchedFragmentIon(product, theoreticalFragmentMz, scan.TheScan.MassSpectrum.YArray[closestMzIndex], 1));
                    }
                }

                return(matchedFragmentIons);
            }

            // search for ions in the spectrum
            foreach (Product product in theoreticalProducts)
            {
                // unknown fragment mass; this only happens rarely for sequences with unknown amino acids
                if (double.IsNaN(product.NeutralMass))
                {
                    continue;
                }

                // get the closest peak in the spectrum to the theoretical peak
                var closestExperimentalMass = scan.GetClosestExperimentalFragmentMass(product.NeutralMass);

                // is the mass error acceptable?
                if (commonParameters.ProductMassTolerance.Within(closestExperimentalMass.monoisotopicMass, product.NeutralMass) && closestExperimentalMass.charge <= scan.PrecursorCharge)
                {
                    matchedFragmentIons.Add(new MatchedFragmentIon(product, closestExperimentalMass.monoisotopicMass.ToMz(closestExperimentalMass.charge),
                                                                   closestExperimentalMass.peaks.First().intensity, closestExperimentalMass.charge));
                }
            }
            if (commonParameters.AddCompIons)
            {
                double protonMassShift = complementaryIonConversionDictionary[commonParameters.DissociationType].ToMass(1);

                foreach (Product product in theoreticalProducts)
                {
                    // unknown fragment mass or diagnostic ion or precursor; skip those
                    if (double.IsNaN(product.NeutralMass) || product.ProductType == ProductType.D || product.ProductType == ProductType.M)
                    {
                        continue;
                    }

                    double compIonMass = scan.PrecursorMass + protonMassShift - product.NeutralMass;

                    // get the closest peak in the spectrum to the theoretical peak
                    var closestExperimentalMass = scan.GetClosestExperimentalFragmentMass(compIonMass);

                    // is the mass error acceptable?
                    if (commonParameters.ProductMassTolerance.Within(closestExperimentalMass.monoisotopicMass, compIonMass) && closestExperimentalMass.charge <= scan.PrecursorCharge)
                    {
                        matchedFragmentIons.Add(new MatchedFragmentIon(product, closestExperimentalMass.monoisotopicMass.ToMz(closestExperimentalMass.charge),
                                                                       closestExperimentalMass.totalIntensity, closestExperimentalMass.charge));
                    }
                }
            }

            return(matchedFragmentIons);
        }