Step 27: CPIC Drug-Gene Recommendation Lookup¶
What This Does¶
Reads your PharmCAT report (step 7) and writes a plain-text list of the medications whose prescribing guidance depends on your result: for every gene where you are not a normal metabolizer, the drugs PharmCAT's own report matched to your phenotype, with the CPIC recommendation text. With pypgx output (step 32) it also compares the two callers and warns about a gene PharmCAT could not call while pypgx did. With the consensus table of step 36 it lists the calls other tools gave PharmCAT (HLA-A and HLA-B from T1K, a CYP2D6 call pypgx and Cyrius agree on) and why a gene was held back. Opt-in: with a list of the medications you take, it also says when one of them inhibits CYP2D6, CYP2C19, CYP2C9, CYP3A4 or CYP3A5, and for CYP2D6 gives the phenotype CPIC predicts on that drug (phenoconversion) beside your genotype phenotype. With step 06's ClinVar hits it also warns when a pathogenic variant in a disease gene PharmCAT does not call makes a drug risky, such as valproate with a POLG variant.
Why¶
PharmCAT produces detailed JSON and HTML reports, but finding the actionable parts takes time. This step distills them into one short file. The drug list comes from the PharmCAT report itself (its drugs section, maintained by PharmCAT with each data release), so a gene PharmCAT calls is never dropped because a table in this pipeline was missing it.
Tool¶
bin/pgx_parse.py, the one PharmCAT reader of the pipeline (Python standard library only). The NextflowCPIC_LOOKUPmodule and the unit testtests/test_cpic_parser.pyrun the same file.
Docker Image¶
PYTHON_IMAGE
Pinned in versions.env; Image versions lists the current tag.
Input¶
- PharmCAT JSON report from step 7: the first
*.report.json(or*_pharmcat.json) in${GENOME_DIR}/${SAMPLE}/pharmcat/, else in${GENOME_DIR}/${SAMPLE}/vcf/. - Optional:
${GENOME_DIR}/${SAMPLE}/pypgx/${SAMPLE}_pypgx_summary.tsvfrom step 32. - Optional:
${GENOME_DIR}/${SAMPLE}/pgx_consensus/${SAMPLE}_pgx_consensus.tsvfrom step 36. - Optional:
${GENOME_DIR}/${SAMPLE}/clinvar/${SAMPLE}_clinvar_hits.tsvfrom step 06. The table it is checked against,assets/pgx_contraindications.tsv, ships with the pipeline; a missing table stops the step. - Optional, opt-in:
MEDICATIONS=FILE, a plain text list of the drugs you take, one per line. Write the generic name first (paroxetine 20 mgis read asparoxetine; a brand name is not recognised).#starts a comment and blank lines are skipped. The file can sit anywhere; it is mounted read-only. A missing list, or a missingassets/pgx_inhibitors.tsv, stops the step. Nothing is ever inferred: without the list there is no phenoconversion. In the Nextflow pipeline the same list is--medications FILE.run-all.shdoes not take one: run this step again withMEDICATIONSafterwards.
Command¶
./scripts/27-cpic-lookup.sh your_name
# With a medication list (opt-in)
MEDICATIONS=/path/to/medications.txt ./scripts/27-cpic-lookup.sh your_name
What the Script Does Internally¶
- Locates the PharmCAT JSON report.
- Runs
bin/pgx_parse.py cpic-reportin the Python image. It reads the gene calls (PharmCAT 3.x flatgenesmap, the 2.x map nested by source, and the older list are all read) and writes the phenotype table. - A gene counts as non-normal only when its phenotype names a changed metabolism or function (poor, intermediate, rapid or ultrarapid metabolizer; decreased, increased, poor or no function), a positive HLA test, a G6PD deficiency, malignant hyperthermia susceptibility, an increased MT-RNR1 risk, an ivacaftor-responsive CFTR, or a VKORC1
-1639genotype with the A allele (-1639 GAor-1639 AA, the warfarin dose-reduction case). A called gene whose phenotype is anything else (n/a,no phenotype assigned, the reference VKORC1 genotype-1639 GG,Uncertain Susceptibility,Indeterminate) isunclassified: it is listed in the section "Called Genes Without a Function Phenotype", is not counted, and gets no drug list. One exception: PharmCAT can leave a geneIndeterminateat gene level while the annotations of its drugs assign it a phenotype (for example a gene with unphased heterozygous positions plus positions missing from the VCF). When the drug annotations PharmCAT gives that gene (those for any of its possible diplotypes when there are any) all name the same phenotype, other thanIndeterminate,No Resultorn/a, the gene takes it, with the note[gene level Indeterminate; phenotype from PharmCAT's drug annotations]in the phenotype table and the text, and its status follows that phenotype. An annotation with no phenotype for the gene is not counted. Several possible diplotypes must also get the same drug guidance, because the drug list shows the first one's. With no annotation that names a phenotype, with annotations that disagree (one that saysIndeterminatedisagrees too), or with possible diplotypes whose guidance differs, it staysIndeterminateandunclassified. PharmCAT's own example report has 3 non-normal genes and 7 unclassified ones. For each gene with a non-normal phenotype it lists the drugs from the report'sdrugssection: CPIC's recommendation for the called diplotype per drug first, then the drugs DPWG or the FDA name. PharmCAT lists an annotation for every diplotype the sample may have, so only the ones for the called diplotype (or, without diplotype labels, its phenotype) are shown. When the report names no drug for the gene, it falls back to the gene'srelatedDrugs, then to a small static table, and finally prints a line saying the gene is not in the drug table, so a gene is never skipped silently. - When PharmCAT lists more than one possible diplotype for a gene and their phenotypes differ (positions missing from the VCF leave it unable to choose), the gene is
ambiguous: it is listed in its own section with the possible phenotypes and no drug guidance, never as its first diplotype. - With the pypgx summary it writes the comparison table and, for a gene PharmCAT reports as not called or ambiguous but pypgx called (CYP2D6 is the usual one), a warning in the recommendations naming every drug PharmCAT links to that gene. When pypgx's call is normal the line is a note instead.
- With step 36's consensus table it writes a section "Calls From Other Tools": each gene passed to PharmCAT as an outside call, from which tool, and whether PharmCAT's report shows it as one (
callSourceOUTSIDE); and each gene held back, with the reason and what each caller said. For a held-back CYP2D6 it names the drugs CYP2D6 affects and says no guidance is given for them, and the pypgx-only warning of point 5 is not printed for it: one caller's call is what the consensus refused. Genes PharmCAT reports as outside calls carry[outside call]in the gene results. An outside call of CYP2D6, HLA-A or HLA-B in PharmCAT's report that the table does not pass on, with the same diplotype, comes from an earlier step 36 run that step 07 has not replaced: it gets no drug guidance, is listed as not called, and a warning says to rerun step 07. When the table is missing (a caller step ran again since) but PharmCAT's report has outside calls of those genes, the step passes the missing table, so none of them is confirmed. MT-RNR1's outside call comes from step 20's chrM calls through step 07, never from step 36: the table never lists it, so it is not checked against it and keeps its drug guidance. - With a medication list, each line is matched by its first word (a space, comma, semicolon, slash or plus ends a word, so
lopinavir/ritonaviris matched as lopinavir; leading commas, semicolons, slashes and pluses are ignored, and a line of only those is skipped) againstassets/pgx_inhibitors.tsv: the FDA's strong and moderate inhibitors of CYP2D6 and CYP2C19, its moderate CYP2C9 inhibitors (it lists no strong one) and its strong CYP3A inhibitors, one row each for CYP3A4 and CYP3A5, as the FDA's table of clinical CYP inhibitors classes them, each row with its source. A ritonavir-boosted combination the FDA classes as one (lopinavir and ritonavir) has a row under ritonavir and one under its partner. For CYP2D6 the step applies CPIC's rule from its opioid guideline: "for patients on strong CYP2D6 inhibitors, the CYP2D6 activity score is adjusted to 0 and the predicted phenotype is a poor metabolizer", and for a moderate inhibitor "the activity score is multiplied by 0.5 and then converted to the predicted phenotype" (CPIC's bands: 0 poor, under 1.25 intermediate, 1.25 to 2.25 normal, above 2.25 ultrarapid). The activity score is the one PharmCAT gives the called diplotype. With several inhibitors of one gene the strongest counts. The result is written asPoor Metabolizer (phenoconverted by paroxetine)beside the genotype phenotype, never in its place, with aWARNING:line in the section "Medications and Phenoconversion", so the summary carries it. Nothing is converted for a gene that is not called, ambiguous or unclassified, or for a moderate inhibitor when the report gives no activity score: the line says why. CPIC has no activity score for CYP2C19, and gives no rule that converts the phenotype of CYP2C9, CYP3A4 or CYP3A5, so an inhibitor of one of these genes gets a note and anot computed: ...value, with no converted phenotype. For a poor metabolizer of these genes (the most common CYP3A5 result) the note does not say the inhibitor can lower the activity further. A line that names no drug of the table is listed as "Not in the inhibitor table", never dropped. A list that names no drug converts nothing and leaves the phenotype table as it is without a list. An unreadable list or table is reported in that section; the rest of the report is written as usual. The FDA's table lists no strong or moderate CYP2B6 inhibitor, so CYP2B6 has no rows. - With step 06's ClinVar hits, each hit classed
PathogenicorLikely_pathogenic(one part ofCLNSIG; a conflicting classification orrisk_factoralone does not count) in a gene ofassets/pgx_contraindications.tsvadds aWARNING:line in the section "Drug Contraindications From Disease Variants" for each drug the table names for the gene, with the label's note, the CPIC level and the source; a drug whose name is on your medication list is markedON THE MEDICATION LIST. The table holds the CPIC gene-drug pairs at level A, B or A/B (CPIC API, queried 2026-11-03) whose gene is a disease gene PharmCAT does not call and whose drug the variant makes risky: POLG with valproic acid (the valproate label contraindicates it in POLG mitochondrial disorders), ASL, ASS1, CPS1, NAGS and OTC with valproic acid (the label contraindicates it in urea cycle disorders), HPRT1 with mycophenolic acid (the label says to avoid it in hereditary HGPRT deficiency) and SCN1A with carbamazepine and phenytoin (CPIC level B, no guideline or label names the gene). Without the hits table the section lists those genes as not checked. The line does not judge inheritance: one variant in a recessive gene usually makes a carrier, not a patient, so the section says to review it with a clinician. - A report that cannot be read, or that yields no gene, writes a "PARSING FAILED" report and the step exits 1. It never writes an all-clear report from a format it could not read.
The comparison used to be written by step 32. It moved here because run-all.sh starts steps 7 and 32 side by side, so step 32 could read a missing or previous-run PharmCAT report; step 27 runs after both.
Output¶
| File | Contents |
|---|---|
cpic/${SAMPLE}_cpic_recommendations.txt |
Gene results, the medications for each non-normal gene, the drug contraindications from disease variants, the called genes without a function phenotype, the calls from other tools (step 36), uncallable genes, and the pypgx warnings |
cpic/${SAMPLE}_phenotypes.tsv |
One row per gene: Gene, Diplotype, Phenotype, Status (normal, non-normal, unclassified, ambiguous or not called). With a medication list that names a drug, a fifth column Phenoconverted_phenotype: the converted phenotype, not converted: <why>, not computed: ... (CYP2C19, CYP2C9, CYP3A4, CYP3A5), or - when no drug on the list inhibits the gene. Phenotype and Status stay the genotype's |
pypgx/${SAMPLE}_pharmcat_comparison.tsv |
PharmCAT and pypgx diplotypes side by side (only when step 32 ran) |
Runtime¶
3 to 5 seconds, measured in three 30-40x WGS runs (runtime).
Interpreting Results¶
Gene Results Table¶
Lists every pharmacogene with its called diplotype and phenotype (placeholders, not a result):
Affected Medications¶
Only genes with a non-normal phenotype (point 3 above) appear here, each with the drugs and the CPIC recommendation PharmCAT matched to your result. A called gene whose phenotype names no changed function (n/a, no phenotype assigned, the reference VKORC1 genotype -1639 GG, Uncertain Susceptibility) is unclassified: it gets no drug list and is listed under "Called Genes Without a Function Phenotype". A variant allele in such a gene can still matter, so check PharmCAT's HTML report for it. Genes that could not be called are listed separately at the end. Their absence from the medications section does NOT mean normal function.
Calls From Other Tools¶
When step 36 ran, this section lists HLA-A, HLA-B and CYP2D6: passed to PharmCAT (then their drug guidance is in the sections above, as for any gene PharmCAT called) or not, and why. indeterminate for CYP2D6 means the callers did not agree, only one ran, or the depth at CYP2D6 could not be trusted: no drug guidance is given for CYP2D6 then, and the drugs it affects are listed so you know what is not covered.
Medications and Phenoconversion¶
Only with a medication list. A drug can make you metabolize like a different phenotype than your genes predict: on a strong CYP2D6 inhibitor a CYP2D6 normal metabolizer is predicted to be a poor metabolizer. This section names each inhibitor on your list, your genotype phenotype, the converted one with CPIC's rule, and the drugs the gene affects. The converted phenotype holds while you take the inhibitor. The drug guidance in "Affected Medications" stays the one for your genotype; read the CPIC guideline with the converted phenotype for the drugs listed here. Your list is only as complete as you made it, and the table holds strong and moderate inhibitors only: a weak inhibitor, a brand name or a drug missing from the table is not checked. This is an aid for your clinician, not advice: do not start, stop or change a medication because of it.
Drug Contraindications From Disease Variants¶
A pathogenic variant in some disease genes makes a drug dangerous, and PharmCAT does not call those genes. This section checks step 06's ClinVar hits against assets/pgx_contraindications.tsv. A WARNING: line names the drug, the variant and its genotype, what the drug label says, and where to read it. Whether it applies to you depends on the disorder and on how many copies carry the variant, so read it with your clinician. Without step 06 the section says these genes were not checked; that is not an all-clear.
PharmCAT and pypgx¶
When step 32 ran, this section names each gene PharmCAT could not call but pypgx did, with pypgx's call and the drugs it affects. Read those drugs with the pypgx call and docs/32-pypgx.md.
What to do with the results¶
- Check whether you take (or might be prescribed) any of the listed medications.
- For any match, read the full CPIC guideline at cpicpgx.org/guidelines.
- Share the report with your prescribing physician or pharmacist.
Limitations¶
- The drug guidance is the one bundled with the pinned PharmCAT release; newer CPIC guidelines arrive with a PharmCAT update.
- The static fallback table is used only when the report names no drug for a gene.
- CYP2D6 has drug guidance here only when pypgx (step 32) and Cyrius (step 21, opt-in) agree and the depth check passed (step 36). Without Cyrius it is always held back.
- Phenoconversion covers the inhibitors in
assets/pgx_inhibitors.tsvonly (strong and moderate CYP2D6 and CYP2C19, moderate CYP2C9, strong CYP3A, per the FDA's table), and computes a converted phenotype for CYP2D6 only. Inducers, weak inhibitors and other genes are not covered. - The disease-gene contraindications cover the genes of
assets/pgx_contraindications.tsvonly, and only variants step 06 finds in ClinVar's pathogenic subset. A variant ClinVar does not list, or a copy-number change, is not seen. - This is NOT medical advice. Always consult a healthcare professional before making medication changes.
Links¶
- CPIC Guidelines
- PharmCAT
- PharmGKB
- CPIC Gene-Drug Pairs Table
- CPIC guideline for CYP2D6, OPRM1 and COMT and opioids (the CYP2D6 inhibitor rule)
- CPIC API gene-drug pairs (the source of
assets/pgx_contraindications.tsv, one query per gene) - Valproate (Depakote) label on DailyMed (POLG and urea cycle contraindications)
- Mycophenolate (CellCept) label on DailyMed (HGPRT deficiency)
- FDA: drugs that interact with CYP enzymes (strong and moderate inhibitors)