spacr.sequencing

Decode pooled-screen FASTQ reads into per-well guide counts.

WHAT IT IS FOR

The Map Barcodes module connects a sequencing run to an image-based screen. It finds the plate-column, guide, and plate-row barcode in each read, resolves those sequences against reference tables, and counts the resulting guides by well. generate_barecode_mapping() is the GUI and Python entry point (the historical barecode spelling remains part of the public API); graph_sequencing_stats() can then help choose a read-fraction cutoff.

WHAT IT NEEDS

src must contain gzip-compressed FASTQ files whose names let spaCR pair R1 and R2 reads. The run also needs a CSV reference table per barcode, with sequence and name columns. A run that decodes the three barcodes spaCR shipped names them as row_csv, column_csv and grna_csv, and a run that decodes any other number of barcodes lists them under barcode_set instead, one entry per barcode. target_sequence anchors the barcode window, while offset_start, expected_end, and a regex naming one group per barcode describe its layout. The shipped regex names columnID, grna and rowID. Use mode='paired' for a quality-weighted R1/R2 consensus or mode='single' with single_direction when only one mate should be read.

WHAT IT PRODUCES

Each sample gets its own output directory beneath src. The essential artifacts are unique_combinations.csv (guide counts by row and column) and qc.csv; annotated_reads.h5 is also written when save_h5 is enabled. Optional barcode QC adds a report and plots under barcode_qc. Run manifests and failure records identify samples that were skipped or could not be processed.

WHAT TO DO NEXT

Inspect the QC table and unmapped fraction before trusting the counts. Use test=True to process one chunk while checking the regex, read direction, and reference orientation, then run the full mapping and pass the resulting unique_combinations.csv files to spacr.ml.perform_regression() as count_data. barecodes_reverse_complement() can make an opposite-orientation copy of a reference CSV.

There are three easy ways to obtain plausible but incomplete output. The anchor match is exact and a wrong regex silently rejects reads; reference sequences are compared in their stored orientation; and a sequence within barcode_mismatches of two references remains unassigned instead of being guessed. Finally, read-level HDF5 output can be much larger than the count tables, and high compression may spend more time saving than decoding, so disable save_h5 unless those individual annotations are needed.

Functions

barecodes_reverse_complement(csv_file)

Write a copy of a barcode CSV with the sequence column reverse-complemented.

create_consensus(seq1, qual1, seq2, qual2)

Return a per-position consensus of two equal-length reads.

display(*args, **kwargs)

Ignore notebook display requests while IPython is unavailable.

extract_sequence_and_quality(sequence, quality, start, end)

Return the [start:end] slice of a sequence and its paired quality string.

generate_barecode_mapping([settings])

Turn a folder of pooled-screen FASTQ files into per-well sgRNA count tables usable by spacr.ml.perform_regression().

get_consensus_base(bases)

Return the higher-quality base from two (base, quality) pairs, preferring non-N.

graph_sequencing_stats(settings)

Pick the fraction cutoff that yields a target mean of unique gRNAs per well.

map_sequences_to_names(csv_file, sequences, rc[, ...])

Look up barcode / gRNA names for a list of DNA reads against a sequence,name mapping CSV.

paired_read_chunked_processing(r1_file, r2_file, ...)

Chunked paired-end FASTQ processing: extract, decode and stream barcodes to disk.

process_chunk(chunk_data)

Extract and map barcodes from a chunk of single- or paired-end FASTQ reads.

reverse_complement(seq)

Return the reverse complement of a DNA sequence via BioPython.

save_df_to_hdf5(df, hdf5_file[, key, comp_type, ...])

Append (or create) df to a table-format HDF5 dataset.

save_qc_df_to_csv(qc_df, qc_csv_file)

Accumulate a one-row QC frame into a CSV, summing it with what is there.

save_unique_combinations_to_csv(unique_combinations, ...)

Append per-barcode-combination counts to a CSV, summing duplicates.

saver_process(save_queue, hdf5_file, save_h5, ...)

Background writer that drains save_queue and persists each item.

