Пример #1
0
        protected override bool LoadBackground(IDocumentContainer container, SrmDocument document, SrmDocument docCurrent)
        {
            var loadMonitor = new LoadMonitor(this, container, container.Document);

            IPeakScoringModel scoringModel = new MProphetPeakScoringModel(
                Path.GetFileNameWithoutExtension(container.DocumentFilePath), null as LinearModelParams,
                MProphetPeakScoringModel.GetDefaultCalculators(docCurrent), true);

            var targetDecoyGenerator = new TargetDecoyGenerator(docCurrent, scoringModel, this, loadMonitor);

            // Get scores for target and decoy groups.
            List <IList <float[]> > targetTransitionGroups, decoyTransitionGroups;

            targetDecoyGenerator.GetTransitionGroups(out targetTransitionGroups, out decoyTransitionGroups);
            if (!decoyTransitionGroups.Any())
            {
                throw new InvalidDataException();
            }

            // Set intial weights based on previous model (with NaN's reset to 0)
            var initialWeights = new double[scoringModel.PeakFeatureCalculators.Count];

            // But then set to NaN the weights that have unknown values for this dataset
            for (var i = 0; i < initialWeights.Length; ++i)
            {
                if (!targetDecoyGenerator.EligibleScores[i])
                {
                    initialWeights[i] = double.NaN;
                }
            }
            var initialParams = new LinearModelParams(initialWeights);

            // Train the model.
            scoringModel = scoringModel.Train(targetTransitionGroups, decoyTransitionGroups, targetDecoyGenerator, initialParams, null, null, scoringModel.UsesSecondBest, true, loadMonitor);

            SrmDocument docNew;

            do
            {
                docCurrent = container.Document;
                docNew     = docCurrent.ChangeSettings(docCurrent.Settings.ChangePeptideIntegration(i =>
                                                                                                    i.ChangeAutoTrain(false).ChangePeakScoringModel((PeakScoringModelSpec)scoringModel)));

                // Reintegrate peaks
                var resultsHandler = new MProphetResultsHandler(docNew, (PeakScoringModelSpec)scoringModel, _cachedFeatureScores);
                resultsHandler.ScoreFeatures(loadMonitor);
                if (resultsHandler.IsMissingScores())
                {
                    throw new InvalidDataException(Resources.ImportPeptideSearchManager_LoadBackground_The_current_peak_scoring_model_is_incompatible_with_one_or_more_peptides_in_the_document_);
                }
                docNew = resultsHandler.ChangePeaks(loadMonitor);
            }while (!CompleteProcessing(container, docNew, docCurrent));

            return(true);
        }
