[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6XF56RXMBTH205NFV1Y1NYR":3,"skill-same:01M6XF56RXMBTH205NFV1Y1NYR":85},{"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":39,"linkOnly":40,"markdownContent":41,"markdownBody":42,"frontMatter":43,"refName":47,"commitSha":48,"skillDirectory":49,"forksCount":14,"repositoryHtmlUrl":50,"repositoryHomepageUrl":6,"ownerHtmlUrl":51,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":52,"install":53,"resources":66},"01M6XF56RXMBTH205NFV1Y1NYR","cancer-genomics-analysis",null,"Computational cancer genomics workflows. Somatic mutation detection and annotation, structural variation characterization, copy number analysis, tumor purity\u002Fploidy estimation, NMF metagene extraction, and DNA damage response network analysis. For cancer mutation databases use cosmic-database; for variant clinical significance use clinvar-database.","fadrienne\u002FMyGitHub","fadrienne","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F197874571?v=4","01M6X64V8VWCRSMFZ4EPS2BWXG","Francesca Adrienne","01M6X64VD5MW4F9PHDWQKS7ZAF",0,"MIT","https:\u002F\u002Fgithub.com\u002Ffadrienne\u002FMyGitHub\u002Fblob\u002Fmain\u002Fopenscience\u002Fbackend\u002Fcli\u002Fskills\u002Fbiology\u002Fcancer-genomics-analysis\u002FSKILL.md",[],[19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38],"cancer genomics analysis","analysis","genomics","structural","number","clinvar","network analysis","biology","nmf","annotation","variant clinical significance","clinical","workflows","computational","DNA","mutation","estimation","databases","network","database","2026-11-10 10:12:30",false,"---\nname: cancer-genomics-analysis\ndescription: Computational cancer genomics workflows. Somatic mutation detection and annotation, structural variation characterization, copy number analysis, tumor purity\u002Fploidy estimation, NMF metagene extraction, and DNA damage response network analysis. For cancer mutation databases use cosmic-database; for variant clinical significance use clinvar-database.\ncategory: biology\nlicense: MIT license\nmetadata:\n    skill-author: InkVell Inc.\n---\n\n# Cancer Genomics Analysis: Computational Workflows\n\n## Overview\n\nCancer Genomics Analysis provides computational pipelines for processing and interpreting cancer genomics data. This skill covers somatic mutation detection and annotation (GATK Mutect2 integration), structural variation characterization, copy number analysis (CNVkit workflows), tumor purity and ploidy estimation, NMF-based metagene extraction from expression data, DNA damage response network analysis, and tumor mutational burden calculation. All workflows produce quantitative outputs suitable for clinical interpretation and publication.\n\n## When to Use This Skill\n\n- Processing somatic variant calls from tumor-normal paired sequencing\n- Annotating VCF files with gene names, functional impact, and clinical significance\n- Detecting and classifying structural variants (deletions, duplications, inversions, translocations)\n- Running copy number analysis pipelines (coverage, segmentation, calling)\n- Estimating tumor purity and ploidy from sequencing data\n- Extracting gene expression signatures via NMF (metagene programs)\n- Analyzing DNA damage response pathway disruption in tumors\n- Calculating tumor mutational burden for immunotherapy biomarker assessment\n\n**Related Skills:** For cancer mutation databases use `cosmic-database`. For variant clinical significance use `clinvar-database`. For gene annotations use `ensembl-database`. For pathway enrichment use `kegg-database` or `reactome-database`.\n\n## Installation\n\n```bash\nuv pip install pyvcf3 cyvcf2 pysam scikit-learn networkx gseapy pandas numpy matplotlib\n```\n\nFor command-line tools (optional):\n```bash\n# GATK, SnpEff, CNVkit are installed separately\n# conda install -c bioconda gatk4 snpeff cnvkit\n```\n\n## Quick Start\n\n```python\nimport cyvcf2\nimport pandas as pd\n\n# Parse somatic VCF\nvcf = cyvcf2.VCF('somatic_mutations.vcf.gz')\nvariants = []\nfor v in vcf:\n    if v.FILTER is None or v.FILTER == 'PASS':\n        variants.append({\n            'chrom': v.CHROM, 'pos': v.POS,\n            'ref': v.REF, 'alt': ','.join(v.ALT),\n            'qual': v.QUAL,\n            'depth': v.INFO.get('DP'),\n            'af': v.INFO.get('AF')\n        })\n\ndf = pd.DataFrame(variants)\nprint(f\"PASS variants: {len(df)}\")\nprint(df.head())\n```\n\n## Core Capabilities\n\n### 1. VCF Parsing & Variant Processing\n\nRead, filter, and annotate variant calls.\n\n```python\nimport cyvcf2\nimport pandas as pd\n\ndef parse_vcf(vcf_path, min_qual=30, min_dp=10, min_af=0.05):\n    \"\"\"Parse VCF with quality filters.\"\"\"\n    vcf = cyvcf2.VCF(vcf_path)\n    variants = []\n\n    for v in vcf:\n        # Apply filters\n        if v.FILTER is not None and v.FILTER != 'PASS':\n            continue\n\n        dp = v.INFO.get('DP', 0)\n        af_values = v.INFO.get('AF')\n        af = af_values if isinstance(af_values, float) else (af_values[0] if af_values else 0)\n\n        if v.QUAL and v.QUAL \u003C min_qual:\n            continue\n        if dp \u003C min_dp:\n            continue\n        if af \u003C min_af:\n            continue\n\n        variants.append({\n            'chrom': v.CHROM, 'pos': v.POS,\n            'ref': v.REF, 'alt': ','.join(v.ALT),\n            'qual': v.QUAL, 'dp': dp, 'af': af,\n            'gene': v.INFO.get('ANN', '').split('|')[3] if v.INFO.get('ANN') else ''\n        })\n\n    return pd.DataFrame(variants)\n\ndf = parse_vcf('tumor_somatic.vcf.gz')\nprint(f\"Filtered variants: {len(df)}\")\nprint(f\"Genes affected: {df['gene'].nunique()}\")\n```\n\n### 2. Somatic Mutation Detection\n\nGATK Mutect2 workflow patterns.\n\n```python\nimport subprocess\n\ndef run_mutect2(tumor_bam, normal_bam, reference, output_vcf,\n                gnomad_resource=None, pon=None):\n    \"\"\"Run GATK Mutect2 for somatic variant calling.\"\"\"\n    cmd = [\n        'gatk', 'Mutect2',\n        '-R', reference,\n        '-I', tumor_bam,\n        '-I', normal_bam,\n        '-tumor', 'TUMOR',\n        '-normal', 'NORMAL',\n        '-O', output_vcf\n    ]\n    if gnomad_resource:\n        cmd.extend(['--germline-resource', gnomad_resource])\n    if pon:\n        cmd.extend(['-pon', pon])\n\n    result = subprocess.run(cmd, capture_output=True, text=True)\n    if result.returncode != 0:\n        raise RuntimeError(f\"Mutect2 failed: {result.stderr}\")\n    return output_vcf\n\ndef filter_mutect_calls(raw_vcf, filtered_vcf, reference):\n    \"\"\"Apply Mutect2 filters.\"\"\"\n    cmd = [\n        'gatk', 'FilterMutectCalls',\n        '-R', reference,\n        '-V', raw_vcf,\n        '-O', filtered_vcf\n    ]\n    subprocess.run(cmd, capture_output=True, text=True, check=True)\n    return filtered_vcf\n\ndef annotate_with_snpeff(vcf_path, output_vcf, genome='GRCh38.105'):\n    \"\"\"Annotate variants with SnpEff.\"\"\"\n    cmd = f\"snpEff ann {genome} {vcf_path} > {output_vcf}\"\n    subprocess.run(cmd, shell=True, capture_output=True, text=True, check=True)\n    return output_vcf\n```\n\n### 3. Structural Variation Detection\n\nClassify and annotate structural variants.\n\n```python\nimport cyvcf2\nimport pandas as pd\n\ndef parse_sv_vcf(vcf_path):\n    \"\"\"Parse structural variant VCF (LUMPY\u002FManta\u002FDelly format).\"\"\"\n    vcf = cyvcf2.VCF(vcf_path)\n    svs = []\n\n    for v in vcf:\n        svtype = v.INFO.get('SVTYPE', 'UNKNOWN')\n        svlen = abs(v.INFO.get('SVLEN', 0)) if v.INFO.get('SVLEN') else 0\n        end = v.INFO.get('END', v.POS)\n        pe = v.INFO.get('PE', 0)  # Paired-end support\n        sr = v.INFO.get('SR', 0)  # Split-read support\n\n        svs.append({\n            'chrom': v.CHROM, 'pos': v.POS, 'end': end,\n            'svtype': svtype, 'svlen': svlen,\n            'pe_support': pe, 'sr_support': sr,\n            'qual': v.QUAL, 'filter': v.FILTER or 'PASS'\n        })\n\n    df = pd.DataFrame(svs)\n    return df\n\nsv_df = parse_sv_vcf('structural_variants.vcf')\nprint(\"SV type distribution:\")\nprint(sv_df['svtype'].value_counts())\nprint(f\"\\nMedian SV length: {sv_df[sv_df['svlen'] > 0]['svlen'].median():.0f} bp\")\n```\n\n### 4. Copy Number Analysis\n\nCNVkit-based workflow for copy number profiling.\n\n```python\nimport subprocess\nimport pandas as pd\nimport numpy as np\n\ndef cnvkit_pipeline(tumor_bam, normal_bam, reference, target_bed, output_dir):\n    \"\"\"Run CNVkit copy number analysis pipeline.\"\"\"\n    # Step 1: Coverage\n    subprocess.run([\n        'cnvkit.py', 'coverage', tumor_bam, target_bed,\n        '-o', f'{output_dir}\u002Ftumor.targetcoverage.cnn'\n    ], check=True)\n\n    # Step 2: Reference from normal\n    subprocess.run([\n        'cnvkit.py', 'reference', f'{output_dir}\u002Fnormal.targetcoverage.cnn',\n        '-f', reference, '-o', f'{output_dir}\u002Freference.cnn'\n    ], check=True)\n\n    # Step 3: Fix and segment\n    subprocess.run([\n        'cnvkit.py', 'fix', f'{output_dir}\u002Ftumor.targetcoverage.cnn',\n        f'{output_dir}\u002Ftumor.antitargetcoverage.cnn',\n        f'{output_dir}\u002Freference.cnn',\n        '-o', f'{output_dir}\u002Ftumor.cnr'\n    ], check=True)\n\n    subprocess.run([\n        'cnvkit.py', 'segment', f'{output_dir}\u002Ftumor.cnr',\n        '-o', f'{output_dir}\u002Ftumor.cns'\n    ], check=True)\n\n    return f'{output_dir}\u002Ftumor.cns'\n\ndef parse_cnvkit_segments(cns_path):\n    \"\"\"Parse CNVkit segmentation output.\"\"\"\n    df = pd.read_csv(cns_path, sep='\\t')\n    # Classify events\n    df['call'] = 'neutral'\n    df.loc[df['log2'] > 0.3, 'call'] = 'gain'\n    df.loc[df['log2'] > 0.8, 'call'] = 'amplification'\n    df.loc[df['log2'] \u003C -0.3, 'call'] = 'loss'\n    df.loc[df['log2'] \u003C -1.0, 'call'] = 'deep_deletion'\n\n    print(\"Copy number events:\")\n    print(df['call'].value_counts())\n    return df\n\ndef estimate_purity_ploidy(segments_df):\n    \"\"\"Estimate tumor purity and ploidy from segments.\"\"\"\n    # Simplified approach using segment log2 ratios\n    log2_values = segments_df['log2'].values\n    weights = segments_df['end'] - segments_df['start']\n\n    # Weighted median for ploidy shift\n    weighted_median = np.average(log2_values, weights=weights)\n    estimated_ploidy = 2 * (2 ** weighted_median)\n\n    # Purity from deviation of peaks from integer CN\n    # (simplified — full methods use allele frequencies)\n    deviation = np.std(log2_values)\n    estimated_purity = min(1.0, deviation * 2)  # Rough heuristic\n\n    return {'purity': estimated_purity, 'ploidy': estimated_ploidy}\n```\n\n### 5. NMF Metagene Extraction\n\nExtract gene expression programs using Non-negative Matrix Factorization.\n\n```python\nfrom sklearn.decomposition import NMF\nimport numpy as np\nimport pandas as pd\n\ndef extract_metagenes(expression_matrix, n_components=5, top_genes=50):\n    \"\"\"Extract metagene programs from expression matrix via NMF.\n\n    Args:\n        expression_matrix: genes x samples DataFrame (non-negative values)\n        n_components: number of metagene programs to extract\n        top_genes: number of top genes to report per metagene\n    \"\"\"\n    # Ensure non-negative\n    X = expression_matrix.values\n    X = np.clip(X, 0, None)\n\n    # Fit NMF\n    model = NMF(n_components=n_components, init='nndsvda', random_state=42,\n                max_iter=500, l1_ratio=0.5)\n    W = model.fit_transform(X)  # genes x components (gene weights)\n    H = model.components_        # components x samples (sample coefficients)\n\n    # Extract top genes per metagene\n    metagenes = {}\n    for k in range(n_components):\n        gene_weights = pd.Series(W[:, k], index=expression_matrix.index)\n        top = gene_weights.nlargest(top_genes)\n        metagenes[f'Metagene_{k+1}'] = top\n\n    # Reconstruction error\n    recon_error = model.reconstruction_err_\n    print(f\"Reconstruction error: {recon_error:.4f}\")\n\n    return metagenes, W, H, model\n\ndef optimal_rank_selection(expression_matrix, k_range=range(2, 11)):\n    \"\"\"Select optimal NMF rank using cophenetic correlation.\"\"\"\n    from scipy.cluster.hierarchy import cophenet, linkage\n    from scipy.spatial.distance import pdist\n\n    X = np.clip(expression_matrix.values, 0, None)\n    scores = {}\n\n    for k in k_range:\n        # Run NMF multiple times\n        consensus = np.zeros((X.shape[1], X.shape[1]))\n        n_runs = 20\n        for i in range(n_runs):\n            model = NMF(n_components=k, init='random', random_state=i, max_iter=300)\n            H = model.fit_transform(X.T).T  # Transpose for sample clustering\n            assignments = np.argmax(H, axis=0)\n            for a in range(X.shape[1]):\n                for b in range(X.shape[1]):\n                    if assignments[a] == assignments[b]:\n                        consensus[a, b] += 1\n        consensus \u002F= n_runs\n\n        # Cophenetic correlation\n        Z = linkage(pdist(1 - consensus), method='average')\n        coph_corr, _ = cophenet(Z, pdist(1 - consensus))\n        scores[k] = coph_corr\n        print(f\"k={k}: cophenetic correlation = {coph_corr:.4f}\")\n\n    optimal_k = max(scores, key=scores.get)\n    print(f\"\\nOptimal rank: {optimal_k}\")\n    return optimal_k, scores\n```\n\n### 6. DNA Damage Response Network\n\nAnalyze DDR pathway disruption in tumors.\n\n```python\nimport networkx as nx\nimport numpy as np\nimport pandas as pd\n\n# Core DDR genes\nDDR_GENES = [\n    'TP53', 'BRCA1', 'BRCA2', 'ATM', 'ATR', 'CHEK1', 'CHEK2',\n    'RAD51', 'PALB2', 'XRCC1', 'PARP1', 'MLH1', 'MSH2', 'MSH6',\n    'ERCC1', 'XPA', 'XPC', 'POLH', 'REV3L', 'FANCA', 'FANCD2'\n]\n\ndef build_ddr_network(expression_df, ddr_genes=DDR_GENES, threshold=0.5):\n    \"\"\"Build DDR correlation network from expression data.\"\"\"\n    # Filter to DDR genes present in data\n    available = [g for g in ddr_genes if g in expression_df.index]\n    ddr_expr = expression_df.loc[available]\n\n    # Compute correlation matrix\n    corr = ddr_expr.T.corr(method='spearman')\n\n    # Build network\n    G = nx.Graph()\n    for i, g1 in enumerate(available):\n        for j, g2 in enumerate(available):\n            if i \u003C j and abs(corr.loc[g1, g2]) > threshold:\n                G.add_edge(g1, g2, weight=corr.loc[g1, g2])\n\n    return G, corr\n\ndef compare_ddr_networks(tumor_expr, normal_expr, ddr_genes=DDR_GENES):\n    \"\"\"Identify disrupted DDR edges in tumor vs normal.\"\"\"\n    G_tumor, corr_tumor = build_ddr_network(tumor_expr, ddr_genes)\n    G_normal, corr_normal = build_ddr_network(normal_expr, ddr_genes)\n\n    # Find disrupted edges\n    disrupted = []\n    for u, v, d in G_normal.edges(data=True):\n        normal_corr = d['weight']\n        tumor_corr = corr_tumor.loc[u, v] if u in corr_tumor.index and v in corr_tumor.columns else 0\n        delta = abs(normal_corr - tumor_corr)\n        if delta > 0.3:\n            disrupted.append({\n                'gene1': u, 'gene2': v,\n                'normal_corr': normal_corr, 'tumor_corr': tumor_corr,\n                'delta': delta\n            })\n\n    return pd.DataFrame(disrupted).sort_values('delta', ascending=False)\n```\n\n### 7. Tumor Mutational Burden\n\nCalculate TMB for immunotherapy biomarker assessment.\n\n```python\nimport cyvcf2\n\ndef calculate_tmb(vcf_path, exome_size_mb=35.0, min_af=0.05, min_dp=10):\n    \"\"\"Calculate tumor mutational burden (mutations per Mb).\"\"\"\n    vcf = cyvcf2.VCF(vcf_path)\n    nonsynonymous_count = 0\n    total_pass = 0\n\n    for v in vcf:\n        if v.FILTER and v.FILTER != 'PASS':\n            continue\n\n        dp = v.INFO.get('DP', 0)\n        af = v.INFO.get('AF', 0)\n        if isinstance(af, tuple):\n            af = af[0]\n\n        if dp \u003C min_dp or af \u003C min_af:\n            continue\n\n        total_pass += 1\n\n        # Check for nonsynonymous (requires SnpEff\u002FVEP annotation)\n        ann = v.INFO.get('ANN', '')\n        if ann and ('missense' in ann.lower() or 'nonsense' in ann.lower() or\n                    'frameshift' in ann.lower() or 'stop_gained' in ann.lower()):\n            nonsynonymous_count += 1\n\n    tmb = total_pass \u002F exome_size_mb\n    tmb_nonsynonymous = nonsynonymous_count \u002F exome_size_mb\n\n    print(f\"Total PASS variants: {total_pass}\")\n    print(f\"Nonsynonymous variants: {nonsynonymous_count}\")\n    print(f\"TMB (all): {tmb:.1f} mut\u002FMb\")\n    print(f\"TMB (nonsynonymous): {tmb_nonsynonymous:.1f} mut\u002FMb\")\n\n    # Classification\n    if tmb >= 10:\n        classification = 'TMB-High'\n    elif tmb >= 5:\n        classification = 'TMB-Intermediate'\n    else:\n        classification = 'TMB-Low'\n    print(f\"Classification: {classification}\")\n\n    return {'tmb': tmb, 'tmb_nonsyn': tmb_nonsynonymous, 'class': classification}\n```\n\n## Typical Workflows\n\n### Workflow 1: Complete Somatic Mutation Calling and Annotation\n\n```python\nimport subprocess\n\n# 1. Call variants\nrun_mutect2('tumor.bam', 'normal.bam', 'ref.fa', 'raw.vcf')\n\n# 2. Filter\nfilter_mutect_calls('raw.vcf', 'filtered.vcf', 'ref.fa')\n\n# 3. Annotate\nannotate_with_snpeff('filtered.vcf', 'annotated.vcf')\n\n# 4. Parse and analyze\ndf = parse_vcf('annotated.vcf')\nprint(f\"Somatic mutations: {len(df)}\")\nprint(f\"Most mutated genes:\")\nprint(df['gene'].value_counts().head(10))\n```\n\n### Workflow 2: Copy Number Analysis with Purity Estimation\n\n```python\n# 1. Run CNVkit pipeline\ncns_file = cnvkit_pipeline('tumor.bam', 'normal.bam', 'ref.fa', 'targets.bed', 'cnv_output\u002F')\n\n# 2. Parse segments\nsegments = parse_cnvkit_segments(cns_file)\n\n# 3. Estimate purity\u002Fploidy\nestimates = estimate_purity_ploidy(segments)\nprint(f\"Estimated purity: {estimates['purity']:.2f}\")\nprint(f\"Estimated ploidy: {estimates['ploidy']:.2f}\")\n\n# 4. Identify focal events\nfocal = segments[(segments['call'].isin(['amplification', 'deep_deletion'])) &\n                  (segments['end'] - segments['start'] \u003C 5e6)]\nprint(f\"\\nFocal events: {len(focal)}\")\nprint(focal[['chromosome', 'start', 'end', 'gene', 'log2', 'call']])\n```\n\n### Workflow 3: NMF Extraction of Gene Expression Signatures\n\n```python\nimport pandas as pd\n\n# 1. Load expression matrix (genes x samples, non-negative)\nexpr = pd.read_csv('tpm_matrix.csv', index_col=0)\nexpr = expr.clip(lower=0)\n\n# 2. Select optimal rank\noptimal_k, scores = optimal_rank_selection(expr, k_range=range(2, 8))\n\n# 3. Extract metagenes\nmetagenes, W, H, model = extract_metagenes(expr, n_components=optimal_k)\n\n# 4. Interpret metagenes with enrichment\nimport gseapy as gp\nfor name, genes in metagenes.items():\n    enr = gp.enrichr(gene_list=list(genes.index), gene_sets='KEGG_2021_Human', outdir=None)\n    top_pathway = enr.results.iloc[0]['Term'] if len(enr.results) > 0 else 'None'\n    print(f\"{name}: top pathway = {top_pathway}\")\n    print(f\"  Top genes: {', '.join(genes.index[:5])}\")\n```\n\n## Best Practices\n\n1. **Always use paired tumor-normal** for somatic calling — tumor-only mode has high false positive rates\n2. **Filter aggressively** — apply PASS filter, minimum depth (>10x), minimum allele frequency (>5% for WES)\n3. **Annotate with standard tools** — SnpEff or VEP for functional annotation; validate key variants in ClinVar\n4. **Check purity before CNV analysis** — low purity tumors underestimate copy number changes\n5. **NMF requires non-negative input** — use TPM or RPKM, not log-transformed values\n6. **TMB calculation** — use consistent exome size (typically 30-40 Mb); nonsynonymous variants only for clinical interpretation\n7. **Validate key findings** in COSMIC and ClinVar databases\n\n## Troubleshooting\n\n**Problem:** VCF parsing fails with cyvcf2\n**Solution:** Ensure VCF is bgzip-compressed and tabix-indexed. Use `bcftools view -O z -o out.vcf.gz in.vcf && tabix -p vcf out.vcf.gz`.\n\n**Problem:** CNVkit segmentation produces too many small segments\n**Solution:** Increase segmentation threshold with `--threshold` parameter. Merge adjacent segments with similar log2 ratios.\n\n**Problem:** NMF produces unstable results across runs\n**Solution:** Use `init='nndsvda'` for deterministic initialization. Run cophenetic correlation analysis to verify rank stability.\n\n**Problem:** TMB calculation gives unexpectedly high values\n**Solution:** Verify exome capture size. Check for germline contamination (apply germline resource filter). Ensure proper Mutect2 filtering.\n\n## Resources\n\n- [GATK Best Practices](https:\u002F\u002Fgatk.broadinstitute.org\u002Fhc\u002Fen-us\u002Fsections\u002F360007226651-Best-Practices-Workflows)\n- [CNVkit Documentation](https:\u002F\u002Fcnvkit.readthedocs.io\u002F)\n- [SnpEff Documentation](https:\u002F\u002Fpcingola.github.io\u002FSnpEff\u002F)\n- [COSMIC Database](https:\u002F\u002Fcancer.sanger.ac.uk\u002Fcosmic)\n- [ClinVar](https:\u002F\u002Fwww.ncbi.nlm.nih.gov\u002Fclinvar\u002F)\n","# Cancer Genomics Analysis: Computational Workflows\n\n## Overview\n\nCancer Genomics Analysis provides computational pipelines for processing and interpreting cancer genomics data. This skill covers somatic mutation detection and annotation (GATK Mutect2 integration), structural variation characterization, copy number analysis (CNVkit workflows), tumor purity and ploidy estimation, NMF-based metagene extraction from expression data, DNA damage response network analysis, and tumor mutational burden calculation. All workflows produce quantitative outputs suitable for clinical interpretation and publication.\n\n## When to Use This Skill\n\n- Processing somatic variant calls from tumor-normal paired sequencing\n- Annotating VCF files with gene names, functional impact, and clinical significance\n- Detecting and classifying structural variants (deletions, duplications, inversions, translocations)\n- Running copy number analysis pipelines (coverage, segmentation, calling)\n- Estimating tumor purity and ploidy from sequencing data\n- Extracting gene expression signatures via NMF (metagene programs)\n- Analyzing DNA damage response pathway disruption in tumors\n- Calculating tumor mutational burden for immunotherapy biomarker assessment\n\n**Related Skills:** For cancer mutation databases use `cosmic-database`. For variant clinical significance use `clinvar-database`. For gene annotations use `ensembl-database`. For pathway enrichment use `kegg-database` or `reactome-database`.\n\n## Installation\n\n```bash\nuv pip install pyvcf3 cyvcf2 pysam scikit-learn networkx gseapy pandas numpy matplotlib\n```\n\nFor command-line tools (optional):\n```bash\n# GATK, SnpEff, CNVkit are installed separately\n# conda install -c bioconda gatk4 snpeff cnvkit\n```\n\n## Quick Start\n\n```python\nimport cyvcf2\nimport pandas as pd\n\n# Parse somatic VCF\nvcf = cyvcf2.VCF('somatic_mutations.vcf.gz')\nvariants = []\nfor v in vcf:\n    if v.FILTER is None or v.FILTER == 'PASS':\n        variants.append({\n            'chrom': v.CHROM, 'pos': v.POS,\n            'ref': v.REF, 'alt': ','.join(v.ALT),\n            'qual': v.QUAL,\n            'depth': v.INFO.get('DP'),\n            'af': v.INFO.get('AF')\n        })\n\ndf = pd.DataFrame(variants)\nprint(f\"PASS variants: {len(df)}\")\nprint(df.head())\n```\n\n## Core Capabilities\n\n### 1. VCF Parsing & Variant Processing\n\nRead, filter, and annotate variant calls.\n\n```python\nimport cyvcf2\nimport pandas as pd\n\ndef parse_vcf(vcf_path, min_qual=30, min_dp=10, min_af=0.05):\n    \"\"\"Parse VCF with quality filters.\"\"\"\n    vcf = cyvcf2.VCF(vcf_path)\n    variants = []\n\n    for v in vcf:\n        # Apply filters\n        if v.FILTER is not None and v.FILTER != 'PASS':\n            continue\n\n        dp = v.INFO.get('DP', 0)\n        af_values = v.INFO.get('AF')\n        af = af_values if isinstance(af_values, float) else (af_values[0] if af_values else 0)\n\n        if v.QUAL and v.QUAL \u003C min_qual:\n            continue\n        if dp \u003C min_dp:\n            continue\n        if af \u003C min_af:\n            continue\n\n        variants.append({\n            'chrom': v.CHROM, 'pos': v.POS,\n            'ref': v.REF, 'alt': ','.join(v.ALT),\n            'qual': v.QUAL, 'dp': dp, 'af': af,\n            'gene': v.INFO.get('ANN', '').split('|')[3] if v.INFO.get('ANN') else ''\n        })\n\n    return pd.DataFrame(variants)\n\ndf = parse_vcf('tumor_somatic.vcf.gz')\nprint(f\"Filtered variants: {len(df)}\")\nprint(f\"Genes affected: {df['gene'].nunique()}\")\n```\n\n### 2. Somatic Mutation Detection\n\nGATK Mutect2 workflow patterns.\n\n```python\nimport subprocess\n\ndef run_mutect2(tumor_bam, normal_bam, reference, output_vcf,\n                gnomad_resource=None, pon=None):\n    \"\"\"Run GATK Mutect2 for somatic variant calling.\"\"\"\n    cmd = [\n        'gatk', 'Mutect2',\n        '-R', reference,\n        '-I', tumor_bam,\n        '-I', normal_bam,\n        '-tumor', 'TUMOR',\n        '-normal', 'NORMAL',\n        '-O', output_vcf\n    ]\n    if gnomad_resource:\n        cmd.extend(['--germline-resource', gnomad_resource])\n    if pon:\n        cmd.extend(['-pon', pon])\n\n    result = subprocess.run(cmd, capture_output=True, text=True)\n    if result.returncode != 0:\n        raise RuntimeError(f\"Mutect2 failed: {result.stderr}\")\n    return output_vcf\n\ndef filter_mutect_calls(raw_vcf, filtered_vcf, reference):\n    \"\"\"Apply Mutect2 filters.\"\"\"\n    cmd = [\n        'gatk', 'FilterMutectCalls',\n        '-R', reference,\n        '-V', raw_vcf,\n        '-O', filtered_vcf\n    ]\n    subprocess.run(cmd, capture_output=True, text=True, check=True)\n    return filtered_vcf\n\ndef annotate_with_snpeff(vcf_path, output_vcf, genome='GRCh38.105'):\n    \"\"\"Annotate variants with SnpEff.\"\"\"\n    cmd = f\"snpEff ann {genome} {vcf_path} > {output_vcf}\"\n    subprocess.run(cmd, shell=True, capture_output=True, text=True, check=True)\n    return output_vcf\n```\n\n### 3. Structural Variation Detection\n\nClassify and annotate structural variants.\n\n```python\nimport cyvcf2\nimport pandas as pd\n\ndef parse_sv_vcf(vcf_path):\n    \"\"\"Parse structural variant VCF (LUMPY\u002FManta\u002FDelly format).\"\"\"\n    vcf = cyvcf2.VCF(vcf_path)\n    svs = []\n\n    for v in vcf:\n        svtype = v.INFO.get('SVTYPE', 'UNKNOWN')\n        svlen = abs(v.INFO.get('SVLEN', 0)) if v.INFO.get('SVLEN') else 0\n        end = v.INFO.get('END', v.POS)\n        pe = v.INFO.get('PE', 0)  # Paired-end support\n        sr = v.INFO.get('SR', 0)  # Split-read support\n\n        svs.append({\n            'chrom': v.CHROM, 'pos': v.POS, 'end': end,\n            'svtype': svtype, 'svlen': svlen,\n            'pe_support': pe, 'sr_support': sr,\n            'qual': v.QUAL, 'filter': v.FILTER or 'PASS'\n        })\n\n    df = pd.DataFrame(svs)\n    return df\n\nsv_df = parse_sv_vcf('structural_variants.vcf')\nprint(\"SV type distribution:\")\nprint(sv_df['svtype'].value_counts())\nprint(f\"\\nMedian SV length: {sv_df[sv_df['svlen'] > 0]['svlen'].median():.0f} bp\")\n```\n\n### 4. Copy Number Analysis\n\nCNVkit-based workflow for copy number profiling.\n\n```python\nimport subprocess\nimport pandas as pd\nimport numpy as np\n\ndef cnvkit_pipeline(tumor_bam, normal_bam, reference, target_bed, output_dir):\n    \"\"\"Run CNVkit copy number analysis pipeline.\"\"\"\n    # Step 1: Coverage\n    subprocess.run([\n        'cnvkit.py', 'coverage', tumor_bam, target_bed,\n        '-o', f'{output_dir}\u002Ftumor.targetcoverage.cnn'\n    ], check=True)\n\n    # Step 2: Reference from normal\n    subprocess.run([\n        'cnvkit.py', 'reference', f'{output_dir}\u002Fnormal.targetcoverage.cnn',\n        '-f', reference, '-o', f'{output_dir}\u002Freference.cnn'\n    ], check=True)\n\n    # Step 3: Fix and segment\n    subprocess.run([\n        'cnvkit.py', 'fix', f'{output_dir}\u002Ftumor.targetcoverage.cnn',\n        f'{output_dir}\u002Ftumor.antitargetcoverage.cnn',\n        f'{output_dir}\u002Freference.cnn',\n        '-o', f'{output_dir}\u002Ftumor.cnr'\n    ], check=True)\n\n    subprocess.run([\n        'cnvkit.py', 'segment', f'{output_dir}\u002Ftumor.cnr',\n        '-o', f'{output_dir}\u002Ftumor.cns'\n    ], check=True)\n\n    return f'{output_dir}\u002Ftumor.cns'\n\ndef parse_cnvkit_segments(cns_path):\n    \"\"\"Parse CNVkit segmentation output.\"\"\"\n    df = pd.read_csv(cns_path, sep='\\t')\n    # Classify events\n    df['call'] = 'neutral'\n    df.loc[df['log2'] > 0.3, 'call'] = 'gain'\n    df.loc[df['log2'] > 0.8, 'call'] = 'amplification'\n    df.loc[df['log2'] \u003C -0.3, 'call'] = 'loss'\n    df.loc[df['log2'] \u003C -1.0, 'call'] = 'deep_deletion'\n\n    print(\"Copy number events:\")\n    print(df['call'].value_counts())\n    return df\n\ndef estimate_purity_ploidy(segments_df):\n    \"\"\"Estimate tumor purity and ploidy from segments.\"\"\"\n    # Simplified approach using segment log2 ratios\n    log2_values = segments_df['log2'].values\n    weights = segments_df['end'] - segments_df['start']\n\n    # Weighted median for ploidy shift\n    weighted_median = np.average(log2_values, weights=weights)\n    estimated_ploidy = 2 * (2 ** weighted_median)\n\n    # Purity from deviation of peaks from integer CN\n    # (simplified — full methods use allele frequencies)\n    deviation = np.std(log2_values)\n    estimated_purity = min(1.0, deviation * 2)  # Rough heuristic\n\n    return {'purity': estimated_purity, 'ploidy': estimated_ploidy}\n```\n\n### 5. NMF Metagene Extraction\n\nExtract gene expression programs using Non-negative Matrix Factorization.\n\n```python\nfrom sklearn.decomposition import NMF\nimport numpy as np\nimport pandas as pd\n\ndef extract_metagenes(expression_matrix, n_components=5, top_genes=50):\n    \"\"\"Extract metagene programs from expression matrix via NMF.\n\n    Args:\n        expression_matrix: genes x samples DataFrame (non-negative values)\n        n_components: number of metagene programs to extract\n        top_genes: number of top genes to report per metagene\n    \"\"\"\n    # Ensure non-negative\n    X = expression_matrix.values\n    X = np.clip(X, 0, None)\n\n    # Fit NMF\n    model = NMF(n_components=n_components, init='nndsvda', random_state=42,\n                max_iter=500, l1_ratio=0.5)\n    W = model.fit_transform(X)  # genes x components (gene weights)\n    H = model.components_        # components x samples (sample coefficients)\n\n    # Extract top genes per metagene\n    metagenes = {}\n    for k in range(n_components):\n        gene_weights = pd.Series(W[:, k], index=expression_matrix.index)\n        top = gene_weights.nlargest(top_genes)\n        metagenes[f'Metagene_{k+1}'] = top\n\n    # Reconstruction error\n    recon_error = model.reconstruction_err_\n    print(f\"Reconstruction error: {recon_error:.4f}\")\n\n    return metagenes, W, H, model\n\ndef optimal_rank_selection(expression_matrix, k_range=range(2, 11)):\n    \"\"\"Select optimal NMF rank using cophenetic correlation.\"\"\"\n    from scipy.cluster.hierarchy import cophenet, linkage\n    from scipy.spatial.distance import pdist\n\n    X = np.clip(expression_matrix.values, 0, None)\n    scores = {}\n\n    for k in k_range:\n        # Run NMF multiple times\n        consensus = np.zeros((X.shape[1], X.shape[1]))\n        n_runs = 20\n        for i in range(n_runs):\n            model = NMF(n_components=k, init='random', random_state=i, max_iter=300)\n            H = model.fit_transform(X.T).T  # Transpose for sample clustering\n            assignments = np.argmax(H, axis=0)\n            for a in range(X.shape[1]):\n                for b in range(X.shape[1]):\n                    if assignments[a] == assignments[b]:\n                        consensus[a, b] += 1\n        consensus \u002F= n_runs\n\n        # Cophenetic correlation\n        Z = linkage(pdist(1 - consensus), method='average')\n        coph_corr, _ = cophenet(Z, pdist(1 - consensus))\n        scores[k] = coph_corr\n        print(f\"k={k}: cophenetic correlation = {coph_corr:.4f}\")\n\n    optimal_k = max(scores, key=scores.get)\n    print(f\"\\nOptimal rank: {optimal_k}\")\n    return optimal_k, scores\n```\n\n### 6. DNA Damage Response Network\n\nAnalyze DDR pathway disruption in tumors.\n\n```python\nimport networkx as nx\nimport numpy as np\nimport pandas as pd\n\n# Core DDR genes\nDDR_GENES = [\n    'TP53', 'BRCA1', 'BRCA2', 'ATM', 'ATR', 'CHEK1', 'CHEK2',\n    'RAD51', 'PALB2', 'XRCC1', 'PARP1', 'MLH1', 'MSH2', 'MSH6',\n    'ERCC1', 'XPA', 'XPC', 'POLH', 'REV3L', 'FANCA', 'FANCD2'\n]\n\ndef build_ddr_network(expression_df, ddr_genes=DDR_GENES, threshold=0.5):\n    \"\"\"Build DDR correlation network from expression data.\"\"\"\n    # Filter to DDR genes present in data\n    available = [g for g in ddr_genes if g in expression_df.index]\n    ddr_expr = expression_df.loc[available]\n\n    # Compute correlation matrix\n    corr = ddr_expr.T.corr(method='spearman')\n\n    # Build network\n    G = nx.Graph()\n    for i, g1 in enumerate(available):\n        for j, g2 in enumerate(available):\n            if i \u003C j and abs(corr.loc[g1, g2]) > threshold:\n                G.add_edge(g1, g2, weight=corr.loc[g1, g2])\n\n    return G, corr\n\ndef compare_ddr_networks(tumor_expr, normal_expr, ddr_genes=DDR_GENES):\n    \"\"\"Identify disrupted DDR edges in tumor vs normal.\"\"\"\n    G_tumor, corr_tumor = build_ddr_network(tumor_expr, ddr_genes)\n    G_normal, corr_normal = build_ddr_network(normal_expr, ddr_genes)\n\n    # Find disrupted edges\n    disrupted = []\n    for u, v, d in G_normal.edges(data=True):\n        normal_corr = d['weight']\n        tumor_corr = corr_tumor.loc[u, v] if u in corr_tumor.index and v in corr_tumor.columns else 0\n        delta = abs(normal_corr - tumor_corr)\n        if delta > 0.3:\n            disrupted.append({\n                'gene1': u, 'gene2': v,\n                'normal_corr': normal_corr, 'tumor_corr': tumor_corr,\n                'delta': delta\n            })\n\n    return pd.DataFrame(disrupted).sort_values('delta', ascending=False)\n```\n\n### 7. Tumor Mutational Burden\n\nCalculate TMB for immunotherapy biomarker assessment.\n\n```python\nimport cyvcf2\n\ndef calculate_tmb(vcf_path, exome_size_mb=35.0, min_af=0.05, min_dp=10):\n    \"\"\"Calculate tumor mutational burden (mutations per Mb).\"\"\"\n    vcf = cyvcf2.VCF(vcf_path)\n    nonsynonymous_count = 0\n    total_pass = 0\n\n    for v in vcf:\n        if v.FILTER and v.FILTER != 'PASS':\n            continue\n\n        dp = v.INFO.get('DP', 0)\n        af = v.INFO.get('AF', 0)\n        if isinstance(af, tuple):\n            af = af[0]\n\n        if dp \u003C min_dp or af \u003C min_af:\n            continue\n\n        total_pass += 1\n\n        # Check for nonsynonymous (requires SnpEff\u002FVEP annotation)\n        ann = v.INFO.get('ANN', '')\n        if ann and ('missense' in ann.lower() or 'nonsense' in ann.lower() or\n                    'frameshift' in ann.lower() or 'stop_gained' in ann.lower()):\n            nonsynonymous_count += 1\n\n    tmb = total_pass \u002F exome_size_mb\n    tmb_nonsynonymous = nonsynonymous_count \u002F exome_size_mb\n\n    print(f\"Total PASS variants: {total_pass}\")\n    print(f\"Nonsynonymous variants: {nonsynonymous_count}\")\n    print(f\"TMB (all): {tmb:.1f} mut\u002FMb\")\n    print(f\"TMB (nonsynonymous): {tmb_nonsynonymous:.1f} mut\u002FMb\")\n\n    # Classification\n    if tmb >= 10:\n        classification = 'TMB-High'\n    elif tmb >= 5:\n        classification = 'TMB-Intermediate'\n    else:\n        classification = 'TMB-Low'\n    print(f\"Classification: {classification}\")\n\n    return {'tmb': tmb, 'tmb_nonsyn': tmb_nonsynonymous, 'class': classification}\n```\n\n## Typical Workflows\n\n### Workflow 1: Complete Somatic Mutation Calling and Annotation\n\n```python\nimport subprocess\n\n# 1. Call variants\nrun_mutect2('tumor.bam', 'normal.bam', 'ref.fa', 'raw.vcf')\n\n# 2. Filter\nfilter_mutect_calls('raw.vcf', 'filtered.vcf', 'ref.fa')\n\n# 3. Annotate\nannotate_with_snpeff('filtered.vcf', 'annotated.vcf')\n\n# 4. Parse and analyze\ndf = parse_vcf('annotated.vcf')\nprint(f\"Somatic mutations: {len(df)}\")\nprint(f\"Most mutated genes:\")\nprint(df['gene'].value_counts().head(10))\n```\n\n### Workflow 2: Copy Number Analysis with Purity Estimation\n\n```python\n# 1. Run CNVkit pipeline\ncns_file = cnvkit_pipeline('tumor.bam', 'normal.bam', 'ref.fa', 'targets.bed', 'cnv_output\u002F')\n\n# 2. Parse segments\nsegments = parse_cnvkit_segments(cns_file)\n\n# 3. Estimate purity\u002Fploidy\nestimates = estimate_purity_ploidy(segments)\nprint(f\"Estimated purity: {estimates['purity']:.2f}\")\nprint(f\"Estimated ploidy: {estimates['ploidy']:.2f}\")\n\n# 4. Identify focal events\nfocal = segments[(segments['call'].isin(['amplification', 'deep_deletion'])) &\n                  (segments['end'] - segments['start'] \u003C 5e6)]\nprint(f\"\\nFocal events: {len(focal)}\")\nprint(focal[['chromosome', 'start', 'end', 'gene', 'log2', 'call']])\n```\n\n### Workflow 3: NMF Extraction of Gene Expression Signatures\n\n```python\nimport pandas as pd\n\n# 1. Load expression matrix (genes x samples, non-negative)\nexpr = pd.read_csv('tpm_matrix.csv', index_col=0)\nexpr = expr.clip(lower=0)\n\n# 2. Select optimal rank\noptimal_k, scores = optimal_rank_selection(expr, k_range=range(2, 8))\n\n# 3. Extract metagenes\nmetagenes, W, H, model = extract_metagenes(expr, n_components=optimal_k)\n\n# 4. Interpret metagenes with enrichment\nimport gseapy as gp\nfor name, genes in metagenes.items():\n    enr = gp.enrichr(gene_list=list(genes.index), gene_sets='KEGG_2021_Human', outdir=None)\n    top_pathway = enr.results.iloc[0]['Term'] if len(enr.results) > 0 else 'None'\n    print(f\"{name}: top pathway = {top_pathway}\")\n    print(f\"  Top genes: {', '.join(genes.index[:5])}\")\n```\n\n## Best Practices\n\n1. **Always use paired tumor-normal** for somatic calling — tumor-only mode has high false positive rates\n2. **Filter aggressively** — apply PASS filter, minimum depth (>10x), minimum allele frequency (>5% for WES)\n3. **Annotate with standard tools** — SnpEff or VEP for functional annotation; validate key variants in ClinVar\n4. **Check purity before CNV analysis** — low purity tumors underestimate copy number changes\n5. **NMF requires non-negative input** — use TPM or RPKM, not log-transformed values\n6. **TMB calculation** — use consistent exome size (typically 30-40 Mb); nonsynonymous variants only for clinical interpretation\n7. **Validate key findings** in COSMIC and ClinVar databases\n\n## Troubleshooting\n\n**Problem:** VCF parsing fails with cyvcf2\n**Solution:** Ensure VCF is bgzip-compressed and tabix-indexed. Use `bcftools view -O z -o out.vcf.gz in.vcf && tabix -p vcf out.vcf.gz`.\n\n**Problem:** CNVkit segmentation produces too many small segments\n**Solution:** Increase segmentation threshold with `--threshold` parameter. Merge adjacent segments with similar log2 ratios.\n\n**Problem:** NMF produces unstable results across runs\n**Solution:** Use `init='nndsvda'` for deterministic initialization. Run cophenetic correlation analysis to verify rank stability.\n\n**Problem:** TMB calculation gives unexpectedly high values\n**Solution:** Verify exome capture size. Check for germline contamination (apply germline resource filter). Ensure proper Mutect2 filtering.\n\n## Resources\n\n- [GATK Best Practices](https:\u002F\u002Fgatk.broadinstitute.org\u002Fhc\u002Fen-us\u002Fsections\u002F360007226651-Best-Practices-Workflows)\n- [CNVkit Documentation](https:\u002F\u002Fcnvkit.readthedocs.io\u002F)\n- [SnpEff Documentation](https:\u002F\u002Fpcingola.github.io\u002FSnpEff\u002F)\n- [COSMIC Database](https:\u002F\u002Fcancer.sanger.ac.uk\u002Fcosmic)\n- [ClinVar](https:\u002F\u002Fwww.ncbi.nlm.nih.gov\u002Fclinvar\u002F)\n",{"name":5,"license":44,"category":26,"metadata":45,"description":7},"MIT license",{"skill-author":46},"InkVell Inc.","main","4aa39efd1cdab0b4657ecee16c92a92011a5b10f","openscience\u002Fbackend\u002Fcli\u002Fskills\u002Fbiology\u002Fcancer-genomics-analysis","https:\u002F\u002Fgithub.com\u002Ffadrienne\u002FMyGitHub","https:\u002F\u002Fgithub.com\u002Ffadrienne","2026-10-28 00:43:09",{"source":8,"skillName":5,"commands":54,"prompt":64,"zipAvailable":65},[55,58,61],{"tool":56,"command":57},"npx","npx skills add fadrienne\u002FMyGitHub --skill cancer-genomics-analysis",{"tool":59,"command":60},"bunx","bunx skills add fadrienne\u002FMyGitHub --skill cancer-genomics-analysis",{"tool":62,"command":63},"pnpm","pnpm dlx skills add fadrienne\u002FMyGitHub --skill cancer-genomics-analysis","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Ffadrienne\u002FMyGitHub\u002Fblob\u002Fmain\u002Fopenscience\u002Fbackend\u002Fcli\u002Fskills\u002Fbiology\u002Fcancer-genomics-analysis\u002FSKILL.md",true,[67,73,77,81],{"path":68,"resourceType":69,"resourceTypeDesc":70,"sizeBytes":71,"sourceHtmlUrl":72},"scripts\u002Fcalculate_tmb.py","SCRIPT","脚本",18605,"https:\u002F\u002Fgithub.com\u002Ffadrienne\u002FMyGitHub\u002Fblob\u002Fmain\u002Fopenscience\u002Fbackend\u002Fcli\u002Fskills\u002Fbiology\u002Fcancer-genomics-analysis\u002Fscripts\u002Fcalculate_tmb.py",{"path":74,"resourceType":69,"resourceTypeDesc":70,"sizeBytes":75,"sourceHtmlUrl":76},"scripts\u002Fddr_network.py",21441,"https:\u002F\u002Fgithub.com\u002Ffadrienne\u002FMyGitHub\u002Fblob\u002Fmain\u002Fopenscience\u002Fbackend\u002Fcli\u002Fskills\u002Fbiology\u002Fcancer-genomics-analysis\u002Fscripts\u002Fddr_network.py",{"path":78,"resourceType":69,"resourceTypeDesc":70,"sizeBytes":79,"sourceHtmlUrl":80},"scripts\u002Fnmf_metagenes.py",13122,"https:\u002F\u002Fgithub.com\u002Ffadrienne\u002FMyGitHub\u002Fblob\u002Fmain\u002Fopenscience\u002Fbackend\u002Fcli\u002Fskills\u002Fbiology\u002Fcancer-genomics-analysis\u002Fscripts\u002Fnmf_metagenes.py",{"path":82,"resourceType":69,"resourceTypeDesc":70,"sizeBytes":83,"sourceHtmlUrl":84},"scripts\u002Fparse_vcf.py",15112,"https:\u002F\u002Fgithub.com\u002Ffadrienne\u002FMyGitHub\u002Fblob\u002Fmain\u002Fopenscience\u002Fbackend\u002Fcli\u002Fskills\u002Fbiology\u002Fcancer-genomics-analysis\u002Fscripts\u002Fparse_vcf.py",[86,117,144,178,205,232],{"skillNo":87,"name":88,"nameZh":6,"description":89,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":90,"categories":91,"keywords":97,"publishedAt":39},"01M7167B28PK20HP7R7ZED2DY0","statistical-power","Sample size calculation, power analysis, and effect size conversion for scientific studies. Use BEFORE data collection (a priori) to determine required N, or after (post-hoc) to compute achieved power. Covers parametric tests (t-test, ANOVA, chi-square, proportions, correlation, regression), simulation-based power for complex\u002Fclustered\u002Fnested designs, and power curves. Use this skill when someone asks 'how many samples do I need', 'what is my power', 'what effect size can I detect', or any variant. Pairs with \u002Fexperimental-design (choose design first, then compute power) and \u002Fstatistical-analysis (analyze data after collection).","https:\u002F\u002Fgithub.com\u002Ffadrienne\u002FMyGitHub\u002Fblob\u002Fmain\u002Fscientific-agent-skills\u002Fskills\u002Fstatistical-power\u002FSKILL.md",[92],{"categoryNo":93,"categoryName":94,"taxonomyType":95,"taxonomyTypeDesc":96},"01JBSEEDCAT000000000000023","Skill与智能体开发","SCENARIO","使用场景",[98,99,100,101,102,103,104,105,106,107,108,20,109,110,111,112,113,114,115,116],"power","statistical power","effect","scipy","regression","choose","design","uv","when","Bash","collection","calculation","ANOVA","conversion","analyze","t-test","chi-square","simulation","sample",{"skillNo":118,"name":119,"nameZh":6,"description":120,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":121,"categories":122,"keywords":126,"publishedAt":39},"01M71677EBCM8EPCE9BZCK8505","statistical-analysis","Guided statistical analysis with test selection and reporting. Use when you need help choosing appropriate tests for your data, assumption checking, power analysis, and APA-formatted results. Best for academic research reporting, test selection guidance. For implementing specific models programmatically use statsmodels.","https:\u002F\u002Fgithub.com\u002Ffadrienne\u002FMyGitHub\u002Fblob\u002Fmain\u002Fscientific-agent-skills\u002Fskills\u002Fstatistical-analysis\u002FSKILL.md",[123],{"categoryNo":124,"categoryName":125,"taxonomyType":95,"taxonomyTypeDesc":96},"01JBSEEDCAT000000000000008","测试与质量",[20,127,98,128,129,130,106,131,132,133,134,135,136,137,138,139,140,141,142,143],"statistical analysis","academic research","implementing","selection","you","reporting","data","for","tests","use","with","test","research","results","statsmodels","models","help",{"skillNo":145,"name":146,"nameZh":6,"description":147,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":148,"categories":149,"keywords":159,"publishedAt":39},"01M71673R93XAHFH81DBNVNG7H","scientific-writing","Core skill for the deep research and writing tool. Write scientific manuscripts in full paragraphs (never bullet points). Use two-stage process with (1) section outlines with key points using research-lookup then (2) convert to flowing prose. IMRAD structure, citations (APA\u002FAMA\u002FVancouver), figures\u002Ftables, reporting guidelines (CONSORT\u002FSTROBE\u002FPRISMA), for research papers and journal submissions.","https:\u002F\u002Fgithub.com\u002Ffadrienne\u002FMyGitHub\u002Fblob\u002Fmain\u002Fscientific-agent-skills\u002Fskills\u002Fscientific-writing\u002FSKILL.md",[150,153,154],{"categoryNo":151,"categoryName":152,"taxonomyType":95,"taxonomyTypeDesc":96},"01JBSEEDCAT000000000000018","写作与文案",{"categoryNo":93,"categoryName":94,"taxonomyType":95,"taxonomyTypeDesc":96},{"categoryNo":155,"categoryName":156,"taxonomyType":157,"taxonomyTypeDesc":158},"01JBSEEDCAT000000000000036","内容创作者","PROFESSION","适用职业",[160,161,162,163,164,165,166,167,168,169,107,170,171,172,173,174,175,176,132,177],"writing","scientific","scientific writing","Citations","deep","deep research","never","papers","journal","false","api","prisma","structure","openrouter","Outlines","core skill","read","features",{"skillNo":179,"name":180,"nameZh":6,"description":181,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":182,"categories":183,"keywords":188,"publishedAt":39},"01M7166ZPKXBF4EBPHVTJPQBB1","scientific-visualization","Meta-skill for publication-ready figures. Use when creating journal submission figures requiring multi-panel layouts, significance annotations, error bars, colorblind-safe palettes, and specific journal formatting (Nature, Science, Cell). Orchestrates matplotlib\u002Fseaborn\u002Fplotly with publication styles. For quick exploration use seaborn or plotly directly.","https:\u002F\u002Fgithub.com\u002Ffadrienne\u002FMyGitHub\u002Fblob\u002Fmain\u002Fscientific-agent-skills\u002Fskills\u002Fscientific-visualization\u002FSKILL.md",[184,187],{"categoryNo":185,"categoryName":186,"taxonomyType":95,"taxonomyTypeDesc":96},"01JBSEEDCAT000000000000013","分析与可视化",{"categoryNo":93,"categoryName":94,"taxonomyType":95,"taxonomyTypeDesc":96},[189,161,190,191,192,193,194,195,196,168,106,197,198,199,200,201,202,203,134,204],"visualization","scientific visualization","error","ready","quick","exploration","meta-skill","Meta","safe","plotly","annotations","formatting","Publication","figures","panel","submission",{"skillNo":206,"name":207,"nameZh":6,"description":208,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":209,"categories":210,"keywords":217,"publishedAt":39},"01M7166VXJWQSSC3RQZP60WBGR","research-code","Debug, profile, review, and restructure Python research and analysis code. Use when analysis scripts crash, produce wrong results, run too slowly, or need a correctness review. Covers: reading tracebacks and diagnosing root causes, hypothesis-driven debugging, reviewing code for common statistical\u002Fnumerical errors, profiling data pipelines, improving reproducibility (seeds, environments, determinism), and structuring analysis scripts for sharing. Distinct from \u002Fexploratory-data-analysis (which understands data) and \u002Fstatistical-analysis (which chooses and runs tests) — this skill focuses on the code itself.","https:\u002F\u002Fgithub.com\u002Ffadrienne\u002FMyGitHub\u002Fblob\u002Fmain\u002Fscientific-agent-skills\u002Fskills\u002Fresearch-code\u002FSKILL.md",[211,214],{"categoryNo":212,"categoryName":213,"taxonomyType":95,"taxonomyTypeDesc":96},"01JBSEEDCAT000000000000021","资料检索与研究",{"categoryNo":215,"categoryName":216,"taxonomyType":157,"taxonomyTypeDesc":158},"01JBSEEDCAT000000000000030","开发工程师",[218,219,139,220,221,222,223,105,224,106,107,20,225,226,227,228,229,230,176,231],"code","research code","which","memory","data-analysis","errors","debugging","common","review","data pipelines","run","scripts","line","write",{"skillNo":233,"name":234,"nameZh":6,"description":235,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":236,"licenseFileUrl":6,"sourceHtmlUrl":237,"categories":238,"keywords":245,"publishedAt":39},"01M7166CF5HSR7SVZYZFWTDX55","markdown-mermaid-writing","Comprehensive markdown and Mermaid diagram writing skill. Use when creating any scientific document, report, analysis, or visualization. Establishes text-based diagrams as the default documentation standard with full style guides (markdown + mermaid), 24 diagram type references, and 9 document templates.","Apache-2.0","https:\u002F\u002Fgithub.com\u002Ffadrienne\u002FMyGitHub\u002Fblob\u002Fmain\u002Fscientific-agent-skills\u002Fskills\u002Fmarkdown-mermaid-writing\u002FSKILL.md",[239,242,243,244],{"categoryNo":240,"categoryName":241,"taxonomyType":95,"taxonomyTypeDesc":96},"01JBSEEDCAT000000000000002","文档处理",{"categoryNo":151,"categoryName":152,"taxonomyType":95,"taxonomyTypeDesc":96},{"categoryNo":93,"categoryName":94,"taxonomyType":95,"taxonomyTypeDesc":96},{"categoryNo":155,"categoryName":156,"taxonomyType":157,"taxonomyTypeDesc":158},[160,246,247,248,249,250,189,251,252,106,107,20,253,254,255,256,257,258,161,176],"markdown mermaid writing","mermaid","markdown","community","diagrams","project","default","team","guides","text","documentation","references","diagram"]