single_read_chunked_processing(r1_file, r2_file, ...)

Chunked single-end FASTQ processing: extract, decode and stream barcodes to disk.

Module Contents

spacr.sequencing.barecodes_reverse_complement(csv_file)[source]

Write a copy of a barcode CSV with the sequence column reverse-complemented.

Output is saved in the same directory with the extension dropped and _RC.csv appended, so rows.csv becomes rows_RC.csv.

Parameters:

csv_file – input CSV path with a sequence column.

Returns:

None.

spacr.sequencing.create_consensus(seq1, qual1, seq2, qual2)[source]

Return a per-position consensus of two equal-length reads.

At each position the higher-quality base is kept; if one call is N the other is preferred regardless of quality.

Parameters:
  • seq1 – first DNA sequence.

  • qual1 – quality string for seq1.

  • seq2 – second DNA sequence.

  • qual2 – quality string for seq2.

Returns:

the consensus sequence as a string.

Raises:

ValueError – if either sequence and quality pair, or the two reads, have different lengths. A partial consensus could assign a barcode to the wrong well, so uneven reads are rejected rather than truncated.

spacr.sequencing.display(*args, **kwargs)[source]

Ignore notebook display requests while IPython is unavailable.

Parameters:
  • args – positional display values accepted for API compatibility.

  • kwargs – display options accepted for API compatibility.

Returns:

None.

spacr.sequencing.extract_sequence_and_quality(sequence, quality, start, end)[source]

Return the [start:end] slice of a sequence and its paired quality string.

Parameters:
  • sequence – DNA sequence.

  • quality – quality string of equal length.

  • start – inclusive start index.

  • end – exclusive end index.

Returns:

tuple (subsequence, subquality).

spacr.sequencing.generate_barecode_mapping(settings=None)[source]

Turn a folder of pooled-screen FASTQ files into per-well sgRNA count tables usable by spacr.ml.perform_regression().

Discovers the R1 and R2 files of each sample under src. Paired vs single-end and R1/R2 orientation are chosen from settings['mode'] and single_direction.

From every read it extracts each barcode the run decodes, using the configured regex and offset window. Each extracted sequence is then turned into a name through that barcode’s own lookup CSV (see map_sequences_to_names()).

Per sample it writes annotated_reads.h5 (optional), unique_combinations.csv (the per-well gRNA counts) and qc.csv.

Parameters:

settings

Settings dict, canonicalized via spacr.settings.set_default_generate_barecode_mapping(). Key entries:

  • src — folder containing *.fastq.gz reads.

  • mode'paired' or 'single'.

  • single_direction'R1' or 'R2' (mode='single' only).

  • regex — regex extracting barcodes from a read.

  • target_sequence, offset_start, expected_end — anchor and slice window used to locate the barcode region.

  • column_csv / row_csv / grna_csv — barcode->name lookup CSVs for the three barcodes spaCR shipped.

  • barcode_set — the barcodes to decode when a run has other than those three, as a list with one entry per barcode. Each entry names the barcode, the reference CSV that names its sequences and the regex group that captures it. Absent, which is what every settings file written before sets existed is, the run decodes the three named above.

  • save_h5, comp_type, comp_level — HDF5 output knobs.

  • chunk_size, n_jobs, test, fill_na.

  • barcode_qc — when true, QC each finished sample with spacr.sequencing_qc.barcode_qc(), writing plots and a report into <dst>/barcode_qc (default False; not filled in by the settings defaults).

  • target_grnas_per_well — expected gRNAs per well, from which that QC step derives its abundance threshold (default 1).

Returns:

None. Writes per-sample outputs into <src>/<sample>_<mode>[_<direction>]/.

Example

from spacr.sequencing import generate_barecode_mapping
generate_barecode_mapping({
    'src': '/data/screen_v1/fastq',
    'mode': 'paired',
    'row_csv': '/data/barcodes/rows.csv',
    'column_csv': '/data/barcodes/cols.csv',
    'grna_csv': '/data/barcodes/grnas.csv',
})

See also

