-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathqPCR_analytic_validation.py
More file actions
65 lines (53 loc) · 2.21 KB
/
qPCR_analytic_validation.py
File metadata and controls
65 lines (53 loc) · 2.21 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import linregress
import os
# ---------------- USER PARAMETERS ----------------
input_file = "cq_input_replicates.csv" # your CSV file
outdir = "results"
plot_standard_curve = True
# ---------------- CREATE OUTPUT DIRECTORY ----------------
if not os.path.exists(outdir):
os.makedirs(outdir)
# ---------------- LOAD DATA ----------------
df = pd.read_csv(input_file) # CSV must be comma-separated (UTF-8)
# Check columns
expected_cols = {'ReplicateID','logCopyNumber','Cq'}
if not expected_cols.issubset(df.columns):
raise ValueError(f"CSV must contain columns: {expected_cols}")
# ---------------- SUMMARY STATS ----------------
summary = df.groupby('logCopyNumber')['Cq'].agg(['mean','std']).reset_index()
summary.rename(columns={'mean':'Cq_mean','std':'Cq_std'}, inplace=True)
# ---------------- STANDARD CURVE ----------------
x = summary['logCopyNumber']
y = summary['Cq_mean']
slope, intercept, r_value, _, _ = linregress(x,y)
efficiency = (10**(-1/slope) - 1) * 100
# ---------------- LOD & LOQ ----------------
blank_cqs = df[df['logCopyNumber'] == 0]['Cq']
if len(blank_cqs) >= 2:
noise_std = blank_cqs.std()
LOD = 3 * noise_std
LOQ = 10 * noise_std
else:
LOD, LOQ = np.nan, np.nan
# ---------------- PLOT STANDARD CURVE ----------------
if plot_standard_curve:
plt.figure(figsize=(6,6))
plt.errorbar(summary['logCopyNumber'], summary['Cq_mean'],
yerr=summary['Cq_std'], fmt='o', capsize=5)
plt.plot(x, slope*x + intercept, 'r')
plt.xlabel("log10(Copy Number)")
plt.ylabel("Cq (mean ± SD)")
plt.title(f"Standard Curve\nSlope={slope:.3f}, R²={r_value**2:.3f}, Eff={efficiency:.1f}%")
plt.tight_layout()
plt.savefig(f"{outdir}/standard_curve.png")
plt.close()
# ---------------- SAVE RESULTS ----------------
with open(f"{outdir}/results_summary.csv","w") as f:
f.write("Slope,Intercept,R²,Efficiency(%),LOD,LOQ\n")
f.write(f"{slope:.3f},{intercept:.3f},{r_value**2:.3f},{efficiency:.1f},{LOD:.2f},{LOQ:.2f}\n")
summary.to_csv(f"{outdir}/replicate_summary.csv", index=False)
print("✅ qPCR analytic validation complete!")
print(f"Results saved in folder: {outdir}/")