Пример #2
0
        public void GenerateComparison(SrmDocument docOriginal, IProgressMonitor progressMonitor)
        {
            DocOriginal = docOriginal;
            _docCompare = docOriginal;
            if (IsModel)
            {
                var handler = new MProphetResultsHandler(DocOriginal, PeakScoringModel);
                handler.ScoreFeatures(progressMonitor, true);
                _docCompare = handler.ChangePeaks(progressMonitor);
            }
            else
            {
                // Add in the necessary annotation definitions so that ImportPeakBoundaries can read them
                var annotationNamesToStrip = new List <string>
                {
                    MProphetResultsHandler.AnnotationName,
                    MProphetResultsHandler.MAnnotationName,
                    APEX_ANNOTATION,
                    START_TIME_ANNOTATION,
                    END_TIME_ANNOTATION
                };
                foreach (var annotationName in annotationNamesToStrip)
                {
                    _docCompare = AddAnnotationIfMissing(_docCompare, annotationName);
                }
                // But strip the values of these annotations if there were any
                var annotationNamesToKeep = _docCompare.Settings.DataSettings.AnnotationDefs
                                            .Where(def => !annotationNamesToStrip.Contains(def.Name))
                                            .Select(def => def.Name).ToList();
                _docCompare = (SrmDocument)_docCompare.StripAnnotationValues(annotationNamesToKeep);
                Importer    = new PeakBoundaryImporter(_docCompare);
                long lineCount = Helpers.CountLinesInFile(FilePath);
                // Peek at the file to see if it has a column called "Apex"
                using (var reader = new StreamReader(FilePath))
                {
                    var   line       = reader.ReadLine();
                    var   fieldNames = PeakBoundaryImporter.FIELD_NAMES.ToList();
                    int   fieldsTotal;
                    int[] fieldIndices;
                    var   separator = PeakBoundaryImporter.DetermineCorrectSeparator(line, fieldNames,
                                                                                     PeakBoundaryImporter.REQUIRED_NO_CHROM, out fieldIndices, out fieldsTotal);
                    ApexPresent = separator != null && fieldIndices[(int)PeakBoundaryImporter.Field.apex_time] != -1;
                }
                _docCompare = Importer.Import(FilePath, progressMonitor, lineCount, true, !ApexPresent);
                if (progressMonitor.IsCanceled)
                {
                    return;
                }
            }
            var matches          = new List <PeakBoundsMatch>();
            var truePeptides     = DocOriginal.Molecules.ToList();
            var pickedPeptides   = _docCompare.Molecules.ToList();
            int nTruePeptides    = truePeptides.Count;
            var chromatogramSets = DocOriginal.Settings.MeasuredResults.Chromatograms;

            for (int i = 0; i < chromatogramSets.Count; i++)
            {
                var chromSet = chromatogramSets[i];
                var set      = chromatogramSets[i];
                for (int j = 0; j < nTruePeptides; j++)
                {
                    var truePeptide   = truePeptides[j];
                    var pickedPeptide = pickedPeptides[j];
                    // We don't care about peak picking performance for decoys
                    if (truePeptide.IsDecoy)
                    {
                        continue;
                    }
                    // We don't care about peak picking performance for standard peptides
                    if (truePeptide.GlobalStandardType != null)
                    {
                        continue;
                    }
                    var trueGroups   = truePeptide.TransitionGroups.ToList();
                    var pickedGroups = pickedPeptide.TransitionGroups.ToList();
                    for (int k = 0; k < trueGroups.Count; k++)
                    {
                        var trueGroup     = trueGroups[k];
                        var pickedGroup   = pickedGroups[k];
                        var trueResults   = trueGroup.Results[i];
                        var pickedResults = pickedGroup.Results[i];
                        if (trueResults.IsEmpty)
                        {
                            continue;
                        }
                        int nChromInfos = trueResults.Count;
                        for (int m = 0; m < nChromInfos; m++)
                        {
                            var trueInfo   = trueResults[m];
                            var pickedInfo = pickedResults[m];
                            // For TRIC testing at the moment
//                            double? qvaluePicked = PeakBoundsMatch.GetScoreValue(pickedInfo,
//                                MProphetResultsHandler.AnnotationName, ci => pickedInfo.QValue);
//                            if (qvaluePicked.HasValue && qvaluePicked.Value > 0.01)
//                                continue;
                            var fileInfo = set.GetFileInfo(trueInfo.FileId);
                            var filePath = fileInfo.FilePath;
                            var key      = new MatchKey(trueGroup.Id.GlobalIndex, trueInfo.FileId.GlobalIndex);
                            matches.Add(new PeakBoundsMatch(trueInfo, pickedInfo, key, chromSet, filePath,
                                                            trueGroup, truePeptide, HasNoQValues, HasNoScores, ApexPresent));
                        }
                    }
                }
            }
            Matches = matches;
            // Detect if the apex time is in seconds, and if so adjust it to minutes
            if (ApexPresent)
            {
                // ReSharper disable PossibleMultipleEnumeration
                var    matchesWithApex = matches.Where(match => match.PickedApex.HasValue).ToArray();
                double maxTime         = 0;
                if (matchesWithApex.Length > 0)
                {
                    maxTime = matchesWithApex.Select(match => match.PickedApex.Value).Max();
                }
                if (maxTime > PeakBoundaryImporter.GetMaxRt(DocOriginal))
                {
                    foreach (var match in matchesWithApex)
                    {
                        // If the end is greater than the Apex, then it must also be in seconds (otherwise minutes)
                        if (match.PickedEndBoundary.HasValue && match.PickedEndBoundary > match.PickedApex)
                        {
                            match.PickedEndBoundary = match.PickedEndBoundary / 60;
                        }
                        match.PickedApex = match.PickedApex / 60;
                        // If the start is now greater than the apex, then it must also be in seconds (otherwise minutes)
                        if (match.PickedStartBoundary.HasValue && match.PickedStartBoundary > match.PickedApex)
                        {
                            match.PickedStartBoundary = match.PickedStartBoundary / 60;
                        }
                    }
                }
                // ReSharper restore PossibleMultipleEnumeration
            }
        }
        public void GenerateComparison(SrmDocument docOriginal, IProgressMonitor progressMonitor)
        {
            DocOriginal = docOriginal;
            _docCompare = docOriginal;
            if (IsModel)
            {
                var handler = new MProphetResultsHandler(DocOriginal, PeakScoringModel)
                {
                    AddAnnotation  = true,
                    AddMAnnotation = true
                };
                handler.ScoreFeatures(progressMonitor);
                _docCompare = handler.ChangePeaks(progressMonitor);
            }
            else
            {
                // Add in the necessary annotation definitions so that ImportPeakBoundaries can read them
                _docCompare = AddAnnotationIfMissing(_docCompare, MProphetResultsHandler.AnnotationName);
                _docCompare = AddAnnotationIfMissing(_docCompare, MProphetResultsHandler.MAnnotationName);
                _docCompare = AddAnnotationIfMissing(_docCompare, APEX_ANNOTATION);
                // But strip the values of these annotations if there were any
                var annotationNamesToStrip = new List <string>
                {
                    MProphetResultsHandler.AnnotationName,
                    MProphetResultsHandler.MAnnotationName,
                    APEX_ANNOTATION
                };
                var annotationNamesToKeep = _docCompare.Settings.DataSettings.AnnotationDefs
                                            .Where(def => !annotationNamesToStrip.Contains(def.Name))
                                            .Select(def => def.Name).ToList();
                _docCompare = (SrmDocument)_docCompare.StripAnnotationValues(annotationNamesToKeep);
                Importer    = new PeakBoundaryImporter(_docCompare);
                long lineCount = Helpers.CountLinesInFile(FilePath);
                // Peek at the file to see if it has a column called "Apex"
                using (var reader = new StreamReader(FilePath))
                {
                    var line       = reader.ReadLine();
                    var fieldNames = PeakBoundaryImporter.FIELD_NAMES.ToList();
                    fieldNames.Add(new [] { APEX_ANNOTATION });
                    int   fieldsTotal;
                    int[] fieldIndices;
                    var   separator = PeakBoundaryImporter.DetermineCorrectSeparator(line, fieldNames,
                                                                                     PeakBoundaryImporter.REQUIRED_NO_CHROM, out fieldIndices, out fieldsTotal);
                    ApexPresent = separator != null && fieldIndices.Last() != -1;
                }
                _docCompare = Importer.Import(FilePath, progressMonitor, lineCount, true, !ApexPresent);
            }
            var matches          = new List <PeakBoundsMatch>();
            var truePeptides     = DocOriginal.Molecules.ToList();
            var pickedPeptides   = _docCompare.Molecules.ToList();
            int nTruePeptides    = truePeptides.Count;
            var chromatogramSets = DocOriginal.Settings.MeasuredResults.Chromatograms;

            for (int i = 0; i < chromatogramSets.Count; i++)
            {
                var set = chromatogramSets[i];
                for (int j = 0; j < nTruePeptides; j++)
                {
                    var truePeptide   = truePeptides[j];
                    var pickedPeptide = pickedPeptides[j];
                    // We don't care about peak picking performance for decoys
                    if (truePeptide.IsDecoy)
                    {
                        continue;
                    }
                    // We don't care about peak picking performance for standard peptides
                    if (truePeptide.GlobalStandardType != null)
                    {
                        continue;
                    }
                    var trueGroups   = truePeptide.TransitionGroups.ToList();
                    var pickedGroups = pickedPeptide.TransitionGroups.ToList();
                    for (int k = 0; k < trueGroups.Count; k++)
                    {
                        var trueGroup     = trueGroups[k];
                        var pickedGroup   = pickedGroups[k];
                        var trueResults   = trueGroup.Results[i];
                        var pickedResults = pickedGroup.Results[i];
                        if (trueResults == null)
                        {
                            continue;
                        }
                        int nChromInfos = trueResults.Count;
                        for (int m = 0; m < nChromInfos; m++)
                        {
                            var trueInfo   = trueResults[m];
                            var pickedInfo = pickedResults[m];
                            var fileInfo   = set.GetFileInfo(trueInfo.FileId);
                            var filePath   = fileInfo.FilePath;
                            var key        = new MatchKey(trueGroup.Id.GlobalIndex, trueInfo.FileId.GlobalIndex);
                            matches.Add(new PeakBoundsMatch(trueInfo, pickedInfo, key, filePath, trueGroup,
                                                            HasNoQValues, HasNoScores, ApexPresent));
                        }
                    }
                }
            }
            Matches = matches;
            // Detect if the apex time is in seconds, and if so adjust it to minutes
            if (ApexPresent)
            {
                double maxTime = matches.Where(match => match.PickedApex.HasValue)
                                 .Select(match => match.PickedApex.Value).Max();
                if (maxTime > PeakBoundaryImporter.GetMaxRt(DocOriginal))
                {
                    foreach (var match in matches.Where(match => match.PickedApex.HasValue))
                    {
                        match.PickedApex = match.PickedApex / 60;
                    }
                }
            }
        }