map_sequences_to_names() — inner barcode->name lookup. spacr.ml.perform_regression() — consumes the resulting unique_combinations.csv as count_data.

spacr.sequencing.get_consensus_base(bases)[source]

Return the higher-quality base from two (base, quality) pairs, preferring non-N.

Parameters:

bases – list of two (base, quality) tuples.

Returns:

the chosen base as a single-character string.

spacr.sequencing.graph_sequencing_stats(settings)[source]

Pick the fraction cutoff that yields a target mean of unique gRNAs per well.

Loads one or more count CSVs, drops control wells, computes per-well gRNA fractions, sweeps thresholds to find the value producing the requested unique-count average, and plots both the sweep curve and the resulting per-plate heatmap.

Parameters:

settings – dict with keys count_data (str or list of CSVs with grna, count, rowID, columnID), target_unique_count, filter_column, control_wells, log_x and log_y.

Returns:

the fraction threshold closest to the target unique count.

calibrate_fraction_threshold IS DELIBERATELY NOT READ HERE, and the reason is structural rather than a division of labour.

THE TWO ARE DIFFERENT QUESTIONS. target_unique_count asks how many gRNAs a well should end up with and answers it from the counts; the calibration asks which cut-off makes imaging and sequencing agree and answers it from the control wells. Both numbers are worth having and the run reports both – so “both” is the right answer about REPORTING. It is the wrong answer about the SWITCH, for three checkable reasons.

ONE: THE INPUTS ARE NOT HERE. The calibration needs the imaging side – a per-cell classifier score, the well each cell is in, and the plate design naming the pure positive- and negative-control blocks. None of those is in this function’s contract, which is the count tables and nothing else. Reading the switch here would either demand keys this function has never documented, or quietly fall back to the counts answer whenever they are absent – a switch that appears honoured while nothing happened, which is the failure the calibration wiring was already once filed for.

TWO: IT WOULD COLLAPSE THE COMPARISON THE RUN EXISTS TO SHOW. In ml._perform_regression the calibration runs FIRST. When it succeeds fraction_threshold is no longer None, so this function is never asked for a threshold at all – it is asked to DRAW, through ml._draw_the_threshold_sweep, whose whole job is to print the calibrated number beside this sweep’s own independent pick. A sweep that also read the switch would hand back the calibrated number, and the run would print it twice as though two methods had agreed.

THREE: ONE READER, ONE WRITER. The switch is read exactly once, where the score table is already loaded and the sweep can actually be run. A second reader in a module that cannot run it could only disagree with the first.

What this function DOES owe the reader is the source of the number it returns, which it now prints: a screen that asked for the calibration and could not have it falls through to this threshold, and a bare number gives no way to tell which of the two questions was answered.

spacr.sequencing.map_sequences_to_names(csv_file, sequences, rc, mismatches=None)[source]

Look up barcode / gRNA names for a list of DNA reads against a sequence,name mapping CSV.

Used inside the spacr sequencing pipeline to translate the row, column, and gRNA barcodes extracted from paired-end reads into their human-readable labels. Only the CSV’s sequence column is reverse-complemented when rc=True; the input sequences are matched verbatim, so callers should orient reads consistently beforehand.

Parameters:
  • csv_file – Path to a CSV with sequence and name columns.

  • sequences – Iterable of DNA sequences to look up.

  • rc – If True, reverse-complement the CSV sequences before building the lookup dict.

Returns:

List of names aligned positionally with sequences; pd.NA for sequences that do not match any entry.

Example

from spacr.sequencing import map_sequences_to_names
names = map_sequences_to_names(
    '/data/barcodes/rows.csv',
    sequences=['ACGT...', 'TTGG...'],
    rc=False,
)

See also

generate_barecode_mapping() — full end-to-end read -> (row, column, gRNA) name pipeline.

spacr.sequencing.paired_read_chunked_processing(r1_file, r2_file, regex, target_sequence, offset_start, expected_end, column_csv, grna_csv, row_csv, save_h5, comp_type, comp_level, hdf5_file, unique_combinations_csv, qc_csv_file, chunk_size=10000, n_jobs=None, test=False, fill_na=False, barcode_set=None)[source]

