public void Run(bool runDoseComparisons, bool runPDDComparisons, string SaveDirectory, object sender)
        {
            // Maximum number of CPU threads
            ParallelOptions cpuParallel = new ParallelOptions {
                MaxDegreeOfParallelism = Environment.ProcessorCount
            };
            ParallelOptions parallel = cpuParallel;
            // I'm only going to code this for 1 GPU
            ParallelOptions gpuParallel = new ParallelOptions {
                MaxDegreeOfParallelism = 1
            };


            // Sets the system to use the correct resources without doubling down on GPU
            if (UseGPU)
            {
                mathematics = new X86Mathematics();
                parallel    = gpuParallel;
            }
            else
            {
                mathematics = new X86Mathematics();
                parallel    = cpuParallel;
            }

            double progress = 0;

            #region safetyChecks
            try
            {
                _ = SourceDirectory.IsNormalized();
            }
            catch (NullReferenceException)
            {
                throw new NullReferenceException("Source directory cannot be null");
            }

            try
            {
                _ = TargetDirectory.IsNormalized();
            }
            catch (NullReferenceException)
            {
                throw new NullReferenceException("Target directory cannot be null");;
            }

            if (SourceListStrings.Length <= 0)
            {
                throw new InvalidOperationException("There are no Dose files in the source directory Tree");
            }
            if (TargetListStrings.Length <= 0)
            {
                throw new InvalidOperationException("There are no Dose files in the Target directory Tree");
            }
            #endregion

            #region setup
            (sender as BackgroundWorker).ReportProgress((int)progress, "Setup: Scanning Source Doses ");
            SourceDosesList = FileHandler.DoseFiles(SourceListStrings);
            (sender as BackgroundWorker).ReportProgress((int)progress, "Setup: Scanning Source Plans ");
            SourcePlanList = FileHandler.PlanFiles(SourceListStrings);
            (sender as BackgroundWorker).ReportProgress((int)progress, "Setup: Scanning Target Doses ");
            TargetDosesList = FileHandler.DoseFiles(TargetListStrings);
            (sender as BackgroundWorker).ReportProgress((int)progress, "Setup: Scanning Target Plans ");
            TargetPlanList = FileHandler.PlanFiles(TargetListStrings);


            #endregion


            DosePairsList  = new ConcurrentBag <MatchedDosePair>();
            ResultMessage  = "Tight Tolerance, " + (100 * TightTol).ToString();
            ResultMessage += "\nMain Tolerance, " + (100 * MainTol).ToString();
            ResultMessage += "\nThreshold, " + (100 * ThresholdTol).ToString() + "\n";
            ResultMessage += MatchedDosePair.ResultHeader;

            progress += 5;

            (sender as BackgroundWorker).ReportProgress((int)progress, "Scanning Source Folder");
            _ = Parallel.ForEach(SourceDosesList, new ParallelOptions {
                MaxDegreeOfParallelism = Environment.ProcessorCount
            }, doseFile =>
            {
                doseFile.SetFieldName(SourcePlanList);
            });

            progress += 5;
            (sender as BackgroundWorker).ReportProgress((int)progress, "Scanning Target Folder");
            _ = Parallel.ForEach(TargetDosesList, new ParallelOptions {
                MaxDegreeOfParallelism = Environment.ProcessorCount
            }, doseFile =>
            {
                doseFile.SetFieldName(TargetPlanList);
            });


            double ProgressIncrimentor = 10.0 / TargetDosesList.Count;
            (sender as BackgroundWorker).ReportProgress((int)progress, "Matching");
            // match each pair for analysis
            _ = Parallel.ForEach(TargetDosesList, cpuParallel, (dose) =>
            {
                progress += ProgressIncrimentor;
                progress %= 100;
                (sender as BackgroundWorker).ReportProgress((int)progress, "Matching");
                var sourceDose = SourceDosesList.Find(x => x.MatchIdentifier == dose.MatchIdentifier);
                if (sourceDose != null)
                {
                    Debug.WriteLine("matched " + dose.FileName + " and " + sourceDose.FileName);
                    DosePairsList.Add(new MatchedDosePair(sourceDose, dose, this.ThresholdTol, this.TightTol,
                                                          this.MainTol));
                }
            });
            if (DosePairsList.Count <= 0)
            {
                return;
            }
            progress            = 39;
            ProgressIncrimentor = 30.0 / DosePairsList.Count;
            progress           %= 100;
            (sender as BackgroundWorker).ReportProgress((int)progress, "PDD Production");
            if (runPDDComparisons)
            {
                _ = Parallel.ForEach(DosePairsList, cpuParallel, pair =>
                {
                    progress += ProgressIncrimentor;
                    progress %= 100;
                    (sender as BackgroundWorker).ReportProgress((int)progress, "PDD Production");
                    pair.GeneratePDD();
                    Debug.WriteLine("Saving " + pair.ChartTitle + " to " + SaveDirectory);
                    try
                    {
                        SaveFile saveFile = new SaveFile(pair.ChartTitle, SaveDirectory);
                        pair.PDDoutString = saveFile.Save(pair.SourcePDD, pair.TargetPDD, pair.ChartFileName, SaveDirectory, pair.ChartTitle, SourceAliasName, TargetAliasName);
                    }
                    catch (Exception)
                    {
                        Debug.WriteLine("Failed to save " + pair.ChartTitle);
                    }
                });
                progress = 69;

                //fix for memory abuse is to limit the number of cores, Arbitrarily I have hard coded it to half the logical cores of the system.
                if (runDoseComparisons)
                {
                    ProgressIncrimentor = 30.0 / DosePairsList.Count;
                    _ = Parallel.ForEach(DosePairsList, parallel, pair =>
                    {
                        progress += ProgressIncrimentor;
                        progress %= 100;
                        (sender as BackgroundWorker).ReportProgress((int)progress, "Comparing " + progress);
                        try
                        {
                            pair.Evaluate(mathematics, fuzzy);
                            ResultMessage += pair.ResultString + '\n';
                        }
                        // Will catch array misalignment problems
                        catch (Exception e)
                        {
                            string temp    = pair.Name + ",Was not Evaluated ,\n";
                            ResultMessage += temp;
                            Debug.WriteLine(temp);
                            Debug.WriteLine(e.Message.ToString());
                            Debug.Write(e.StackTrace.ToString());
                        }
                    });
                }
            }
        }
 public int CreateSourceList(string folder)
 {
     SourceDirectory   = folder;
     SourceListStrings = FileHandler.LoadListRdDcmList(folder);
     return(SourceListStrings.Length);
 }
 public int CreateTargetList(string folder)
 {
     TargetDirectory   = folder;
     TargetListStrings = FileHandler.LoadListRdDcmList(folder);
     return(TargetListStrings.Length);
 }