Example #1
0
 // This method gets called by the runtime. Use this method to add services to the container.
 public void ConfigureServices(IServiceCollection services)
 {
     // (1) - Dependency Inyection
     DependencyInjectionConfig.Register(services);
     // (2) - AutoMapper Configuration
     AutoMapperConfig.Register(services);
     // (3) - Swagger Configuration
     SwaggerConfig.Register(services);
     // (4) - Setting Configuration
     AppSettingsConfig.Register(services, _env, Configuration);
     // (5) -
     services.AddControllers();
     // (6) - Filters configurations
     FiltersConfig.Register(services);
 }
Example #2
0
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
            FiltersConfig.RegisterGlobalFilters(GlobalFilters.Filters);

            var roller      = Enum.GetNames(typeof(IdentityRoles));
            var roleManager = MembershipTools.NewRoleManager();

            foreach (var rol in roller)
            {
                if (!roleManager.RoleExists(rol))
                {
                    roleManager.Create(new Role()
                    {
                        Name = rol
                    });
                }
            }
        }
Example #3
0
        protected void ConfigureApp(IContainer container, IAppBuilder app)
        {
            HttpConfiguration = new HttpConfiguration
            {
                DependencyResolver = new AutofacWebApiDependencyResolver(container)
            };

            HttpConfiguration.Formatters.Clear();
            HttpConfiguration.Formatters.Add(new JsonMediaTypeFormatter());
            HttpConfiguration.Formatters.JsonFormatter.SerializerSettings = new Newtonsoft.Json.JsonSerializerSettings();
            //HttpConfiguration.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/octet-stream"));

            app.UseAutofacMiddleware(container);
            app.UseAutofacWebApi(HttpConfiguration);

            //ConfigureOAuth(app);
            RouteConfig.Register(HttpConfiguration);
            FiltersConfig.Register(HttpConfiguration);

            app.UseCors(CorsOptions.AllowAll);
            app.UseWebApi(HttpConfiguration);
            app.Use <GlobalExceptionMiddleware>();
        }
Example #4
0
        public static void GetSummaryForDirectory(string foldersPath, int timeColumnIndex, int eyeColumnIndex, int spotColumnIndex,
                                                  CalcConfig calcConfig, FiltersConfig filtersConfig)
        {
            var fileDataProcessor = new FileDataProcessor();

            string[] directories = Directory.GetDirectories(foldersPath);
            var      sb          = new StringBuilder();

            foreach (var directoryPath in directories)
            {
                foreach (var filePath in Directory.GetFiles(directoryPath))
                {
                    if (filePath.EndsWith("result_out.txt"))
                    {
                        //var csvData = fileDataProcessor.CalculateFileData(filePath, timeColumnIndex, eyeColumnIndex, spotColumnIndex, calcConfig, filtersConfig);
                        //sb.Append(directoryPath + Environment.NewLine);
                        //sb.Append(csvData);
                    }
                }
            }

            SaveText(@"D:\BulkResult.txt", sb.ToString());
        }
Example #5
0
 public static void GetPOMSummary(SpotGazeFileData fileData, FiltersConfig pursuitWindowsFilterConfig)
 {
     var pursuitCalculations = DataAnalyzer.CountSingleTypeSignalPursuitParameters(fileData, pursuitWindowsFilterConfig);
     var sinGain             = pursuitCalculations.Gains.FirstOrDefault().Value;
     var sinAccuracy         = pursuitCalculations.Accuracies.FirstOrDefault().Value;
 }