Chunked paired-end FASTQ processing: extract, decode and stream barcodes to disk.

Reads R1/R2 in chunk_size blocks, farms them out to process_chunk() workers, and lets saver_process() write HDF5 / CSV outputs concurrently.

Parameters:
  • r1_file – gzipped R1 FASTQ path.

  • r2_file – gzipped R2 FASTQ path.

  • regex – regex naming one group per barcode. The three spaCR shipped are read from rowID, columnID and grna.

  • target_sequence – anchor sequence used to locate the barcode region.

  • offset_start – offset from target_sequence to begin extraction.

  • expected_end – length of the extracted consensus region.

  • column_csv – column-barcode reference CSV.

  • grna_csv – gRNA-barcode reference CSV.

  • row_csv – row-barcode reference CSV.

  • save_h5 – persist the full reads DataFrame to HDF5.

  • comp_type – HDF5 compression library.

  • comp_level – HDF5 compression level.

  • hdf5_file – HDF5 output path.

  • unique_combinations_csv – destination CSV for aggregated combinations.

  • qc_csv_file – destination CSV for QC statistics.

  • chunk_size – reads per batch. Default 10000.

  • n_jobs – worker processes; defaults to cpu_count() - 3.

  • test – process only the first chunk and print a preview.

  • fill_na – fill unmapped IDs with raw barcode sequences.

  • barcode_set – the barcodes to decode, as a spacr.settings.BarcodeSet of any size. None decodes the three barcodes spaCR shipped from the three reference CSVs above, which is what every run did before a set could be given; a set is used instead of them.

Returns:

None.

spacr.sequencing.process_chunk(chunk_data)[source]

Extract and map barcodes from a chunk of single- or paired-end FASTQ reads.

Anchors on target_sequence, extracts a consensus window, splits that window with the named-group regex, and maps every barcode it holds to a name through that barcode’s own reference table.

THE CHUNK ARRIVES IN ONE OF TWO SHAPES. A tuple is the historical one and decodes the three barcodes this module has always decoded, a plate column, a guide and a plate row, from three reference CSV paths. A mapping carries a barcode set instead and decodes however many barcodes that set holds, one or ten, writing a sequence column and a name column for each of them.

The regex must name a group for every barcode being decoded, and the run stops naming the barcode that has no group rather than decoding the rest. For the historical three the column and the row are read from columnID and rowID where the regex defines those, and from column and row where it does not, so a pattern written before those names were settled goes on matching.

Parameters:

chunk_data – a 9-tuple for single-end reads (r1_chunk, regex, target_sequence, offset_start, expected_end, column_csv, grna_csv, row_csv, fill_na), a 10-tuple for paired-end reads (r1_chunk, r2_chunk, ...) with the same trailing fields, or a mapping holding r1_chunk, r2_chunk (absent or None for single-end reads), regex, target_sequence, offset_start, window_length, barcode_set and fill_na.

Returns:

tuple (df, unique_combinations, qc_df) — the annotated reads, holding the read and then each barcode’s sequence and name; the number of reads behind each unique combination of barcode names; and a one-row QC frame of missing values and total reads.

Raises:

ValueError – when the chunk is neither of those shapes, when the window length is not positive, when the regex names no group for one of the barcodes, or when a FASTQ record is malformed.

spacr.sequencing.reverse_complement(seq)[source]

Return the reverse complement of a DNA sequence via BioPython.

Parameters:

seq – DNA sequence.

Returns:

reverse-complemented sequence as a string.

spacr.sequencing.save_df_to_hdf5(df, hdf5_file, key='df', comp_type='zlib', comp_level=5)[source]

Append (or create) df to a table-format HDF5 dataset.

Parameters:
  • df – DataFrame to persist.

  • hdf5_file – destination HDF5 file path.

  • key – dataset key inside the store. Default 'df'.

  • comp_type – compression library. Default 'zlib'.

  • comp_level – compression level 0-9. Default 5.

Returns:

None.

Raises:

