private CcgPopulation NewPopulation(string areaCode)
 {
     var populations = pholioReader.GetCcgPracticePopulations(areaCode);
     var population = new CcgPopulation
     {
         AreaCode = areaCode,
         PracticeCodeToPopulation = populations,
         TotalPopulation = populations.Values.Sum()
     };
     return population;
 }
        /// <summary>
        /// Whether or not there is enough data available to cover 
        /// </summary>
        public static bool Validates(IEnumerable<CoreDataSet> data, CcgPopulation ccgPopulation)
        {
            // Practices that have values
            var areaCodesWithValues = data.Select(x => x.AreaCode);

            // Population represented by indicator values
            double populationRepresentingAvailableData = ccgPopulation.PracticeCodeToPopulation
                .Where(x => areaCodesWithValues.Contains(x.Key))
                .Sum(x => x.Value);

            // Does the data available cover enough of the population
            return populationRepresentingAvailableData >= ccgPopulation.TotalPopulation * 0.9;
        }
        public CcgAverageCalculator(IList<CoreDataSet> dataList, CcgPopulation ccgPopulation, IndicatorMetadata indicatorMetadata)
        {
            Unit unit = indicatorMetadata.Unit;

            if (indicatorMetadata.ValueTypeId == ValueTypeId.Ratio)
            {
                return;
            }

            if (dataList.Any(x => x.IsCountValid && x.IsDenominatorValid))
            {
                var validData = new CoreDataSetFilter(dataList).SelectWhereCountAndDenominatorAreValid().ToList();

                if (RuleAreEnoughPracticeValuesByPopulation.Validates(validData, ccgPopulation))
                {
                    Average = WeightedAverageCalculator.CalculateAverage(validData, unit);
                    Average.AreaCode = ccgPopulation.AreaCode;
                }
            }
            else if (dataList.Any(x => x.IsValueValid))
            {
                var practiceCodeToPopulationMap = ccgPopulation.PracticeCodeToPopulation;

                // Keep only data where population is available
                var dataWithPopulation = dataList.Where(x => practiceCodeToPopulationMap.ContainsKey(x.AreaCode)).ToList();

                if (RuleAreEnoughPracticeValuesByPopulation.Validates(dataWithPopulation, ccgPopulation))
                {
                    Average = CoreDataSet.GetNullObject(ccgPopulation.AreaCode);

                    // Population weighted average
                    Average.Value = dataWithPopulation.Sum(data => (data.Value * practiceCodeToPopulationMap[data.AreaCode])) /
                              ccgPopulation.TotalPopulation;
                }
            }
        }
 private CcgPopulationProvider ValidPopulationProvider()
 {
     var ccgPopulation = new CcgPopulation
     {
         AreaCode = areaCode,
         TotalPopulation = 100,
         PracticeCodeToPopulation = new Dictionary<string, double> {
             {"a", 50},
             {"b", 50}
         }
     };
     var populationProvider = new Mock<CcgPopulationProvider>(MockBehavior.Strict);
     populationProvider.Protected();
     populationProvider.Setup(x => x
         .GetPopulation(areaCode))
         .Returns(ccgPopulation);
     return populationProvider.Object;
 }
 public static bool Validates(Grouping grouping, IEnumerable<CoreDataSet> data, CcgPopulation ccgPopulation)
 {
     return RuleAreEnoughPracticeValuesByPopulation.Validates(data, ccgPopulation) &&
            RuleShouldCcgAverageBeCalculatedForGroup.Validates(grouping);
 }
        public Dictionary<int, IndicatorStatsResponse> GetIndicatorStats()
        {
            profileIds = _parameters.RestrictResultsToProfileIdList;
            parentArea = AreaFactory.NewArea(areasReader, _parameters.ParentAreaCode);

            var roots = GetRoots();
            var responseObjects = new Dictionary<int, IndicatorStatsResponse>();

            SetAreaCodesToIgnore();

            if (parentArea.IsCcg)
            {
                ccgPopulation = new CcgPopulationProvider(pholioReader).GetPopulation(parentArea.Code);
            }

            childAreaCount = new ChildAreaCounter(areasReader)
                .GetChildAreasCount(parentArea, _parameters.ChildAreaTypeId);

            int rootIndex = 0;
            foreach (var root in roots)
            {
                Grouping grouping = root.Grouping[0];
                IndicatorMetadata metadata = indicatorMetadataRepository.GetIndicatorMetadata(grouping);
                TimePeriod timePeriod = new DataPointOffsetCalculator(grouping, _parameters.DataPointOffset, metadata.YearType).TimePeriod;

                IEnumerable<double> values = GetValuesForStats(grouping, timePeriod);

                IndicatorStatsResponse statsAndStatF;
                if (values != null)
                {
                    IndicatorStatsPercentiles statsPercentiles = new IndicatorStatsCalculator(values).GetStats();
                    var formatter = NumericFormatterFactory.New(metadata, groupDataReader);
                    indicatorStatsProcessor.Truncate(statsPercentiles);

                    statsAndStatF = new IndicatorStatsResponse
                    {
                        IID = metadata.IndicatorId,
                        Stats = statsPercentiles,
                        StatsF = formatter.FormatStats(statsPercentiles),
                        HaveRequiredValues = doEnoughAreasHaveValues
                    };
                }
                else
                {
                    // No stats calculated
                    statsAndStatF = new IndicatorStatsResponse
                    {
                        IID = metadata.IndicatorId,
                        HaveRequiredValues = doEnoughAreasHaveValues
                    };
                }
                responseObjects[rootIndex] = statsAndStatF;

                rootIndex++;
            }

            return responseObjects;
        }