/// <summary>
        /// Factory method for creating the Workflow object using the WorkflowType information in the parameter object
        /// </summary>
        /// <param name="workflowParameters"></param>
        /// <returns></returns>
        public static TargetedWorkflow CreateWorkflow(WorkflowParameters workflowParameters)
        {
            TargetedWorkflow wf;

            switch (workflowParameters.WorkflowType)
            {
            case Globals.TargetedWorkflowTypes.Undefined:
                wf = new BasicTargetedWorkflow(workflowParameters as TargetedWorkflowParameters);
                break;

            case Globals.TargetedWorkflowTypes.UnlabelledTargeted1:
                wf = new BasicTargetedWorkflow(workflowParameters as TargetedWorkflowParameters);
                break;

            case Globals.TargetedWorkflowTypes.O16O18Targeted1:
                wf = new O16O18Workflow(workflowParameters as TargetedWorkflowParameters);
                break;

            case Globals.TargetedWorkflowTypes.N14N15Targeted1:
                wf = new N14N15Workflow2(workflowParameters as TargetedWorkflowParameters);
                break;

            case Globals.TargetedWorkflowTypes.SipperTargeted1:
                wf = new SipperTargetedWorkflow(workflowParameters as TargetedWorkflowParameters);
                break;

            case Globals.TargetedWorkflowTypes.TargetedAlignerWorkflow1:
                wf = new TargetedAlignerWorkflow(workflowParameters as TargetedWorkflowParameters);
                break;

            case Globals.TargetedWorkflowTypes.TopDownTargeted1:
                wf = new TopDownTargetedWorkflow(workflowParameters as TargetedWorkflowParameters);
                break;

            case Globals.TargetedWorkflowTypes.PeakDetectAndExportWorkflow1:
                throw new System.NotImplementedException("Cannot create this workflow type here.");

            case Globals.TargetedWorkflowTypes.BasicTargetedWorkflowExecutor1:
                throw new System.NotImplementedException("Cannot create this workflow type here.");

            case Globals.TargetedWorkflowTypes.UIMFTargetedMSMSWorkflowCollapseIMS:
                wf = new UIMFTargetedMSMSWorkflowCollapseIMS(workflowParameters as TargetedWorkflowParameters);
                break;

            default:
                wf = new BasicTargetedWorkflow(workflowParameters as TargetedWorkflowParameters);
                break;
            }

            return(wf);
        }
        public override void Execute()
        {
            List <TargetedResultBase> resultsPassingCriteria;

            _targetedResultRepository = new TargetedResultRepository();


            var featuresAreImportedFromFile = !string.IsNullOrEmpty(AlignerParameters.ImportedFeaturesFilename);

            if (featuresAreImportedFromFile)
            {
                //load them from the Features file
                var importer = new UnlabelledTargetedResultFromTextImporter(AlignerParameters.ImportedFeaturesFilename);
                var repo     = importer.Import();
                _targetedResultRepository.Results = repo.Results;
            }
            else
            {
                Check.Require(Run.ResultCollection.MSPeakResultList != null && Run.ResultCollection.MSPeakResultList.Count > 0, "Dataset's Peak-level data is empty. This is needed for chromatogram generation.");

                //execute targeted feature finding to find the massTags in the raw data

                _workflow = new BasicTargetedWorkflow(Run, AlignerParameters);

                var    netGrouping    = 0.2;
                double chromTolerance = 5;  //in ppm

                var progressString = "First trying to find alignment targets using narrow mass tolerances.... ";
                ReportProgress(0, progressString);
                var firstPassResults = FindTargetsThatPassSpecifiedMassTolerance(netGrouping, chromTolerance);

                if (firstPassResults.Count < 10)
                {
                    //try another netGrouping
                    netGrouping = 0.3;

                    chromTolerance = 20;
                    progressString = "Couldn't find enough. Now trying wider mass tolerance = " + chromTolerance;
                    ReportProgress(0, progressString);
                    var secondPassResults = FindTargetsThatPassSpecifiedMassTolerance(netGrouping, chromTolerance);
                    firstPassResults.AddRange(secondPassResults);
                }

                if (firstPassResults.Count < 10)
                {
                    netGrouping    = 0.4;
                    chromTolerance = 50;

                    progressString = "Ok this is a tough one. Now going even wider. Mass tolerance = " + chromTolerance;
                    ReportProgress(0, progressString);
                    var thirdPassResults = FindTargetsThatPassSpecifiedMassTolerance(netGrouping, chromTolerance);
                    firstPassResults.AddRange(thirdPassResults);
                }

                var ppmErrors = getMassErrors(firstPassResults);
                var filteredUsingGrubbsPPMErrors = MathUtilities.filterWithGrubbsApplied(ppmErrors);


                var canUseNarrowTolerances = executeDecisionOnUsingTightTolerances(filteredUsingGrubbsPPMErrors);



                if (canUseNarrowTolerances)
                {
                    var avgPPMError = filteredUsingGrubbsPPMErrors.Average();
                    var stdev       = MathUtilities.GetStDev(filteredUsingGrubbsPPMErrors);

                    var tolerance = Math.Abs(avgPPMError) + 2 * stdev;
                    this.AlignerParameters.ChromGenTolerance = (int)Math.Ceiling(tolerance);
                    this.AlignerParameters.MSToleranceInPPM  = (int)Math.Ceiling(tolerance);

                    progressString = "STRICT_Matches_AveragePPMError = \t" + avgPPMError.ToString("0.00") + "; Stdev = \t" + stdev.ToString("0.00000");
                    ReportProgress(0, progressString);

                    progressString = "NOTE: using the new PPMTolerance=  " + this.AlignerParameters.ChromGenTolerance;
                    ReportProgress(0, progressString);

                    _workflow = new BasicTargetedWorkflow(Run, AlignerParameters);
                }
                else
                {
                    double avgPPMError = 0;
                    double stdev       = 0;
                    if (filteredUsingGrubbsPPMErrors.Count != 0)
                    {
                        avgPPMError = filteredUsingGrubbsPPMErrors.Average();
                        stdev       = MathUtilities.GetStDev(filteredUsingGrubbsPPMErrors);
                    }


                    progressString = "STRICT_Matches_AveragePPMError = \t" + avgPPMError.ToString("0.00") + "; Stdev = \t" + stdev.ToString("0.00000");
                    ReportProgress(0, progressString);

                    progressString = "Cannot use narrow ppm tolerances during NET/Mass alignment. Either the massError was too high or couldn't find enough strict matches.";
                    ReportProgress(0, progressString);

                    // find a way to work with datasets with masses way off but low stdev
                }


                resultsPassingCriteria = FindTargetsThatPassCriteria();

                _targetedResultRepository.AddResults(resultsPassingCriteria);
            }

            var canDoAlignment = _targetedResultRepository.Results.Count > 0;

            if (canDoAlignment)
            {
                doAlignment();
            }
        }
 protected override void DoPostInitialization()
 {
     base.DoPostInitialization();
     _workflow = new BasicTargetedWorkflow(Run, WorkflowParameters as TargetedWorkflowParameters);
 }