public void test1(string settingsFileName)
        {
            var methodName = MethodBase.GetCurrentMethod().Name;

            var deconToolsParamFile = Test.GetTestFile(methodName, settingsFileName);

            Console.WriteLine("Reading " + deconToolsParamFile.FullName);

            var loader = new DeconToolsFilterLoader(deconToolsParamFile.FullName);

            loader.DisplayFilters();

            var testFeature1 = new MSFeature
            {
                Abundance         = 16117,
                DriftTime         = 20.584f,
                Fit               = 0.0264f,
                Fwhm              = 0.0689f,
                InterferenceScore = 0,
                MassMonoisotopic  = 2902.229,
                Mz      = 726.5646,
                ScanIMS = 126,
                ScanLC  = 384,
                Charge  = 4
            };


            var isValid = DeconToolsFilterUtil.IsValidMSFeature(testFeature1, loader.DeconToolsFilterList);

            Assert.IsTrue(isValid);

            //384,126,4,16117,726.5646,0.0264,2904.08709,2902.229,2903.23217,0.0689,55.2,9527,14254,0,0,20.584,,0
        }
コード例 #2
0
        public static bool IsValidMSFeature(MSFeature msFeature, List <DeconToolsFilter> deconToolsFilterList)
        {
            var searchQuery = from filter in deconToolsFilterList
                              where msFeature.Charge >= filter.ChargeMinimum &&
                              msFeature.Charge <= filter.ChargeMaximum &&
                              msFeature.Abundance >= filter.AbundanceMinimum &&
                              msFeature.Abundance <= filter.AbundanceMaximum &&
                              msFeature.Fit <= filter.FitScoreMaximum &&
                              msFeature.InterferenceScore <= filter.InterferenceScoreMaximum
                              select filter;

            return(searchQuery.Any());
        }
コード例 #3
0
        private bool PassesFilters(MSFeature msFeature)
        {
            if (ColumnMap.ContainsKey("MSFeature.Frame"))
            {
                if (msFeature.ScanLC < Settings.ScanLCMin || msFeature.ScanLC > Settings.ScanLCMax)
                {
                    return(false);
                }
            }

            if (ColumnMap.ContainsKey("MSFeature.ScanIMS"))
            {
                if (msFeature.ScanIMS < Settings.ScanIMSMin || msFeature.ScanIMS > Settings.ScanIMSMax)
                {
                    return(false);
                }
            }

            if (ColumnMap.ContainsKey("MSFeature.MassMonoisotopic"))
            {
                if (msFeature.MassMonoisotopic < Settings.MassMonoisotopicStart || msFeature.MassMonoisotopic > Settings.MassMonoisotopicEnd)
                {
                    return(false);
                }
            }

            if (ColumnMap.ContainsKey("MSFeature.ErrorFlag"))
            {
                if (msFeature.ErrorFlag == 1)
                {
                    return(false);
                }
            }


            var deconToolsFilterTableIsBeingUsed = (Settings.FilterUsingHardCodedFilters && Settings.DeconToolsFilterList != null && Settings.DeconToolsFilterList.Count > 0);

            if (deconToolsFilterTableIsBeingUsed)
            {
                if (!DeconToolsFilterUtil.IsValidMSFeature(msFeature, Settings.DeconToolsFilterList))
                {
                    return(false);
                }
            }
            else
            {
                if (ColumnMap.ContainsKey("MSFeature.Fit"))
                {
                    if (msFeature.Fit > Settings.FitMax)
                    {
                        return(false);
                    }
                }

                if (ColumnMap.ContainsKey("MSFeature.InterferenceScore"))
                {
                    if (msFeature.InterferenceScore > Settings.InterferenceScoreMax)
                    {
                        return(false);
                    }
                }

                if (ColumnMap.ContainsKey("MSFeature.Abundance"))
                {
                    if (msFeature.Abundance < Settings.IntensityMin)
                    {
                        return(false);
                    }
                }
            }

            return(true);
        }
