Exemplo n.º 1
0
        /// <summary>
        /// Builds a dictionary key using a provided sex and measurement value.
        /// </summary>
        /// <param name="measurement">The measurement in metric units</param>
        /// <param name="sex">Whether the child is male or female</param>
        /// <returns>int; represents the integer dictionary key for the given sex and measurement values</returns>
        internal int BuildKey(Sex sex, double measurement)
        {
            if (StatisticsHelper.IsWholeNumber(measurement))
            {
                int sexKeyPart         = sex == Sex.Male ? 1 : 2;
                int measurementKeyPart = (int)(measurement * 100) + sexKeyPart;
                return(measurementKeyPart);
            }

            return(-1);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Calculates a z-score for a given indicator, pair of measurements (measurement1-for-measurement2, as
        /// in "BMI-for-Age"), and gender.
        /// </summary>
        /// <param name="indicator">The indicator to use for computing the z-score (e.g. BMI, Height-for-Age, Weight-for-Age)</param>
        /// <param name="measurement">
        /// The first measurement value. Must be in metric units and must be greater than or equal to zero. For
        /// example, if the indicator is 'Height-for-Age', then measurement represents the child's height in
        /// centimeters. If using 'Weight-for-Age', then the measurement represents the child's weight in
        /// kilograms.
        /// </param>
        /// <param name="age">The age of the child in months. Must be greater than or equal to 61. Automatically rounded to 5 decimal values.</param>
        /// <param name="sex">Whether the child is male or female</param>
        /// <returns>double; the z-score for the given inputs</return>
        internal double CalculateZScore(Indicator indicator, double measurement, double age, Sex sex)
        {
            if (measurement < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(measurement));
            }
            if (!IsValidMeasurement(indicator, age))
            {
                throw new ArgumentOutOfRangeException(nameof(age));
            }

            age = Math.Round(age, 5);

            Dictionary <int, Lookup> reference = null;

            switch (indicator)
            {
            case Indicator.BodyMassIndexForAge:
                reference = WHO2007_BMI;
                break;

            case Indicator.WeightForAge:
                reference = WHO2007_WeightAge;
                break;

            case Indicator.HeightForAge:
                reference = WHO2007_HeightAge;
                break;

            default:
                throw new ArgumentOutOfRangeException(nameof(indicator));
            }

            int    key    = BuildKey(sex, age);
            Lookup lookup = null;
            bool   found  = reference.TryGetValue(key, out lookup);

            if (found)
            {
                return(StatisticsHelper.CalculateZScore(measurement, lookup.L, lookup.M, lookup.S, true));
            }
            else
            {
                var interpolatedValues = InterpolateLMS(sex, age, reference);
                return(StatisticsHelper.CalculateZScore(measurement, interpolatedValues.Item1, interpolatedValues.Item2, interpolatedValues.Item3, true));
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// Calculates a z-score for the given indicator, age in months, measurement value, and gender.
        /// </summary>
        /// <param name="indicator">The indicator to use for computing the z-score (e.g. BMI-for-age, Height-for-Age, Weight-for-Age, etc.)</param>
        /// <param name="measurement1">
        /// The first measurement value. Must be in metric units. For example, if the indicator is Height-for-Age,
        /// then measurement1 represents the child's height in centimeters.
        /// </param>
        /// <param name="measurement2">
        /// The second measurement. Typically age of the child in months. For example, if the indicator is
        /// 'Height-for-Age', then measurement2 represents the child's age. If  the indicator is instead
        /// 'Weight-for-Length' or 'Weight-for-Height' then measurement2 represents the child's length or
        /// height (respectively) and must be a non-zero value provided in centimeters. Automatically
        /// rounded to 5 decimal values.
        /// </param>
        /// <param name="sex">Whether the child is male or female</param>
        /// <returns>double; the calculated z-score for the given inputs</return>
        internal double CalculateZScore(Indicator indicator, double measurement1, double measurement2, Sex sex)
        {
            if (measurement1 < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(measurement1));
            }
            if (!IsValidMeasurement(indicator, measurement2))
            {
                throw new ArgumentOutOfRangeException(nameof(measurement2));
            }

            measurement2 = Math.Round(measurement2, 5);

            IDictionary <int, Lookup> reference = null;

            switch (indicator)
            {
            case Indicator.BodyMassIndexForAge:
                reference = CDC2000_BMI;
                break;

            case Indicator.HeadCircumferenceForAge:
                reference = CDC2000_HeadCircumference;
                break;

            case Indicator.LengthForAge:
                reference = CDC2000_LengthForAge;
                break;

            case Indicator.HeightForAge:
                reference = CDC2000_HeightForAge;
                break;

            case Indicator.WeightForAge:
                reference = CDC2000_WeightForAge;
                break;

            case Indicator.WeightForLength:
                reference = CDC2000_WeightForLength;
                break;

            case Indicator.WeightForHeight:
                reference = CDC2000_WeightForHeight;
                break;

            default:
                throw new ArgumentOutOfRangeException(nameof(indicator));
            }

            int    key    = BuildKey(sex, measurement2);
            Lookup lookup = null;
            bool   found  = reference.TryGetValue(key, out lookup);

            if (found)
            {
                return(StatisticsHelper.CalculateZScore(measurement1, lookup.L, lookup.M, lookup.S, false));
            }
            else
            {
                var interpolatedValues = InterpolateLMS(sex, measurement2, reference);
                return(StatisticsHelper.CalculateZScore(measurement1, interpolatedValues.Item1, interpolatedValues.Item2, interpolatedValues.Item3, false));
            }
        }
Exemplo n.º 4
0
        /// <summary>
        /// Calculates a z-score for a given indicator, pair of measurements (measurement1-for-measurement2, as
        /// in "BMI-for-Age"), and gender.
        /// </summary>
        /// <param name="indicator">The indicator to use for computing the z-score (e.g. BMI, Height-for-Age, Weight-for-Age, etc.)</param>
        /// <param name="measurement1">
        /// The first measurement value. Must be in metric units and must be greater than or equal to zero. For
        /// example, if the indicator is 'Height-for-Age', then measurement1 represents the child's height in
        /// centimeters. Note that subscapular skinfold and triceps skinfold require measurement1 be provided
        /// in millimeters.
        /// </param>
        /// <param name="measurement2">
        /// The second measurement. Typically age of the child in days. For example, if the indicator is
        /// 'Height-for-Age', then measurement2 represents the child's age. If the indicator is instead
        /// 'Weight-for-Length' or 'Weight-for-Height' then measurement2 represents the child's length or
        /// height (respectively) and must be a non-zero value provided in centimeters. Automatically
        /// rounded to 5 decimal values if measuring height or length and automatically rounded to a whole
        /// number if measuring age in days.
        /// </param>
        /// <param name="sex">Whether the child is male or female</param>
        /// <returns>double; the z-score for the given inputs</return>
        internal double CalculateZScore(Indicator indicator, double measurement1, double measurement2, Sex sex)
        {
            if (measurement1 < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(measurement1));
            }
            if (!IsValidMeasurement(indicator, measurement2))
            {
                throw new ArgumentOutOfRangeException(nameof(measurement2));
            }

            measurement2 = Math.Round(measurement2, 5);

            Dictionary <int, Lookup> reference = null;
            bool shouldRound = true;

            switch (indicator)
            {
            case Indicator.BodyMassIndexForAge:
                reference = WHO2006_BMI;
                break;

            case Indicator.WeightForLength:
                reference   = WHO2006_WeightForLength;
                shouldRound = false;
                break;

            case Indicator.WeightForHeight:
                reference   = WHO2006_WeightForHeight;
                shouldRound = false;
                break;

            case Indicator.WeightForAge:
                reference = WHO2006_WeightForAge;
                break;

            case Indicator.ArmCircumferenceForAge:
                reference = WHO2006_ArmCircumference;
                break;

            case Indicator.HeadCircumferenceForAge:
                reference = WHO2006_HeadCircumference;
                break;

            case Indicator.HeightForAge:
            case Indicator.LengthForAge:
                reference = WHO2006_LengthHeightForAge;
                break;

            case Indicator.SubscapularSkinfoldForAge:
                reference = WHO2006_SubscapularSkinfoldForAge;
                break;

            case Indicator.TricepsSkinfoldForAge:
                reference = WHO2006_TricepsSkinfoldForAge;
                break;

            default:
                throw new ArgumentOutOfRangeException(nameof(indicator));
            }

            if (shouldRound && !StatisticsHelper.IsWholeNumber(measurement2))
            {
                measurement2 = Math.Round(measurement2, 0);
            }

            int    key    = BuildKey(sex, measurement2);
            Lookup lookup = null;
            bool   found  = reference.TryGetValue(key, out lookup);

            if (found)
            {
                return(StatisticsHelper.CalculateZScore(measurement1, lookup.L, lookup.M, lookup.S, true));
            }
            else if (indicator == Indicator.WeightForLength || indicator == Indicator.WeightForHeight)
            {
                var interpolatedLMS = InterpolateLMS(sex, measurement2, reference);
                return(StatisticsHelper.CalculateZScore(measurement1, interpolatedLMS.Item1, interpolatedLMS.Item2, interpolatedLMS.Item3, true));
            }
            else
            {
                throw new InvalidOperationException($"Could not find a lookup match for value {Math.Round(measurement2, 2).ToString("N2")}");
            }
        }