public static void WriteNDPResultForSytoscape(List <SpectrumData> allSpecList, string outputPath)    //output NDP for Sytoscape input
 {
     using (StreamWriter sw = new StreamWriter(outputPath)) {
         for (int i = 0; i < allSpecList.Count - 1; i++)
         {
             for (int j = i + 1; j < allSpecList.Count; j++)
             {
                 double ndp = Cal_Cosine_Product.CalCosineProduct(allSpecList[i], allSpecList[j]);
                 if (ndp >= 0.01)
                 {
                     List <double> commonNeutralLostList = new List <double>();
                     for (int m = 0; m < allSpecList[i].neutralLossList.Count; m++)
                     {
                         for (int n = 0; n < allSpecList[j].neutralLossList.Count; n++)
                         {
                             if (Cal_Cosine_Product.IsEqualMZ(allSpecList[i].neutralLossList[m], allSpecList[j].neutralLossList[n]))   // judge whether 2 mz values <=0.01
                             {
                                 commonNeutralLostList.Add(Math.Round(allSpecList[i].neutralLossList[m], 2));
                             }
                         }
                     }
                     commonNeutralLostList = commonNeutralLostList.Distinct().ToList();
                     commonNeutralLostList = commonNeutralLostList.OrderBy(x => x).ToList();
                     sw.Write(allSpecList[i].group.Replace(" ", "") + "," + ndp + "," + allSpecList[j].group.Replace(" ", "") + ",");
                     for (int k = 0; k < commonNeutralLostList.Count; k++)
                     {
                         sw.Write(commonNeutralLostList[k] + ",");
                     }
                     sw.WriteLine();
                 }
             }
         }
     }
 }
        /**
         * Merge multiple idMSMS (if mz difference less than 0.01, pick the higher intensity one)
         * This function is used in two cases:1, merge 20-50ev idMSMSs, 2, merge idMSMSs in the same pcgroup with NDP>threshold
         */
        private static SpectrumData MergeSpectraToOne(List <SpectrumData> spectraWithSamePcgrp)
        {
            SpectrumData maxSpectrum = new SpectrumData();

            maxSpectrum.peakList = new List <PeakData>();
            maxSpectrum.group    = spectraWithSamePcgrp.OrderByDescending(x => double.Parse(x.group.Split('_')[0])).ToList()[0].group; //choose the highest mz as precursor(if this is 20-50ev, group is the same, then no influnce)
            List <PeakData> allPeaksInOneGroup = new List <PeakData>();

            for (int i = 0; i < spectraWithSamePcgrp.Count; i++)
            {
                allPeaksInOneGroup.AddRange(spectraWithSamePcgrp[i].peakList);
            }
            var allpeaks = from peaks in allPeaksInOneGroup
                           group peaks by peaks.mz;

            foreach (var peaks in allpeaks)
            {
                PeakData maxPeak = peaks.OrderByDescending(x => x.intensity).ToList()[0]; //choose the highest intensity peak in one mz
                maxSpectrum.peakList.Add(maxPeak);
            }
            for (int m = 0; m < maxSpectrum.peakList.Count; m++)   //remove redundancy(two mz <0.01)
            {
                for (int n = m + 1; n < maxSpectrum.peakList.Count; n++)
                {
                    if (Cal_Cosine_Product.IsEqualMZ(maxSpectrum.peakList[m].mz, maxSpectrum.peakList[n].mz))
                    {
                        if (maxSpectrum.peakList[m].intensity >= maxSpectrum.peakList[n].intensity)
                        {
                            maxSpectrum.peakList.RemoveAt(n);
                            n = n - 1;
                        }
                        else
                        {
                            maxSpectrum.peakList[m] = maxSpectrum.peakList[n];
                            n = n - 1;
                        }
                    }
                }
            }
            for (int i = 0; i < maxSpectrum.peakList.Count; i++)   //assign max precursor to all peaks
            {
                maxSpectrum.peakList[i].precursor = maxSpectrum.group;
            }
            maxSpectrum.peakList = maxSpectrum.peakList.OrderBy(x => x.mz).ToList();
            return(maxSpectrum);
        }