Example #6
0
        public static string GetCsvOutput(bool addHeader, List <EyeMoveCalculation> saccadeCalculations,
                                          List <EyeMoveCalculation> antiSaccadeCalculations, EyeMoveCalculation pursuitMoveCalculations, CalcConfig config, FiltersConfig filtersConfig)
        {
            string csvDelimiter = " "; //"\t";
            var    sb           = new StringBuilder();

            sb.Append("Saccades:");
            sb.Append(Environment.NewLine);
            if (addHeader)
            {
                sb.Append("ID" + csvDelimiter);
                sb.Append("FromFixationPoint" + csvDelimiter);
                sb.Append("EyeMoveType" + csvDelimiter);
                sb.Append("Latency" + csvDelimiter);
                sb.Append("Duration" + csvDelimiter);
                sb.Append("Distance" + csvDelimiter);
                sb.Append("Amplitude" + csvDelimiter);
                sb.Append("AvgVelocity" + csvDelimiter);
                sb.Append("MaxVelocity" + csvDelimiter);
                sb.Append("Gain" + Environment.NewLine);
            }

            foreach (var outputItem in saccadeCalculations)
            {
                sb.Append(outputItem.EyeMove.Id + csvDelimiter);
                sb.Append(outputItem.EyeMove.IsFirstMove + csvDelimiter);
                sb.Append(outputItem.EyeMove.EyeMoveType + csvDelimiter);
                sb.Append(outputItem.Latency + csvDelimiter);
                sb.Append(outputItem.Duration + csvDelimiter);
                sb.Append(outputItem.Distance + csvDelimiter);
                sb.Append(outputItem.Amplitude + csvDelimiter);
                sb.Append(outputItem.AvgVelocity + csvDelimiter);
                sb.Append(outputItem.MaxVelocity + csvDelimiter);
                sb.Append(outputItem.Gain + csvDelimiter);
                sb.Append(Environment.NewLine);
            }

            sb.Append(Environment.NewLine);
            sb.Append(Environment.NewLine);
            sb.Append("AntiSaccades:");
            sb.Append(Environment.NewLine);
            if (addHeader)
            {
                sb.Append("ID" + csvDelimiter);
                sb.Append("FromFixationPoint" + csvDelimiter);
                sb.Append("EyeMoveType" + csvDelimiter);
                sb.Append("Latency" + csvDelimiter);
                sb.Append("Duration" + csvDelimiter);
                sb.Append("Distance" + csvDelimiter);
                sb.Append("Amplitude" + csvDelimiter);
                sb.Append("AvgVelocity" + csvDelimiter);
                sb.Append("MaxVelocity" + csvDelimiter);
                sb.Append("Gain" + Environment.NewLine);
            }

            foreach (var outputItem in antiSaccadeCalculations)
            {
                sb.Append(outputItem.EyeMove.Id + csvDelimiter);
                sb.Append(outputItem.EyeMove.IsFirstMove + csvDelimiter);
                sb.Append(outputItem.EyeMove.EyeMoveType + csvDelimiter);
                sb.Append(outputItem.Latency + csvDelimiter);
                sb.Append(outputItem.Duration + csvDelimiter);
                sb.Append(outputItem.Distance + csvDelimiter);
                sb.Append(outputItem.Amplitude + csvDelimiter);
                sb.Append(outputItem.AvgVelocity + csvDelimiter);
                sb.Append(outputItem.MaxVelocity + csvDelimiter);
                sb.Append(outputItem.Gain + csvDelimiter);
                sb.Append(Environment.NewLine);
            }

            sb.Append(Environment.NewLine);
            sb.Append(Environment.NewLine);
            sb.Append("Pursuit:");
            sb.Append(Environment.NewLine);

            if (addHeader)
            {
                sb.Append("Long Sin Gain" + csvDelimiter);
                sb.Append("Mid Sin Gain" + csvDelimiter);
                sb.Append("Short Sin Gain" + csvDelimiter);
                sb.Append("Long Sin Accuracy" + csvDelimiter);
                sb.Append("Mid Sin Accuracy" + csvDelimiter);
                sb.Append("Short Sin Accuracy" + csvDelimiter);
                sb.Append(Environment.NewLine);
            }


            sb.Append(pursuitMoveCalculations.PursuitLongSinGain + csvDelimiter);
            sb.Append(pursuitMoveCalculations.PursuitMidSinGain + csvDelimiter);
            sb.Append(pursuitMoveCalculations.PursuitShortSinGain + csvDelimiter);
            sb.Append(pursuitMoveCalculations.PursuitLongSinAccuracy + csvDelimiter);
            sb.Append(pursuitMoveCalculations.PursuitMidSinAccuracy + csvDelimiter);
            sb.Append(pursuitMoveCalculations.PursuitShortSinAccuracy + csvDelimiter);
            sb.Append(Environment.NewLine);

            sb.Append(Environment.NewLine);
            sb.Append(Environment.NewLine);
            sb.Append("Found");
            sb.Append(Environment.NewLine);
            sb.Append($"Saccades: {saccadeCalculations.Count}");
            sb.Append(Environment.NewLine);
            sb.Append($"AntiSaccades: {antiSaccadeCalculations.Count}");
            sb.Append(Environment.NewLine);
            sb.Append($"Inorrect AntiSaccades: {19 - antiSaccadeCalculations.Count}");

            sb.Append(Environment.NewLine);
            sb.Append(Environment.NewLine);
            sb.Append("Settings");
            sb.Append(Environment.NewLine);
            sb.Append($"Distance From Screen: {csvDelimiter} {config.DistanceFromScreen}");
            sb.Append(Environment.NewLine);
            sb.Append($"Tracker Frequency: {csvDelimiter} {config.TrackerFrequency}");
            sb.Append(Environment.NewLine);
            sb.Append(Environment.NewLine);
            sb.Append("Sacade Search Configuration");
            sb.Append(Environment.NewLine);
            sb.Append($"Min.Latency: {csvDelimiter} {config.SaccadeMoveFinderConfig.MinLatency}");
            sb.Append(Environment.NewLine);
            sb.Append($"Min.Duration: {csvDelimiter}  {config.SaccadeMoveFinderConfig.MinDuration}");
            sb.Append(Environment.NewLine);
            sb.Append($"Control Window Length: {csvDelimiter} {config.SaccadeMoveFinderConfig.ControlWindowLength}");
            sb.Append(Environment.NewLine);
            sb.Append($"Control Amplitude Divider: {csvDelimiter} {config.SaccadeMoveFinderConfig.ControlAmpDivider}");
            sb.Append(Environment.NewLine);
            sb.Append($"Move Search Window Length: {csvDelimiter} {config.SaccadeMoveFinderConfig.MoveSearchWindowLength}");
            sb.Append(Environment.NewLine);
            sb.Append($"Move Min.Length: {csvDelimiter} {config.SaccadeMoveFinderConfig.MinLength}");
            sb.Append(Environment.NewLine);
            sb.Append($"Min.Inhibition: {csvDelimiter} {config.SaccadeMoveFinderConfig.MinInhibition}");
            sb.Append(Environment.NewLine);
            sb.Append($"Min.Amplitude: {csvDelimiter} {config.AntiSaccadeMoveFinderConfig.MinAmp}");
            sb.Append(Environment.NewLine);
            sb.Append($"Max.Amplitude: {csvDelimiter} {config.AntiSaccadeMoveFinderConfig.MaxAmp}");
            sb.Append(Environment.NewLine);
            sb.Append(Environment.NewLine);

            sb.Append("AntiSacade Search Configuration");
            sb.Append(Environment.NewLine);
            sb.Append($"Min.Latency: {csvDelimiter} {config.AntiSaccadeMoveFinderConfig.MinLatency}");
            sb.Append(Environment.NewLine);
            sb.Append($"Min.Duration: {csvDelimiter}  {config.AntiSaccadeMoveFinderConfig.MinDuration}");
            sb.Append(Environment.NewLine);
            sb.Append($"Control Window Length: {csvDelimiter} {config.AntiSaccadeMoveFinderConfig.ControlWindowLength}");
            sb.Append(Environment.NewLine);
            sb.Append($"Control Amplitude Divider: {csvDelimiter} {config.AntiSaccadeMoveFinderConfig.ControlAmpDivider}");
            sb.Append(Environment.NewLine);
            sb.Append($"Move Search Window Length: {csvDelimiter} {config.AntiSaccadeMoveFinderConfig.MoveSearchWindowLength}");
            sb.Append(Environment.NewLine);
            sb.Append($"Move Min.Length: {csvDelimiter} {config.AntiSaccadeMoveFinderConfig.MinLength}");
            sb.Append(Environment.NewLine);
            sb.Append($"Min.Inhibition: {csvDelimiter} {config.AntiSaccadeMoveFinderConfig.MinInhibition}");
            sb.Append(Environment.NewLine);
            sb.Append($"Min.Amplitude: {csvDelimiter} {config.AntiSaccadeMoveFinderConfig.MinAmp}");
            sb.Append(Environment.NewLine);
            sb.Append($"Max.Amplitude: {csvDelimiter} {config.AntiSaccadeMoveFinderConfig.MaxAmp}");
            sb.Append(Environment.NewLine);

            if (filtersConfig.FilterByButterworth)
            {
                sb.Append(Environment.NewLine);
                sb.Append($"Filter Butterworth Settings:");
                sb.Append(Environment.NewLine);
                sb.Append($"Pass Type: {csvDelimiter} {filtersConfig.ButterworthPassType}");
                sb.Append(Environment.NewLine);
                sb.Append($"Frequency: {csvDelimiter} {filtersConfig.ButterworthFrequency}");
                sb.Append(Environment.NewLine);
                sb.Append($"Resonance: {csvDelimiter} {filtersConfig.ButterworthResonance}");
                sb.Append(Environment.NewLine);
                sb.Append($"SampleRate: {csvDelimiter} {filtersConfig.ButterworthSampleRate}");
                sb.Append(Environment.NewLine);
            }

            if (filtersConfig.FilterBySavitzkyGolay)
            {
                sb.Append(Environment.NewLine);
                sb.Append($"Filter Savitzky-Golay Settings:");
                sb.Append(Environment.NewLine);
                sb.Append($"Number Of Points: {csvDelimiter} {filtersConfig.SavitzkyGolayNumberOfPoints}");
                sb.Append(Environment.NewLine);
                sb.Append($"Derivative Order: {csvDelimiter} {filtersConfig.SavitzkyGolayDerivativeOrder}");
                sb.Append(Environment.NewLine);
                sb.Append($"Polynominal Order: {csvDelimiter} {filtersConfig.SavitzkyGolayPolynominalOrder}");
                sb.Append(Environment.NewLine);
            }

            if (saccadeCalculations?.Count > 0)
            {
                var saccStats = GetStatsForCollection(saccadeCalculations);
                sb.Append(Environment.NewLine);
                sb.Append("Saccade Statistics");
                sb.Append(Environment.NewLine);
                sb.Append(saccStats);
            }

            if (antiSaccadeCalculations?.Count > 0)
            {
                var antiSaccStats = GetStatsForCollection(antiSaccadeCalculations);
                sb.Append(Environment.NewLine);
                sb.Append("AntiSaccade Statistics");
                sb.Append(Environment.NewLine);
                sb.Append(antiSaccStats);
            }
            return(sb.ToString());
        }
        public static PursuitGainCalculations CountSingleTypeSignalPursuitParameters(SpotGazeFileData fileData, FiltersConfig filterConfig)
        {
            var mincal = fileData.Spot.Min();
            var maxcal = fileData.Spot.Max();
            var amp    = (maxcal - mincal) / 2;
            var srod   = (maxcal + mincal) / 2;

            var maxIndex  = fileData.Spot.ToList().IndexOf(maxcal);
            var minIndex  = fileData.Spot.ToList().IndexOf(mincal);
            var sinLenght = Convert.ToDouble(Math.Abs(maxIndex - minIndex));

            var kspIndexes            = new List <int>();
            var accuracyKspDiffValues = new List <double>();
            var accuracyKspSpotValues = new List <double>();

            for (int i = 0; i < fileData.Spot.Length; i++)
            {
                var xSpot = fileData.Spot[i];

                if (Math.Abs(xSpot - srod) > amp * 0.995D)
                {
                    kspIndexes.Add(i);

                    //Accuracy
                    var xEye    = fileData.Eye[i];
                    var diffVal = Math.Abs(xEye - xSpot);
                    accuracyKspDiffValues.Add(diffVal);
                    accuracyKspSpotValues.Add(Math.Abs(xSpot));
                }
            }

            var kspEyeValues  = new List <double>();
            var kspSpotValues = new List <double>();

            var results = new List <double>();

            var filteredControlWindows = new List <Dictionary <double, double> >();
            var kspDiffValues          = new List <Dictionary <double, double> >();

            //fix first sin
            var kspStartIndex = 0;

            for (int i = 0; i < kspIndexes.Count - 1; i++)
            {
                var result = kspIndexes[i + 1] - kspIndexes[i];
                if (result > 30)
                {
                    kspStartIndex = i;
                    break;
                }
            }

            //fix last sin
            var kspEndIndex = kspIndexes.Count;

            for (int y = kspIndexes.Count; y-- > 1;)
            {
                var endRsult = kspIndexes[y] - kspIndexes[y - 1];
                if (endRsult > 20)
                {
                    kspEndIndex = y;
                    break;
                }
            }

            kspIndexes = kspIndexes.Skip(kspStartIndex + 1).Take(kspEndIndex - kspStartIndex - 1).ToList();

            for (int j = 0; j < kspIndexes.Count; j++)
            {
                var index = kspIndexes[j];

                var controlWindow       = new List <double>();
                var controlTimeDeltas   = new List <double>();
                var controlWindowLength = Convert.ToInt32(Math.Round(sinLenght / 5, 0));

                if (j > 0)
                {
                    controlWindow     = fileData.Eye.Skip(index - (controlWindowLength / 2)).Take(controlWindowLength).ToList();
                    controlTimeDeltas = fileData.TimeDeltas.Skip(index - (controlWindowLength / 2)).Take(controlWindowLength).ToList();
                }
                else
                {
                    controlWindow     = fileData.Eye.Skip(index).Take(controlWindowLength).ToList();
                    controlTimeDeltas = fileData.TimeDeltas.Skip(index).Take(controlWindowLength).ToList();
                }

                if (filterConfig.FilterByButterworth)
                {
                    controlWindow = FilterController.FilterByButterworth(filterConfig, controlWindow.ToArray()).ToList();
                }

                var filteredWindowItems = new Dictionary <double, double>();
                for (int g = 0; g < controlWindow.Count(); g++)
                {
                    filteredWindowItems.Add(controlTimeDeltas[g], controlWindow[g]);
                }
                filteredControlWindows.Add(filteredWindowItems);

                double eyeValue = controlWindow.Average();

                var spotValue = fileData.Spot[index];
                var result    = eyeValue / spotValue;
                results.Add(result);
            }

            var gainCalculations = new Dictionary <string, double?>();
            var longSinGain      = results.Average();

            gainCalculations.Add("Long", longSinGain);

            var longSinW1  = accuracyKspDiffValues.Sum();
            var longSinW2  = accuracyKspSpotValues.Sum();
            var longSinAcc = 1D - (longSinW1 / longSinW2);

            var accuracyCalculations = new Dictionary <string, double?>();

            accuracyCalculations.Add("Long", longSinAcc);

            return(new PursuitGainCalculations
            {
                Gains = gainCalculations,
                Accuracies = accuracyCalculations,
                FilteredControlWindows = filteredControlWindows
            });
        }
        public static PursuitGainCalculations CountCompoundSignalPursuitParameters(SpotGazeFileData fileData, FiltersConfig filterConfig)
        {
            var mncal = fileData.Spot.Min();
            var mxcal = fileData.Spot.Max();
            var amp   = (mxcal - mncal) / 2;
            var srod  = (mxcal + mncal) / 2;

            var start = fileData.Eye.FirstOrDefault(x => x == srod);


            var testValues = new List <double>();

            var kspIndexes            = new List <KeyValuePair <double, int> >();
            var accuracyKspSpotValues = new List <KeyValuePair <double, double> >();
            var accuracyKspDiffValues = new List <KeyValuePair <double, double> >();

            double sinLongStart;
            double sinMidStart;
            double sinShortStart;
            double sinLongEnd;
            double sinMidEnd;
            double sinShortEnd;

            if (fileData.FileType == FileType.Maruniec)
            {
                // maruniec do zrobienia
                sinMidStart   = 37 * Consts.TimeScaleFactorStandard;
                sinShortStart = 79 * Consts.TimeScaleFactorStandard;
            }
            else
            {
                sinLongStart = 12 * Consts.TimeScaleFactorStandard;
                sinLongEnd   = 32 * Consts.TimeScaleFactorStandard;

                sinMidStart = 40 * Consts.TimeScaleFactorStandard;
                sinMidEnd   = 68 * Consts.TimeScaleFactorStandard;

                sinShortStart = 77 * Consts.TimeScaleFactorStandard;
                sinShortEnd   = 90 * Consts.TimeScaleFactorStandard;
            }

            var unifiedTimeStamps = InputDataHelper.GetTimeStampsScaled(fileData.Time, fileData.FileType);

            for (int i = 0; i < fileData.Spot.Length; i++)
            {
                var xSpot = fileData.Spot[i];

                var sinLenght = 240D;

                if (unifiedTimeStamps[i] >= sinMidStart && unifiedTimeStamps[i] <= sinShortStart)
                {
                    sinLenght = 120D;
                }
                else if (unifiedTimeStamps[i] >= sinShortStart)
                {
                    sinLenght = 30D;
                }


                if (Math.Abs(xSpot - srod) > amp * 0.995D)
                {
                    kspIndexes.Add(new KeyValuePair <double, int>(sinLenght, i));

                    //Accuracy
                    var xEye    = fileData.Eye[i];
                    var diffVal = Math.Abs(xEye - xSpot);
                    accuracyKspDiffValues.Add(new KeyValuePair <double, double>(sinLenght, diffVal));
                    accuracyKspSpotValues.Add(new KeyValuePair <double, double>(sinLenght, Math.Abs(xSpot)));
                }
            }


            var kspEyeValues  = new List <double>();
            var kspSpotValues = new List <double>();

            var results                = new List <KeyValuePair <double, double> >();
            var isPositive             = true;
            var times                  = new List <double>();
            var filteredControlWindows = new List <Dictionary <double, double> >();
            var kspDiffValues          = new List <Dictionary <double, double> >();

            for (int j = 0; j < kspIndexes.Count; j++)
            {
                var sinLenght = kspIndexes[j].Key;
                var index     = kspIndexes[j].Value;

                var time = InputDataHelper.GetScaledTimeFromIndex(fileData, index).GetValueOrDefault();
                times.Add(time);

                var controlWindow       = new List <double>();
                var controlTimeDeltas   = new List <double>();
                var controlWindowLength = Convert.ToInt32(Math.Round(sinLenght / 5, 0));

                if (j > 0)
                {
                    controlWindow     = fileData.Eye.Skip(index - (controlWindowLength / 2)).Take(controlWindowLength).ToList();
                    controlTimeDeltas = fileData.TimeDeltas.Skip(index - (controlWindowLength / 2)).Take(controlWindowLength).ToList();
                }
                else
                {
                    controlWindow     = fileData.Eye.Skip(index).Take(controlWindowLength).ToList();
                    controlTimeDeltas = fileData.TimeDeltas.Skip(index).Take(controlWindowLength).ToList();
                }

                if (filterConfig.FilterByButterworth)
                {
                    controlWindow = FilterController.FilterByButterworth(filterConfig, controlWindow.ToArray()).ToList();
                }

                var filteredWindowItems = new Dictionary <double, double>();
                for (int g = 0; g < controlWindow.Count(); g++)
                {
                    filteredWindowItems.Add(controlTimeDeltas[g], controlWindow[g]);
                }
                filteredControlWindows.Add(filteredWindowItems);

                double eyeValue;
                if (isPositive)
                {
                    eyeValue   = controlWindow.Average(); //Max();
                    isPositive = false;
                }
                else
                {
                    eyeValue   = controlWindow.Average(); //Min();
                    isPositive = true;
                }

                if (sinLenght == 30D)
                {
                    testValues.Add(eyeValue);
                }

                //var eyeValue = fileData.Eye[index];
                var spotValue = fileData.Spot[index];
                var result    = eyeValue / spotValue;
                results.Add(new KeyValuePair <double, double>(sinLenght, result));
            }

            var longSinGain = new double?();

            if (results.Where(x => x.Key == 240D).Count() > 0)
            {
                longSinGain = results.Where(x => x.Key == 240D).Select(x => x.Value).Average();
            }

            var midSinGain = new double?();

            if (results.Where(x => x.Key == 120D).Select(x => x.Value).Count() > 0)
            {
                midSinGain = results.Where(x => x.Key == 120D).Select(x => x.Value).Average();
            }

            var shortSinGain = new double?();

            if (results.Where(x => x.Key == 30D).Select(x => x.Value).Count() > 0)
            {
                shortSinGain = results.Where(x => x.Key == 30D).Select(x => x.Value).Average();
            }

            var gainCalculations = new Dictionary <string, double?>();

            if (longSinGain.HasValue)
            {
                gainCalculations.Add("Long", longSinGain.GetValueOrDefault());
            }
            else
            {
                gainCalculations.Add("Long", null);
            }

            if (midSinGain.HasValue)
            {
                gainCalculations.Add("Mid", midSinGain.GetValueOrDefault());
            }
            else
            {
                gainCalculations.Add("Mid", null);
            }

            if (shortSinGain.HasValue)
            {
                gainCalculations.Add("Short", shortSinGain.GetValueOrDefault());
            }
            else
            {
                gainCalculations.Add("Short", null);
            }

            var longSinAcc = new double?();

            if (accuracyKspDiffValues.Where(x => x.Key == 240D).Count() > 0 && accuracyKspSpotValues.Where(x => x.Key == 240D).Count() > 0)
            {
                var longSinW1 = accuracyKspDiffValues.Where(x => x.Key == 240D).Select(x => x.Value).Sum();
                var longSinW2 = accuracyKspSpotValues.Where(x => x.Key == 240D).Select(x => x.Value).Sum();
                longSinAcc = 1D - (longSinW1 / longSinW2);
            }

            var midSinAcc = new double?();

            if (accuracyKspDiffValues.Where(x => x.Key == 120D).Count() > 0 && accuracyKspDiffValues.Where(x => x.Key == 120D).Count() > 0)
            {
                var midSinW1 = accuracyKspDiffValues.Where(x => x.Key == 120D).Select(x => x.Value).Sum();
                var midSinW2 = accuracyKspSpotValues.Where(x => x.Key == 120D).Select(x => x.Value).Sum();
                midSinAcc = 1D - (midSinW1 / midSinW2);
            }


            var shortSinAcc = new double?();

            if (accuracyKspDiffValues.Where(x => x.Key == 30D).Count() > 0 && accuracyKspDiffValues.Where(x => x.Key == 30D).Count() > 0)
            {
                var shortSinW1 = accuracyKspDiffValues.Where(x => x.Key == 30D).Select(x => x.Value).Sum();
                var shortSinW2 = accuracyKspSpotValues.Where(x => x.Key == 30D).Select(x => x.Value).Sum();
                shortSinAcc = 1D - (shortSinW1 / shortSinW2);
            }
            else
            {
                shortSinAcc = null;
            }

            var accuracyCalculations = new Dictionary <string, double?>();

            accuracyCalculations.Add("Long", longSinAcc);
            accuracyCalculations.Add("Mid", midSinAcc);
            accuracyCalculations.Add("Short", shortSinAcc);

            return(new PursuitGainCalculations {
                Gains = gainCalculations, Accuracies = accuracyCalculations,
                FilteredControlWindows = filteredControlWindows
            });
        }