[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M73GTM0WZTEZ0Y2WHVC3NPC7":3,"skill-same:01M73GTM0WZTEZ0Y2WHVC3NPC7":48},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":19,"linkOnly":20,"markdownContent":21,"markdownBody":22,"frontMatter":23,"refName":24,"commitSha":25,"skillDirectory":26,"forksCount":27,"repositoryHtmlUrl":28,"repositoryHomepageUrl":29,"ownerHtmlUrl":30,"ownerBlogUrl":31,"ownerDescription":32,"updatedAt":33,"install":34,"resources":47},"01M73GTM0WZTEZ0Y2WHVC3NPC7","gwas-database",null,"NHGRI-EBI GWAS Catalog REST API for SNP-trait associations from published GWAS. Query studies, associations, variants, traits, genes, summary stats. Build PRS candidates, analyze pleiotropy, fetch stats for Manhattan plots. No auth.","bg-szy\u002FTOP-SKILLS","bg-szy","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F106576190?v=4","01M73A4E8KPV67SFXRY8XZGNBX","ShuZhiyong","01M73A4E96MQ294MHM74TZBVQD",6,"Apache-2.0","https:\u002F\u002Fgithub.com\u002Fbg-szy\u002FTOP-SKILLS\u002Fblob\u002Fmaster\u002Fskills\u002Fawesome-skills\u002Fgwas-database\u002FSKILL.md",[],[],"2026-11-11 15:11:14",false,"---\nname: gwas-database\ndescription: \"NHGRI-EBI GWAS Catalog REST API for SNP-trait associations from published GWAS. Query studies, associations, variants, traits, genes, summary stats. Build PRS candidates, analyze pleiotropy, fetch stats for Manhattan plots. No auth.\"\nlicense: Apache-2.0\n---\n\n# GWAS Catalog Database — SNP-Trait Association Queries\n\n## Overview\n\nThe NHGRI-EBI GWAS Catalog is a curated collection of published genome-wide association studies, mapping SNP-trait associations with genomic context. The REST API provides programmatic access to studies, associations, variants, traits, genes, and summary statistics. All responses are HAL+JSON with embedded `_links` for pagination.\n\n## When to Use\n\n- Finding genetic variants associated with a disease or trait (e.g., \"which SNPs are linked to type 2 diabetes?\")\n- Retrieving genome-wide significant associations for a specific variant (rs ID)\n- Exploring the genetic architecture of complex traits (number of loci, effect sizes)\n- Checking variant pleiotropy (how many traits a single SNP affects)\n- Downloading summary statistics for meta-analysis or polygenic risk score construction\n- Identifying published GWAS studies by disease, gene, or PubMed ID\n- Cross-referencing EFO trait ontology terms with GWAS evidence\n- Building candidate gene lists from GWAS association regions\n- Use **omics-plotting** SKILL to render Manhattan, QQ, and forest plots from the summary statistics \u002F association results\n- For **drug target validation from GWAS hits**, use `opentargets-database` instead\n- For **variant functional annotation** (consequence prediction, regulatory impact), use Ensembl VEP via `gget`\n\n## Prerequisites\n\n```bash\npip install requests matplotlib numpy\n```\n\n**API access**:\n- **No authentication** required -- fully open access\n- **Rate limits**: no official limit, but add `time.sleep(0.2)` between requests to be courteous\n- **Base URL**: `https:\u002F\u002Fwww.ebi.ac.uk\u002Fgwas\u002Frest\u002Fapi`\n- **Response format**: HAL+JSON with `_embedded` data and `_links` for pagination\n- **Pagination**: default 20 results per page; max 500 via `size` parameter\n\n## Quick Start\n\n```python\nimport requests\nimport time\n\nBASE = \"https:\u002F\u002Fwww.ebi.ac.uk\u002Fgwas\u002Frest\u002Fapi\"\n\ndef gwas_get(endpoint, params=None):\n    \"\"\"GWAS Catalog REST API helper with rate limiting and pagination support.\"\"\"\n    url = f\"{BASE}\u002F{endpoint}\"\n    resp = requests.get(url, params=params or {})\n    resp.raise_for_status()\n    time.sleep(0.2)\n    return resp.json()\n\n# Find studies for a trait keyword. Study records have no top-level `title`\n# — the publication title lives at `publicationInfo.title`; the trait label\n# lives at `diseaseTrait.trait`.\ndata = gwas_get(\"studies\u002Fsearch\u002FfindByDiseaseTrait\", {\"diseaseTrait\": \"diabetes\"})\nstudies = data[\"_embedded\"][\"studies\"]\nprint(f\"Found {len(studies)} studies for 'diabetes'\")\nfor s in studies[:3]:\n    title = (s.get(\"publicationInfo\") or {}).get(\"title\", \"N\u002FA\")\n    trait = (s.get(\"diseaseTrait\") or {}).get(\"trait\", \"N\u002FA\")\n    print(f\"  {s['accessionId']} | {trait[:40]:\u003C40} | {title[:60]}\")\n```\n\n## Core API\n\n### Module 1: Study Search\n\nSearch GWAS studies by disease trait keyword or PubMed ID.\n\n```python\n# Search studies by disease trait\ndata = gwas_get(\"studies\u002Fsearch\u002FfindByDiseaseTrait\", {\"diseaseTrait\": \"breast cancer\"})\nstudies = data[\"_embedded\"][\"studies\"]\nfor s in studies[:5]:\n    pi = s.get(\"publicationInfo\") or {}\n    print(f\"  {s['accessionId']} | PMID:{pi.get('pubmedId','N\u002FA')} | {pi.get('title','')[:60]}\")\n\ntime.sleep(0.2)\n\n# Search by PubMed ID. NOTE: the older `findByPubmedId` 404s on \u002Fstudies\u002F;\n# the working endpoint is `findByPublicationIdPubmedId`.\ndata = gwas_get(\"studies\u002Fsearch\u002FfindByPublicationIdPubmedId\", {\"pubmedId\": \"25673413\"})\nstudies = data[\"_embedded\"][\"studies\"]\nprint(f\"Studies from PMID 25673413: {len(studies)}\")\nfor s in studies:\n    trait = (s.get(\"diseaseTrait\") or {}).get(\"trait\", \"N\u002FA\")\n    print(f\"  {s['accessionId']}: {trait}\")\n```\n\n### Module 2: Association Queries\n\nRetrieve SNP-trait associations filtered by trait (EFO term), variant, or p-value.\n\n```python\n# Associations by EFO trait. The old path `efoTraits\u002F{shortForm}\u002Fassociations`\n# also works *if* you have the current shortForm — but trait shortForms have\n# been re-mapped to MONDO (e.g. EFO_0000249 → MONDO_0004975). The most reliable\n# path is `associations\u002Fsearch\u002FfindByEfoTrait?efoTrait=\u003Ccanonical trait name>`.\ndata = gwas_get(\"associations\u002Fsearch\u002FfindByEfoTrait\",\n                {\"efoTrait\": \"type 2 diabetes mellitus\", \"size\": 50})\nassocs = data[\"_embedded\"][\"associations\"]\nprint(f\"Associations for 'type 2 diabetes mellitus': {len(assocs)}\")\n\nfor a in assocs[:5]:\n    pval = a.get(\"pvalue\", None)\n    genes = []\n    for locus in a.get(\"loci\", []) or []:\n        for gene in locus.get(\"authorReportedGenes\", []) or []:\n            genes.append(gene.get(\"geneName\", \"\"))\n    loci = a.get(\"loci\") or [{}]\n    snps = [r.get(\"snps\", [{}])[0].get(\"rsId\", \"N\u002FA\")\n            for r in (loci[0].get(\"strongestRiskAlleles\") or [])]\n    print(f\"  rs={snps} | p={pval} | genes={genes}\")\n```\n\n```python\n# Associations for a specific variant. NOTE: association records do not embed\n# `efoTraits` inline — they expose them via the `_links.efoTraits.href`\n# HAL link. Follow the link (cached if needed) to resolve trait names.\ndata = gwas_get(\"singleNucleotidePolymorphisms\u002Frs7903146\u002Fassociations\", {\"size\": 5})\nassocs = data[\"_embedded\"][\"associations\"]\nprint(f\"Associations for rs7903146 (first page): {len(assocs)}\")\n\ndef association_traits(assoc):\n    \"\"\"Resolve efoTraits via the HAL link on an association record.\"\"\"\n    href = (assoc.get(\"_links\") or {}).get(\"efoTraits\", {}).get(\"href\")\n    if not href:\n        return []\n    r = requests.get(href, timeout=15)\n    if not r.ok:\n        return []\n    return [t.get(\"trait\") for t in r.json().get(\"_embedded\", {}).get(\"efoTraits\", [])]\n\nfor a in assocs[:5]:\n    traits = association_traits(a)\n    print(f\"  p={a.get('pvalue')} | OR={a.get('orPerCopyNum', 'N\u002FA')} | traits={traits}\")\n    time.sleep(0.1)\n```\n\n### Module 3: Variant Lookup\n\nQuery variant details by rsID, chromosomal region, or cytogenetic band.\n\n```python\n# Lookup single variant\ndata = gwas_get(\"singleNucleotidePolymorphisms\u002Frs7903146\")\nloc = data.get(\"locations\", [{}])[0]\nprint(f\"rs7903146: chr{loc.get('chromosomeName', '?')}:{loc.get('chromosomePosition', '?')}\")\nprint(f\"  Functional class: {data.get('functionalClass', 'N\u002FA')}\")\nprint(f\"  Merged into: {data.get('merged', 'N\u002FA')}\")\n\ntime.sleep(0.2)\n\n# Search variants by chromosomal region\ndata = gwas_get(\"singleNucleotidePolymorphisms\u002Fsearch\u002FfindByChromBpLocationRange\",\n                {\"chrom\": \"10\", \"bpStart\": \"114750000\", \"bpEnd\": \"114800000\", \"size\": 50})\nsnps = data[\"_embedded\"][\"singleNucleotidePolymorphisms\"]\nprint(f\"Variants in chr10:114750000-114800000: {len(snps)}\")\nfor v in snps[:5]:\n    print(f\"  {v['rsId']}: {v.get('functionalClass', 'N\u002FA')}\")\n```\n\n```python\n# Search variants by gene name (the cytogenetic-band endpoint\n# `findByCytogeneticBand` was removed — use gene or chromosome-range instead).\ndata = gwas_get(\"singleNucleotidePolymorphisms\u002Fsearch\u002FfindByGene\",\n                {\"geneName\": \"TCF7L2\", \"size\": 5})\nsnps = data[\"_embedded\"][\"singleNucleotidePolymorphisms\"]\nprint(f\"Variants in TCF7L2: {len(snps)}\")\n```\n\n### Module 4: Trait Search\n\nBrowse and search EFO-mapped traits in the GWAS Catalog.\n\n```python\n# Search traits by exact name (the older `findByDescription` endpoint was\n# removed — search\u002FefoTrait now expects the canonical trait label).\ndata = gwas_get(\"efoTraits\u002Fsearch\u002FfindByEfoTrait\", {\"trait\": \"Alzheimer disease\"})\ntraits = data[\"_embedded\"][\"efoTraits\"]\nprint(f\"Traits matching 'Alzheimer disease': {len(traits)}\")\nfor t in traits[:5]:\n    print(f\"  {t['shortForm']}: {t['trait']}  (uri={t['uri']})\")\n\ntime.sleep(0.2)\n\n# Get specific trait by shortForm. NOTE: many legacy EFO IDs have been\n# re-mapped to MONDO (e.g. old `EFO_0000249` for Alzheimer is now\n# `MONDO_0004975` — `efoTraits\u002FEFO_0000249` returns 404). Resolve via search\n# above first, then use the current shortForm:\nshort_form = traits[0][\"shortForm\"]   # e.g. 'MONDO_0004975'\ndata = gwas_get(f\"efoTraits\u002F{short_form}\")\nprint(f\"Trait: {data['trait']}\")\nprint(f\"  URI       : {data['uri']}\")\nprint(f\"  shortForm : {data['shortForm']}\")\n```\n\n### Module 5: Summary Statistics\n\nAccess study-level summary statistics for downstream analysis (meta-analysis, PRS).\n\n```python\n# List studies with available summary statistics\ndata = gwas_get(\"studies\u002Fsearch\u002FfindByFullPvalueSet\", {\"fullPvalueSet\": True, \"size\": 10})\nstudies = data[\"_embedded\"][\"studies\"]\nprint(f\"Studies with summary stats (first page): {len(studies)}\")\nfor s in studies[:5]:\n    trait = (s.get(\"diseaseTrait\") or {}).get(\"trait\", \"N\u002FA\")\n    print(f\"  {s['accessionId']}: {trait[:50]}\")\n\ntime.sleep(0.2)\n\n# Summary statistics metadata is NOT exposed via the REST API\n# (`studies\u002F{acc}\u002FsummaryStatistics` returns 404). Use the GWAS Catalog FTP\n# directly — paths are predictable by study accession:\nftp_base = \"http:\u002F\u002Fftp.ebi.ac.uk\u002Fpub\u002Fdatabases\u002Fgwas\u002Fsummary_statistics\"\nacc = studies[0][\"accessionId\"]\nftp_url = f\"{ftp_base}\u002F{acc[:-3]}001-{acc[:-3]}999\u002F{acc}\u002F\"\nprint(f\"Summary stats FTP directory: {ftp_url}\")\n```\n\n```python\n# Download summary statistics file (FTP)\n# Summary statistics are hosted on the GWAS Catalog FTP, not the REST API\nimport urllib.request\n\nstudy_id = \"GCST006867\"  # Example study\nftp_base = \"http:\u002F\u002Fftp.ebi.ac.uk\u002Fpub\u002Fdatabases\u002Fgwas\u002Fsummary_statistics\"\n# Actual paths vary by study; check the study page for the download link\n# Example: ftp_base\u002F{study_id}\u002F{study_id}.tsv.gz\nurl = f\"{ftp_base}\u002F{study_id}\"\nprint(f\"Summary stats FTP directory: {url}\")\n# Use requests.get() or urllib to download the .tsv.gz file\n```\n\n### Module 6: Gene and Publication Search\n\nFind GWAS associations by gene name or retrieve publication metadata.\n\n```python\n# Search associations by gene\ndata = gwas_get(\"singleNucleotidePolymorphisms\u002Fsearch\u002FfindByGene\",\n                {\"geneName\": \"BRCA1\", \"size\": 50})\nsnps = data[\"_embedded\"][\"singleNucleotidePolymorphisms\"]\nprint(f\"Variants near BRCA1: {len(snps)}\")\nfor v in snps[:5]:\n    locs = v.get(\"locations\", [{}])\n    pos = locs[0].get(\"chromosomePosition\", \"?\") if locs else \"?\"\n    print(f\"  {v['rsId']}: chr{locs[0].get('chromosomeName', '?')}:{pos}\")\n\ntime.sleep(0.2)\n\n# Get study publication details\ndata = gwas_get(\"studies\u002FGCST000392\")\npub = data.get(\"publicationInfo\", {})\nprint(f\"Study: {data['accessionId']}\")\nprint(f\"  Author: {pub.get('author', {}).get('fullname', 'N\u002FA')}\")\nprint(f\"  Journal: {pub.get('publication', 'N\u002FA')}\")\nprint(f\"  PMID: {pub.get('pubmedId', 'N\u002FA')}\")\nprint(f\"  Date: {pub.get('publicationDate', 'N\u002FA')}\")\n```\n\n## Key Concepts\n\n### Data Entities and Relationships\n\nThe GWAS Catalog organizes data as interconnected entities:\n\n| Entity | Description | Key Identifier | Example |\n|--------|-------------|---------------|---------|\n| **Study** | A published GWAS experiment | GCST accession (e.g., `GCST000392`) | Wellcome Trust Case Control Consortium study |\n| **Association** | A SNP-trait association with p-value and effect size | Internal ID | rs7903146 associated with T2D at p=1e-40 |\n| **Variant (SNP)** | A single nucleotide polymorphism | rs number (e.g., `rs7903146`) | TCF7L2 variant |\n| **Trait** | A disease\u002Fphenotype mapped to EFO ontology | EFO ID (e.g., `EFO_0001360`) | Type 2 diabetes mellitus |\n| **Gene** | A gene near or harboring GWAS variants | Gene symbol (e.g., `TCF7L2`) | Transcription factor 7-like 2 |\n\n**Relationships**: Study --(reports)--> Association --(involves)--> Variant + Trait. Variants map to genomic positions and nearby genes.\n\n### HAL+JSON Response Structure\n\nAll API responses follow HAL (Hypertext Application Language) format:\n\n| Top-level Section | Contents | Access Pattern |\n|-------------------|----------|----------------|\n| `_embedded` | Primary data objects (studies, associations, etc.) | `response[\"_embedded\"][\"studies\"]` |\n| `_links` | Navigation links (self, next, prev, first, last) | `response[\"_links\"][\"next\"][\"href\"]` |\n| `page` | Pagination metadata (size, totalElements, totalPages, number) | `response[\"page\"][\"totalElements\"]` |\n\n### Genome-wide Significance\n\nThe standard genome-wide significance threshold is **p \u003C= 5 x 10^-8**, correcting for approximately 1 million independent tests across the human genome. Associations below this threshold are considered suggestive. The GWAS Catalog includes associations at various significance levels -- always check p-values when filtering results.\n\n### Key Identifiers\n\n- **GCST IDs**: GWAS Catalog study accessions (e.g., `GCST000392`)\n- **rs numbers**: dbSNP reference SNP identifiers (e.g., `rs7903146`)\n- **EFO terms**: Experimental Factor Ontology for trait standardization (e.g., `EFO_0001360` for type 2 diabetes)\n- **Cytogenetic bands**: Chromosomal location notation (e.g., `10q25.2`)\n\n## Common Workflows\n\n### Workflow 1: Disease Genetic Architecture\n\n**Goal**: Map the genetic landscape of a disease by collecting all genome-wide significant loci.\n\n```python\nimport requests, time\n\nBASE = \"https:\u002F\u002Fwww.ebi.ac.uk\u002Fgwas\u002Frest\u002Fapi\"\n\ndef gwas_get(endpoint, params=None):\n    url = f\"{BASE}\u002F{endpoint}\"\n    resp = requests.get(url, params=params or {})\n    resp.raise_for_status()\n    time.sleep(0.2)\n    return resp.json()\n\n# Step 1: Resolve trait → current shortForm via findByEfoTrait\n# (the older `findByDescription` endpoint was removed).\ntraits = gwas_get(\"efoTraits\u002Fsearch\u002FfindByEfoTrait\", {\"trait\": \"schizophrenia\"})\nefo_id = traits[\"_embedded\"][\"efoTraits\"][0][\"shortForm\"]\nprint(f\"Using EFO: {efo_id}\")\n\n# Step 2: Get all associations for this trait — nested path\n# `efoTraits\u002F{shortForm}\u002Fassociations` works once you have the canonical shortForm.\nall_assocs = []\npage = 0\nwhile True:\n    data = gwas_get(f\"efoTraits\u002F{efo_id}\u002Fassociations\",\n                    {\"size\": 500, \"page\": page})\n    assocs = data[\"_embedded\"][\"associations\"]\n    all_assocs.extend(assocs)\n    if page >= data[\"page\"][\"totalPages\"] - 1:\n        break\n    page += 1\n\n# Step 3: Filter genome-wide significant\nsignificant = [a for a in all_assocs if a.get(\"pvalue\") and a[\"pvalue\"] \u003C 5e-8]\nprint(f\"Total associations: {len(all_assocs)}, genome-wide significant: {len(significant)}\")\n\n# Step 4: Extract variant and effect details\nfor a in significant[:10]:\n    risk_alleles = a.get(\"loci\", [{}])[0].get(\"strongestRiskAlleles\", [])\n    snp = risk_alleles[0].get(\"snps\", [{}])[0].get(\"rsId\", \"N\u002FA\") if risk_alleles else \"N\u002FA\"\n    or_val = a.get(\"orPerCopyNum\", \"N\u002FA\")\n    beta = a.get(\"betaNum\", \"N\u002FA\")\n    print(f\"  {snp} | p={a['pvalue']:.2e} | OR={or_val} | beta={beta}\")\n```\n\n### Workflow 2: Variant Pleiotropy Analysis\n\n**Goal**: Determine how many distinct traits a single variant is associated with.\n\n```python\nimport requests, time\n\nBASE = \"https:\u002F\u002Fwww.ebi.ac.uk\u002Fgwas\u002Frest\u002Fapi\"\n\ndef gwas_get(endpoint, params=None):\n    url = f\"{BASE}\u002F{endpoint}\"\n    resp = requests.get(url, params=params or {})\n    resp.raise_for_status()\n    time.sleep(0.2)\n    return resp.json()\n\nrs_id = \"rs7903146\"  # Well-known pleiotropic variant\n\n# Get all associations for this variant\ndata = gwas_get(f\"singleNucleotidePolymorphisms\u002F{rs_id}\u002Fassociations\", {\"size\": 500})\nassocs = data[\"_embedded\"][\"associations\"]\n\n# Association records don't embed efoTraits inline — follow the HAL\n# `_links.efoTraits.href` link per association. Cache per-href to avoid\n# duplicate fetches.\ntrait_set = {}\nhref_cache = {}\ndef fetch_traits(href):\n    if href in href_cache:\n        return href_cache[href]\n    r = requests.get(href, timeout=15)\n    href_cache[href] = (r.json().get(\"_embedded\", {}).get(\"efoTraits\", [])) if r.ok else []\n    return href_cache[href]\n\nfor a in assocs:\n    href = (a.get(\"_links\") or {}).get(\"efoTraits\", {}).get(\"href\")\n    if not href:\n        continue\n    for t in fetch_traits(href):\n        tid = t.get(\"shortForm\", \"unknown\")\n        if tid not in trait_set:\n            trait_set[tid] = {\"trait\": t.get(\"trait\", \"N\u002FA\"),\n                              \"best_pval\": a.get(\"pvalue\", 1), \"count\": 0}\n        trait_set[tid][\"count\"] += 1\n        if a.get(\"pvalue\") and a[\"pvalue\"] \u003C trait_set[tid][\"best_pval\"]:\n            trait_set[tid][\"best_pval\"] = a[\"pvalue\"]\n    time.sleep(0.1)\n\nprint(f\"{rs_id} is associated with {len(trait_set)} distinct traits:\")\nfor tid, info in sorted(trait_set.items(), key=lambda x: x[1][\"best_pval\"]):\n    print(f\"  {tid}: {info['trait']} (best p={info['best_pval']:.2e}, n={info['count']})\")\n```\n\n### Workflow 3: Summary Statistics Manhattan Plot\n\n**Goal**: Download summary statistics for a study and create a Manhattan plot.\n\n```python\nimport numpy as np\nimport pandas as pd\n\n# Summary statistics as a CHR\u002FBP\u002FP table (simulated here for demonstration).\n# In practice: download from GWAS Catalog FTP, e.g.\n# url = \"http:\u002F\u002Fftp.ebi.ac.uk\u002Fpub\u002Fdatabases\u002Fgwas\u002Fsummary_statistics\u002FGCSTXXXXXX\u002F...\"\n# import gzip, requests; data = gzip.decompress(requests.get(url).content)\nnp.random.seed(42)\nn_snps = 5000\npvalues = np.random.uniform(0, 1, size=n_snps)\npvalues[:20] = 10 ** np.random.uniform(-15, -8, size=20)   # add some \"hits\"\nsumstats = pd.DataFrame({\n    \"CHR\": np.random.choice(range(1, 23), size=n_snps),\n    \"BP\": np.random.randint(1, 250_000_000, size=n_snps),\n    \"P\": pvalues,\n})\nsumstats.to_csv(\"gwas.csv\", index=False)\nprint(f\"Summary stats: {len(sumstats)} SNPs, {(sumstats['P'] \u003C 5e-8).sum()} genome-wide sig -> gwas.csv\")\n# Render with the omics-plotting SKILL (`skills\u002Fdata-visualization\u002Fomics-plotting\u002FSKILL.md`) \"Manhattan\" recipe -> figures\u002Fmanhattan_plot.png\n```\n\n## Key Parameters\n\n| Parameter | Function\u002FEndpoint | Default | Range \u002F Options | Effect |\n|-----------|-------------------|---------|-----------------|--------|\n| `size` | All paginated endpoints | `20` | `1`-`500` | Results per page |\n| `page` | All paginated endpoints | `0` | `0`-`totalPages-1` | Page number (0-indexed) |\n| `diseaseTrait` | `studies\u002Fsearch\u002FfindByDiseaseTrait` | -- | Any string | Trait keyword search |\n| `pubmedId` | `studies\u002Fsearch\u002FfindByPublicationIdPubmedId` | -- | Valid PMID | Study lookup by publication (`findByPubmedId` 404s on \u002Fstudies\u002F) |\n| `geneName` | `snps\u002Fsearch\u002FfindByGene` | -- | Gene symbol | Variants near a gene |\n| `chrom`, `bpStart`, `bpEnd` | `snps\u002Fsearch\u002FfindByChromBpLocationRange` | -- | chr:start-end | Regional variant query |\n| `fullPvalueSet` | `studies\u002Fsearch\u002FfindByFullPvalueSet` | -- | `True`\u002F`False` | Filter studies with summary stats |\n| `trait` | `efoTraits\u002Fsearch\u002FfindByEfoTrait` | -- | Canonical trait name | Trait lookup by exact name (`findByDescription` was removed) |\n| `efoTrait` | `associations\u002Fsearch\u002FfindByEfoTrait` | -- | Canonical trait name | All associations for a trait |\n\n## Best Practices\n\n1. **Paginate large result sets**: Default page size is 20; set `size=500` and loop over pages for complete data retrieval. Check `page.totalElements` to know the full count before iterating.\n\n2. **Use EFO IDs for precise trait queries**: Free-text search may return related but different traits. Look up the exact EFO ID first, then query associations by EFO ID for precision.\n\n3. **Always check p-values**: The catalog contains associations at various significance levels. Filter to p \u003C 5e-8 for genome-wide significant results unless you specifically need suggestive associations.\n\n4. **Be ancestry-aware**: Effect sizes and allele frequencies vary across populations. Check the `initialSampleSize` and `replicationSampleSize` fields to understand the ancestry composition of each study.\n\n5. **Add rate-limiting delays**: Although no official limit exists, `time.sleep(0.2)` between requests prevents server overload and avoids temporary blocks.\n\n6. **Cache frequently accessed data**: Study and trait metadata rarely change. Cache results locally when running batch analyses to reduce redundant API calls.\n\n7. **Anti-pattern -- Don't rely solely on reported genes**: Author-reported genes may not be the causal gene. Cross-reference with functional annotation tools and eQTL databases for biological interpretation.\n\n## Common Recipes\n\n### Recipe 1: Cross-Reference with PGS Catalog\n\nIdentify polygenic scores available for a GWAS trait.\n\n```python\nimport requests, time\n\n# Step 1: Get EFO\u002FMONDO shortForm from GWAS Catalog\n# (the old `findByDescription` endpoint was removed; use `findByEfoTrait`)\nBASE = \"https:\u002F\u002Fwww.ebi.ac.uk\u002Fgwas\u002Frest\u002Fapi\"\ntraits = requests.get(f\"{BASE}\u002FefoTraits\u002Fsearch\u002FfindByEfoTrait\",\n                      params={\"trait\": \"coronary artery disease\"}).json()\nefo_id = traits[\"_embedded\"][\"efoTraits\"][0][\"shortForm\"]\ntime.sleep(0.2)\n\n# Step 2: Query PGS Catalog for scores using same EFO\npgs_url = f\"https:\u002F\u002Fwww.pgscatalog.org\u002Frest\u002Fscore\u002Fsearch?trait_id={efo_id}\"\npgs_data = requests.get(pgs_url).json()\nprint(f\"PGS scores for {efo_id}: {pgs_data.get('count', 0)}\")\nfor score in pgs_data.get(\"results\", [])[:5]:\n    print(f\"  {score['id']}: {score['name']} (variants: {score.get('variants_number', '?')})\")\n```\n\n### Recipe 2: Regional Association Summary\n\nCollect all GWAS associations in a genomic region.\n\n```python\nimport requests, time\n\nBASE = \"https:\u002F\u002Fwww.ebi.ac.uk\u002Fgwas\u002Frest\u002Fapi\"\n\n# Query region: chr9:21,900,000-22,200,000 (CDKN2A\u002F2B locus)\ndata = requests.get(f\"{BASE}\u002FsingleNucleotidePolymorphisms\u002Fsearch\u002FfindByChromBpLocationRange\",\n                    params={\"chrom\": \"9\", \"bpStart\": \"21900000\",\n                            \"bpEnd\": \"22200000\", \"size\": 200}).json()\ntime.sleep(0.2)\nsnps = data[\"_embedded\"][\"singleNucleotidePolymorphisms\"]\nprint(f\"Variants in CDKN2A\u002F2B locus: {len(snps)}\")\n\n# Get associations for each variant\nregion_assocs = []\nfor v in snps[:10]:  # Limit for demo\n    rs = v[\"rsId\"]\n    try:\n        a_data = requests.get(f\"{BASE}\u002FsingleNucleotidePolymorphisms\u002F{rs}\u002Fassociations\",\n                              params={\"size\": 50}).json()\n        time.sleep(0.2)\n        for a in a_data[\"_embedded\"][\"associations\"]:\n            for t in a.get(\"efoTraits\", []):\n                region_assocs.append({\"rsId\": rs, \"trait\": t[\"trait\"],\n                                      \"pvalue\": a.get(\"pvalue\")})\n    except Exception:\n        continue\n\nprint(f\"Total associations in region: {len(region_assocs)}\")\n```\n\n### Recipe 3: Effect Size Forest Plot\n\nVisualize effect sizes across studies for a single variant.\n\n```python\nimport re\nimport pandas as pd\nimport requests, time\n\nBASE = \"https:\u002F\u002Fwww.ebi.ac.uk\u002Fgwas\u002Frest\u002Fapi\"\ndata = requests.get(f\"{BASE}\u002FsingleNucleotidePolymorphisms\u002Frs1801282\u002Fassociations\",\n                    params={\"size\": 100}).json()\ntime.sleep(0.2)\nassocs = data[\"_embedded\"][\"associations\"]\n\ndef parse_ci(text):\n    \"\"\"Pull [low-high] confidence bounds out of the GWAS Catalog 'range' string.\"\"\"\n    nums = re.findall(r\"[0-9]*\\.?[0-9]+\", text or \"\")\n    return (float(nums[0]), float(nums[1])) if len(nums) >= 2 else (float(\"nan\"), float(\"nan\"))\n\n# Build a forest-plot table: label, estimate (OR), ci_low, ci_high\nrows = []\nfor a in assocs:\n    or_val = a.get(\"orPerCopyNum\")\n    trait = a.get(\"efoTraits\", [{}])[0].get(\"trait\", \"N\u002FA\") if a.get(\"efoTraits\") else \"N\u002FA\"\n    if or_val and or_val > 0:\n        lo, hi = parse_ci(a.get(\"range\", \"\"))\n        rows.append({\"label\": trait[:30], \"estimate\": or_val, \"ci_low\": lo, \"ci_high\": hi})\n\neffects = pd.DataFrame(rows)\neffects.to_csv(\"effects.csv\", index=False)\nprint(f\"Effect sizes: {len(effects)} entries -> effects.csv\")\n# Render with the omics-plotting SKILL (`skills\u002Fdata-visualization\u002Fomics-plotting\u002FSKILL.md`) \"Forest\" recipe (null line at OR=1) -> figures\u002Fforest_plot.png\n```\n\n## Troubleshooting\n\n| Problem | Cause | Solution |\n|---------|-------|----------|\n| `404 Not Found` | Invalid GCST, rs ID, or EFO ID | Verify identifier exists via search endpoint first |\n| Empty `_embedded` | No results for query | Broaden search terms or check spelling; try partial match |\n| `ConnectionError` \u002F timeout | EBI server temporarily down | Retry with exponential backoff; check https:\u002F\u002Fwww.ebi.ac.uk\u002Fgwas\u002Fstatus |\n| Truncated results | Default pagination (20 per page) | Set `size=500` and iterate over `page` parameter |\n| Missing OR\u002Fbeta values | Not all associations report effect sizes | Check both `orPerCopyNum` and `betaNum` fields; some studies report only p-values |\n| Stale data | Catalog updated quarterly | Check `lastUpdateDate` on studies; re-query if needed |\n| `KeyError: '_embedded'` | Endpoint returns single object, not list | Direct lookups (by ID) return a single object; `_embedded` only appears in search\u002Flist results |\n| Summary stats unavailable | Not all studies deposit summary stats | Filter with `findByFullPvalueSet=True` to find studies with available data |\n\n## Bundled Resources\n\n### `references\u002Fapi_endpoints.md`\n\n**Covers**: Complete endpoint catalog for all 6 REST API groups (studies, associations, variants, traits, genes, summary statistics) with query parameters, plus response field tables for the main entity types (association fields, study fields, variant fields), HTTP error codes, and pagination patterns.\n\n**Relocated inline**: Core query patterns and the most common endpoints are demonstrated in Core API modules with full code examples. HAL+JSON structure and key identifier formats are in Key Concepts.\n\n**Omitted from original api_reference.md (794 lines)**: Advanced query composition patterns (multi-parameter chaining beyond what Core API shows), child\u002Fparent trait traversal details, detailed changelog\u002Fversioning notes. These are specialized and covered by EBI documentation.\n\n## Related Skills\n\n- **gget-genomic-databases** -- gene lookups, variant annotation, BLAST (upstream ID resolution)\n- **ensembl-database (planned)** -- variant effect prediction, regulatory annotations\n- **opentargets-database (planned)** -- drug target validation from GWAS hits\n- **clinvar-database (planned)** -- clinical variant interpretation\n- **bioservices-multi-database** -- cross-database queries integrating GWAS with pathway data\n\n## References\n\n- [GWAS Catalog website](https:\u002F\u002Fwww.ebi.ac.uk\u002Fgwas\u002F) -- main portal for browsing and searching\n- [GWAS Catalog REST API documentation](https:\u002F\u002Fwww.ebi.ac.uk\u002Fgwas\u002Frest\u002Fdocs\u002Fapi) -- official API reference\n- [GWAS Catalog GitHub](https:\u002F\u002Fgithub.com\u002FEBISPOT\u002Fgoci) -- source code and issue tracker\n- [Summary Statistics FTP](http:\u002F\u002Fftp.ebi.ac.uk\u002Fpub\u002Fdatabases\u002Fgwas\u002Fsummary_statistics\u002F) -- bulk summary statistics downloads\n- [PGS Catalog](https:\u002F\u002Fwww.pgscatalog.org\u002F) -- polygenic score database using GWAS data\n","# GWAS Catalog Database — SNP-Trait Association Queries\n\n## Overview\n\nThe NHGRI-EBI GWAS Catalog is a curated collection of published genome-wide association studies, mapping SNP-trait associations with genomic context. The REST API provides programmatic access to studies, associations, variants, traits, genes, and summary statistics. All responses are HAL+JSON with embedded `_links` for pagination.\n\n## When to Use\n\n- Finding genetic variants associated with a disease or trait (e.g., \"which SNPs are linked to type 2 diabetes?\")\n- Retrieving genome-wide significant associations for a specific variant (rs ID)\n- Exploring the genetic architecture of complex traits (number of loci, effect sizes)\n- Checking variant pleiotropy (how many traits a single SNP affects)\n- Downloading summary statistics for meta-analysis or polygenic risk score construction\n- Identifying published GWAS studies by disease, gene, or PubMed ID\n- Cross-referencing EFO trait ontology terms with GWAS evidence\n- Building candidate gene lists from GWAS association regions\n- Use **omics-plotting** SKILL to render Manhattan, QQ, and forest plots from the summary statistics \u002F association results\n- For **drug target validation from GWAS hits**, use `opentargets-database` instead\n- For **variant functional annotation** (consequence prediction, regulatory impact), use Ensembl VEP via `gget`\n\n## Prerequisites\n\n```bash\npip install requests matplotlib numpy\n```\n\n**API access**:\n- **No authentication** required -- fully open access\n- **Rate limits**: no official limit, but add `time.sleep(0.2)` between requests to be courteous\n- **Base URL**: `https:\u002F\u002Fwww.ebi.ac.uk\u002Fgwas\u002Frest\u002Fapi`\n- **Response format**: HAL+JSON with `_embedded` data and `_links` for pagination\n- **Pagination**: default 20 results per page; max 500 via `size` parameter\n\n## Quick Start\n\n```python\nimport requests\nimport time\n\nBASE = \"https:\u002F\u002Fwww.ebi.ac.uk\u002Fgwas\u002Frest\u002Fapi\"\n\ndef gwas_get(endpoint, params=None):\n    \"\"\"GWAS Catalog REST API helper with rate limiting and pagination support.\"\"\"\n    url = f\"{BASE}\u002F{endpoint}\"\n    resp = requests.get(url, params=params or {})\n    resp.raise_for_status()\n    time.sleep(0.2)\n    return resp.json()\n\n# Find studies for a trait keyword. Study records have no top-level `title`\n# — the publication title lives at `publicationInfo.title`; the trait label\n# lives at `diseaseTrait.trait`.\ndata = gwas_get(\"studies\u002Fsearch\u002FfindByDiseaseTrait\", {\"diseaseTrait\": \"diabetes\"})\nstudies = data[\"_embedded\"][\"studies\"]\nprint(f\"Found {len(studies)} studies for 'diabetes'\")\nfor s in studies[:3]:\n    title = (s.get(\"publicationInfo\") or {}).get(\"title\", \"N\u002FA\")\n    trait = (s.get(\"diseaseTrait\") or {}).get(\"trait\", \"N\u002FA\")\n    print(f\"  {s['accessionId']} | {trait[:40]:\u003C40} | {title[:60]}\")\n```\n\n## Core API\n\n### Module 1: Study Search\n\nSearch GWAS studies by disease trait keyword or PubMed ID.\n\n```python\n# Search studies by disease trait\ndata = gwas_get(\"studies\u002Fsearch\u002FfindByDiseaseTrait\", {\"diseaseTrait\": \"breast cancer\"})\nstudies = data[\"_embedded\"][\"studies\"]\nfor s in studies[:5]:\n    pi = s.get(\"publicationInfo\") or {}\n    print(f\"  {s['accessionId']} | PMID:{pi.get('pubmedId','N\u002FA')} | {pi.get('title','')[:60]}\")\n\ntime.sleep(0.2)\n\n# Search by PubMed ID. NOTE: the older `findByPubmedId` 404s on \u002Fstudies\u002F;\n# the working endpoint is `findByPublicationIdPubmedId`.\ndata = gwas_get(\"studies\u002Fsearch\u002FfindByPublicationIdPubmedId\", {\"pubmedId\": \"25673413\"})\nstudies = data[\"_embedded\"][\"studies\"]\nprint(f\"Studies from PMID 25673413: {len(studies)}\")\nfor s in studies:\n    trait = (s.get(\"diseaseTrait\") or {}).get(\"trait\", \"N\u002FA\")\n    print(f\"  {s['accessionId']}: {trait}\")\n```\n\n### Module 2: Association Queries\n\nRetrieve SNP-trait associations filtered by trait (EFO term), variant, or p-value.\n\n```python\n# Associations by EFO trait. The old path `efoTraits\u002F{shortForm}\u002Fassociations`\n# also works *if* you have the current shortForm — but trait shortForms have\n# been re-mapped to MONDO (e.g. EFO_0000249 → MONDO_0004975). The most reliable\n# path is `associations\u002Fsearch\u002FfindByEfoTrait?efoTrait=\u003Ccanonical trait name>`.\ndata = gwas_get(\"associations\u002Fsearch\u002FfindByEfoTrait\",\n                {\"efoTrait\": \"type 2 diabetes mellitus\", \"size\": 50})\nassocs = data[\"_embedded\"][\"associations\"]\nprint(f\"Associations for 'type 2 diabetes mellitus': {len(assocs)}\")\n\nfor a in assocs[:5]:\n    pval = a.get(\"pvalue\", None)\n    genes = []\n    for locus in a.get(\"loci\", []) or []:\n        for gene in locus.get(\"authorReportedGenes\", []) or []:\n            genes.append(gene.get(\"geneName\", \"\"))\n    loci = a.get(\"loci\") or [{}]\n    snps = [r.get(\"snps\", [{}])[0].get(\"rsId\", \"N\u002FA\")\n            for r in (loci[0].get(\"strongestRiskAlleles\") or [])]\n    print(f\"  rs={snps} | p={pval} | genes={genes}\")\n```\n\n```python\n# Associations for a specific variant. NOTE: association records do not embed\n# `efoTraits` inline — they expose them via the `_links.efoTraits.href`\n# HAL link. Follow the link (cached if needed) to resolve trait names.\ndata = gwas_get(\"singleNucleotidePolymorphisms\u002Frs7903146\u002Fassociations\", {\"size\": 5})\nassocs = data[\"_embedded\"][\"associations\"]\nprint(f\"Associations for rs7903146 (first page): {len(assocs)}\")\n\ndef association_traits(assoc):\n    \"\"\"Resolve efoTraits via the HAL link on an association record.\"\"\"\n    href = (assoc.get(\"_links\") or {}).get(\"efoTraits\", {}).get(\"href\")\n    if not href:\n        return []\n    r = requests.get(href, timeout=15)\n    if not r.ok:\n        return []\n    return [t.get(\"trait\") for t in r.json().get(\"_embedded\", {}).get(\"efoTraits\", [])]\n\nfor a in assocs[:5]:\n    traits = association_traits(a)\n    print(f\"  p={a.get('pvalue')} | OR={a.get('orPerCopyNum', 'N\u002FA')} | traits={traits}\")\n    time.sleep(0.1)\n```\n\n### Module 3: Variant Lookup\n\nQuery variant details by rsID, chromosomal region, or cytogenetic band.\n\n```python\n# Lookup single variant\ndata = gwas_get(\"singleNucleotidePolymorphisms\u002Frs7903146\")\nloc = data.get(\"locations\", [{}])[0]\nprint(f\"rs7903146: chr{loc.get('chromosomeName', '?')}:{loc.get('chromosomePosition', '?')}\")\nprint(f\"  Functional class: {data.get('functionalClass', 'N\u002FA')}\")\nprint(f\"  Merged into: {data.get('merged', 'N\u002FA')}\")\n\ntime.sleep(0.2)\n\n# Search variants by chromosomal region\ndata = gwas_get(\"singleNucleotidePolymorphisms\u002Fsearch\u002FfindByChromBpLocationRange\",\n                {\"chrom\": \"10\", \"bpStart\": \"114750000\", \"bpEnd\": \"114800000\", \"size\": 50})\nsnps = data[\"_embedded\"][\"singleNucleotidePolymorphisms\"]\nprint(f\"Variants in chr10:114750000-114800000: {len(snps)}\")\nfor v in snps[:5]:\n    print(f\"  {v['rsId']}: {v.get('functionalClass', 'N\u002FA')}\")\n```\n\n```python\n# Search variants by gene name (the cytogenetic-band endpoint\n# `findByCytogeneticBand` was removed — use gene or chromosome-range instead).\ndata = gwas_get(\"singleNucleotidePolymorphisms\u002Fsearch\u002FfindByGene\",\n                {\"geneName\": \"TCF7L2\", \"size\": 5})\nsnps = data[\"_embedded\"][\"singleNucleotidePolymorphisms\"]\nprint(f\"Variants in TCF7L2: {len(snps)}\")\n```\n\n### Module 4: Trait Search\n\nBrowse and search EFO-mapped traits in the GWAS Catalog.\n\n```python\n# Search traits by exact name (the older `findByDescription` endpoint was\n# removed — search\u002FefoTrait now expects the canonical trait label).\ndata = gwas_get(\"efoTraits\u002Fsearch\u002FfindByEfoTrait\", {\"trait\": \"Alzheimer disease\"})\ntraits = data[\"_embedded\"][\"efoTraits\"]\nprint(f\"Traits matching 'Alzheimer disease': {len(traits)}\")\nfor t in traits[:5]:\n    print(f\"  {t['shortForm']}: {t['trait']}  (uri={t['uri']})\")\n\ntime.sleep(0.2)\n\n# Get specific trait by shortForm. NOTE: many legacy EFO IDs have been\n# re-mapped to MONDO (e.g. old `EFO_0000249` for Alzheimer is now\n# `MONDO_0004975` — `efoTraits\u002FEFO_0000249` returns 404). Resolve via search\n# above first, then use the current shortForm:\nshort_form = traits[0][\"shortForm\"]   # e.g. 'MONDO_0004975'\ndata = gwas_get(f\"efoTraits\u002F{short_form}\")\nprint(f\"Trait: {data['trait']}\")\nprint(f\"  URI       : {data['uri']}\")\nprint(f\"  shortForm : {data['shortForm']}\")\n```\n\n### Module 5: Summary Statistics\n\nAccess study-level summary statistics for downstream analysis (meta-analysis, PRS).\n\n```python\n# List studies with available summary statistics\ndata = gwas_get(\"studies\u002Fsearch\u002FfindByFullPvalueSet\", {\"fullPvalueSet\": True, \"size\": 10})\nstudies = data[\"_embedded\"][\"studies\"]\nprint(f\"Studies with summary stats (first page): {len(studies)}\")\nfor s in studies[:5]:\n    trait = (s.get(\"diseaseTrait\") or {}).get(\"trait\", \"N\u002FA\")\n    print(f\"  {s['accessionId']}: {trait[:50]}\")\n\ntime.sleep(0.2)\n\n# Summary statistics metadata is NOT exposed via the REST API\n# (`studies\u002F{acc}\u002FsummaryStatistics` returns 404). Use the GWAS Catalog FTP\n# directly — paths are predictable by study accession:\nftp_base = \"http:\u002F\u002Fftp.ebi.ac.uk\u002Fpub\u002Fdatabases\u002Fgwas\u002Fsummary_statistics\"\nacc = studies[0][\"accessionId\"]\nftp_url = f\"{ftp_base}\u002F{acc[:-3]}001-{acc[:-3]}999\u002F{acc}\u002F\"\nprint(f\"Summary stats FTP directory: {ftp_url}\")\n```\n\n```python\n# Download summary statistics file (FTP)\n# Summary statistics are hosted on the GWAS Catalog FTP, not the REST API\nimport urllib.request\n\nstudy_id = \"GCST006867\"  # Example study\nftp_base = \"http:\u002F\u002Fftp.ebi.ac.uk\u002Fpub\u002Fdatabases\u002Fgwas\u002Fsummary_statistics\"\n# Actual paths vary by study; check the study page for the download link\n# Example: ftp_base\u002F{study_id}\u002F{study_id}.tsv.gz\nurl = f\"{ftp_base}\u002F{study_id}\"\nprint(f\"Summary stats FTP directory: {url}\")\n# Use requests.get() or urllib to download the .tsv.gz file\n```\n\n### Module 6: Gene and Publication Search\n\nFind GWAS associations by gene name or retrieve publication metadata.\n\n```python\n# Search associations by gene\ndata = gwas_get(\"singleNucleotidePolymorphisms\u002Fsearch\u002FfindByGene\",\n                {\"geneName\": \"BRCA1\", \"size\": 50})\nsnps = data[\"_embedded\"][\"singleNucleotidePolymorphisms\"]\nprint(f\"Variants near BRCA1: {len(snps)}\")\nfor v in snps[:5]:\n    locs = v.get(\"locations\", [{}])\n    pos = locs[0].get(\"chromosomePosition\", \"?\") if locs else \"?\"\n    print(f\"  {v['rsId']}: chr{locs[0].get('chromosomeName', '?')}:{pos}\")\n\ntime.sleep(0.2)\n\n# Get study publication details\ndata = gwas_get(\"studies\u002FGCST000392\")\npub = data.get(\"publicationInfo\", {})\nprint(f\"Study: {data['accessionId']}\")\nprint(f\"  Author: {pub.get('author', {}).get('fullname', 'N\u002FA')}\")\nprint(f\"  Journal: {pub.get('publication', 'N\u002FA')}\")\nprint(f\"  PMID: {pub.get('pubmedId', 'N\u002FA')}\")\nprint(f\"  Date: {pub.get('publicationDate', 'N\u002FA')}\")\n```\n\n## Key Concepts\n\n### Data Entities and Relationships\n\nThe GWAS Catalog organizes data as interconnected entities:\n\n| Entity | Description | Key Identifier | Example |\n|--------|-------------|---------------|---------|\n| **Study** | A published GWAS experiment | GCST accession (e.g., `GCST000392`) | Wellcome Trust Case Control Consortium study |\n| **Association** | A SNP-trait association with p-value and effect size | Internal ID | rs7903146 associated with T2D at p=1e-40 |\n| **Variant (SNP)** | A single nucleotide polymorphism | rs number (e.g., `rs7903146`) | TCF7L2 variant |\n| **Trait** | A disease\u002Fphenotype mapped to EFO ontology | EFO ID (e.g., `EFO_0001360`) | Type 2 diabetes mellitus |\n| **Gene** | A gene near or harboring GWAS variants | Gene symbol (e.g., `TCF7L2`) | Transcription factor 7-like 2 |\n\n**Relationships**: Study --(reports)--> Association --(involves)--> Variant + Trait. Variants map to genomic positions and nearby genes.\n\n### HAL+JSON Response Structure\n\nAll API responses follow HAL (Hypertext Application Language) format:\n\n| Top-level Section | Contents | Access Pattern |\n|-------------------|----------|----------------|\n| `_embedded` | Primary data objects (studies, associations, etc.) | `response[\"_embedded\"][\"studies\"]` |\n| `_links` | Navigation links (self, next, prev, first, last) | `response[\"_links\"][\"next\"][\"href\"]` |\n| `page` | Pagination metadata (size, totalElements, totalPages, number) | `response[\"page\"][\"totalElements\"]` |\n\n### Genome-wide Significance\n\nThe standard genome-wide significance threshold is **p \u003C= 5 x 10^-8**, correcting for approximately 1 million independent tests across the human genome. Associations below this threshold are considered suggestive. The GWAS Catalog includes associations at various significance levels -- always check p-values when filtering results.\n\n### Key Identifiers\n\n- **GCST IDs**: GWAS Catalog study accessions (e.g., `GCST000392`)\n- **rs numbers**: dbSNP reference SNP identifiers (e.g., `rs7903146`)\n- **EFO terms**: Experimental Factor Ontology for trait standardization (e.g., `EFO_0001360` for type 2 diabetes)\n- **Cytogenetic bands**: Chromosomal location notation (e.g., `10q25.2`)\n\n## Common Workflows\n\n### Workflow 1: Disease Genetic Architecture\n\n**Goal**: Map the genetic landscape of a disease by collecting all genome-wide significant loci.\n\n```python\nimport requests, time\n\nBASE = \"https:\u002F\u002Fwww.ebi.ac.uk\u002Fgwas\u002Frest\u002Fapi\"\n\ndef gwas_get(endpoint, params=None):\n    url = f\"{BASE}\u002F{endpoint}\"\n    resp = requests.get(url, params=params or {})\n    resp.raise_for_status()\n    time.sleep(0.2)\n    return resp.json()\n\n# Step 1: Resolve trait → current shortForm via findByEfoTrait\n# (the older `findByDescription` endpoint was removed).\ntraits = gwas_get(\"efoTraits\u002Fsearch\u002FfindByEfoTrait\", {\"trait\": \"schizophrenia\"})\nefo_id = traits[\"_embedded\"][\"efoTraits\"][0][\"shortForm\"]\nprint(f\"Using EFO: {efo_id}\")\n\n# Step 2: Get all associations for this trait — nested path\n# `efoTraits\u002F{shortForm}\u002Fassociations` works once you have the canonical shortForm.\nall_assocs = []\npage = 0\nwhile True:\n    data = gwas_get(f\"efoTraits\u002F{efo_id}\u002Fassociations\",\n                    {\"size\": 500, \"page\": page})\n    assocs = data[\"_embedded\"][\"associations\"]\n    all_assocs.extend(assocs)\n    if page >= data[\"page\"][\"totalPages\"] - 1:\n        break\n    page += 1\n\n# Step 3: Filter genome-wide significant\nsignificant = [a for a in all_assocs if a.get(\"pvalue\") and a[\"pvalue\"] \u003C 5e-8]\nprint(f\"Total associations: {len(all_assocs)}, genome-wide significant: {len(significant)}\")\n\n# Step 4: Extract variant and effect details\nfor a in significant[:10]:\n    risk_alleles = a.get(\"loci\", [{}])[0].get(\"strongestRiskAlleles\", [])\n    snp = risk_alleles[0].get(\"snps\", [{}])[0].get(\"rsId\", \"N\u002FA\") if risk_alleles else \"N\u002FA\"\n    or_val = a.get(\"orPerCopyNum\", \"N\u002FA\")\n    beta = a.get(\"betaNum\", \"N\u002FA\")\n    print(f\"  {snp} | p={a['pvalue']:.2e} | OR={or_val} | beta={beta}\")\n```\n\n### Workflow 2: Variant Pleiotropy Analysis\n\n**Goal**: Determine how many distinct traits a single variant is associated with.\n\n```python\nimport requests, time\n\nBASE = \"https:\u002F\u002Fwww.ebi.ac.uk\u002Fgwas\u002Frest\u002Fapi\"\n\ndef gwas_get(endpoint, params=None):\n    url = f\"{BASE}\u002F{endpoint}\"\n    resp = requests.get(url, params=params or {})\n    resp.raise_for_status()\n    time.sleep(0.2)\n    return resp.json()\n\nrs_id = \"rs7903146\"  # Well-known pleiotropic variant\n\n# Get all associations for this variant\ndata = gwas_get(f\"singleNucleotidePolymorphisms\u002F{rs_id}\u002Fassociations\", {\"size\": 500})\nassocs = data[\"_embedded\"][\"associations\"]\n\n# Association records don't embed efoTraits inline — follow the HAL\n# `_links.efoTraits.href` link per association. Cache per-href to avoid\n# duplicate fetches.\ntrait_set = {}\nhref_cache = {}\ndef fetch_traits(href):\n    if href in href_cache:\n        return href_cache[href]\n    r = requests.get(href, timeout=15)\n    href_cache[href] = (r.json().get(\"_embedded\", {}).get(\"efoTraits\", [])) if r.ok else []\n    return href_cache[href]\n\nfor a in assocs:\n    href = (a.get(\"_links\") or {}).get(\"efoTraits\", {}).get(\"href\")\n    if not href:\n        continue\n    for t in fetch_traits(href):\n        tid = t.get(\"shortForm\", \"unknown\")\n        if tid not in trait_set:\n            trait_set[tid] = {\"trait\": t.get(\"trait\", \"N\u002FA\"),\n                              \"best_pval\": a.get(\"pvalue\", 1), \"count\": 0}\n        trait_set[tid][\"count\"] += 1\n        if a.get(\"pvalue\") and a[\"pvalue\"] \u003C trait_set[tid][\"best_pval\"]:\n            trait_set[tid][\"best_pval\"] = a[\"pvalue\"]\n    time.sleep(0.1)\n\nprint(f\"{rs_id} is associated with {len(trait_set)} distinct traits:\")\nfor tid, info in sorted(trait_set.items(), key=lambda x: x[1][\"best_pval\"]):\n    print(f\"  {tid}: {info['trait']} (best p={info['best_pval']:.2e}, n={info['count']})\")\n```\n\n### Workflow 3: Summary Statistics Manhattan Plot\n\n**Goal**: Download summary statistics for a study and create a Manhattan plot.\n\n```python\nimport numpy as np\nimport pandas as pd\n\n# Summary statistics as a CHR\u002FBP\u002FP table (simulated here for demonstration).\n# In practice: download from GWAS Catalog FTP, e.g.\n# url = \"http:\u002F\u002Fftp.ebi.ac.uk\u002Fpub\u002Fdatabases\u002Fgwas\u002Fsummary_statistics\u002FGCSTXXXXXX\u002F...\"\n# import gzip, requests; data = gzip.decompress(requests.get(url).content)\nnp.random.seed(42)\nn_snps = 5000\npvalues = np.random.uniform(0, 1, size=n_snps)\npvalues[:20] = 10 ** np.random.uniform(-15, -8, size=20)   # add some \"hits\"\nsumstats = pd.DataFrame({\n    \"CHR\": np.random.choice(range(1, 23), size=n_snps),\n    \"BP\": np.random.randint(1, 250_000_000, size=n_snps),\n    \"P\": pvalues,\n})\nsumstats.to_csv(\"gwas.csv\", index=False)\nprint(f\"Summary stats: {len(sumstats)} SNPs, {(sumstats['P'] \u003C 5e-8).sum()} genome-wide sig -> gwas.csv\")\n# Render with the omics-plotting SKILL (`skills\u002Fdata-visualization\u002Fomics-plotting\u002FSKILL.md`) \"Manhattan\" recipe -> figures\u002Fmanhattan_plot.png\n```\n\n## Key Parameters\n\n| Parameter | Function\u002FEndpoint | Default | Range \u002F Options | Effect |\n|-----------|-------------------|---------|-----------------|--------|\n| `size` | All paginated endpoints | `20` | `1`-`500` | Results per page |\n| `page` | All paginated endpoints | `0` | `0`-`totalPages-1` | Page number (0-indexed) |\n| `diseaseTrait` | `studies\u002Fsearch\u002FfindByDiseaseTrait` | -- | Any string | Trait keyword search |\n| `pubmedId` | `studies\u002Fsearch\u002FfindByPublicationIdPubmedId` | -- | Valid PMID | Study lookup by publication (`findByPubmedId` 404s on \u002Fstudies\u002F) |\n| `geneName` | `snps\u002Fsearch\u002FfindByGene` | -- | Gene symbol | Variants near a gene |\n| `chrom`, `bpStart`, `bpEnd` | `snps\u002Fsearch\u002FfindByChromBpLocationRange` | -- | chr:start-end | Regional variant query |\n| `fullPvalueSet` | `studies\u002Fsearch\u002FfindByFullPvalueSet` | -- | `True`\u002F`False` | Filter studies with summary stats |\n| `trait` | `efoTraits\u002Fsearch\u002FfindByEfoTrait` | -- | Canonical trait name | Trait lookup by exact name (`findByDescription` was removed) |\n| `efoTrait` | `associations\u002Fsearch\u002FfindByEfoTrait` | -- | Canonical trait name | All associations for a trait |\n\n## Best Practices\n\n1. **Paginate large result sets**: Default page size is 20; set `size=500` and loop over pages for complete data retrieval. Check `page.totalElements` to know the full count before iterating.\n\n2. **Use EFO IDs for precise trait queries**: Free-text search may return related but different traits. Look up the exact EFO ID first, then query associations by EFO ID for precision.\n\n3. **Always check p-values**: The catalog contains associations at various significance levels. Filter to p \u003C 5e-8 for genome-wide significant results unless you specifically need suggestive associations.\n\n4. **Be ancestry-aware**: Effect sizes and allele frequencies vary across populations. Check the `initialSampleSize` and `replicationSampleSize` fields to understand the ancestry composition of each study.\n\n5. **Add rate-limiting delays**: Although no official limit exists, `time.sleep(0.2)` between requests prevents server overload and avoids temporary blocks.\n\n6. **Cache frequently accessed data**: Study and trait metadata rarely change. Cache results locally when running batch analyses to reduce redundant API calls.\n\n7. **Anti-pattern -- Don't rely solely on reported genes**: Author-reported genes may not be the causal gene. Cross-reference with functional annotation tools and eQTL databases for biological interpretation.\n\n## Common Recipes\n\n### Recipe 1: Cross-Reference with PGS Catalog\n\nIdentify polygenic scores available for a GWAS trait.\n\n```python\nimport requests, time\n\n# Step 1: Get EFO\u002FMONDO shortForm from GWAS Catalog\n# (the old `findByDescription` endpoint was removed; use `findByEfoTrait`)\nBASE = \"https:\u002F\u002Fwww.ebi.ac.uk\u002Fgwas\u002Frest\u002Fapi\"\ntraits = requests.get(f\"{BASE}\u002FefoTraits\u002Fsearch\u002FfindByEfoTrait\",\n                      params={\"trait\": \"coronary artery disease\"}).json()\nefo_id = traits[\"_embedded\"][\"efoTraits\"][0][\"shortForm\"]\ntime.sleep(0.2)\n\n# Step 2: Query PGS Catalog for scores using same EFO\npgs_url = f\"https:\u002F\u002Fwww.pgscatalog.org\u002Frest\u002Fscore\u002Fsearch?trait_id={efo_id}\"\npgs_data = requests.get(pgs_url).json()\nprint(f\"PGS scores for {efo_id}: {pgs_data.get('count', 0)}\")\nfor score in pgs_data.get(\"results\", [])[:5]:\n    print(f\"  {score['id']}: {score['name']} (variants: {score.get('variants_number', '?')})\")\n```\n\n### Recipe 2: Regional Association Summary\n\nCollect all GWAS associations in a genomic region.\n\n```python\nimport requests, time\n\nBASE = \"https:\u002F\u002Fwww.ebi.ac.uk\u002Fgwas\u002Frest\u002Fapi\"\n\n# Query region: chr9:21,900,000-22,200,000 (CDKN2A\u002F2B locus)\ndata = requests.get(f\"{BASE}\u002FsingleNucleotidePolymorphisms\u002Fsearch\u002FfindByChromBpLocationRange\",\n                    params={\"chrom\": \"9\", \"bpStart\": \"21900000\",\n                            \"bpEnd\": \"22200000\", \"size\": 200}).json()\ntime.sleep(0.2)\nsnps = data[\"_embedded\"][\"singleNucleotidePolymorphisms\"]\nprint(f\"Variants in CDKN2A\u002F2B locus: {len(snps)}\")\n\n# Get associations for each variant\nregion_assocs = []\nfor v in snps[:10]:  # Limit for demo\n    rs = v[\"rsId\"]\n    try:\n        a_data = requests.get(f\"{BASE}\u002FsingleNucleotidePolymorphisms\u002F{rs}\u002Fassociations\",\n                              params={\"size\": 50}).json()\n        time.sleep(0.2)\n        for a in a_data[\"_embedded\"][\"associations\"]:\n            for t in a.get(\"efoTraits\", []):\n                region_assocs.append({\"rsId\": rs, \"trait\": t[\"trait\"],\n                                      \"pvalue\": a.get(\"pvalue\")})\n    except Exception:\n        continue\n\nprint(f\"Total associations in region: {len(region_assocs)}\")\n```\n\n### Recipe 3: Effect Size Forest Plot\n\nVisualize effect sizes across studies for a single variant.\n\n```python\nimport re\nimport pandas as pd\nimport requests, time\n\nBASE = \"https:\u002F\u002Fwww.ebi.ac.uk\u002Fgwas\u002Frest\u002Fapi\"\ndata = requests.get(f\"{BASE}\u002FsingleNucleotidePolymorphisms\u002Frs1801282\u002Fassociations\",\n                    params={\"size\": 100}).json()\ntime.sleep(0.2)\nassocs = data[\"_embedded\"][\"associations\"]\n\ndef parse_ci(text):\n    \"\"\"Pull [low-high] confidence bounds out of the GWAS Catalog 'range' string.\"\"\"\n    nums = re.findall(r\"[0-9]*\\.?[0-9]+\", text or \"\")\n    return (float(nums[0]), float(nums[1])) if len(nums) >= 2 else (float(\"nan\"), float(\"nan\"))\n\n# Build a forest-plot table: label, estimate (OR), ci_low, ci_high\nrows = []\nfor a in assocs:\n    or_val = a.get(\"orPerCopyNum\")\n    trait = a.get(\"efoTraits\", [{}])[0].get(\"trait\", \"N\u002FA\") if a.get(\"efoTraits\") else \"N\u002FA\"\n    if or_val and or_val > 0:\n        lo, hi = parse_ci(a.get(\"range\", \"\"))\n        rows.append({\"label\": trait[:30], \"estimate\": or_val, \"ci_low\": lo, \"ci_high\": hi})\n\neffects = pd.DataFrame(rows)\neffects.to_csv(\"effects.csv\", index=False)\nprint(f\"Effect sizes: {len(effects)} entries -> effects.csv\")\n# Render with the omics-plotting SKILL (`skills\u002Fdata-visualization\u002Fomics-plotting\u002FSKILL.md`) \"Forest\" recipe (null line at OR=1) -> figures\u002Fforest_plot.png\n```\n\n## Troubleshooting\n\n| Problem | Cause | Solution |\n|---------|-------|----------|\n| `404 Not Found` | Invalid GCST, rs ID, or EFO ID | Verify identifier exists via search endpoint first |\n| Empty `_embedded` | No results for query | Broaden search terms or check spelling; try partial match |\n| `ConnectionError` \u002F timeout | EBI server temporarily down | Retry with exponential backoff; check https:\u002F\u002Fwww.ebi.ac.uk\u002Fgwas\u002Fstatus |\n| Truncated results | Default pagination (20 per page) | Set `size=500` and iterate over `page` parameter |\n| Missing OR\u002Fbeta values | Not all associations report effect sizes | Check both `orPerCopyNum` and `betaNum` fields; some studies report only p-values |\n| Stale data | Catalog updated quarterly | Check `lastUpdateDate` on studies; re-query if needed |\n| `KeyError: '_embedded'` | Endpoint returns single object, not list | Direct lookups (by ID) return a single object; `_embedded` only appears in search\u002Flist results |\n| Summary stats unavailable | Not all studies deposit summary stats | Filter with `findByFullPvalueSet=True` to find studies with available data |\n\n## Bundled Resources\n\n### `references\u002Fapi_endpoints.md`\n\n**Covers**: Complete endpoint catalog for all 6 REST API groups (studies, associations, variants, traits, genes, summary statistics) with query parameters, plus response field tables for the main entity types (association fields, study fields, variant fields), HTTP error codes, and pagination patterns.\n\n**Relocated inline**: Core query patterns and the most common endpoints are demonstrated in Core API modules with full code examples. HAL+JSON structure and key identifier formats are in Key Concepts.\n\n**Omitted from original api_reference.md (794 lines)**: Advanced query composition patterns (multi-parameter chaining beyond what Core API shows), child\u002Fparent trait traversal details, detailed changelog\u002Fversioning notes. These are specialized and covered by EBI documentation.\n\n## Related Skills\n\n- **gget-genomic-databases** -- gene lookups, variant annotation, BLAST (upstream ID resolution)\n- **ensembl-database (planned)** -- variant effect prediction, regulatory annotations\n- **opentargets-database (planned)** -- drug target validation from GWAS hits\n- **clinvar-database (planned)** -- clinical variant interpretation\n- **bioservices-multi-database** -- cross-database queries integrating GWAS with pathway data\n\n## References\n\n- [GWAS Catalog website](https:\u002F\u002Fwww.ebi.ac.uk\u002Fgwas\u002F) -- main portal for browsing and searching\n- [GWAS Catalog REST API documentation](https:\u002F\u002Fwww.ebi.ac.uk\u002Fgwas\u002Frest\u002Fdocs\u002Fapi) -- official API reference\n- [GWAS Catalog GitHub](https:\u002F\u002Fgithub.com\u002FEBISPOT\u002Fgoci) -- source code and issue tracker\n- [Summary Statistics FTP](http:\u002F\u002Fftp.ebi.ac.uk\u002Fpub\u002Fdatabases\u002Fgwas\u002Fsummary_statistics\u002F) -- bulk summary statistics downloads\n- [PGS Catalog](https:\u002F\u002Fwww.pgscatalog.org\u002F) -- polygenic score database using GWAS data\n",{"name":5,"license":15,"description":7},"master","fd76f882a04e445e899d5cfb2732f2105ea054ee","skills\u002Fawesome-skills\u002Fgwas-database",0,"https:\u002F\u002Fgithub.com\u002Fbg-szy\u002FTOP-SKILLS","https:\u002F\u002Fbg-szy.github.io\u002FTOP-SKILLS\u002F","https:\u002F\u002Fgithub.com\u002Fbg-szy","https:\u002F\u002Fwww.ecust.edu.cn\u002F","a student of East China University of Science and Technology","2026-11-12 05:55:03",{"source":8,"skillName":5,"commands":35,"prompt":45,"zipAvailable":46},[36,39,42],{"tool":37,"command":38},"npx","npx skills add bg-szy\u002FTOP-SKILLS --skill gwas-database",{"tool":40,"command":41},"bunx","bunx skills add bg-szy\u002FTOP-SKILLS --skill gwas-database",{"tool":43,"command":44},"pnpm","pnpm dlx skills add bg-szy\u002FTOP-SKILLS --skill gwas-database","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fbg-szy\u002FTOP-SKILLS\u002Fblob\u002Fmaster\u002Fskills\u002Fawesome-skills\u002Fgwas-database\u002FSKILL.md",true,[],[49,58,66,74,82,89],{"skillNo":50,"name":51,"nameZh":6,"description":52,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":53,"licenseFileUrl":54,"sourceHtmlUrl":55,"categories":56,"keywords":57,"publishedAt":19},"01M73WM4TPHEJ57D7G2AZ0ABVT","inbox-guardian-for-gmail","Review a personal Gmail inbox with local, owner-approved spam rules. Use for audit-first quarantine, Trash, repeated-evidence sender learning, and header review. Do not use for automatic unsubscribe requests or unreviewed mailbox actions.","MIT","https:\u002F\u002Fgithub.com\u002Fbg-szy\u002FTOP-SKILLS\u002Fblob\u002Fmaster\u002Fskills\u002Fmarketplace\u002Finbox-guardian-for-gmail\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fbg-szy\u002FTOP-SKILLS\u002Fblob\u002Fmaster\u002Fskills\u002Fmarketplace\u002Finbox-guardian-for-gmail\u002FSKILL.md",[],[],{"skillNo":59,"name":60,"nameZh":6,"description":61,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":62,"licenseFileUrl":6,"sourceHtmlUrl":63,"categories":64,"keywords":65,"publishedAt":19},"01M73QERWCH2YEGTPC346PKGWW","chatgpt-app-builder","Guide developers through creating and updating ChatGPT apps.\nCovers the full lifecycle: brainstorming ideas against UX guidelines, bootstrapping projects, implementing tools\u002Fviews, debugging, running dev servers, deploying and connecting apps to ChatGPT.\nUse when a user wants to create or update a ChatGPT app \u002F MCP server for ChatGPT, or use the Skybridge framework.","NOASSERTION","https:\u002F\u002Fgithub.com\u002Fbg-szy\u002FTOP-SKILLS\u002Fblob\u002Fmaster\u002Fskills\u002Fmarketplace\u002Fchatgpt-app-builder\u002FSKILL.md",[],[],{"skillNo":67,"name":68,"nameZh":6,"description":69,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":53,"licenseFileUrl":70,"sourceHtmlUrl":71,"categories":72,"keywords":73,"publishedAt":19},"01M73PZFMKXPVJQCV7T0BBV6EV","brewpage-publish","Publish content to brewpage.app — text, markdown, JSON, file, or multi-file site. Asks namespace and password, returns public URL. Triggers: publish, share link, upload to brewpage, host page, brewpage, publish site, upload site, upload directory, deploy site, сделай публичную ссылку, опубликуй.","https:\u002F\u002Fgithub.com\u002Fbg-szy\u002FTOP-SKILLS\u002Fblob\u002Fmaster\u002Fskills\u002Fmarketplace\u002Fbrewpage-publish\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fbg-szy\u002FTOP-SKILLS\u002Fblob\u002Fmaster\u002Fskills\u002Fmarketplace\u002Fbrewpage-publish\u002FSKILL.md",[],[],{"skillNo":75,"name":76,"nameZh":6,"description":77,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":78,"licenseFileUrl":6,"sourceHtmlUrl":79,"categories":80,"keywords":81,"publishedAt":19},"01M73KATEQ37JEDHHGKYHSZK40","zinc-database","Query the ZINC22 virtual compound library (CartBlanche API, billions of make-on-demand + purchasable molecules). Look up substances by ZINC ID, resolve a SMILES to its ZINC ID (exact match), inspect purchasability\u002Fcatalogs, and assemble compound sets for docking. Property (MW\u002FlogP) filtering is done locally with RDKit. For bioactivity use chembl-database-bioactivity; for approved drugs use drugbank-database-access.","CC-BY-4.0","https:\u002F\u002Fgithub.com\u002Fbg-szy\u002FTOP-SKILLS\u002Fblob\u002Fmaster\u002Fskills\u002Fawesome-skills\u002Fzinc-database\u002FSKILL.md",[],[],{"skillNo":83,"name":84,"nameZh":6,"description":85,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":53,"licenseFileUrl":6,"sourceHtmlUrl":86,"categories":87,"keywords":88,"publishedAt":19},"01M73KAN6B77H0VZ0J0P4XX5M7","zarr-python","Stores and queries chunked N-D scientific arrays with Zarr-Python 3, including codecs, sharding, S3\u002FGCS storage, and NumPy\u002FDask\u002FXarray integration. Use for array layout, bounded I\u002FO, format migration, or scientific metadata preservation.","https:\u002F\u002Fgithub.com\u002Fbg-szy\u002FTOP-SKILLS\u002Fblob\u002Fmaster\u002Fskills\u002Fawesome-skills\u002Fzarr-python\u002FSKILL.md",[],[],{"skillNo":90,"name":91,"nameZh":6,"description":92,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":53,"licenseFileUrl":6,"sourceHtmlUrl":93,"categories":94,"keywords":95,"publishedAt":19},"01M73K8904EZK0FDY5Z9A5NQ47","waypoint-bio","Supports work with Outpost Bio's open microbiome foundation models - the Waypoint checkpoints (Waypoint-6m, Waypoint-45m, Waypoint-170m), the Atlas pretraining corpus, the Compass eight-task benchmark, or the `waypoint` CLI from the `waypoint-bio` package. Covers embedding microbiome samples, fine-tuning on taxonomic abundance data, benchmarking a checkpoint on Compass, pretraining a GPT-2 model on taxonomic abundance profiles, and converting MetaPhlAn, Kraken2, QIIME 2, or MGnify abundance tables into waypoint format.","https:\u002F\u002Fgithub.com\u002Fbg-szy\u002FTOP-SKILLS\u002Fblob\u002Fmaster\u002Fskills\u002Fawesome-skills\u002Fwaypoint-bio\u002FSKILL.md",[],[]]