コード例 #4
0
        /// <summary>
        /// Saves the data from a ISOS csv file to an List of MSFeature Objects.
        /// </summary>
        private List <MSFeature> SaveDataToMSFeatureList()
        {
            var    msFeatureList = new List <MSFeature>();
            string line;

            NumOfUnfilteredMSFeatures = 0;
            var msFeatureIndex = 0;
            var currentFrame   = 0;

            // Read the rest of the Stream, 1 line at a time, and save the appropriate data into new Objects
            for (var i = 0; (line = m_isosFileReader.ReadLine()) != null; i++)
            {
                try
                {
                    var columns = line.Split(',', '\t', '\n');

                    var msFeature = new MSFeature {
                        IndexInFile = i
                    };

                    if (ColumnMap.ContainsKey("MSFeature.Frame"))
                    {
                        var frame = Int32.Parse(columns[ColumnMap["MSFeature.Frame"]]);

                        ScanLCToFrameTypeMap.Mapping.TryGetValue(frame, out var frameType);

                        // Ignore this MS Feature if it belongs to a Frame Type that is not correct
                        if (Settings.FrameTypeFilter != UIMFData.FrameType.Calibration && frameType != Settings.FrameTypeFilter)
                        {
                            continue;
                        }

                        if (i == 0)
                        {
                            currentFrame = frame;
                            ScanLCMap.Mapping.Add(ScanLCMap.ScanLCIndex, frame);
                        }
                        if (frame != currentFrame)
                        {
                            currentFrame = frame;
                            ScanLCMap.ScanLCIndex++;
                            ScanLCMap.Mapping.Add(ScanLCMap.ScanLCIndex, frame);
                        }

                        msFeature.ScanLC = ScanLCMap.ScanLCIndex;
                    }

                    if (ColumnMap.ContainsKey("MSFeature.ScanIMS"))
                    {
                        msFeature.ScanIMS = Int32.Parse(columns[ColumnMap["MSFeature.ScanIMS"]], System.Globalization.NumberStyles.Any);
                    }
                    if (ColumnMap.ContainsKey("MSFeature.Charge"))
                    {
                        msFeature.Charge = (byte)Int16.Parse(columns[ColumnMap["MSFeature.Charge"]], System.Globalization.NumberStyles.Any);
                    }
                    if (ColumnMap.ContainsKey("MSFeature.Abundance"))
                    {
                        msFeature.Abundance = (int)float.Parse(columns[ColumnMap["MSFeature.Abundance"]], System.Globalization.NumberStyles.Any);
                    }
                    if (ColumnMap.ContainsKey("MSFeature.IntensityUnSummed"))
                    {
                        msFeature.IntensityUnSummed = (int)float.Parse(columns[ColumnMap["MSFeature.IntensityUnSummed"]], System.Globalization.NumberStyles.Any);
                    }
                    if (ColumnMap.ContainsKey("MSFeature.Mz"))
                    {
                        msFeature.Mz = double.Parse(columns[ColumnMap["MSFeature.Mz"]], System.Globalization.NumberStyles.Any);
                    }
                    if (ColumnMap.ContainsKey("MSFeature.Fit"))
                    {
                        msFeature.Fit = float.Parse(columns[ColumnMap["MSFeature.Fit"]], System.Globalization.NumberStyles.Any);
                    }
                    if (ColumnMap.ContainsKey("MSFeature.InterferenceScore"))
                    {
                        msFeature.InterferenceScore = float.Parse(columns[ColumnMap["MSFeature.InterferenceScore"]], System.Globalization.NumberStyles.Any);
                    }
                    if (ColumnMap.ContainsKey("MSFeature.MassMonoisotopic"))
                    {
                        msFeature.MassMonoisotopic = double.Parse(columns[ColumnMap["MSFeature.MassMonoisotopic"]], System.Globalization.NumberStyles.Any);
                    }
                    if (ColumnMap.ContainsKey("MSFeature.MassMostAbundant"))
                    {
                        msFeature.MassMostAbundantIsotope = double.Parse(columns[ColumnMap["MSFeature.MassMostAbundant"]], System.Globalization.NumberStyles.Any);
                    }
                    if (ColumnMap.ContainsKey("MSFeature.Fwhm"))
                    {
                        msFeature.Fwhm = float.Parse(columns[ColumnMap["MSFeature.Fwhm"]], System.Globalization.NumberStyles.Any);
                    }
                    if (ColumnMap.ContainsKey("MSFeature.DriftTimeIMS"))
                    {
                        msFeature.DriftTime = float.Parse(columns[ColumnMap["MSFeature.DriftTimeIMS"]], System.Globalization.NumberStyles.Any);
                    }
                    if (ColumnMap.ContainsKey("MSFeature.ErrorFlag"))
                    {
                        msFeature.ErrorFlag = (byte)(columns[ColumnMap["MSFeature.ErrorFlag"]].Equals(string.Empty) ? 0 : Int16.Parse(columns[ColumnMap["MSFeature.ErrorFlag"]], System.Globalization.NumberStyles.Any));
                    }
                    if (ColumnMap.ContainsKey("MSFeature.IsSaturated"))
                    {
                        msFeature.IsSaturated = Convert.ToBoolean(Int16.Parse(columns[ColumnMap["MSFeature.IsSaturated"]], System.Globalization.NumberStyles.Any));
                    }

                    if (PassesFilters(msFeature))
                    {
                        msFeature.Id = msFeatureIndex;
                        msFeatureList.Add(msFeature);
                        m_isosFileWriter.WriteLine(line);
                        msFeatureIndex++;
                    }

                    NumOfUnfilteredMSFeatures++;
                }
                catch (Exception e)
                {
                    Logger.Log("Error while reading line in isos file. Skipping Line #" + (i + 2));
                    Console.WriteLine(e.StackTrace);
                }
            }

            m_isosFileReader.Close();
            m_isosFileWriter.Close();

            return(msFeatureList);
        }
