Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ and narrowing it would buy nothing.
- overlaps are decided on the protospacer, distances and the CDS position
from the cut site. `location` and `promoter` are separate columns
because a cut in exon 1 is usually both;
- the table keys back to `guides_alignment_metadata.tsv` on `guide_id`
- the table keys back to `guide_genome_annotation.tsv` on `guide_id`
plus the four site columns, and repeats nothing else. A guide with two
sites needs all five to join unambiguously;
- **pandas reads a written `TRUE`/`FALSE` column back as bool.** Both of
Expand Down Expand Up @@ -326,12 +326,12 @@ and narrowing it would buy nothing.
- `run` writes only inside `outdir`, and only three folders: the results
in `alignments/`, this invocation's record in `run_metadata/` and the
log in `logs/`. Nothing of the run's own sits beside an input;
- `alignments/` holds four files: `guides_alignment_metadata.tsv`, one
- `alignments/` holds four files: `guide_genome_annotation.tsv`, one
row per library entry per site and the only one with the whole picture;
`guides_mapping.bed`, its PAM-bearing rows for a browser, named by
spacer; `columns.yaml`, generated from the same definitions as the
table, so it always describes the folder it sits in; and `qc.tsv`,
counts;
`guide_mapping.bed`, its PAM-bearing rows for a browser, named by
spacer; `guide_genome_annotation_columns.yaml`, generated from the
same definitions as the table, so it always describes the folder it
sits in; and `qc.tsv`, counts;
- orientation is decided from both readings, held in the same scan: an
entry is `reverse_complement` only when its reversed reading has a
PAM-bearing site and the sequence as given does not. A `CCN` 5' of a
Expand Down
4 changes: 2 additions & 2 deletions docs/element-mapping.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ read the output ([Agents and skills](agents-and-skills.md)).

```bash
cau element-mapping run \
--alignment results/alignments/guides_alignment_metadata.tsv \
--annotation results/annotations/guides_gene_annotation.tsv \
--alignment results/alignments/guide_genome_annotation.tsv \
--annotation results/annotations/guide_gene_annotation.tsv \
--elements elements.bed \
--outdir results/
```
Expand Down
2 changes: 1 addition & 1 deletion docs/guide-annotation.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ Then annotate:

```bash
cau guide-annotation run \
--alignment results/alignments/guides_alignment_metadata.tsv \
--alignment results/alignments/guide_genome_annotation.tsv \
--store gencode.v43.protein_coding.parquet \
--promoters gencode.v43.protein_coding.TSS1bp.bed6 \
--outdir results/
Expand Down
2 changes: 1 addition & 1 deletion docs/igvf-export.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ the output ([Agents and skills](agents-and-skills.md)).

```bash
cau igvf-export run \
--alignment results/alignments/guides_alignment_metadata.tsv \
--alignment results/alignments/guide_genome_annotation.tsv \
--mapping results/elements/guide_element_mapping.tsv \
--elements elements.bed \
--store gencode.v43.protein_coding.parquet \
Expand Down
2 changes: 1 addition & 1 deletion docs/reference/accession.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ target?"; `guide_id` answers "same oligo?".
Nothing in a sequence says where the protospacer ends, so a sequence with its
PAM still attached is accepted and gets a different accession, silently. One
spacer in sixteen ends in `GG`. Decide which bases are the protospacer first;
`guides_alignment_metadata.tsv`'s `spacer` column already has.
`guide_genome_annotation.tsv`'s `spacer` column already has.

## The encoding

