Layering the sex-hormone axis onto the pigmentation substrate

What this establishes. Everything up to here built the pigmentation network — the cell-autonomous melanogenesis machinery (NB1–7) and the loci that map onto it (NB4, NB8–12). This notebook adds a second, separate layer: the sex-hormone / steroid axis, connected to the pigmentation core through the one biologically correct route — a hormone → melanocyte receptor → MITF bridge — with every new node gated on whether the receptor is actually expressed in melanocytes and every new edge cited.

This notebook is purely additive and downstream: it reads the NB7 substrate and writes its own merged files. It does not modify NB7 or any pigmentation notebook — the pigmentation substrate stays pure pigmentation.

Why layer hormones at all (the two-level architecture). A companion result in this project — the disorder “quadrant” architecture — shows human pigment has two separable control levels: a cell-autonomous synthesis floor (uniform, only lowerable; the substrate of population skin-color variation) and a diffusible-signal layer (the only way to push pigment up, or make it regional / whole-body / sex-specific — endocrine hormones, or paracrine KITLG / EDN3). The pigmentation network we built is the floor. This notebook builds the diffusible layer’s endocrine arm and wires it in.

Why sex hormones specifically (the evolutionary motivation). A companion comparative-genomics scan (primate sexual dichromatism, comparative-genomics/) finds that the genes under intensified selection in dichromatic lineages are not the synthesis enzymes but the diffusible layer: the paracrine signals KITLG / EDN3 and sex-steroid metabolism enzymes. That scan is interim (its own numbers are provisional pending a stricter-QC rerun), so it is used here only as motivation — the firm ground in this notebook is the melanocyte-expression data and the cited receptor biology, not the selection values.

What this contributes. A tagged hormone layer merged (in this notebook’s own files) onto the NB7 substrate: the sex-steroid receptors that pass a melanocyte-expression gate, connected to MITF by cited edges, so the previously disconnected hormone gene set becomes a linked part of the pigmentation network — and the coupling can be inspected and tested.

Key terms — so this notebook stands on its own (you shouldn’t need the other notebooks to read this one).

  • Pigmentation substrate (NB7) — the merged, multi-layer melanocyte network built earlier in this project (Raghunath mechanism + KEGG/Reactome pathways + a TF→target regulon + STRING/OmniPath), ~800 gene nodes / ~7,800 edges, every edge carrying provenance and a citation. MITF is its master transcription factor; TYR / TYRP1 / DCT are the melanin-synthesis enzymes it switches on.
  • Cell-autonomous synthesis floor — the melanin-making machinery that runs inside every melanocyte (TYR, TYRP1, OCA2, SLC45A2…). Breaking it lowers pigment uniformly (albinism); there is no single cell-autonomous gene that raises it uniformly.
  • Diffusible-signal layer — signals that reach the melanocyte from outside: endocrine hormones (melanocortin α-MSH; sex steroids) and paracrine growth factors (KITLG/SCF, EDN3). This is the only route by which pigment can be pushed up or made regional / sex-specific.
  • Melanocyte receptor — the protein on the melanocyte a hormone binds: MC1R (melanocortin), GPER1 / ESR2 (estrogen), AR (androgen), EDNRB (endothelin). The receptor is the bridge node: a hormone acts on pigment only through a receptor the melanocyte actually expresses.
  • Melanocyte eGene (Zhang 2018) — a gene with a significant cis-eQTL in purified primary human melanocytes. A cis-eQTL requires the gene to be expressed in that cell type, so eGene status is direct, tissue-correct evidence of melanocyte expression. (Absence is inconclusive — an eQTL also needs genetic variance.)
  • Interlayer edge — a new edge linking a hormone-layer node to a pigmentation-layer node (e.g. GPER1 → MITF), as opposed to edges within either layer. These are what “link the two networks.”

Step 1 — The two-level architecture, and where hormones enter

The pigmentation network is the floor. What this notebook adds is the endocrine arm of the diffusible layer. The bridge has a fixed shape everywhere it occurs:

hormone-source enzyme → circulating / local ligand → receptor on the melanocyte → cAMP/CREB → MITF → melanin genes

The melanocortin arm of this bridge already exists in the substrate: α-MSH (POMC) → MC1R → CREB1 → MITF is present in NB7 (MC1R→MITF is a multi-layer edge). What is missing is the sex-steroid arm — the estrogen and androgen receptors are not in the pigmentation substrate at all, which is exactly why the 53-gene hormone set sits disconnected from it. This notebook adds the sex-steroid receptors that a melanocyte actually expresses, and their cited receptor → MITF edges.