Пример #4
0
        private bool Reintegrate(ModelAndFeatures modelAndFeatures, bool isAnnotateScoring, bool isOverwritePeaks)
        {
            try
            {
                var resultsHandler = new MProphetResultsHandler(_doc, modelAndFeatures.ScoringModel, modelAndFeatures.Features)
                {
                    OverrideManual = isOverwritePeaks,
                    AddAnnotation = isAnnotateScoring,
                    AddMAnnotation = isAnnotateScoring
                };

                var progressMonitor = new CommandProgressMonitor(_out, new ProgressStatus(string.Empty));

                resultsHandler.ScoreFeatures(progressMonitor);
                if (resultsHandler.IsMissingScores())
                {
                    _out.WriteLine(Resources.CommandLine_Reintegrate_Error__The_current_peak_scoring_model_is_incompatible_with_one_or_more_peptides_in_the_document__Please_train_a_new_model_);
                    return false;
                }
                _doc = resultsHandler.ChangePeaks(progressMonitor);

                return true;
            }
            catch (Exception x)
            {
                _out.WriteLine(Resources.CommandLine_Reintegrate_Error__Failed_to_reintegrate_peaks_successfully_);
                _out.WriteLine(x.Message);
                return false;
            }
        }
Пример #5
0
 public void GenerateComparison(SrmDocument docOriginal, IProgressMonitor progressMonitor)
 {
     DocOriginal = docOriginal;
     _docCompare = docOriginal;
     if (IsModel)
     {
         var handler = new MProphetResultsHandler(DocOriginal, PeakScoringModel)
         {
             AddAnnotation = true,
             AddMAnnotation = true
         };
         handler.ScoreFeatures(progressMonitor);
         _docCompare = handler.ChangePeaks(progressMonitor);
     }
     else
     {
         // Add in the necessary annotation definitions so that ImportPeakBoundaries can read them
         _docCompare = AddAnnotationIfMissing(_docCompare, MProphetResultsHandler.AnnotationName);
         _docCompare = AddAnnotationIfMissing(_docCompare, MProphetResultsHandler.MAnnotationName);
         _docCompare = AddAnnotationIfMissing(_docCompare, APEX_ANNOTATION);
         // But strip the values of these annotations if there were any
         var annotationNamesToStrip = new List<string>
         {
             MProphetResultsHandler.AnnotationName,
             MProphetResultsHandler.MAnnotationName,
             APEX_ANNOTATION
         };
         var annotationNamesToKeep = _docCompare.Settings.DataSettings.AnnotationDefs
             .Where(def => !annotationNamesToStrip.Contains(def.Name))
             .Select(def => def.Name).ToList();
         _docCompare = (SrmDocument)_docCompare.StripAnnotationValues(annotationNamesToKeep);
         Importer = new PeakBoundaryImporter(_docCompare);
         long lineCount = Helpers.CountLinesInFile(FilePath);
         // Peek at the file to see if it has a column called "Apex"
         using (var reader = new StreamReader(FilePath))
         {
             var line = reader.ReadLine();
             var fieldNames = PeakBoundaryImporter.FIELD_NAMES.ToList();
             fieldNames.Add(new [] {APEX_ANNOTATION});
             int fieldsTotal;
             int[] fieldIndices;
             var separator = PeakBoundaryImporter.DetermineCorrectSeparator(line, fieldNames,
                 PeakBoundaryImporter.REQUIRED_NO_CHROM, out fieldIndices, out fieldsTotal);
             ApexPresent = separator != null && fieldIndices.Last() != -1;
         }
         _docCompare = Importer.Import(FilePath, progressMonitor, lineCount, true, !ApexPresent);
     }
     var matches = new List<PeakBoundsMatch>();
     var truePeptides = DocOriginal.Molecules.ToList();
     var pickedPeptides = _docCompare.Molecules.ToList();
     int nTruePeptides = truePeptides.Count;
     var chromatogramSets = DocOriginal.Settings.MeasuredResults.Chromatograms;
     for (int i = 0; i < chromatogramSets.Count; i++)
     {
         var set = chromatogramSets[i];
         for (int j = 0; j < nTruePeptides; j++)
         {
             var truePeptide = truePeptides[j];
             var pickedPeptide = pickedPeptides[j];
             // We don't care about peak picking performance for decoys
             if (truePeptide.IsDecoy)
                 continue;
             // We don't care about peak picking performance for standard peptides
             if (truePeptide.GlobalStandardType != null)
                 continue;
             var trueGroups = truePeptide.TransitionGroups.ToList();
             var pickedGroups = pickedPeptide.TransitionGroups.ToList();
             for (int k = 0; k < trueGroups.Count; k++)
             {
                 var trueGroup = trueGroups[k];
                 var pickedGroup = pickedGroups[k];
                 var trueResults = trueGroup.Results[i];
                 var pickedResults = pickedGroup.Results[i];
                 if (trueResults == null)
                     continue;
                 int nChromInfos = trueResults.Count;
                 for (int m = 0; m < nChromInfos; m++)
                 {
                     var trueInfo = trueResults[m];
                     var pickedInfo = pickedResults[m];
                     var fileInfo = set.GetFileInfo(trueInfo.FileId);
                     var filePath = fileInfo.FilePath;
                     var key = new MatchKey(trueGroup.Id.GlobalIndex, trueInfo.FileId.GlobalIndex);
                     matches.Add(new PeakBoundsMatch(trueInfo, pickedInfo, key, filePath, trueGroup,
                         HasNoQValues, HasNoScores, ApexPresent));
                 }
             }
         }
     }
     Matches = matches;
     // Detect if the apex time is in seconds, and if so adjust it to minutes
     if (ApexPresent)
     {
         double maxTime = matches.Where(match => match.PickedApex.HasValue)
                                 .Select(match => match.PickedApex.Value).Max();
         if (maxTime > PeakBoundaryImporter.GetMaxRt(DocOriginal))
         {
             foreach (var match in matches.Where(match => match.PickedApex.HasValue))
             {
                 match.PickedApex = match.PickedApex / 60;
             }
         }
     }
 }
