# ChIP-qPCR statistics: percent input, fold enrichment over IgG and what counts as n

> Calculate percent input using the input dilution, compare conditions as a log ratio per independent chromatin preparation, and use IgG as a background check rather than the denominator. Python and R code with a simulation.

Canonical: https://www.licklider.ai/guides/chip-qpcr-percent-input/
Section: Guides › Normalised data and fold change
Author: Licklider · Published 2026-11-12 · Last reviewed 2026-11-12 (UTC)

> **Quick answer.** In ChIP-qPCR, express each immunoprecipitation (IP) as **percent input**: 100 × 2^((Ct of input − log2 of the dilution factor) − Ct of IP), using the mean Ct of the technical wells; the dilution factor is 100 for a 1% input (subtract 6.644 cycles) and 50 for a 2% input (subtract 5.644 cycles); if the input was diluted further before qPCR, multiply the factors. Treat each **independent chromatin preparation** (experiment) as n, and when both conditions were processed in each experiment, compare them as the **log2 ratio** of percent input within each experiment, tested across experiments (a paired analysis); otherwise compare log2 percent input unpaired. Use the IgG (or no-antibody) control and a negative region to show that the signal is above background, and report a target at background level as such; in our simulation IgG worked poorly as the denominator, because its background varied on its own. In a simulation of 4 paired experiments (3 qPCR wells per sample) where a drug halved binding, the paired log ratio of percent input detected it in 87.9% of studies, the same comparison using fold enrichment over IgG detected it in only 28.2%, and an unpaired test of log2 percent input detected it in 54.0%.

**Terms used below.** *ChIP (chromatin immunoprecipitation)*: pulling down DNA bound by a protein with an antibody, then measuring a region by qPCR. *Ct (Cq)*: the qPCR cycle at which the signal crosses a threshold; one cycle less means about twice as much DNA. *Input*: a sample of the starting chromatin, often 1% or 2% of what went into the IP. *Dilution factor*: 100 ÷ the input percentage (100 for 1%, 50 for 2%, 10 for 10%). *Percent input*: the IP signal as a percentage of the total chromatin. *IgG / no-antibody control*: an IP with a non-specific antibody or none, measuring background. *Fold enrichment over IgG*: IP signal ÷ IgG signal. *Negative region*: a genomic region expected to be unbound by the protein, used as a background check. *Technical replicate*: a repeat qPCR well of the same DNA. *Paired analysis*: comparing conditions within each experiment, valid because the two preparations of one experiment are made on the same day from the same cell batch, with the same antibody lot and operator, so day-to-day variation cancels from the ratio. *Welch t-test*: a two-group t-test that does not assume equal spread. *Holm correction*: a multiple-comparison correction that controls the chance of any false positive across a set of tests. *Mixed model*: a regression in which each experiment gets its own baseline (a random effect). *NaN / NA*: the placeholders Python and R return for a missing or impossible value. *MIQE*: the Minimum Information for Publication of Quantitative Real-Time PCR Experiments guidelines. *Independent chromatin preparation*: cells treated, cross-linked, sonicated and immunoprecipitated on a separate occasion. *Log2 ratio*: the base-2 logarithm of drug ÷ vehicle; 0 means no change, −1 a halving. *One-sample t-test*: tests whether the mean of the per-experiment log2 ratios differs from 0; it is the same as a paired t-test on log2 percent input. *Primer efficiency*: how close each qPCR cycle comes to doubling the product, measured from a dilution series. *95% confidence interval (CI)*: the range of values compatible with the data. *Power*: the chance of detecting an effect that is really there. *False positive*: a "significant" result when there is no real effect.

## Which analysis for your question

| Question | Analysis | Report |
| --- | --- | --- |
| Does a treatment change binding at a region? | Percent input per preparation (mean Ct of the wells); log2 ratio treated ÷ control per experiment; one-sample t-test against 0 | Ratio with 95% CI, n experiments |
| Treated and control preparations not made in the same experiments | Welch t-test on log2 percent input, preparations as n; expect less power than the paired design | Ratio with 95% CI |
| Is there binding at all? | Percent input at the target compared with the IgG control and a negative region, in every experiment; Cell Signaling considers a signal-to-noise ratio (target percent input ÷ IgG or negative-region percent input) above 3 ideal | Percent input of IP, IgG and negative region |
| Several regions | The same per region (loop over regions), with a Holm correction across regions (`p.adjust(p, "holm")` in R) | Ratios with adjusted p |
| Several treatments vs one control | Log2 ratio of each treatment vs control per experiment; one-sample t-tests with a Holm correction across all treatments (and regions) you report together, or a mixed model of log2 percent input with experiment as a random effect | Ratios with 95% CI and adjusted p |
| A region near background in some samples | Report it as not above background; do not compute ratios from IgG-level signals | Percent input with the background level |