The evolutionary motivation is a companion scan of primate sexual dichromatism — shown next, and used for motivation only (its values are interim).

Step 0 — Input provenance

This notebook reads seven version-controlled files. Each is documented here as executable provenance: the INPUTS manifest in the next cell records, for every file, what it is, its external source (with the DATA_SOURCES.md entry or docs/specs/*.spec.md where one exists), and how it is produced. The load_input() helper loads each file and prints its provenance plus a SHA256 of the exact bytes read, so nothing downstream is an unsourced read.

File What it is Source Produced by
comparative-genomics/analysis/certified_hits.csv Certified selection hits (K, direction) from the primate scan — motivation only, no load-bearing claim here HPC HyPhy aBSREL/RELAX scan comparative-genomics pipeline (commit c67a6ae)
comparative-genomics/analysis/data/hormone_axes.csv 53 sex-hormone genes × endocrine axis KEGG hsa00140 (steroid hormone biosynthesis) + hsa04912 (GnRH signaling) + design-added receptors/cofactors Notebook 13
data/processed/nb13_melanocyte_receptor_expression.csv Receptor-in-melanocyte expression gate Zhang et al. 2018, Genome Res 28:1621, PMID 30333196, doi:10.1101/gr.233304.117 (106 primary-melanocyte cis-eQTL; Tables S6/S11) + cited literature hand-curated for NB13
data/processed/nb13_bridge_citations.csv Citation backbone for each hormone→pigment bridge (6 PMIDs, all verified against PubMed) primary literature (Natale 2016, Filardo 2002, Tadokoro 1997, Zouboulis 2007, Spałkowska 2021, Im 2002) hand-curated for NB13
data/processed/nb13_hormone_interlayer_edges.csv The hormone-receptor → pigmentation-core edges added by NB13, each with PMID + expression gate primary literature (per-edge citation_pmid) hand-curated for NB13
data/processed/nb7_substrate_nodes.csv 803-node harmonized pigmentation substrate docs/specs/nb7_substrate.spec.md Notebook 07
data/processed/nb7_substrate_edges.csv 7819 substrate edges docs/specs/nb7_substrate.spec.md Notebook 07
Show code
import os, hashlib
import pandas as pd
REPO = os.environ.get("PIGNET_REPO", os.path.abspath(os.path.join(os.getcwd(), "..")))

# --- Provenance manifest: every raw input, its source, and how to regenerate it. ---
INPUTS = {
    "certified_hits": {
        "path": "comparative-genomics/analysis/certified_hits.csv",
        "what": "certified selection hits (gene, set, K, direction) from the primate dichromatism scan "
                "— MOTIVATION ONLY; no selection value is a load-bearing claim in this notebook",
        "source": "HPC HyPhy aBSREL/RELAX scan output (DATA_SOURCES.md; comparative-genomics/analysis/README.md)",
        "produced_by": "comparative-genomics pipeline (commit c67a6ae)",
    },
    "hormone_axes": {
        "path": "comparative-genomics/analysis/data/hormone_axes.csv",
        "what": "53 sex-hormone genes labeled by endocrine axis",
        "source": "Seeded from KEGG steroid hormone biosynthesis (hsa00140, 27 genes) + KEGG GnRH signaling (hsa04912, 8 genes), plus androgen/estrogen receptor->target genes (AR, ESR1/2, GPER1, FSHR, LHCGR) and steroid-signaling cofactors/carriers (NCOA1/2/3, NCOR1/2, SHBG, FKBP5, SCARB1, LDLR, STAR, KISS1/1R) added per design; then axis-annotated",
        "produced_by": "Notebook 13 (KEGG pathway pull + design-added receptors/cofactors, then axis-annotated)",
    },
    "receptor_gate": {
        "path": "data/processed/nb13_melanocyte_receptor_expression.csv",
        "what": "receptor-in-melanocyte expression gate (is each hormone receptor expressed in melanocytes?)",
        "source": "Zhang et al. 2018, Genome Res 28:1621-1635, PMID 30333196, doi:10.1101/gr.233304.117 "
                  "(106 primary-melanocyte cis-eQTL; Tables S6/S11) + cited dermatology literature",
        "produced_by": "hand-curated for NB13 (per-row source column carries the citation)",
    },
    "bridge_citations": {
        "path": "data/processed/nb13_bridge_citations.csv",
        "what": "citation backbone: one row per hormone->pigment bridge finding, with PMID/DOI/tier",
        "source": "primary literature; all 6 PMIDs verified against PubMed "
                  "(Natale 2016, Filardo 2002, Tadokoro 1997, Zouboulis 2007, Spalkowska 2021, Im 2002)",
        "produced_by": "hand-curated for NB13",
    },
    "interlayer_edges": {
        "path": "data/processed/nb13_hormone_interlayer_edges.csv",
        "what": "hormone-receptor -> pigmentation-core edges added by NB13, each with citation_pmid + expression_gate",
        "source": "primary literature (per-edge citation_pmid column)",
        "produced_by": "hand-curated for NB13",
    },
    "substrate_nodes": {
        "path": "data/processed/nb7_substrate_nodes.csv",
        "what": "803-node harmonized pigmentation substrate (read-only input; NB13 merges onto a copy)",
        "source": "docs/specs/nb7_substrate.spec.md",
        "produced_by": "Notebook 07 (harmonized multi-layer substrate)",
    },
    "substrate_edges": {
        "path": "data/processed/nb7_substrate_edges.csv",
        "what": "7819 harmonized substrate edges (read-only input)",
        "source": "docs/specs/nb7_substrate.spec.md",
        "produced_by": "Notebook 07 (harmonized multi-layer substrate)",
    },
}

def load_input(key):
    """Load a manifest input, printing its provenance and a checksum of the exact bytes read."""
    m = INPUTS[key]; fp = os.path.join(REPO, m["path"])
    raw = open(fp, "rb").read(); sha = hashlib.sha256(raw).hexdigest()[:16]
    df = pd.read_csv(fp)
    print(f"[{key}] {m['path']}")
    print(f"    what     : {m['what']}")
    print(f"    source   : {m['source']}")
    print(f"    produced : {m['produced_by']}")
    print(f"    loaded   : {df.shape[0]} rows x {df.shape[1]} cols | sha256[:16]={sha}\n")
    return df

CERT   = load_input("certified_hits")
HAX    = load_input("hormone_axes")
GATE   = load_input("receptor_gate")
CITES  = load_input("bridge_citations")
EDGES13= load_input("interlayer_edges")
NODES7 = load_input("substrate_nodes")
EDGES7 = load_input("substrate_edges")
[certified_hits] comparative-genomics/analysis/certified_hits.csv
    what     : certified selection hits (gene, set, K, direction) from the primate dichromatism scan — MOTIVATION ONLY; no selection value is a load-bearing claim in this notebook
    source   : HPC HyPhy aBSREL/RELAX scan output (DATA_SOURCES.md; comparative-genomics/analysis/README.md)
    produced : comparative-genomics pipeline (commit c67a6ae)
    loaded   : 9 rows x 6 cols | sha256[:16]=0ce07e83840d4a2c

[hormone_axes] comparative-genomics/analysis/data/hormone_axes.csv
    what     : 53 sex-hormone genes labeled by endocrine axis
    source   : Seeded from KEGG steroid hormone biosynthesis (hsa00140, 27 genes) + KEGG GnRH signaling (hsa04912, 8 genes), plus androgen/estrogen receptor->target genes (AR, ESR1/2, GPER1, FSHR, LHCGR) and steroid-signaling cofactors/carriers (NCOA1/2/3, NCOR1/2, SHBG, FKBP5, SCARB1, LDLR, STAR, KISS1/1R) added per design; then axis-annotated
    produced : Notebook 13 (KEGG pathway pull + design-added receptors/cofactors, then axis-annotated)
    loaded   : 53 rows x 2 cols | sha256[:16]=bba7cfd487770220

[receptor_gate] data/processed/nb13_melanocyte_receptor_expression.csv
    what     : receptor-in-melanocyte expression gate (is each hormone receptor expressed in melanocytes?)
    source   : Zhang et al. 2018, Genome Res 28:1621-1635, PMID 30333196, doi:10.1101/gr.233304.117 (106 primary-melanocyte cis-eQTL; Tables S6/S11) + cited dermatology literature
    produced : hand-curated for NB13 (per-row source column carries the citation)
    loaded   : 8 rows x 9 cols | sha256[:16]=6bcbfc85952192db

[bridge_citations] data/processed/nb13_bridge_citations.csv
    what     : citation backbone: one row per hormone->pigment bridge finding, with PMID/DOI/tier
    source   : primary literature; all 6 PMIDs verified against PubMed (Natale 2016, Filardo 2002, Tadokoro 1997, Zouboulis 2007, Spalkowska 2021, Im 2002)
    produced : hand-curated for NB13
    loaded   : 6 rows x 7 cols | sha256[:16]=e251eadb6f0bc8a0

[interlayer_edges] data/processed/nb13_hormone_interlayer_edges.csv
    what     : hormone-receptor -> pigmentation-core edges added by NB13, each with citation_pmid + expression_gate
    source   : primary literature (per-edge citation_pmid column)
    produced : hand-curated for NB13
    loaded   : 4 rows x 13 cols | sha256[:16]=eae079f132296fd3

[substrate_nodes] data/processed/nb7_substrate_nodes.csv
    what     : 803-node harmonized pigmentation substrate (read-only input; NB13 merges onto a copy)
    source   : docs/specs/nb7_substrate.spec.md
    produced : Notebook 07 (harmonized multi-layer substrate)
    loaded   : 803 rows x 17 cols | sha256[:16]=4053c652a8d4f832

[substrate_edges] data/processed/nb7_substrate_edges.csv
    what     : 7819 harmonized substrate edges (read-only input)
    source   : docs/specs/nb7_substrate.spec.md
    produced : Notebook 07 (harmonized multi-layer substrate)
    loaded   : 7819 rows x 12 cols | sha256[:16]=688c378fc1364cad
Show code
# Companion comparative-genomics scan (primate sexual dichromatism) — MOTIVATION ONLY.
# These K-values are INTERIM; no selection value is a load-bearing claim in this notebook.
axis = HAX.set_index("gene")["axis_category"].to_dict()
ch = CERT.copy()
ch["axis"] = ch["gene"].map(axis).fillna("(pigmentation)")
sel = ch[ch["direction"] == "intensified"][["gene", "set", "axis", "K"]].sort_values("K", ascending=False)
print("Intensified-selection hits in dichromatic primate lineages (INTERIM — motivation only):\n")
print(sel.to_string(index=False))
print("\nThe hormone signal is concentrated in sex-steroid METABOLISM enzymes (HSD17B*, CYP7B1);")
print("with the paracrine pigment signals KITLG/EDN3, it is the diffusible layer — not the synthesis floor.")
Intensified-selection hits in dichromatic primate lineages (INTERIM — motivation only):

    gene          set                 axis        K
 HSD17B1      hormone        estrogen_axis 2.931883
HSD17B12      hormone steroid_biosynthesis 2.524380
  SRD5A1      hormone        androgen_axis 2.323385
  TFAP2A pigmentation       (pigmentation) 1.928376
  CYP7B1      hormone steroid_biosynthesis 1.373693
 HSD17B7      hormone steroid_biosynthesis 1.315246
   KITLG pigmentation       (pigmentation) 1.301218
    EDN3 pigmentation       (pigmentation) 1.283118

The hormone signal is concentrated in sex-steroid METABOLISM enzymes (HSD17B*, CYP7B1);
with the paracrine pigment signals KITLG/EDN3, it is the diffusible layer — not the synthesis floor.

Step 2 — The bridge model

A hormone can influence pigment only through a receptor on the melanocyte. So the bridge is always hormone → melanocyte receptor → MITF, and the receptor is the load-bearing node. Two questions gate every proposed bridge, in order:

  1. Is the receptor actually expressed in melanocytes? (Step 3 — else the hormone cannot act there.)
  2. Does a cited study show the hormone changes melanogenesis through it, and in which direction? (Step 4.)

Step 3 — Expression gate: is the receptor actually in the melanocyte?

Before adding any receptor as a bridge node we gate it on Zhang et al. 2018 — cis-eQTL mapping in 106 purified primary human melanocytes (this project’s tissue-correct melanocyte reference; NB8). A significant melanocyte cis-eQTL is direct proof the gene is expressed and regulated in melanocytes; for genes without a significant eQTL we fall back to the published expression literature (eQTL-absence is inconclusive, not negative).

Show code
GATE[["gene", "axis", "zhang_melanocyte_eGene_q", "melanocyte_evidence",
      "literature_expression", "literature_note"]]

Figure — the expression gate. Each candidate receptor is placed by evidence tier: tissue-correct (a significant Zhang melanocyte cis-eQTL), literature-only, or excluded. Only receptors clearing the gate become bridge nodes; ESR1 (melanocytes are ERα-negative) and CYP19A1 (a paracrine aromatase source, not a receptor) are excluded.

Show code
import os
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt, matplotlib as mpl, numpy as np
mpl.rcParams.update({"font.size":9,"axes.titlesize":10,"axes.titleweight":"bold","svg.fonttype":"none","figure.dpi":150,"axes.edgecolor":"#444"})
os.makedirs("figures", exist_ok=True)
# Verdict tier is derived from GATE's structured columns; the explicit bridge role
# reflects the documented reasoning in Step 3 (kept beside the code so it is auditable).
_tier = {"melanocyte_cis_eGene":"tissue-correct"}
def _gate_tier(row):
    note = str(row.literature_note)
    # exclusion signals take precedence over an "expressed" flag (e.g. ESR1: trans-eQTL "yes" but ERa-NEGATIVE by IHC)
    if "NEGATIVE" in note or "NOT shown" in note or "not a functional bridge" in note: return "excluded"
    if row.melanocyte_evidence == "melanocyte_cis_eGene": return "tissue-correct"
    if str(row.expressed_in_melanocyte)=="yes":           return "literature"      # trans-eQTL / IHC
    return "literature"
_role = {"MC1R":"bridge (positive control)","EDNRB":"bridge (positive control)","TYR":"pigment control",
         "GPER1":"bridge (estrogen arm)","ESR2":"bridge (weak)","AR":"regional only (genital)",
         "ESR1":"EXCLUDED (ER\u03b1-negative)","CYP19A1":"not a receptor (paracrine source)"}
_tcol = {"tissue-correct":"#2f6d3a","literature":"#8fce97","excluded":"#c0662e"}
_gx   = {"tissue-correct":3.0,"literature":2.0,"excluded":0.6}
G = GATE.copy(); G["tier"] = [ _gate_tier(r) for r in G.itertuples() ]
# AR is a special-cased literature-regional (amber), keep its distinct colour
_order = ["MC1R","EDNRB","GPER1","ESR2","AR","ESR1","CYP19A1","TYR"]
G = G.set_index("gene").loc[[g for g in _order if g in set(G.gene)]].reset_index()
fig, ax = plt.subplots(figsize=(8.6,4.4))
for i,r in enumerate(G.itertuples()):
    y=len(G)-1-i; role=_role.get(r.gene, ""); col=_tcol[r.tier]
    if r.gene=="AR": col="#e0a35c"
    ax.scatter(_gx[r.tier], y, s=200, color=col, edgecolor="white", lw=1, zorder=3)
    ax.text(0.05, y, r"$\it{%s}$"%r.gene, fontsize=8.5, va="center", ha="left", fontweight="bold")
    ax.text(3.35, y, role, fontsize=7, va="center", color=col)
    q=getattr(r,"zhang_melanocyte_eGene_q")
    if q==q: ax.text(_gx[r.tier], y-0.34, f"q={q:g}", fontsize=5.6, ha="center", color="#555")
ax.axvspan(2.6,3.2,color="#eef6ef",zorder=0)
ax.text(3.0,7.7,"tissue-correct\n(Zhang melanocyte cis-eQTL)",ha="center",fontsize=6.5,color="#2f6d3a")
ax.text(2.0,7.7,"literature\nexpression",ha="center",fontsize=6.5,color="#666")
ax.text(0.6,7.7,"excluded",ha="center",fontsize=6.5,color="#c0662e")
ax.set_xlim(0,6.8); ax.set_ylim(-0.7,8.3); ax.set_yticks([]); ax.set_xticks([])
ax.set_title("Expression gate: which sex-steroid receptors are functional melanocyte bridges", loc="left", fontsize=9.5)
for s in ax.spines.values(): s.set_visible(False)
fig.tight_layout(); fig.savefig("figures/nb13_expression_gate.png",dpi=150,bbox_inches="tight"); plt.show()

Reading the gate. The estrogen and melanocortin / endothelin arms clear it on tissue-correct data: GPER1 (membrane estrogen receptor) is a significant melanocyte cis-eGene (q≈0.005) and is confirmed expressed by RNAseq; ESR2 (ERβ) is in ~90 % of epidermal melanocytes by IHC; and the positive controls MC1R and EDNRB are cis-eGenes as expected. AR is expressed and functional only in regional (genital) melanocytes — the weakest arm. ESR1 (ERα) is not a functional bridge: multiple IHC studies find normal melanocytes ERα-negative, so despite a faint melanocyte trans-eQTL signal it is excluded. CYP19A1 (aromatase) is expressed in skin (sebaceous / dermal), a paracrine estrogen source, but not shown to be melanocyte-intrinsic — so it enters as context, not a node.

Step 4 — The cited interlayer edges

Each receptor → MITF / pigment edge is added only with a verified citation and a provenance tier (established = textbook / multiple sources; paper_supported = one solid human study; weak_or_indirect / _regional = thin or region-specific). Every PMID below was checked against PubMed by an independent verification pass — none are asserted from memory. That check also corrected the estrogen mechanism: the functional melanocyte estrogen receptor is the membrane GPER, not ERα, and it raises cAMP — converging on the same cAMP → CREB → MITF node the melanocortin (MC1R) arm uses.

Show code
print("Verified citations (every PMID confirmed real against PubMed):\n")
print(CITES[["pmid", "first_author", "year", "journal", "tier"]].to_string(index=False))

print("\n\nInterlayer edges added (hormone receptor → pigmentation core):\n")
for _, r in EDGES13.iterrows():
    print(f"  {r['gene_a']:6s}{r['gene_b']:5s} [{r['axis']}, {r['evidence_tier']}, {r['direction_effect']}]")
    print(f"         {r['mechanism']}")
    print(f"         PMID {r['citation_pmid']}{r['note']}\n")
Verified citations (every PMID confirmed real against PubMed):

    pmid first_author  year           journal             tier
27115344    Natale CA  2016             eLife  paper_supported
11773440   Filardo EJ  2002    Mol Endocrinol  paper_supported
34833446 Spałkowska M  2021 Medicina (Kaunas)  paper_supported
 9326383   Tadokoro T  1997 J Invest Dermatol  paper_supported
17326004 Zouboulis CC  2007    Horm Metab Res  paper_supported
11850590         Im S  2002  J Korean Med Sci weak_or_indirect


Interlayer edges added (hormone receptor → pigmentation core):

  GPER1  → MITF  [estrogen, paper_supported, increases_melanin]
         17β-estradiol → GPER (membrane) → cAMP → pCREB → MITF
         PMID 27115344;11773440  —  The strong estrogen bridge; melasma/pregnancy mechanism; converges on the SAME cAMP/CREB/MITF node as melanocortin.

  ESR2   → MITF  [estrogen, weak_or_indirect, increases_melanin(putative)]
         estradiol → ERβ (nuclear) → transcriptional (functional role secondary to GPER)
         PMID 34833446  —  ERβ IS expressed in melanocytes, but the functional estrogen→melanin effect is attributed to GPER, not ERβ — included as expressed node, low-tier edge.

  AR     → TYR   [androgen, paper_supported_regional, increases_melanin]
         androgen (T→DHT) → AR → ↑tyrosinase activity
         PMID 9326383  —  Regional (genital) melanocytes; generalization to all epidermal melanocytes NOT shown. The weakest/most-caveated arm.

  MC1R   → MITF  [melanocortin, established, increases_melanin]
         α-MSH → MC1R → cAMP → PKA → CREB → MITF
         PMID nan  —  Textbook; ALREADY in the pigmentation substrate. The endocrine bridge the disorder architecture names as the whole-body up-dial.

Step 5 — Merge the hormone layer onto the substrate (in this notebook’s own files)

The merge reads the NB7 substrate read-only and writes new files (nb13_merged_substrate_{nodes,edges}.csv). nb7_substrate_*.csv is never modified — the pigmentation substrate stays pure; this notebook only produces a downstream, layered view.

Show code
# READ the pigmentation substrate (NB7) read-only; WRITE NB13's own merged files.
nodes, edges = NODES7.copy(), EDGES7.copy()
n0, e0 = len(nodes), len(edges)

existing = set(nodes["gene"])
new_receptors = [g for g in ["GPER1", "ESR2", "AR"] if g not in existing]   # MC1R/EDNRB already present
new_rows = []
for g in new_receptors:
    r = GATE[GATE["gene"] == g].iloc[0]
    new_rows.append(dict(gene=g, supporting_layers="hormone_bridge", n_edge_bearing_layers=1,
                         citation=f"NB13 hormone layer; {r['melanocyte_evidence']}; {r['literature_note']}",
                         citation_source="Zhang2018 (PMID 30333196) + verified literature (nb13_bridge_citations.csv)"))
merged_nodes = pd.concat([nodes, pd.DataFrame(new_rows)], ignore_index=True)

add = []
for _, r in EDGES13.iterrows():
    if r["gene_a"] == "MC1R":       # melanocortin bridge already in the substrate
        continue
    add.append(dict(gene_a=r["gene_a"], gene_b=r["gene_b"], source=r["source"], target=r["target"],
                    merged_sign=r["sign"], supporting_layers="hormone_bridge", n_supporting_layers=1,
                    layer_evidence_type=f"hormone_bridge:{r['axis']}", tier=r["evidence_tier"],
                    citation=f"PMID {r['citation_pmid']}"))
merged_edges = pd.concat([edges, pd.DataFrame(add)], ignore_index=True)

merged_nodes.to_csv(os.path.join(REPO, "data/processed/nb13_merged_substrate_nodes.csv"), index=False)
merged_edges.to_csv(os.path.join(REPO, "data/processed/nb13_merged_substrate_edges.csv"), index=False)

print(f"Pigmentation substrate (NB7, read-only):  {n0} nodes, {e0} edges")
print(f"NB13 merged view (new files):             {len(merged_nodes)} nodes (+{len(new_rows)}), "
      f"{len(merged_edges)} edges (+{len(add)})")
print(f"Added receptor nodes: {new_receptors}")
print("nb7_substrate_*.csv NOT modified; wrote nb13_merged_substrate_{nodes,edges}.csv")
Pigmentation substrate (NB7, read-only):  803 nodes, 7819 edges
NB13 merged view (new files):             806 nodes (+3), 7822 edges (+3)
Added receptor nodes: ['GPER1', 'ESR2', 'AR']
nb7_substrate_*.csv NOT modified; wrote nb13_merged_substrate_{nodes,edges}.csv

Figure — the diffusible layer bridging into the pigmentation core

Show code
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
from matplotlib.patches import FancyBboxPatch, FancyArrowPatch

fig, ax = plt.subplots(figsize=(9.8, 5.4)); ax.axis("off"); ax.set_xlim(0, 10); ax.set_ylim(0, 10)
def box(x, y, w, h, txt, fc, ec, fs=9, tc="#20180f", bold=False):
    ax.add_patch(FancyBboxPatch((x - w / 2, y - h / 2), w, h, boxstyle="round,pad=0.02,rounding_size=0.12", fc=fc, ec=ec, lw=1.4))
    ax.text(x, y, txt, ha="center", va="center", fontsize=fs, color=tc, fontweight=("bold" if bold else "normal"))
def arrow(x1, y1, x2, y2, color, style="-", lw=1.9):
    ax.add_patch(FancyArrowPatch((x1, y1), (x2, y2), arrowstyle="-|>", mutation_scale=14, color=color, lw=lw, linestyle=style, shrinkA=6, shrinkB=6))

ax.text(5, 9.65, "Layering the diffusible signals onto the pigmentation core", ha="center", fontsize=12.5, fontweight="bold", color="#20180f")
ax.text(1.9, 8.95, "DIFFUSIBLE LAYER  (this notebook)", ha="center", fontsize=8.5, color="#8a3d10", fontweight="bold")
ax.text(7.7, 8.95, "PIGMENTATION CORE  (NB1–7, unchanged)", ha="center", fontsize=8.5, color="#2f5d62", fontweight="bold")
yM, yG, yE, yA, yN = 7.4, 5.9, 4.7, 3.4, 1.9
for k, y in [("α-MSH", yM), ("Estradiol", (yG + yE) / 2), ("DHT", yA), ("EDN3", yN)]:
    box(1.0, y, 1.55, 0.66, k, "#f2ede4", "#c9bfa9", 8.5)
for g, y, c in [("MC1R", yM, "#3f6f7d"), ("GPER1", yG, "#B8541A"), ("ESR2", yE, "#B8541A"), ("AR", yA, "#7a5a2a"), ("EDNRB", yN, "#3f6f7d")]:
    box(3.5, y, 1.35, 0.6, g, "#faf6ee", c, 9.5, tc=c, bold=True)
box(5.75, 6.55, 1.5, 0.78, "cAMP →\npCREB", "#eef3ea", "#8FA9AD", 8.5)
box(7.45, 5.2, 1.4, 0.95, "MITF", "#e7efe4", "#2f5d62", 13, tc="#2f5d62", bold=True)
box(9.15, 5.2, 1.45, 1.7, "TYR · TYRP1\nDCT · OCA2\n\nsynthesis\nfloor", "#f3f0e8", "#c9bfa9", 8, tc="#4a4030")
arrow(1.78, yM, 2.83, yM, "#3f6f7d"); arrow(1.78, (yG + yE) / 2, 2.9, yG, "#B8541A")
arrow(1.78, (yG + yE) / 2, 2.9, yE, "#B8541A", ":", 1.4); arrow(1.78, yA, 2.83, yA, "#7a5a2a", ":", 1.4)
arrow(1.78, yN, 2.83, yN, "#3f6f7d")
arrow(4.18, yM, 5.15, 6.7, "#3f6f7d"); arrow(4.18, yG, 5.15, 6.4, "#B8541A")
arrow(6.5, 6.4, 6.95, 5.55, "#2f5d62")
arrow(4.18, yE, 6.78, 5.05, "#B8541A", ":", 1.4)
arrow(4.18, yA, 8.55, 4.75, "#7a5a2a", ":", 1.4)
arrow(4.18, yN, 6.9, 4.95, "#3f6f7d")
arrow(8.17, 5.2, 8.42, 5.2, "#2f5d62")
ax.text(0.35, 0.72, "solid = expression-gated + cited (established / paper-supported)      ·····  dashed = weak or regional", fontsize=7.4, color="#6a5d4c")
ax.text(0.35, 0.28, "Estrogen acts through membrane GPER (not ERα — melanocytes are ERα-negative), converging on the SAME cAMP→CREB→MITF node as melanocortin.", fontsize=7.1, color="#8a3d10", style="italic")
fig.savefig("figures/nb13_hormone_bridge.png", dpi=140, bbox_inches="tight")
plt.show()

Discussion — what the linked layer buys, and what it doesn’t

The two gene networks are now one substrate. The sex-steroid receptors a melanocyte actually expresses (GPER1, ESR2) are wired into MITF alongside the pre-existing melanocortin (MC1R) and endothelin (EDNRB) bridges, so the hormone set is no longer a disconnected island next to the pigmentation core. The coupling is concrete and inspectable: one can now trace a path from a sex-steroid enzyme, through its ligand and a melanocyte receptor, into the melanogenesis regulon.

A convergence worth naming. The membrane estrogen receptor GPER and the melanocortin receptor MC1R both raise cAMP → CREB → MITF. The endocrine “up” signals for pigment funnel through the same node the disorder architecture identified as the whole-body dial — now shown for a second hormone axis.

The estrogen arm is the strong one. GPER1 is a melanocyte eGene and the functional estrogen receptor (Natale 2016); estrogen→melanin is the well-documented biology of melasma / pregnancy hyperpigmentation.

Known gaps

  • ERα (ESR1) is excluded, not included. Normal melanocytes are ERα-negative by IHC; a naive “estrogen receptor” edge would have been wrong. The verification pass caught this.
  • The androgen arm is weak / regional. AR is functional in genital melanocytes (Tadokoro 1997); generalization to all epidermal melanocytes is not shown — it is a low-tier, flagged edge, not a claim.
  • The enzymes are not melanocyte-expressed, and that is correct. The sex-steroid metabolism enzymes act systemically / in other skin cells and reach the melanocyte as a ligand, through the receptor — so their absence from the melanocyte-eGene table is expected.
  • The comparative-genomics selection signal is interim and is used only as motivation; no selection value is load-bearing here.
  • eGene absence ≠ non-expression. ESR2 / AR are gated to the literature, not to eQTL; a dedicated melanocyte expression pull (e.g. Human Protein Atlas single-cell) would tighten these.
  • Reference architecture, European-ancestry melanocytes (Zhang’s cultures) — the canonical regulatory route, not a cross-population contrast.

Outputs

Processed CSVs (data/processed/): nb13_melanocyte_receptor_expression.csv (expression gate), nb13_bridge_citations.csv (verified PMIDs), nb13_hormone_interlayer_edges.csv (cited edges), nb13_merged_substrate_{nodes,edges}.csv (NB13’s own merged view — NB7 unchanged). Figure (notebooks/figures/): nb13_hormone_bridge.png.

Back to top