예제 #1
0
        /// <summary>
        /// Evaluates the specified form and totals to determine if any of the different
        /// return conditions could produce a case where the Asia Impairment Scale is C o D.
        /// </summary>
        /// <param name="neurologyForm">Form that was used to produce the totals.</param>
        /// <param name="totals">Totals retunred by the algorithm.</param>
        /// <param name="couldBeAsiaC">out variable use as flag indicating if this case is a possible ASIA C.</param>
        /// <param name="couldBeAsiaD">out variable use as flag indicating if this case is a possible ASIA D.</param>
        private static void CouldBeAsiaCorD(NeurologyForm neurologyForm, NeurologyFormTotals totals, out bool couldBeAsiaC, out bool couldBeAsiaD)
        {
            couldBeAsiaC = false;
            couldBeAsiaD = false;
            NeurologyFormLevel rightMotor = null;
            NeurologyFormLevel leftMotor = null;

            // Check if the patient could be motor incoplete via sphincter contraction
            // Otherwise we need to check for motor function more than 3 levels below motor level.
            var couldHaveAnalContraction = neurologyForm.AnalContraction == BinaryObservation.Yes || neurologyForm.AnalContraction == BinaryObservation.NT;
            //var couldNotHaveAnalContraction = neurologyForm.AnalContraction == BinaryObservation.No || neurologyForm.AnalContraction == BinaryObservation.NT;

            var nliEnum = totals.GetNeurologicalLevelsOfInjury().GetEnumerator();

            while (nliEnum.MoveNext() && (!couldBeAsiaC || !couldBeAsiaD))
            {
                //var otherMotorIsMoreThanThreeLevelsBelowNli = (neurologyForm.)

                // RIGHT MOTOR
                // If not motor incomplete already, find the right motor level that correspond to this particular neurological level
                if (!couldHaveAnalContraction && (rightMotor == null || rightMotor.Ordinal < nliEnum.Current.Ordinal))
                {
                    var rightMotorValues = totals.GetRightMotorValues().GetEnumerator();
                    rightMotor = null;

                    while (rightMotor == null && rightMotorValues.MoveNext())
                    {
                        if (rightMotorValues.Current.Ordinal >= nliEnum.Current.Ordinal)
                            rightMotor = rightMotorValues.Current;
                    }

                    rightMotorValues.Dispose();
                }

                // LEFT MOTOR
                // If not motor incomplete already, find the left motor level that correspond to this particular neurological level
                if (!couldHaveAnalContraction && (leftMotor == null || leftMotor.Ordinal < nliEnum.Current.Ordinal))
                {
                    var leftMotorValues = totals.GetLeftMotorValues().GetEnumerator();
                    leftMotor = null;

                    while (leftMotor == null && leftMotorValues.MoveNext())
                    {
                        if (leftMotorValues.Current.Ordinal >= nliEnum.Current.Ordinal)
                            leftMotor = leftMotorValues.Current;
                    }

                    leftMotorValues.Dispose();
                }

                //if (couldNotHaveAnalContraction
                //    && (rightMotor == null || totals.MostCaudalRightLevelWithMotorFunction.Ordinal - rightMotor.Ordinal <= 3)
                //    && (leftMotor == null || totals.MostCaudalLeftLevelWithMotorFunction.Ordinal - leftMotor.Ordinal <= 3))
                //    couldBeAsiaB = true;

                // If the test is not motor incomplete at this level, do not continue to count motor levels, move to the next nli available.
                if (!couldHaveAnalContraction
                    && totals.MostCaudalRightLevelWithMotorFunction.Ordinal - rightMotor.Ordinal <= 3
                    && totals.MostCaudalLeftLevelWithMotorFunction.Ordinal - leftMotor.Ordinal <= 3)
                    continue;

                // When motor incomplete and the nli is S1 or more caudal, it is automatically D since there are no myotomes to count from.
                // We can break the loop.
                if (nliEnum.Current.Ordinal > 24) // Greater than L5 (24)
                {
                    couldBeAsiaD = true;
                    break;
                }

                // If motor incomplete, count the motor levels with muscle grade greater than two
                var levelsWithMuscleGradeGreaterThanTwo = 0;
                var levelsWithMuscleGradeLessThanThree = 0;
                var eligibleLevelCount = 0;
                var currentLevel = nliEnum.Current.Next;

                while (currentLevel != null)
                {
                    if (currentLevel.IsKeyMuscle)
                    {
                        eligibleLevelCount += 2;

                        if (currentLevel.RightMotorValue > 2 || currentLevel.RightMotorImpairmentNotDueToSci || NtRegex.IsMatch(currentLevel.RightMotorName))
                            levelsWithMuscleGradeGreaterThanTwo++;

                        if ((currentLevel.RightMotorValue < 3 || NtRegex.IsMatch(currentLevel.RightMotorName)) && !currentLevel.RightMotorImpairmentNotDueToSci)
                            levelsWithMuscleGradeLessThanThree++;

                        if (currentLevel.LeftMotorValue > 2 || currentLevel.LeftMotorImpairmentNotDueToSci || NtRegex.IsMatch(currentLevel.LeftMotorName))
                            levelsWithMuscleGradeGreaterThanTwo++;

                        if ((currentLevel.LeftMotorValue < 3 || NtRegex.IsMatch(currentLevel.LeftMotorName)) && !currentLevel.LeftMotorImpairmentNotDueToSci)
                            levelsWithMuscleGradeLessThanThree++;
                    }

                    currentLevel = currentLevel.Next;
                }

                // If not more than half the myotomes contain values less to 3, this is an Asia C
                if (levelsWithMuscleGradeLessThanThree > eligibleLevelCount / 2)
                    couldBeAsiaC = true;

                // If at least half the myotomes below the current NLI containing values greater or equal to 3, hooray! it is ASIA D.
                if (levelsWithMuscleGradeGreaterThanTwo >= eligibleLevelCount / 2)
                    couldBeAsiaD = true;
            }

            nliEnum.Dispose();
        }