The Thermo Fisher ChIP analysis guide and the Cell Signaling Technology SimpleChIP protocol give the percent input formula; for a 2% input, Cell Signaling Technology writes "Percent Input = 2% x 2 (C[T] 2%Input Sample - C[T] IP Sample)", where the bracketed difference is the exponent, and notes that "background signals are typically below 0.1% of input, and a signal-to-noise ratio greater than 3 is considered ideal" ([Cell Signaling Technology](https://www.cellsignal.com/learn-and-support/protocols/protocol-chip-magnetic), also in its [SimpleChIP Plus protocol](https://www.cellsignal.com/learn-and-support/protocols/protocol-simplechip-plus-magnetic); [Thermo Fisher](https://www.thermofisher.com/us/en/home/life-science/epigenetics-noncoding-rna-research/chromatin-remodeling/chromatin-immunoprecipitation-chip/chip-analysis.html)). For a 1% input, the input Ct is lowered by log2(100) = 6.644 cycles before the subtraction. Haring and colleagues, discussing fold enrichment over background, write: "We strongly recommend not to use this method, because the background signal levels do vary between primer sets, samples and experiments"; they also advise that amplification efficiency "should be as close as possible to two" and that "the ChIP-QPCR results should be within the linear range of amplification" ([Haring et al. 2007](https://doi.org/10.1186/1746-4811-3-11)). For qPCR expression ratios, Ganger and colleagues advise to "apply parametric statistical techniques in the logscale", adding that "using parametric statistics directly on relative expression ratios is never valid"; the same reasoning applies to percent input, a ratio of two qPCR signals, and a t-test on log2 ratios is exactly that log-scale test ([Ganger et al. 2017](https://doi.org/10.1186/s12859-017-1949-5)).

## Worked example: a drug with no real effect

Constructed data: ChIP at one target region in **4 independent experiments**. In each, vehicle- and drug-treated cells give separate chromatin preparations, each with an IP, an IgG control and a 1% input, each run in 3 qPCR wells (72 wells). By design, **the drug does not change binding**. The true percent input (about 2%) varies between experiments (standard deviation 0.5 on the log2 scale, as cross-linking, sonication and antibody performance vary) and a little between the two preparations of one experiment; IgG background varies more, and its late Ct makes its wells noisier. The data's random seed was the first one tried and was not chosen to favour a particular result. Stored code and data: [chip.csv](/guides/chip-qpcr-percent-input/chip.csv), [model.py](/guides/chip-qpcr-percent-input/model.py), [make_data.py](/guides/chip-qpcr-percent-input/make_data.py), [analysis.py](/guides/chip-qpcr-percent-input/analysis.py), [analysis.R](/guides/chip-qpcr-percent-input/analysis.R) and [the analysis output](/guides/chip-qpcr-percent-input/analysis_output.txt); analysis.py and analysis.R print the same output.

| Experiment | % input, vehicle | % input, drug | Ratio drug ÷ vehicle | IgG % input, vehicle / drug | Fold over IgG, vehicle | Fold over IgG, drug |
| --- | --- | --- | --- | --- | --- | --- |
| 1 | 2.34 | 2.02 | 0.86 | 0.031 / 0.064 | 76 | 32 |
| 2 | 0.92 | 0.98 | 1.06 | 0.067 / 0.025 | 14 | 39 |
| 3 | 2.82 | 2.12 | 0.75 | 0.045 / 0.039 | 63 | 54 |
| 4 | 2.36 | 3.14 | 1.33 | 0.049 / 0.079 | 49 | 40 |

For example, in experiment 1 the vehicle input averaged Ct 24.81 and the IP 23.58, so percent input = 100 × 2^((24.81 − 6.644) − 23.58) = 2.34 (see the analysis output for each value).

| Analysis, drug vs vehicle | Result |
| --- | --- |
| A. qPCR wells as n (12 vs 12), Welch t-test on % input (not valid: wells repeat one preparation) | ratio 0.98, p = 0.91 |
| B. Experiments as n but unpaired (4 vs 4), Welch t-test on log2 % input | ratio 0.98, p = 0.95 |
| **C. Log2 ratio of % input per experiment, paired (n = 4)** | **0.98 (95% CI 0.66 to 1.45), p = 0.87** |
| D. Log2 ratio of fold enrichment over IgG per experiment, paired (n = 4) | 0.95 (95% CI 0.27 to 3.34), p = 0.91 |

Percent input in experiment 2 was less than half that of the others in both conditions, which is why pairing within experiments matters. The fold enrichment over IgG swung from 14 to 76 because the IgG signal varies on its own, which made D's interval much wider (0.27 to 3.34, against 0.66 to 1.45 for C). Across 5,000 simulated studies of this design ([simulation.py](/guides/chip-qpcr-percent-input/simulation.py), [the simulation output](/guides/chip-qpcr-percent-input/simulation_output.txt)):

| Scenario | A. Wells as n (invalid) | B. Experiments, unpaired (log2) | C. % input, paired log ratio | D. Fold over IgG, paired log ratio |
| --- | --- | --- | --- | --- |
| No drug effect, 4 experiments (false positives) | 7.1% | 0.5% | 5.0% | 4.8% |
| Drug halves binding, 4 experiments (power) | 97.6% | 54.0% | **87.9%** | 28.2% |
| Drug halves binding, 6 experiments (power) | 99.6% | 83.7% | **99.5%** | 51.2% |
| Drug halves binding, 3 experiments (power) | 93.0% | 31.2% | 58.3% | 18.6% |

These percentages describe this simulated design (3 wells per sample, the variation in model.py), not every ChIP experiment. Treating the 12 IP wells per condition as independent gave too many false positives (7.1%) because wells repeat the same chromatin. Comparing experiments without pairing was far too cautious (0.5%) and weaker (54.0%), because the day-to-day differences stay in the comparison; when the design allows, pair. The paired log ratio of percent input kept false positives at 5% and detected a halving in most studies. Dividing by IgG still kept false positives near 5%, but the IgG's own variation cut the power to 28.2%, which is why IgG belongs in the background check, not the denominator. In this model the IgG background varies independently of the IP; if in your hands IgG tracks the IP from preparation to preparation, dividing by it costs less.

The code expects one row per qPCR well with columns `experiment`, `condition` (vehicle or drug), `sample` (input, IP or IgG), `well` and `ct`, with a 1% input; for a 2% input change `log2(100)` to `log2(50)` in both languages. It needs both conditions in every experiment; if a label is misspelled or a sample is missing, the result is NaN in Python or NA in R. The snippets print analysis C only; the full scripts print all four analyses and the IgG values. The constructed example has no negative region; add one as another `sample` level and calculate its percent input the same way. Rename your columns and labels to match, and run the code in the folder that holds the CSV file. Python needs NumPy, pandas and SciPy; the R code uses base R only.

```python
import numpy as np, pandas as pd
from scipy import stats

d = pd.read_csv("chip.csv")
m = d.groupby(["experiment", "condition", "sample"]).ct.mean().unstack()      # mean Ct of the wells
pct = (100 * 2 ** ((m.input - np.log2(100)) - m.IP)).unstack()                 # % input, 1% input sample
r = np.log2(pct.drug / pct.vehicle); t = stats.ttest_1samp(r, 0); ci = t.confidence_interval()
print(f"drug / vehicle {2 ** r.mean():.2f} (95% CI {2 ** ci.low:.2f} to {2 ** ci.high:.2f}), p = {t.pvalue:.2g}")
# drug / vehicle 0.98 (95% CI 0.66 to 1.45), p = 0.87
```

```r
d <- read.csv("chip.csv")
m <- tapply(d$ct, list(paste(d$experiment, d$condition), d$sample), mean)       # mean Ct of the wells
pct <- 100 * 2^((m[, "input"] - log2(100)) - m[, "IP"])                          # % input, 1% input sample
ex <- sort(unique(d$experiment))
r <- log2(pct[paste(ex, "drug")] / pct[paste(ex, "vehicle")]); t <- t.test(r)
round(c(ratio = 2^mean(r), lower = 2^t$conf.int[1], upper = 2^t$conf.int[2], p = t$p.value), 2)
# ratio 0.98, lower 0.66, upper 1.45, p 0.87
```

## Before you analyse

1. **Plan at least 3 independent chromatin preparations per condition (our recommendation; more for small effects)**, done on separate occasions, with both conditions in each; qPCR wells are technical replicates and are averaged first. With 3 experiments the paired test has 2 degrees of freedom; in our simulation it detected a halving in 58.3% of studies, against 87.9% with 4.
2. **Check primer efficiency and the linear range** with a dilution series of input DNA (for example 1:5 steps): efficiency = (10^(−1/slope) − 1) × 100% from a regression of Ct on log10 amount (a slope of −3.32 gives 100%), and report it, as Haring and colleagues and the MIQE guidelines recommend ([Bustin et al. 2009](https://doi.org/10.1373/clinchem.2008.112797)).
3. **Record the input fraction** (1%, 2%, 10%) and apply its log2 dilution factor in every calculation.
4. **Include an IgG or no-antibody control and a negative region in every experiment**, and report their percent input to show the target is above background.
5. **Analyse on the log scale and pair by experiment** ([fold change](/guides/statistics-on-fold-change/)); if a sample is at background level, report it as such rather than forcing a ratio ([detection limit](/guides/values-below-detection-limit/)).

## Check what an AI assistant ran

1. **The assistant ran a t-test on all qPCR wells.** Ask for the mean Ct per sample and one value per preparation.
2. **The assistant divided by IgG and reported fold enrichment as the main result.** Ask for percent input, with IgG reported as background.
3. **The assistant forgot the input dilution.** Ask which input fraction was used and whether log2 of the dilution factor was subtracted.
4. **The assistant compared experiments without pairing, or tested percentages directly.** Ask for the log2 ratio per experiment.

## Report it

> ChIP was performed in [4] independent experiments, each with separate chromatin preparations for vehicle- and drug-treated cells, an IgG control and a [1]% input; each sample was run in [3] qPCR wells (primer efficiency [95–102]%). Percent input was calculated as 100 × 2^((Ct input − log2 [dilution factor: 100 for a 1% input, 50 for 2%]) − Ct IP) from mean Ct values, and the log2 ratio drug ÷ vehicle was compared with 0 by a one-sample t-test across experiments (R [4.3.3]). IgG gave [0.025–0.079]% input (printed by analysis.py).

> In the constructed example, which has no effect built in, the drug did not clearly change binding at the target region (drug ÷ vehicle [0.98], 95% CI [0.66] to [1.45]; p = [0.87]; n = [4] experiments).

Replace the bracketed values with your own.

## References

- Haring M, Offermann S, Danker T, Horst I, Peterhansel C, Stam M (2007). Chromatin immunoprecipitation: optimization, quantitative analysis and data normalization. *Plant Methods* 3:11. [doi:10.1186/1746-4811-3-11](https://doi.org/10.1186/1746-4811-3-11)
- Ganger MT, Dietz GD, Ewing SJ (2017). A common base method for analysis of qPCR data and the application of simple blocking in qPCR experiments. *BMC Bioinformatics* 18:534. [doi:10.1186/s12859-017-1949-5](https://doi.org/10.1186/s12859-017-1949-5)
- Bustin SA, Benes V, Garson JA, et al. (2009). The MIQE guidelines: minimum information for publication of quantitative real-time PCR experiments. *Clinical Chemistry* 55:611–622. [doi:10.1373/clinchem.2008.112797](https://doi.org/10.1373/clinchem.2008.112797)
- Cell Signaling Technology. SimpleChIP enzymatic chromatin IP protocol (magnetic beads). [cellsignal.com](https://www.cellsignal.com/learn-and-support/protocols/protocol-chip-magnetic)
- Cell Signaling Technology. SimpleChIP Plus enzymatic chromatin IP protocol (magnetic beads). [cellsignal.com](https://www.cellsignal.com/learn-and-support/protocols/protocol-simplechip-plus-magnetic)
- Thermo Fisher Scientific. ChIP analysis. [thermofisher.com](https://www.thermofisher.com/us/en/home/life-science/epigenetics-noncoding-rna-research/chromatin-remodeling/chromatin-immunoprecipitation-chip/chip-analysis.html)

## Related

- [qPCR ΔΔCt statistics](https://www.licklider.ai/guides/qpcr-delta-delta-ct-statistics/)
- [Statistics on fold change](https://www.licklider.ai/guides/statistics-on-fold-change/)
- [What counts as n](https://www.licklider.ai/guides/what-counts-as-n/)
- [Values below the detection limit](https://www.licklider.ai/guides/values-below-detection-limit/)

## How this page was made

- Written and published by Licklider. Recommendations cite peer-reviewed methods papers and manufacturer protocols listed under References; cited passages were checked against the source text.
- The worked example uses constructed data. Its numbers were produced by stored code (Python 3.13 with SciPy 1.18.1; R 4.3.3, base R), and the two languages print identical output; the simulation was run in Python.
- Separate review passes checked the statistics, the citations and readability before publication.