コード例 #5
0
        public static void WriteLCIMSMSFeatureToFile(IEnumerable <LCIMSMSFeature> lcImsMsFeatureEnumerable)
        {
            var baseFileName    = Regex.Split(Settings.InputFileName, "_isos")[0];
            var outputDirectory = string.Empty;

            if (!string.IsNullOrWhiteSpace(Settings.OutputDirectory))
            {
                outputDirectory = Settings.OutputDirectory;
            }

            var featuresFilePath     = Path.Combine(outputDirectory, baseFileName + "_LCMSFeatures.txt");
            var featureToPeakMapPath = Path.Combine(outputDirectory, baseFileName + "_LCMSFeatureToPeakMap.txt");

            using (var featureWriter = new StreamWriter(featuresFilePath))
                using (var mapWriter = new StreamWriter(featureToPeakMapPath))
                {
                    var headerCols = new List <string>
                    {
                        "Feature_Index",
                        "Original_Index",
                        "Monoisotopic_Mass",
                        "Average_Mono_Mass",
                        "UMC_MW_Min",
                        "UMC_MW_Max",
                        "Scan_Start",
                        "Scan_End",
                        "Scan",
                        "IMS_Scan",
                        "IMS_Scan_Start",
                        "IMS_Scan_End",
                        "Avg_Interference_Score",
                        "Decon2ls_Fit_Score",
                        "UMC_Member_Count",
                        "Saturated_Member_Count",
                        "Max_Abundance",
                        "Abundance",
                        "Class_Rep_MZ",
                        "Class_Rep_Charge",
                        "Charge_Max",
                        "Drift_Time",
                        "Conformation_Fit_Score",
                        "LC_Fit_Score",
                        "Average_Isotopic_Fit",
                        "Members_Percentage",
                        "Combined_Score"
                    };

                    featureWriter.WriteLine(string.Join("\t", headerCols));

                    mapWriter.WriteLine("Feature_Index\tPeak_Index\tFiltered_Peak_Index");

                    var index = 0;

                    foreach (var lcimsmsFeature in lcImsMsFeatureEnumerable)
                    {
                        MSFeature msFeatureRep = null;

                        var    maxAbundance            = int.MinValue;
                        var    msFeatureCount          = 0;
                        var    saturatedMSFeatureCount = 0;
                        var    repMinIMSScan           = 0;
                        var    repMaxIMSScan           = 0;
                        long   totalAbundance          = 0;
                        var    minMass   = double.MaxValue;
                        var    maxMass   = double.MinValue;
                        double totalMass = 0;
                        double totalFit  = 0;
                        double totalInterferenceScore       = 0;
                        double totalAbundanceTimesDriftTime = 0;

                        var sortByScanLCQuery = (from imsMsFeature in lcimsmsFeature.imsMsFeatureList
                                                 orderby imsMsFeature.ScanLC
                                                 select imsMsFeature).ToList();

                        var scanLCStart = sortByScanLCQuery.First().ScanLC;
                        var scanLCEnd   = sortByScanLCQuery.Last().ScanLC;

                        foreach (var imsMsFeature in sortByScanLCQuery)
                        {
                            var minIMSScan = int.MaxValue;
                            var maxIMSScan = int.MinValue;

                            var isFeatureRep = false;

                            foreach (var msFeature in imsMsFeature.MSFeatureList)
                            {
                                var filteredFeatureId = msFeature.FilteredIndex >= 0 ? msFeature.FilteredIndex.ToString() : string.Empty;
                                mapWriter.WriteLine(index + "\t" + msFeature.IndexInFile + "\t" + filteredFeatureId);

                                if (msFeature.Abundance > maxAbundance)
                                {
                                    msFeatureRep = msFeature;
                                    maxAbundance = msFeature.Abundance;
                                    isFeatureRep = true;
                                }

                                if (msFeature.MassMonoisotopic < minMass)
                                {
                                    minMass = msFeature.MassMonoisotopic;
                                }
                                if (msFeature.MassMonoisotopic > maxMass)
                                {
                                    maxMass = msFeature.MassMonoisotopic;
                                }

                                if (msFeature.ScanIMS < minIMSScan)
                                {
                                    minIMSScan = msFeature.ScanIMS;
                                }
                                if (msFeature.ScanIMS > maxIMSScan)
                                {
                                    maxIMSScan = msFeature.ScanIMS;
                                }

                                if (msFeature.IsSaturated)
                                {
                                    saturatedMSFeatureCount++;
                                }

                                totalAbundance += msFeature.Abundance;
                                totalAbundanceTimesDriftTime += (double)msFeature.Abundance * msFeature.DriftTime;
                                totalMass += msFeature.MassMonoisotopic;
                                totalFit  += msFeature.Fit;
                                totalInterferenceScore += msFeature.InterferenceScore;
                                msFeatureCount++;
                            }

                            if (isFeatureRep)
                            {
                                repMinIMSScan = minIMSScan;
                                repMaxIMSScan = maxIMSScan;
                            }
                        }

                        var averageMass = totalMass / Math.Max(msFeatureCount, 1);
                        var averageFit  = 1.0 - totalFit / Math.Max(msFeatureCount, 1) / Math.Max(Settings.FitMax, 0.001);
                        var averageInterferenceScore = (totalInterferenceScore / Math.Max(msFeatureCount, 1));
                        var averageDecon2lsFit       = totalFit / Math.Max(msFeatureCount, 1);

                        if (float.IsInfinity(lcimsmsFeature.IMSScore) || float.IsNaN(lcimsmsFeature.IMSScore))
                        {
                            lcimsmsFeature.IMSScore = 0;
                        }
                        if (float.IsInfinity(lcimsmsFeature.LCScore) || float.IsNaN(lcimsmsFeature.LCScore))
                        {
                            lcimsmsFeature.IMSScore = 0;
                        }

                        // When conformation detection is enabled, this is the number of members of this feature divided by the member count of the conformer with the most members
                        var memberPercentage = ValidateScore(msFeatureCount / (double)lcimsmsFeature.MaxMemberCount);

                        var combinedScore = ValidateScore((lcimsmsFeature.IMSScore + averageFit + memberPercentage) / 3.0);

                        var driftTimeWeightedAverage = totalAbundanceTimesDriftTime / totalAbundance;

                        var outLine = new List <string>
                        {
                            index.ToString(),                               // Feature_Index
                            lcimsmsFeature.OriginalIndex.ToString(),        // Original_Index
                            averageMass.ToString("0.0####"),                // Monoisotopic_Mass
                            averageMass.ToString("0.0####"),                // Average_Mono_Mass
                            minMass.ToString("0.0####"),                    // UMC_MW_Min
                            maxMass.ToString("0.0####"),                    // UMC_MW_Max
                            ScanLCMap.Mapping[scanLCStart].ToString(),      // Scan_Start, aka Frame Start
                            ScanLCMap.Mapping[scanLCEnd].ToString()         // Scan_End, aka Frame End
                        };

                        if (msFeatureRep != null)
                        {
                            outLine.Add(ScanLCMap.Mapping[msFeatureRep.ScanLC].ToString()); // Central Frame for this feature (class representative frame)
                            outLine.Add(msFeatureRep.ScanIMS.ToString());                   // Central IMS scan for this feature (class representative scan)
                        }
                        else
                        {
                            outLine.Add(string.Empty);
                            outLine.Add(string.Empty);
                        }

                        outLine.Add(repMinIMSScan.ToString());                                                 // IMS_Scan_Start
                        outLine.Add(repMaxIMSScan.ToString());                                                 // IMS_Scan_End
                        outLine.Add(PRISM.StringUtilities.ValueToString(averageInterferenceScore, 5));         // Avg_Interference_Score; closer to 0 is better
                        outLine.Add(PRISM.StringUtilities.ValueToString(averageDecon2lsFit, 5));               // Average Decon2ls_Fit_Score; closer to 0 is better
                        outLine.Add(msFeatureCount.ToString());                                                // UMC_Member_Count
                        outLine.Add(saturatedMSFeatureCount.ToString());                                       // Saturated_Member_Count
                        outLine.Add(maxAbundance.ToString());                                                  // Maximum abundance


                        if (Settings.UseConformationDetection)
                        {
                            outLine.Add(PRISM.StringUtilities.ValueToString(lcimsmsFeature.AbundanceSumRaw, 5)); // Overall feature Abundance
                        }
                        else
                        {
                            outLine.Add(totalAbundance.ToString());                                            // Overall feature Abundance
                        }

                        if (msFeatureRep != null)
                        {
                            outLine.Add(msFeatureRep.Mz.ToString("0.0####"));                                  // Class representative m/z
                        }
                        else
                        {
                            outLine.Add(string.Empty);
                        }

                        outLine.Add(lcimsmsFeature.Charge.ToString());                                        // ClassRepCharge
                        outLine.Add(lcimsmsFeature.Charge.ToString());                                        // ChargeMax

                        if (Settings.UseConformationDetection)
                        {
                            outLine.Add(PRISM.StringUtilities.ValueToString(lcimsmsFeature.DriftTime, 5)); // Class drift time
                        }
                        else
                        {
                            outLine.Add(PRISM.StringUtilities.ValueToString(driftTimeWeightedAverage, 5)); // Class drift time
                        }


                        outLine.Add(PRISM.StringUtilities.ValueToString(lcimsmsFeature.IMSScore, 5)); // Conformation_Fit_Score
                        outLine.Add(PRISM.StringUtilities.ValueToString(lcimsmsFeature.LCScore, 5));  // LC_Fit_Score
                        outLine.Add(PRISM.StringUtilities.ValueToString(averageFit, 5));              // Average_Isotopic_Fit; closer to 1 is better, since computed as 1 - DeconTools_Fit
                        outLine.Add(PRISM.StringUtilities.ValueToString(memberPercentage, 5));        // Members_Percentage (1 if this conformer is the conformer with the most members)
                        outLine.Add(PRISM.StringUtilities.ValueToString(combinedScore, 5));           // Combined_Score

                        featureWriter.WriteLine(string.Join("\t", outLine));

                        index++;
                    }
                }
        }
