bio-hi-c-analysis-hic-data-io
Loads, converts, and manipulates Hi-C contact matrices in cooler format (.cool/.mcool/.scool) and Juicer .hic, using cooler (Python + CLI), hic2cool, and hictk. Covers the single-resolution mcool URI (file.mcool::/resolutions/<bp>), the load-bearing divisive-vs-multiplicative weight-naming rule (KR/VC/VC_SQRT auto-divisive vs cooler's multiplicative weight), what survives .hic<->.cool conversion (FRAG matrices and norm vectors do not), raw-vs-balanced coarsening, the .pairs upper-triangle/chromsize-order contract, and chrom-naming/bin-table provenance. Use when loading a cooler, converting .hic to .mcool, selecting a resolution, building a cooler from pairs or a matrix, coarsening/zoomifying, importing Juicer norm vectors, or debugging all-NaN balanced matrices and chr1-vs-1 empty fetches.
What this skill does
## Version Compatibility
Reference examples tested with: cooler 0.10+, hic2cool 1.0+, hictk 1.0+, bioframe 0.7+
Before using code patterns, verify installed versions match. If versions differ:
- Python: `pip show <package>` then `help(module.function)` to check signatures
- CLI: `<tool> --version` then `<tool> --help` to confirm flags
If code throws ImportError, AttributeError, or TypeError, introspect the installed
package and adapt the example to match the actual API rather than retrying.
Two version boundaries change BEHAVIOUR, not just signatures: hic2cool >= 0.5.0 stores Juicer norms un-inverted (divisive); < 0.5.0 inverted them to multiplicative, so two coolers made from one .hic by different hic2cool versions disagree numerically. cooler standardized creation/balance signatures around 0.8-0.10 (`balance_cooler` keyword-only after `clr`; `store=False` default). Record the converter version in provenance.
# Hi-C Data I/O
**"Load my Hi-C contact matrix, convert it, and pull out a region."** -> Open the cooler at one resolution, fetch raw or balanced pixels, and convert across .hic/.cool/.mcool while knowing what does not survive the round trip.
- Python: `cooler.Cooler('file.mcool::/resolutions/10000').matrix(balance=True).fetch('chr1')`
- CLI: `hic2cool convert in.hic out.mcool -r 0` / `hictk convert in.hic out.mcool` / `cooler cload pairs ...`
## The Single Most Important Modern Insight -- cooler Stores Observed Counts; .hic Bakes In Norms, So Conversion Is Never Lossless Both Ways
A `.cool` is a thin, open, HDF5-native *store*: three tables (`chroms`, `bins`, `pixels`) holding raw observed integer counts in an upper-triangle COO layout, plus optional cached `weight` bias columns. Balancing, expected, O/E, eigenvectors -- everything else is computed downstream on demand. Juicer's `.hic` is the opposite philosophy: a sealed binary *deliverable* with all resolutions, precomputed normalization vectors, and expected vectors welded in. Every footgun in this skill descends from that split:
- **Conversion translates between two philosophies, not two encodings.** `.hic -> .cool` loses FRAG (restriction-fragment) matrices (cooler has no FRAG concept) and Juicer's precomputed expected; a norm whose vector is missing arrives as all-NaN. `.cool -> .hic` loses asymmetric matrices, arbitrary extra pixel value columns, and non-Hi-C labeled arrays.
- **The `weight` column NAME is load-bearing.** cooler's own ICE `weight` is applied MULTIPLICATIVELY by `matrix(balance=True)`. Juicer KR/VC norms are DIVISIVE. `Cooler.matrix(divisive_weights=None)` (the default) decides by column name: weights named **KR, VC, or VC_SQRT are auto-treated as divisive**; everything else (including `weight`) is multiplicative. Import a KR vector under the name `weight` and it is applied the wrong way -- garbage, no error.
- **`.mcool` is a container of resolutions, not a matrix.** Every downstream tool wants a single-resolution URI `file.mcool::/resolutions/<bp>`, never the bare `.mcool`. Each resolution is balanced from scratch; the 100kb `weight` is NOT derivable from the 10kb `weight`.
## Format and Tool Taxonomy
| Format / Tool | Role | Mechanism | When |
|---------------|------|-----------|------|
| `.cool` | single-resolution store | HDF5 chroms/bins/pixels, raw counts + optional weight | one resolution; the analysis unit |
| `.mcool` | multi-resolution container | `/resolutions/<bp>/` each a full cooler | HiGlass tilesets; pick a resolution via URI |
| `.scool` | single-cell container | shared bins, `/cells/<name>/pixels` | scHi-C; avoids duplicating the bin table per cell |
| `.hic` (Juicer) | sealed deliverable | binary, all resolutions + baked norm/expected | Juicer/Juicebox ecosystem; BP or FRAG bins |
| `.pairs` (4DN) | upstream contact list | bgzip + pairix index; upper-triangle, flipped | input to `cooler cload`; provenance of the matrix |
| cooler (CLI+Py) | the open standard store/API | pandas/scipy selectors; `cload`/`balance`/`zoomify`/`dump` | the default; cooltools integration |
| hic2cool | .hic -> .cool/.mcool | 4DN-canonical norm handler (>=0.5.0 un-inverted) | importing Juicer norms; BP only |
| hictk | fast cross-format convert/dump | C++; reads .hic v6-9 + cooler, writes .hic v9 + cooler | large files; faster than hic2cool/straw; no FRAG, no asymmetric |
## Decision Tree by Scenario
| Scenario | Recommended | Why |
|----------|-------------|-----|
| Bare `.mcool`, tool errors / wrong scale | append `::/resolutions/<bp>` URI | the .mcool is a container; tools need one resolution |
| `.hic` -> `.mcool`, want Juicer KR/SCALE preserved | `hic2cool convert -r 0` | 4DN-canonical norm handling; keeps divisive names |
| `.hic` -> cooler, large file, speed matters | `hictk convert` | C++, order-of-magnitude faster; but no FRAG |
| `.hic` was FRAG-binned | re-bin from pairs in BP | FRAG does not survive any converter -> contact-pairs |
| Build a cooler from `.pairs` | `cooler cload pairs -c1 -p1 -c2 -p2 sizes.txt:bp` | needs flipped/deduped pairs -> contact-pairs |
| Need lower resolution | `cooler zoomify --balance` (sum RAW, re-ICE) | cannot sum balanced pixels; re-balance per resolution |
| Imported KR/VC norms | keep their original names | the KR/VC/VC_SQRT auto-divisive rule fires only on those names |
| `matrix(balance=True)` raises / all NaN | balance first; NaN rows = masked bins | unbalanced file has no weight; masked bins are expected NaN |
| `fetch('1')` returns empty on a `chr1` file | harmonize chrom naming first | chr1-vs-1 silently zeros every join, no error |
| Balance/normalize for analysis | -> matrix-operations | ICE/KR mechanics, O/E, expected live there |
| Two coolers, compare pixels | confirm bin tables byte-identical | different contigs/order shift every bin_id |
| scHi-C many cells | `cooler.create_scool` (`.scool`) -> single-cell | shared bin table; per-cell pixels |
## Load a Cooler and Select a Resolution
```python
import cooler
cooler.fileops.list_coolers('matrix.mcool') # e.g. ['/resolutions/1000', '/resolutions/10000', ...]
clr = cooler.Cooler('matrix.mcool::/resolutions/10000') # single-resolution URI, never the bare .mcool
clr.binsize, clr.chromnames, clr.info['sum'] # info is unvalidated metadata, not a guarantee
'weight' in clr.bins().columns # is this resolution balanced?
```
`clr.matrix().fetch(region)` takes a UCSC region string or a bare chrom name; one arg -> symmetric square, two args -> rectangular submatrix (incl. trans). `clr.bins().fetch('chr1')`, `clr.pixels().fetch(region)` slice the tables.
## Fetch Balanced vs Raw Pixels
**Goal:** Pull a chromosome submatrix as a dense array, correctly balanced.
**Approach:** Confirm the file carries a `weight` column, then `matrix(balance=True)`; on a balanced file, all-NaN rows are masked low-coverage bins (correct), not a bug. For Juicer-imported KR/VC/VC_SQRT weights, name them correctly and the divisive auto-rule fires; force it with `divisive_weights=` only if a custom column is misnamed.
```python
balanced = clr.matrix(balance=True).fetch('chr1') # multiplicative cooler weight
raw = clr.matrix(balance=False).fetch('chr1') # observed counts
kr = clr.matrix(balance='KR').fetch('chr1') # KR/VC/VC_SQRT auto-treated as divisive by name
sparse = clr.matrix(balance=True, sparse=True).fetch('chr1') # scipy COO for large chromosomes
```
## Convert .hic to cooler (and Back)
```bash
hic2cool convert in.hic out.mcool -r 0 # -r 0 = all resolutions -> .mcool; norm vectors un-inverted (>=0.5.0)
hic2cool convert in.hic out.cool -r 10000 # single resolution -> .cool
hic2cool extract-norms in.hic out.mcool # add Juicer norm vectors to an existing matching cooler
hictk convert in.hic out.mcool # fast C++ path; --resolutions toRelated in Ads & Marketing
ads
IncludedMulti-platform paid advertising audit and optimization skill. Analyzes Google, Meta, YouTube, LinkedIn, TikTok, Microsoft, and Apple Ads. 250+ checks with scoring, parallel agents, industry templates, and AI creative generation.
banana
IncludedAI image generation Creative Director powered by Google Gemini Nano Banana models. Use this skill for ANY request involving image creation, editing, visual asset production, or creative direction. Triggers on: generate an image, create a photo, edit this picture, design a logo, make a banner, visual for my anything, and all /banana commands. Handles text-to-image, image editing, multi-turn creative sessions, batch workflows, and brand presets.
rpg-migration-analyzer
IncludedAnalyzes legacy RPG (Report Program Generator) programs from AS/400 and IBM i systems for migration to modern Java applications. Extracts business logic from RPG III/IV/ILE source code, identifies data structures (D-specs), file operations (F-specs), program dependencies (CALLB/CALLP), and converts RPG constructs to Java equivalents. Generates migration reports, complexity estimates, and Java implementation strategies with POJO classes, JPA entities, and service methods. Use when modernizing AS/400 or IBM i legacy systems, analyzing RPG source files (.rpg, .rpgle, .RPGLE), converting RPG to Java, mapping data specifications to Java classes, planning legacy system migration, or when user mentions RPG analysis, Report Program Generator, RPG III/IV/ILE, AS/400 modernization, IBM i migration, packed decimal conversion, or mainframe application rewrite.
brand-library-architect
IncludedBuild a complete brand library for a product — visual asset render pipeline, brand documentation set (BRAND, COPY, MANIFESTO, BIOS, FAQ, GLOSSARY, TONE, PRICING), open-source convention files (README, CONTRIBUTING, SECURITY, CODE_OF_CONDUCT), and a self-contained press kit. This skill should be used when the user asks to "build a brand library / brand kit / press kit / brand assets" for a product, "set up a brand library workflow," "create a positioning manifesto plus visual identity," or any combination of brand documentation + visual asset pipeline. Apply phase-by-phase or run end-to-end. Templates are product-agnostic and use {{TOKEN}} placeholders the skill prompts the user to fill.
writing-tech-post
IncludedAuthors engineering blog posts end-to-end: launch deep-dives, incident postmortems, architecture migrations, performance case studies, tutorials, AI/agent system writeups, security disclosures, and research-to-product translations. Picks the correct archetype, plans the abstraction ladder, enforces an evidence cadence (diagrams, benchmarks, profiles, traces, code, ablations), tunes voice against publisher house styles (Datadog, Vercel, GitHub, AWS, Meta, Cloudflare, Jane Street), and runs a pre-publish gate for narrative momentum and disclosure ethics. Use when drafting a new engineering post, restructuring a draft that feels flat, deciding which evidence form belongs where, validating that depth and product context are balanced, or preparing a postmortem, migration, or performance narrative for external publication. Do not use for API reference documentation, README authoring, marketing copy, release notes, generic SEO content, ghost-written executive thought leadership, or non-engineering long-form essays.
blog-google
IncludedGoogle API integration for blog performance: PageSpeed Insights, CrUX Core Web Vitals with 25-week history, Search Console performance, URL Inspection, Indexing API, GA4 organic traffic, NLP entity analysis for E-E-A-T, YouTube video search for embedding, and Google Ads Keyword Planner. Progressive feature availability based on credential tier (API key, OAuth/service account, GA4, Ads). Shares config with claude-seo at ~/.config/claude-seo/google-api.json. Use when user says "google data", "page speed", "core web vitals", "search console", "indexation", "GA4", "keyword research", "nlp entities", "blog performance", "youtube search", "google api setup".