예제 #2
0
        /// <summary>
        /// Produces a summarized version of a NeurologyFormTotals object which can be used to be displayed in an interface or be stored in a database.
        /// The values in the summary return will have ranges instead of lists of values.
        /// </summary>
        /// <param name="totals">The form totals object to be used to generate the summary.</param>
        /// <returns>
        /// Summarized version of the totals where the enumerations get replaced by ranges.
        /// </returns>
        public static NeurologyFormTotalsSummary GetTotalsSummaryFor(NeurologyFormTotals totals)
        {
            var ais = totals.GetAsiaImpairmentScaleValues();
            var isAsiaA = ais.Contains("A");
            var couldBeOtherThanAsiaA = !isAsiaA || ais.Length > 1;

            var summary = new NeurologyFormTotalsSummary
                {
                    AsiaImpairmentScale = ais,
                    Completeness = isAsiaA ? (couldBeOtherThanAsiaA ? "C,I" : "C") : "I",
                    LeftLowerMotorTotal = GetSummaryStringFor(totals.LeftLowerMotorTotal, totals.LeftLowerMotorTotalHasImpairmentNotDueToSci, totals.LeftLowerMotorContainsNt),
                    LeftMotor = GetLevelsRange(totals.GetLeftMotorValues(), false),
                    LeftMotorZpp = isAsiaA ? GetLevelsRange(totals.GetLeftMotorZppValues(), couldBeOtherThanAsiaA) : NotApplicable,
                    LeftMotorTotal = GetSummaryStringFor(totals.LeftUpperMotorTotal + totals.LeftLowerMotorTotal,
                                                            totals.LeftUpperMotorTotalHasImpairmentNotDueToSci || totals.LeftLowerMotorTotalHasImpairmentNotDueToSci,
                                                            totals.LeftUpperMotorContainsNt || totals.LeftLowerMotorContainsNt),
                    LeftPrickTotal = GetSummaryStringFor(totals.LeftPrickTotal, totals.LeftPrickTotalHasImpairmentNotDueToSci, totals.LeftPrickContainsNt),
                    LeftSensory = GetLevelsRange(totals.GetLeftSensoryValues(), false),
                    LeftSensoryZpp = isAsiaA ? GetLevelsRange(totals.GetLeftSensoryZppValues(), couldBeOtherThanAsiaA) : NotApplicable,
                    LeftTouchTotal = GetSummaryStringFor(totals.LeftTouchTotal, totals.LeftTouchTotalHasImpairmentNotDueToSci, totals.LeftTouchContainsNt),
                    LeftUpperMotorTotal = GetSummaryStringFor(totals.LeftUpperMotorTotal, totals.LeftUpperMotorTotalHasImpairmentNotDueToSci, totals.LeftUpperMotorContainsNt),
                    LowerMotorTotal = GetSummaryStringFor(totals.LowerMotorTotal,
                                                        totals.RightLowerMotorTotalHasImpairmentNotDueToSci || totals.LeftLowerMotorTotalHasImpairmentNotDueToSci,
                                                        totals.RightLowerMotorContainsNt || totals.LeftLowerMotorContainsNt),
                    NeurologicalLevelOfInjury = GetLevelsRange(totals.GetNeurologicalLevelsOfInjury(), false),
                    PrickTotal = GetSummaryStringFor(totals.RightPrickTotal + totals.LeftPrickTotal,
                                                        totals.RightPrickTotalHasImpairmentNotDueToSci || totals.LeftPrickTotalHasImpairmentNotDueToSci,
                                                        totals.RightPrickContainsNt || totals.LeftPrickContainsNt),
                    RightLowerMotorTotal = GetSummaryStringFor(totals.RightLowerMotorTotal, totals.RightLowerMotorTotalHasImpairmentNotDueToSci, totals.RightLowerMotorContainsNt),
                    RightMotor = GetLevelsRange(totals.GetRightMotorValues(), false),
                    RightMotorZpp = isAsiaA ? GetLevelsRange(totals.GetRightMotorZppValues(), couldBeOtherThanAsiaA) : NotApplicable,
                    RightMotorTotal = GetSummaryStringFor(totals.RightUpperMotorTotal + totals.RightLowerMotorTotal,
                                                            totals.RightUpperMotorTotalHasImpairmentNotDueToSci || totals.RightLowerMotorTotalHasImpairmentNotDueToSci,
                                                            totals.RightUpperMotorContainsNt || totals.RightLowerMotorContainsNt),
                    RightPrickTotal = GetSummaryStringFor(totals.RightPrickTotal, totals.RightPrickTotalHasImpairmentNotDueToSci, totals.RightPrickContainsNt),
                    RightSensory = GetLevelsRange(totals.GetRightSensoryValues(), false),
                    RightSensoryZpp = isAsiaA ? GetLevelsRange(totals.GetRightSensoryZppValues(), couldBeOtherThanAsiaA) : NotApplicable,
                    RightTouchTotal = GetSummaryStringFor(totals.RightTouchTotal, totals.RightTouchTotalHasImpairmentNotDueToSci, totals.RightTouchContainsNt),
                    RightUpperMotorTotal = GetSummaryStringFor(totals.RightUpperMotorTotal, totals.RightUpperMotorTotalHasImpairmentNotDueToSci, totals.RightUpperMotorContainsNt),
                    TouchTotal = GetSummaryStringFor(totals.RightTouchTotal + totals.LeftTouchTotal,
                                                        totals.RightTouchTotalHasImpairmentNotDueToSci || totals.LeftTouchTotalHasImpairmentNotDueToSci,
                                                        totals.RightTouchContainsNt || totals.LeftTouchContainsNt),
                    UpperMotorTotal = GetSummaryStringFor(totals.UpperMotorTotal,
                                                            totals.RightUpperMotorTotalHasImpairmentNotDueToSci || totals.LeftUpperMotorTotalHasImpairmentNotDueToSci,
                                                            totals.RightUpperMotorContainsNt || totals.LeftUpperMotorContainsNt)
                };

            return summary;
        }