コード例 #6
0
        public static void WriteLCIMSMSFeatureToFile(IEnumerable <LCIMSMSFeature> lcimsmsFeatureEnumerable)
        {
            var baseFileName    = Regex.Split(Settings.InputFileName, "_isos")[0];
            var outputDirectory = "";

            if (!string.IsNullOrWhiteSpace(Settings.OutputDirectory))
            {
                outputDirectory = Settings.OutputDirectory;
            }

            var featuresFilePath     = Path.Combine(outputDirectory, baseFileName + "_LCMSFeatures.txt");
            var featureToPeakMapPath = Path.Combine(outputDirectory, baseFileName + "_LCMSFeatureToPeakMap.txt");

            using (var featureWriter = new StreamWriter(featuresFilePath))
                using (var mapWriter = new StreamWriter(featureToPeakMapPath))
                {
                    var headerCols = new List <string>
                    {
                        "Feature_Index",
                        "Original_Index",
                        "Monoisotopic_Mass",
                        "Average_Mono_Mass",
                        "UMC_MW_Min",
                        "UMC_MW_Max",
                        "Scan_Start",
                        "Scan_End",
                        "Scan",
                        "IMS_Scan",
                        "IMS_Scan_Start",
                        "IMS_Scan_End",
                        "Avg_Interference_Score",
                        "Decon2ls_Fit_Score",
                        "UMC_Member_Count",
                        "Saturated_Member_Count",
                        "Max_Abundance",
                        "Abundance",
                        "Class_Rep_MZ",
                        "Class_Rep_Charge",
                        "Charge_Max",
                        "Drift_Time",
                        "Conformation_Fit_Score",
                        "LC_Fit_Score",
                        "Average_Isotopic_Fit",
                        "Members_Percentage",
                        "Combined_Score"
                    };

                    featureWriter.WriteLine(string.Join("\t", headerCols));

                    mapWriter.WriteLine("Feature_Index\tPeak_Index\tFiltered_Peak_Index");

                    var index = 0;

                    foreach (var lcimsmsFeature in lcimsmsFeatureEnumerable)
                    {
                        MSFeature msFeatureRep = null;

                        var    maxAbundance            = int.MinValue;
                        var    msFeatureCount          = 0;
                        var    saturatedMSFeatureCount = 0;
                        var    repMinIMSScan           = 0;
                        var    repMaxIMSScan           = 0;
                        long   totalAbundance          = 0;
                        var    minMass   = double.MaxValue;
                        var    maxMass   = double.MinValue;
                        double totalMass = 0;
                        double totalFit  = 0;
                        double totalInterferenceScore       = 0;
                        double totalAbundanceTimesDriftTime = 0;

                        var sortByScanLCQuery = (from imsmsFeature in lcimsmsFeature.IMSMSFeatureList
                                                 orderby imsmsFeature.ScanLC
                                                 select imsmsFeature).ToList();

                        var scanLCStart = sortByScanLCQuery.First().ScanLC;
                        var scanLCEnd   = sortByScanLCQuery.Last().ScanLC;

                        foreach (var imsmsFeature in sortByScanLCQuery)
                        {
                            var minIMSScan = int.MaxValue;
                            var maxIMSScan = int.MinValue;

                            var isFeatureRep = false;

                            foreach (var msFeature in imsmsFeature.MSFeatureList)
                            {
                                var filteredFeatureId = msFeature.FilteredIndex >= 0 ? msFeature.FilteredIndex.ToString() : "";
                                mapWriter.WriteLine(index + "\t" + msFeature.IndexInFile + "\t" + filteredFeatureId);

                                if (msFeature.Abundance > maxAbundance)
                                {
                                    msFeatureRep = msFeature;
                                    maxAbundance = msFeature.Abundance;
                                    isFeatureRep = true;
                                }

                                if (msFeature.MassMonoisotopic < minMass)
                                {
                                    minMass = msFeature.MassMonoisotopic;
                                }
                                if (msFeature.MassMonoisotopic > maxMass)
                                {
                                    maxMass = msFeature.MassMonoisotopic;
                                }

                                if (msFeature.ScanIMS < minIMSScan)
                                {
                                    minIMSScan = msFeature.ScanIMS;
                                }
                                if (msFeature.ScanIMS > maxIMSScan)
                                {
                                    maxIMSScan = msFeature.ScanIMS;
                                }

                                if (msFeature.IsSaturated)
                                {
                                    saturatedMSFeatureCount++;
                                }

                                totalAbundance += msFeature.Abundance;
                                totalAbundanceTimesDriftTime += (double)msFeature.Abundance * msFeature.DriftTime;
                                totalMass += msFeature.MassMonoisotopic;
                                totalFit  += msFeature.Fit;
                                totalInterferenceScore += msFeature.InterferenceScore;
                                msFeatureCount++;
                            }

                            if (isFeatureRep)
                            {
                                repMinIMSScan = minIMSScan;
                                repMaxIMSScan = maxIMSScan;
                            }
                        }

                        var averageMass = totalMass / msFeatureCount;
                        var averageFit  = 1.0 - ((totalFit / msFeatureCount) / Settings.FitMax);
                        var averageInterferenceScore = (totalInterferenceScore / msFeatureCount);
                        var averageDecon2lsFit       = (totalFit / msFeatureCount);

                        if (float.IsInfinity(lcimsmsFeature.IMSScore) || float.IsNaN(lcimsmsFeature.IMSScore))
                        {
                            lcimsmsFeature.IMSScore = 0;
                        }
                        if (float.IsInfinity(lcimsmsFeature.LCScore) || float.IsNaN(lcimsmsFeature.LCScore))
                        {
                            lcimsmsFeature.IMSScore = 0;
                        }

                        var memberPercentage = msFeatureCount / (double)lcimsmsFeature.MaxMemberCount;
                        if (double.IsInfinity(memberPercentage) || double.IsNaN(memberPercentage))
                        {
                            memberPercentage = 0.0;
                        }

                        var combinedScore = (lcimsmsFeature.IMSScore + averageFit + memberPercentage) / 3.0;
                        if (double.IsInfinity(combinedScore) || double.IsNaN(combinedScore))
                        {
                            combinedScore = 0.0;
                        }

                        var driftTimeWeightedAverage = totalAbundanceTimesDriftTime / totalAbundance;

                        var outLine = new List <string>
                        {
                            index.ToString(),
                            lcimsmsFeature.OriginalIndex.ToString(),
                            averageMass.ToString("0.0####"),
                            averageMass.ToString("0.0####"),
                            minMass.ToString("0.0####"),
                            maxMass.ToString("0.0####"),
                            ScanLCMap.Mapping[scanLCStart].ToString(),
                            ScanLCMap.Mapping[scanLCEnd].ToString()
                        };

                        if (msFeatureRep != null)
                        {
                            outLine.Add(ScanLCMap.Mapping[msFeatureRep.ScanLC].ToString());
                            outLine.Add(msFeatureRep.ScanIMS.ToString());
                        }
                        else
                        {
                            outLine.Add("");
                            outLine.Add("");
                        }

                        outLine.Add(repMinIMSScan.ToString());
                        outLine.Add(repMaxIMSScan.ToString());
                        outLine.Add(PRISM.StringUtilities.ValueToString(averageInterferenceScore, 5));
                        outLine.Add(PRISM.StringUtilities.ValueToString(averageDecon2lsFit, 5));
                        outLine.Add(msFeatureCount.ToString());
                        outLine.Add(saturatedMSFeatureCount.ToString());
                        outLine.Add(maxAbundance.ToString());


                        if (Settings.UseConformationDetection)
                        {
                            outLine.Add(PRISM.StringUtilities.ValueToString(lcimsmsFeature.AbundanceSumRaw, 5));
                        }
                        else
                        {
                            outLine.Add(totalAbundance.ToString());
                        }

                        if (msFeatureRep != null)
                        {
                            outLine.Add(msFeatureRep.Mz.ToString("0.0####"));
                        }
                        else
                        {
                            outLine.Add("");
                        }

                        outLine.Add(lcimsmsFeature.Charge.ToString());  // ClassRepCharge
                        outLine.Add(lcimsmsFeature.Charge.ToString());  // ChargeMax

                        if (Settings.UseConformationDetection)
                        {
                            outLine.Add(PRISM.StringUtilities.ValueToString(lcimsmsFeature.DriftTime, 5));
                        }
                        else
                        {
                            outLine.Add(PRISM.StringUtilities.ValueToString(driftTimeWeightedAverage, 5));
                        }


                        outLine.Add(PRISM.StringUtilities.ValueToString(lcimsmsFeature.IMSScore, 5)); // Conformation_Fit_Score
                        outLine.Add(PRISM.StringUtilities.ValueToString(lcimsmsFeature.LCScore, 5));  // LC_Fit_Score
                        outLine.Add(PRISM.StringUtilities.ValueToString(averageFit, 5));              // Average_Isotopic_Fit
                        outLine.Add(PRISM.StringUtilities.ValueToString(memberPercentage, 5));        // Members_Percentage
                        outLine.Add(PRISM.StringUtilities.ValueToString(combinedScore, 5));           // Combined_Score

                        featureWriter.WriteLine(string.Join("\t", outLine));

                        index++;
                    }
                }
        }