FDA Validation of a PCR Test: Run Control Specification (Part 5)

The purpose of run control specification is to find what is the acceptable range of values to accept a sample. For example, if a Texas Red value is detected in cycle 38 (Ct 38), this is too late in the PCR cycles and the signal could be due to contamination. Thus the sample is thrown out.

To get the acceptable ranges, the PCR test is run on clinical positive controls (FFPE and fresh frozen). Because Texas Red serves as an internal control, we look at its values to decide whether we accept/reject a sample.

The objective of the Run Control Specification is to find a range of Texas Red values that will deem a sample to be acceptable.

The code can be found on github.

We want to find the acceptable Texas Red range for the clinical samples. We analyze the positive controls and get prediction intervals based on the observed values.

The results of the Texas Red channel at 0.9, 0.95 and 0.99 confidence and 0.9, 0.95 and 0.99 coverage looks like:

 FluorConfidenceCoverage Level2-sided Lower Prediction Interval2-sided Upper Prediction Interval
Positive ControlTexas Red0.990.929.9631.38
Positive ControlTexas Red0.990.9529.9631.38
Positive ControlTexas Red0.990.9929.9631.38
Positive ControlTexas Red0.950.929.9631.38
Positive ControlTexas Red0.950.9529.9631.38
Positive ControlTexas Red0.950.9929.9631.38
Positive ControlTexas Red0.90.930.0431.35
Positive ControlTexas Red0.90.9529.9631.38
Positive ControlTexas Red0.90.9929.9631.38

From these results we choose the broadest range (29.96-31.38) because we want to be liberal accepting samples. For this range, any confidence and coverage level will do except 0.9 confidence 0.9 coverage.

How to get the Prediction Intervals

We make a data frame of the positive controls only (not the negative controls):

positive_control = df[df$Content == 'Pos Ctrl-1' | df$Content == 'Pos Ctrl-2' | df$Content == 'Pos Ctrl-3' | df$Content == 'Pos Ctrl-4', ]

And then a data frame for each channel Texas Red, Cy5, and FAM:
pc_TexRed = positive_control[positive_control$Fluor == 'Texas Red',]
pc_Cy5 = positive_control[positive_control$Fluor == 'Cy5', ]
pc_Fam = positive_control[positive_control$Fluor == 'FAM', ]

In the next section, I’ll show the analysis on Texas Red but this can be applied to all channels.

  1. Outlier removal by the Tukey rules on quartiles +/- 1.5 IQR
  2. pc_TexRed_noOutliers <- outlierKD (pc_TexRed, Cq)

  3. Test if the data looks normal or not:
  4. shapiro.test (pc_TexRed_noOutliers$Cq)
    The results give us:

    Results of Hypothesis Test

    Alternative Hypothesis:

    Test Name: Shapiro-Wilk normality test

    Data: pc_TexRed_noOutliers$Cq

    Test Statistic: W = 0.9494407

    P-value: 0.001008959

    which means the data is not normal.

  5. The tolerance package calculates prediction intervals.

    Load the library:

    library (tolerance)

    If the data looks normal, use the normtol function

    normtol.int (cleaned_df$Cq, alpha=alpha_num, P= coverage_level, side=2)

    If the data does not look normal, use a nonparametric tolerance function

    nptol.int (cleaned_df$Cq, alpha=alpha_num, P= coverage_level, side=2)

    Since the data is not normal, we'll use nptol.int. This loops through multiple confidence and coverage levels.

    confidence_levels <- c(0.99, 0.95, 0.90)
    nonparametric_coverage_levels <- c (0.90, 0.95, 0.99)

    for (confidence_level in confidence_levels) {
    alpha_num = 1 - confidence_level
    for (coverage_level in nonparametric_coverage_levels) {
    nonparametric <- ddply (all_controls_no_outliers, c('Fluor'), .fun = nptol_function, alpha=alpha_num, coverage_level=coverage_level )

    if (all (is.na (current_nonparametric))) {
    current_nonparametric <- nonparametric
    } else {
    current_nonparametric <- merge (current_nonparametric, nonparametric, all=TRUE)
    } # end coverage_level
    } # end confidence_level

This code generates the results table at the top if this post.

No comment yet

1 ping

  1. FDA Validation of Companion Diagnostic (PCR test) – Part 1 / n » Pauline PI - investigating science, math, and biology says:

    […] to examine: Part 2. Pre-processing Part 3. Analytical Specificity Part 4. Accuracy Part 5. Run Control Specification Part 6. Reportable Range Part 7. Limit of Detection (LoD) Part 8. Precision (repeatability & […]

Comments have been disabled.