Пример #6
0
        public void OkDialog()
        {
            var helper = new MessageBoxHelper(this);

            double qCutoff = double.MaxValue;
            if (reintegrateQCutoff.Checked)
            {
                if (!helper.ValidateDecimalTextBox(textBoxCutoff, 0.0, 1.0, out qCutoff))
                    return;
            }

            using (var longWaitDlg = new LongWaitDlg
                {
                    Text = Resources.ReintegrateDlg_OkDialog_Reintegrating,
                })
            {
                try
                {
                    if (_driverPeakScoringModel.SelectedItem == null || !_driverPeakScoringModel.SelectedItem.IsTrained)
                    {
                        throw new InvalidDataException(Resources.ReintegrateDlg_OkDialog_You_must_train_and_select_a_model_in_order_to_reintegrate_peaks_);
                    }
                    var scoringModel = _driverPeakScoringModel.SelectedItem;
                    var resultsHandler = new MProphetResultsHandler(Document, scoringModel)
                    {
                        QValueCutoff = qCutoff,
                        OverrideManual = checkBoxOverwrite.Checked,
                        AddAnnotation = checkBoxAnnotation.Checked,
                        AddMAnnotation = checkBoxAnnotation.Checked
                    };
                    longWaitDlg.PerformWork(this, 1000, pm =>
                        {
                            resultsHandler.ScoreFeatures(pm);
                            if (resultsHandler.IsMissingScores())
                            {
                                throw new InvalidDataException(Resources.ReintegrateDlg_OkDialog_The_current_peak_scoring_model_is_incompatible_with_one_or_more_peptides_in_the_document___Please_train_a_new_model_);
                            }
                            // TODO: Add a checkbox for including decoys.  Probably most of the time real users won't want to bother with reintegrating decoys
                            Document = resultsHandler.ChangePeaks(pm);
                        });
                    if (longWaitDlg.IsCanceled)
                        return;
                }
                catch (Exception x)
                {
                    var message = TextUtil.LineSeparate(string.Format(Resources.ReintegrateDlg_OkDialog_Failed_attempting_to_reintegrate_peaks_),
                                                                      x.Message);
                    MessageDlg.ShowWithException(this, message, x);
                    return;
                }
            }

            var newPeakScoringModel = _driverPeakScoringModel.SelectedItem;
            if (!Equals(newPeakScoringModel, Document.Settings.PeptideSettings.Integration.PeakScoringModel))
            {
                Document = Document.ChangeSettings(Document.Settings.ChangePeptideIntegration(
                    i => i.ChangePeakScoringModel(newPeakScoringModel)));
            }

            DialogResult = DialogResult.OK;
        }
        public void TestMProphetResultsHandler()
        {
            var testFilesDir = new TestFilesDir(TestContext, ZIP_FILE);
            var documentFile = testFilesDir.GetTestPath("MProphetGold-trained.sky");
            SrmDocument doc = ResultsUtil.DeserializeDocument(documentFile);
            // Load libraries
            doc = doc.ChangeSettings(doc.Settings.ChangePeptideLibraries(libraries =>
                {
                    var lib = libraries.Libraries[0];
                    return libraries.ChangeLibrarySpecs(new LibrarySpec[]
                        {
                            new BiblioSpecLiteSpec(lib.Name, testFilesDir.GetTestPath(lib.FileNameHint))
                        });
                }));
            // Load an empty doc, so that we can make a change and
            // cause the .skyd to be loaded
            var docContainer = new ResultsTestDocumentContainer(null, documentFile);
            docContainer.SetDocument(doc, null, true);
            docContainer.AssertComplete();
            SrmDocument docOriginal = docContainer.Document;
            var peakScoringModel = docOriginal.Settings.PeptideSettings.Integration.PeakScoringModel;
            var resultsHandler = new MProphetResultsHandler(docOriginal, peakScoringModel) { QValueCutoff = Q_CUTOFF };

            // 1. Reintegrate and export report produces expected file
            resultsHandler.ScoreFeatures();
            var docNew = resultsHandler.ChangePeaks();
            var reportSpec = MakeReportSpec();
            if (IsSaveAll)
            {
                // For regenerating expected files if things change
                ReportToCsv(reportSpec, docNew, testFilesDir.GetTestPath(REPORT_EXPECTED), CultureInfo.GetCultureInfo("en-US"));
                ReportToCsv(reportSpec, docNew, testFilesDir.GetTestPathIntl(REPORT_EXPECTED), CultureInfo.GetCultureInfo("fr-FR"));
            }
            string docNewActual = testFilesDir.GetTestPath(REPORT_ACTUAL);
            string docNewExpected = testFilesDir.GetTestPathLocale(REPORT_EXPECTED);
            ReportToCsv(reportSpec, docNew, docNewActual, CultureInfo.CurrentCulture);
            AssertEx.FileEquals(docNewExpected, docNewActual);

            // 2. Reintegrating again gives no change in document
            var resultsHandlerRepeat = new MProphetResultsHandler(docNew, peakScoringModel) { QValueCutoff = Q_CUTOFF };
            resultsHandlerRepeat.ScoreFeatures();
            var docRepeat = resultsHandlerRepeat.ChangePeaks();
            Assert.AreSame(docRepeat, docNew);
            Assert.AreNotSame(docOriginal, docNew);

            // 3. Export mProphet results gives expected file
            var calcs = peakScoringModel.PeakFeatureCalculators;
            var mProphetActual = testFilesDir.GetTestPath(MPROPHET_ACTUAL);
            var mProphetExpected = testFilesDir.GetTestPathLocale(MPROPHET_EXPECTED);
            if (IsSaveAll)
            {
                // For regenerating files
                SaveMProphetFeatures(resultsHandler, testFilesDir.GetTestPath(MPROPHET_EXPECTED), CultureInfo.GetCultureInfo("en-US"), calcs);
                SaveMProphetFeatures(resultsHandler, testFilesDir.GetTestPathIntl(MPROPHET_EXPECTED), CultureInfo.GetCultureInfo("fr-FR"), calcs);
            }
            SaveMProphetFeatures(resultsHandler, mProphetActual, CultureInfo.CurrentCulture, calcs);
            AssertEx.FileEquals(mProphetExpected, mProphetActual);

            // 4. Export mProphet -> Import Peak Boundaries leads to same result as reintegrate
            var resultsHandlerQAll = new MProphetResultsHandler(docOriginal, peakScoringModel) {QValueCutoff = 1.0};
            resultsHandlerQAll.ScoreFeatures();
            var docNewQAll = resultsHandlerQAll.ChangePeaks();
            var peakBoundaryImporter = new PeakBoundaryImporter(docNewQAll);
            long lineCount = Helpers.CountLinesInFile(mProphetActual);
            peakBoundaryImporter.Import(mProphetActual, null, lineCount);
            var docImport = peakBoundaryImporter.Document;
            // Serialized documents are easier to debug when something is different
            string strDocNew = SerializeDoc(docNewQAll);
            string strDocImport = SerializeDoc(docImport);
            AssertEx.NoDiff(strDocNew, strDocImport);
            Assert.AreSame(docNewQAll, docImport);

            // 5. Reintegration with q value cutoff of <0 causes all peaks set to null
            var handlerAllNull = new MProphetResultsHandler(docOriginal, peakScoringModel) {QValueCutoff = -0.001};
            handlerAllNull.ScoreFeatures();
            var docNull = handlerAllNull.ChangePeaks();
            foreach (var transitionNode in docNull.PeptideTransitions)
                foreach(var chromInfo in transitionNode.ChromInfos)
                    Assert.IsTrue(chromInfo.IsEmpty || transitionNode.IsDecoy);

            // 6. Reintegration adjusts example peak to null at q=0.005 cutoff, but adjusts it to a non-null peak at q=0.20
            const int groupNum = 11;
            var midQNode = resultsHandler.Document.PeptideTransitionGroups.ToList()[groupNum];
            foreach (var chromInfo in midQNode.Transitions.SelectMany(transition => transition.ChromInfos))
                Assert.IsTrue(chromInfo.IsEmpty);
            resultsHandler.QValueCutoff = Q_CUTOFF_HIGH;
            resultsHandler.ChangePeaks();
            var midQNodeNew = resultsHandler.Document.PeptideTransitionGroups.ToList()[groupNum];
            foreach (var chromInfo in midQNodeNew.Transitions.SelectMany(transition => transition.ChromInfos))
                Assert.IsFalse(chromInfo.IsEmpty);

            // 7. Labeled peptide pairs still have matching peaks
            foreach (var peptideNode in resultsHandler.Document.Peptides)
            {
                Assert.AreEqual(2, peptideNode.TransitionGroupCount);
                var groupList = peptideNode.TransitionGroups.ToList();
                var lightGroup = groupList[0];
                var heavyGroup = groupList[0];
                var lightChromInfo = lightGroup.ChromInfos.ToList()[0];
                var heavyChromInfo = heavyGroup.ChromInfos.ToList()[0];
                Assert.AreEqual(lightChromInfo.StartRetentionTime, heavyChromInfo.StartRetentionTime);
                Assert.AreEqual(lightChromInfo.EndRetentionTime, heavyChromInfo.EndRetentionTime);
                Assert.AreEqual(lightChromInfo.RetentionTime, heavyChromInfo.RetentionTime);
            }

            // 8. Verify that chosen peaks and q values are the same as those in mProphet paper:
            // http://www.nature.com/nmeth/journal/v8/n5/full/nmeth.1584.html#/supplementary-information
            // TODO: Grab this data from the mProphet paper

            // Release open streams
            docContainer.Release();
        }
 private static void SaveMProphetFeatures(MProphetResultsHandler resultsHandler, 
     string saveFile,
     CultureInfo cultureInfo,
     IList<IPeakFeatureCalculator> calcs)
 {
     using (var saver = new FileSaver(saveFile))
     using (var writer = new StreamWriter(saver.SafeName))
     {
         resultsHandler.WriteScores(writer, cultureInfo, calcs);
         writer.Flush();
         writer.Close();
         saver.Commit();
     }
 }