Expand Down
6 changes: 3 additions & 3 deletions src/crispr_analysis_utils/cli/element_mapping.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@ def add_arguments(parser: argparse.ArgumentParser) -> None:
description=(
"Classify every guide against the elements a screen targets. "
"--outdir gets elements/ with guide_element_mapping.tsv and "
"columns.yaml, run_metadata/ and logs/."
"guide_element_mapping_columns.yaml, run_metadata/ and logs/."
),
)
run_parser.add_argument(
"--alignment",
required=True,
help="guides_alignment_metadata.tsv from `cau guide-alignment run`.",
help="guide_genome_annotation.tsv from `cau guide-alignment run`.",
)
run_parser.add_argument(
"--elements",
Expand All @@ -39,7 +39,7 @@ def add_arguments(parser: argparse.ArgumentParser) -> None:
"--annotation",
default=None,
help=(
"guides_gene_annotation.tsv from `cau guide-annotation run`, "
"guide_gene_annotation.tsv from `cau guide-annotation run`, "
"which fills the distance_to_tss column."
),
)
Expand Down
4 changes: 2 additions & 2 deletions src/crispr_analysis_utils/cli/guide_alignment.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ def add_arguments(parser: argparse.ArgumentParser) -> None:
help="Find every guide's genomic site.",
description=(
"Scan a reference for every guide's exact site. --outdir gets "
"alignments/ with the results (guides_alignment_metadata.tsv, "
"guides_mapping.bed, columns.yaml, qc.tsv), "
"alignments/ with the results (guide_genome_annotation.tsv, "
"guide_mapping.bed, guide_genome_annotation_columns.yaml, qc.tsv), "
"run_metadata/ with this invocation's record, and logs/."
),
)
Expand Down
4 changes: 2 additions & 2 deletions src/crispr_analysis_utils/cli/guide_annotation.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,14 @@ def add_arguments(parser: argparse.ArgumentParser) -> None:
help="Annotate every aligned site against the genes of a store.",
description=(
"Place every mapped site in a gene. --outdir gets annotations/ "
"with guides_gene_annotation.tsv and columns.yaml, run_metadata/ "
"with guide_gene_annotation.tsv and guide_gene_annotation_columns.yaml, run_metadata/ "
"with this invocation's record, and logs/."
),
)
annotate.add_argument(
"--alignment",
required=True,
help="guides_alignment_metadata.tsv from `cau guide-alignment run`.",
help="guide_genome_annotation.tsv from `cau guide-alignment run`.",
)
annotate.add_argument(
"--store",
Expand Down
4 changes: 2 additions & 2 deletions src/crispr_analysis_utils/cli/igvf_export.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@ def add_arguments(parser: argparse.ArgumentParser) -> None:
description=(
"Assemble the IGVF per-guide metadata table from the alignment, "
"the element mapping and the annotation store. --outdir gets "
"igvf/ with guide_metadata.tsv and columns.yaml, run_metadata/ "
"igvf/ with guide_metadata.tsv and guide_metadata_columns.yaml, run_metadata/ "
"and logs/."
),
)
run_parser.add_argument(
"--alignment",
required=True,
help="guides_alignment_metadata.tsv from `cau guide-alignment run`.",
help="guide_genome_annotation.tsv from `cau guide-alignment run`.",
)
run_parser.add_argument(
"--mapping",
Expand Down
14 changes: 7 additions & 7 deletions src/crispr_analysis_utils/element_mapping.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
COLUMNS = {
"guide_id": (
"The sequence that was aligned. With the four site columns, the key"
" back to guides_alignment_metadata.tsv, which holds the rest."
" back to guide_genome_annotation.tsv, which holds the rest."
),
"chr": "Contig of this site. Empty when the guide matches nowhere.",
"start": "First base of the protospacer, 0-based.",
Expand All @@ -62,7 +62,7 @@
"Bases from the cut site to the nearest protein-coding TSS, signed in"
" that gene's orientation. How far a safe-targeting site has to be to"
" be safe depends on the screen, so threshold this yourself rather"
" than trusting the class alone. From guides_gene_annotation.tsv, so"
" than trusting the class alone. From guide_gene_annotation.tsv, so"
" empty without it."
),
}
Expand Down Expand Up @@ -150,7 +150,7 @@ def map_to_elements(
Every guide in the library, so the ones that map nowhere are
classified too. Defaults to the guides the sites name.
distances
``guides_gene_annotation.tsv``, for its ``distance_to_tss``. Without
``guide_gene_annotation.tsv``, for its ``distance_to_tss``. Without
it that column is empty; the classes do not depend on it.

Returns
Expand Down Expand Up @@ -397,7 +397,7 @@ def _round(value: float) -> float | int:


def write_columns_yaml(path: str | os.PathLike[str]) -> None:
"""Write columns.yaml, generated from `COLUMNS` so it cannot drift."""
"""Write guide_element_mapping_columns.yaml, generated from `COLUMNS` so it cannot drift."""
lines = ["# What each column of this folder's output holds.", "", f"{TABLE}:"]
lines += [f' {name}: "{_one_line(text)}"' for name, text in COLUMNS.items()]
Path(path).write_text("\n".join(lines) + "\n", encoding="utf-8")
Expand Down Expand Up @@ -521,7 +521,7 @@ def run(
Parameters
----------
alignment
``guides_alignment_metadata.tsv`` from `guide_alignment.run`, or the
``guide_genome_annotation.tsv`` from `guide_alignment.run`, or the
same table as a DataFrame. Every guide in it is classified, including
the ones that match nowhere.
elements
Expand All @@ -530,7 +530,7 @@ def run(
Where the table goes. Created if it does not exist; nothing is ever
written outside it.
annotation
``guides_gene_annotation.tsv`` from `guide_annotation.run`, which
``guide_gene_annotation.tsv`` from `guide_annotation.run`, which
fills the ``distance_to_tss`` column.

Returns
Expand Down Expand Up @@ -606,7 +606,7 @@ def run(
distances=distances,
)
write_mapping_tsv(outdir / RESULTS_DIR / TABLE, mapping)
write_columns_yaml(outdir / RESULTS_DIR / "columns.yaml")
write_columns_yaml(outdir / RESULTS_DIR / "guide_element_mapping_columns.yaml")
write_qc_tsv(outdir / RESULTS_DIR / "qc.tsv", mapping, regions, sites)

state["counts"] = counts(mapping)
Expand Down
10 changes: 5 additions & 5 deletions src/crispr_analysis_utils/guide_alignment/pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
that.

`outdir` gets three folders and nothing else: ``alignments/`` with the
results (``guides_alignment_metadata.tsv``, ``guides_mapping.bed``,
``columns.yaml``, ``qc.tsv``), ``run_metadata/`` with
results (``guide_genome_annotation.tsv``, ``guide_mapping.bed``,
``guide_genome_annotation_columns.yaml``, ``qc.tsv``), ``run_metadata/`` with
this invocation's record, and ``logs/``.
"""

Expand Down Expand Up @@ -269,10 +269,10 @@ def _run(
)
tables = outdir / RESULTS_DIR
write_guides_tsv(
tables / "guides_alignment_metadata.tsv", library, summaries, scan.sites
tables / "guide_genome_annotation.tsv", library, summaries, scan.sites
)
write_guides_bed(tables / "guides_mapping.bed", library, scan.sites)
write_columns_yaml(tables / "columns.yaml")
write_guides_bed(tables / "guide_mapping.bed", library, scan.sites)
write_columns_yaml(tables / "guide_genome_annotation_columns.yaml")
write_qc_tsv(tables / "qc.tsv", summaries, counts=state["counts"])

state["classes"] = _ordered((summary.site_class for summary in summaries), CLASSES)
Expand Down
18 changes: 9 additions & 9 deletions src/crispr_analysis_utils/guide_alignment/summary.py
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@ def fan_out_sites(
" genome has that same base."
),
}
"""Every column of guides_alignment_metadata.tsv, and what it holds."""
"""Every column of guide_genome_annotation.tsv, and what it holds."""

BED_COLUMNS = {
"chr": "Contig of the match.",
Expand All @@ -329,11 +329,11 @@ def fan_out_sites(
"score": "Always 0; BED6 wants the field.",
"strand": "Strand the protospacer reads 5' to 3' on.",
}
"""The six fields of guides_mapping.bed, which has no header of its own."""
"""The six fields of guide_mapping.bed, which has no header of its own."""


def guide_columns() -> list[str]:
"""The columns of guides_alignment_metadata.tsv, in order.
"""The columns of guide_genome_annotation.tsv, in order.

One row per library entry per site, so the guide's own columns repeat on
every site it has, and an entry with no site gets one row whose site
Expand All @@ -354,7 +354,7 @@ def write_guides_tsv(
summaries: Sequence[GuideSummary],
sites: Mapping[int, Sequence[Site]],
) -> None:
"""Write guides_alignment_metadata.tsv: every entry, a row per site.
"""Write guide_genome_annotation.tsv: every entry, a row per site.

Parameters
----------
Expand Down Expand Up @@ -419,7 +419,7 @@ def write_guides_bed(
guides: Sequence[Guide],
sites: Mapping[int, Sequence[Site]],
) -> None:
"""Write guides_mapping.bed: every site a guide could be cut at.
"""Write guide_mapping.bed: every site a guide could be cut at.

Parameters
----------
Expand All @@ -438,7 +438,7 @@ def write_guides_bed(
of a guide that matches more than once. Sorted by contig, then position.
A match with no PAM
is not somewhere anything can be cut, so it is left out;
guides_alignment_metadata.tsv has them all.
guide_genome_annotation.tsv has them all.
"""
# One row per distinct guide, not per entry: two entries of one sequence
# would otherwise give byte-identical rows and bedtools would count twice.
Expand All @@ -460,7 +460,7 @@ def write_guides_bed(


def write_columns_yaml(path: str | os.PathLike[str]) -> None:
"""Write columns.yaml: what every column of the outputs holds.
"""Write guide_genome_annotation_columns.yaml: what every column holds.

Parameters
----------
Expand All @@ -473,15 +473,15 @@ def write_columns_yaml(path: str | os.PathLike[str]) -> None:
tables themselves.
"""
lines = ["# What each column of this folder's outputs holds.", ""]
lines.append("guides_alignment_metadata.tsv:")
lines.append("guide_genome_annotation.tsv:")
columns = iter(COLUMNS.items())
for heading, count in GROUPS:
lines.append(f" # {heading}")
for _ in range(count):
column, description = next(columns)
lines.append(f' {column}: "{_one_line(description)}"')
lines.append("")
lines.append("guides_mapping.bed:")
lines.append("guide_mapping.bed:")
for column, description in BED_COLUMNS.items():
lines.append(f' {column}: "{_one_line(description)}"')
lines.append("")
Expand Down
6 changes: 3 additions & 3 deletions src/crispr_analysis_utils/guide_annotation/pipeline.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""The gene annotation: read the aligned sites, place them in genes, write the table.

`outdir` gets three folders and nothing else: ``annotations/`` with the one
results table and its ``columns.yaml``, ``run_metadata/`` with this
results table and its ``guide_gene_annotation_columns.yaml``, ``run_metadata/`` with this
invocation's record, and ``logs/``.
"""

Expand Down Expand Up @@ -75,7 +75,7 @@ def run(
Parameters
----------
alignment
``guides_alignment_metadata.tsv`` from `guide_alignment.run`, or the
``guide_genome_annotation.tsv`` from `guide_alignment.run`, or the
same table as a DataFrame. Only the sites with a PAM are annotated,
which is what it means for a guide to map.
store
Expand Down Expand Up @@ -192,7 +192,7 @@ def _run(
with _timed(state, "outputs"):
tables = outdir / RESULTS_DIR
write_annotation_tsv(tables / TABLE, annotated)
write_columns_yaml(tables / "columns.yaml")
write_columns_yaml(tables / "guide_gene_annotation_columns.yaml")

state["counts"] = counts(annotated)
state["complete"] = True
Expand Down
6 changes: 3 additions & 3 deletions src/crispr_analysis_utils/guide_annotation/summary.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,9 @@
" so the guide expresses poorly from a U6 promoter."
),
}
"""Every column of guides_gene_annotation.tsv, and what it holds."""
"""Every column of guide_gene_annotation.tsv, and what it holds."""

TABLE = "guides_gene_annotation.tsv"
TABLE = "guide_gene_annotation.tsv"
"""The one results table."""


Expand Down Expand Up @@ -109,7 +109,7 @@ def write_annotation_tsv(path: str | os.PathLike[str], annotated: pd.DataFrame)


def write_columns_yaml(path: str | os.PathLike[str]) -> None:
"""Write columns.yaml: what every column of the table holds.
"""Write guide_gene_annotation_columns.yaml: what every column holds.

Parameters
----------
Expand Down
8 changes: 4 additions & 4 deletions src/crispr_analysis_utils/igvf_export.py
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,7 @@ def build_table(
Parameters
----------
alignment
``guides_alignment_metadata.tsv``.
``guide_genome_annotation.tsv``.
mapping
``guide_element_mapping.tsv``.
elements
Expand Down Expand Up @@ -484,7 +484,7 @@ def write_table(path: str | os.PathLike[str], table: pd.DataFrame) -> None:


def write_columns_yaml(path: str | os.PathLike[str]) -> None:
"""Write columns.yaml, generated from `COLUMNS` so it cannot drift."""
"""Write guide_metadata_columns.yaml, generated from `COLUMNS` so it cannot drift."""
lines = ["# What each column of this folder's output holds.", "", f"{TABLE}:"]
lines += [f' {name}: "{" ".join(text.split())}"' for name, text in COLUMNS.items()]
Path(path).write_text("\n".join(lines) + "\n", encoding="utf-8")
Expand Down Expand Up @@ -523,7 +523,7 @@ def run(
Parameters
----------
alignment
``guides_alignment_metadata.tsv``.
``guide_genome_annotation.tsv``.
mapping
``guide_element_mapping.tsv``.
elements
Expand Down Expand Up @@ -597,7 +597,7 @@ def run(
table = build_table(align, maps, info)

write_table(outdir / RESULTS_DIR / TABLE, table)
write_columns_yaml(outdir / RESULTS_DIR / "columns.yaml")
write_columns_yaml(outdir / RESULTS_DIR / "guide_metadata_columns.yaml")
state["counts"] = counts(table, info)
state["complete"] = True
state["finished"] = _now()
Expand Down
2 changes: 1 addition & 1 deletion src/crispr_analysis_utils/skills/cau-accession/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ One spacer in sixteen ends in `GG`, so you cannot tell by looking.
designed at 20 nt and the sequences are 21, the first base is that G and is
not part of the protospacer.
- If the user has already run `cau guide-alignment`, the `spacer` column of
`guides_alignment_metadata.tsv` is the protospacer, and the `accession`
`guide_genome_annotation.tsv` is the protospacer, and the `accession`
column is already there.

Never guess which bases to strip.
Expand Down
Loading
Loading