Exception – after printing context, when the HDF5 write fails.

spacr.sequencing.save_qc_df_to_csv(qc_df, qc_csv_file)[source]

Accumulate a one-row QC frame into a CSV, summing it with what is there.

Both frames are put on a positional index before they are added. The incoming row is labelled NaN_Counts and is written with index=False, so the copy read back from disk is labelled 0: DataFrame.add aligned those two labels to nothing, took the union, and the file gained a ROW per chunk instead of accumulating. A run of five chunks reported five sets of totals and no total; the QC column a reader would check for dropped reads was one chunk’s worth, whichever landed last.

Parameters:
  • qc_df – numeric QC metrics (e.g. missing counts, total reads).

  • qc_csv_file – destination CSV path.

Returns:

None.

Raises:

Exception – after printing context, when the CSV write fails.

spacr.sequencing.save_unique_combinations_to_csv(unique_combinations, csv_file)[source]

Append per-barcode-combination counts to a CSV, summing duplicates.

The columns to group by are the frame’s own, every column except the count. They used to be the three this module decoded, named here as a literal, which is one of the two places a run had to hold exactly three barcodes. Reading them off the frame is not a loosening: the frame comes from the groupby that produced it, so its columns ARE the combination being counted, whether that is one barcode or six.

Parameters:
  • unique_combinations – DataFrame holding one column per barcode and a numeric count column.

  • csv_file – destination CSV path (created if absent).

Returns:

None.

Raises:

Exception – after printing context, when the CSV write fails.

spacr.sequencing.saver_process(save_queue, hdf5_file, save_h5, unique_combinations_csv, qc_csv_file, comp_type, comp_level)[source]

Background writer that drains save_queue and persists each item.

Runs until the sentinel "STOP" arrives on the queue.

Parameters:
  • save_queue – multiprocessing queue delivering (df, unique_combinations, qc_df) tuples.

  • hdf5_file – HDF5 destination for full annotated reads.

  • save_h5 – enable HDF5 writes of the reads DataFrame.

  • unique_combinations_csv – destination CSV for aggregated barcode combinations.

  • qc_csv_file – destination CSV for QC statistics.

  • comp_type – HDF5 compression library.

  • comp_level – HDF5 compression level.

Returns:

None.

spacr.sequencing.single_read_chunked_processing(r1_file, r2_file, regex, target_sequence, offset_start, expected_end, column_csv, grna_csv, row_csv, save_h5, comp_type, comp_level, hdf5_file, unique_combinations_csv, qc_csv_file, chunk_size=10000, n_jobs=None, test=False, fill_na=False, barcode_set=None)[source]

Chunked single-end FASTQ processing: extract, decode and stream barcodes to disk.

Parameters:
  • r1_file – gzipped R1 FASTQ path.

  • r2_file – unused placeholder kept for interface parity with the paired variant.

  • regex – regex naming one group per barcode. The three spaCR shipped are read from rowID, columnID and grna.

  • target_sequence – anchor sequence used to locate the barcode region.

  • offset_start – offset from target_sequence to begin extraction.

  • expected_end – length of the extracted barcode region.

  • column_csv – column-barcode reference CSV.

  • grna_csv – gRNA-barcode reference CSV.

  • row_csv – row-barcode reference CSV.

  • save_h5 – persist the full reads DataFrame to HDF5.

  • comp_type – HDF5 compression library.

  • comp_level – HDF5 compression level.

  • hdf5_file – HDF5 output path.

  • unique_combinations_csv – destination CSV for aggregated combinations.

  • qc_csv_file – destination CSV for QC statistics.

  • chunk_size – reads per batch. Default 10000.

  • n_jobs – worker processes; defaults to cpu_count() - 3.

  • test – process only the first chunk and print a preview.

  • fill_na – fill unmapped IDs with raw barcode sequences.

  • barcode_set – the barcodes to decode, as a spacr.settings.BarcodeSet of any size. None decodes the three barcodes spaCR shipped from the three reference CSVs above, which is what every run did before a set could be given; a set is used instead of them.

Returns:

None.