spacr.sequencing¶
Workflow inputs and outputs¶
Map Barcodes¶
Supply the references that encode your experiment. Inspect mapped counts and barcode QC before pairing well-level guide counts with phenotype scores.
Open: Home → Map Barcodes.
Inputs and outputs below include conditional alternatives. The guidance and handoff notes say which route applies.
Inputs
Sequencing reads — Single-end or paired FASTQ files, with the matching barcode reference tables.
Outputs
Guide counts per well — Map Barcodes run folder: unique_combinations.csv and annotated_reads.h5. Well identity requires the corresponding barcode references. Relevant columns, depending on the route:
count.
After this module
Regression: Pair guide counts with phenotype scores using consistent plate/well keys.
Barcode QC: Check mapping and coverage before guide filtering.
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¶
|
Write a copy of a barcode CSV with the |
|
Return a per-position consensus of two equal-length reads. |
|
Ignore notebook display requests while IPython is unavailable. |
|
Return the |
|
Turn a folder of pooled-screen FASTQ files into per-well sgRNA count tables usable by |
|
Return the higher-quality base from two |
|
Pick the fraction cutoff that yields a target mean of unique gRNAs per well. |
|
Look up barcode / gRNA names for a list of DNA reads against a |
|
Chunked paired-end FASTQ processing: extract, decode and stream barcodes to disk. |
|
Extract and map barcodes from a chunk of single- or paired-end FASTQ reads. |
|
Return the reverse complement of a DNA sequence via BioPython. |
|
Append (or create) |
|
Accumulate a one-row QC frame into a CSV, summing it with what is there. |
|
Append per-barcode-combination counts to a CSV, summing duplicates. |
|
Background writer that drains |
|
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
sequencecolumn reverse-complemented.Output is saved in the same directory with the extension dropped and
_RC.csvappended, sorows.csvbecomesrows_RC.csv.- Parameters:
csv_file – input CSV path with a
sequencecolumn.- 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
Nthe 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 fromsettings['mode']andsingle_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) andqc.csv.- Parameters:
settings –
Settings dict, canonicalized via
spacr.settings.set_default_generate_barecode_mapping(). Key entries:src— folder containing*.fastq.gzreads.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 withspacr.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 resultingunique_combinations.csvascount_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 withgrna,count,rowID,columnID),target_unique_count,filter_column,control_wells,log_xandlog_y.- Returns:
the fraction threshold closest to the target unique count.
calibrate_fraction_thresholdIS DELIBERATELY NOT READ HERE, and the reason is structural rather than a division of labour.THE TWO ARE DIFFERENT QUESTIONS.
target_unique_countasks 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_regressionthe calibration runs FIRST. When it succeedsfraction_thresholdis no longerNone, so this function is never asked for a threshold at all – it is asked to DRAW, throughml._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,namemapping 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
sequencecolumn is reverse-complemented whenrc=True; the inputsequencesare matched verbatim, so callers should orient reads consistently beforehand.- Parameters:
csv_file – Path to a CSV with
sequenceandnamecolumns.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.NAfor 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_sizeblocks, farms them out toprocess_chunk()workers, and letssaver_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,columnIDandgrna.target_sequence – anchor sequence used to locate the barcode region.
offset_start – offset from
target_sequenceto 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.BarcodeSetof 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-groupregex, 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
columnIDandrowIDwhere the regex defines those, and fromcolumnandrowwhere 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 holdingr1_chunk,r2_chunk(absent or None for single-end reads),regex,target_sequence,offset_start,window_length,barcode_setandfill_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)
dfto atable-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_Countsand is written withindex=False, so the copy read back from disk is labelled0:DataFrame.addaligned 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
countcolumn.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_queueand 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,columnIDandgrna.target_sequence – anchor sequence used to locate the barcode region.
offset_start – offset from
target_sequenceto 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.BarcodeSetof 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.
Nested helpers¶
- _map_within.resolve(sequence)¶
Return the unique reference name within the mismatch budget.
Exact matches bypass the scan. Inexact results, including an ambiguous
pd.NA, are cached by their string representation so a repeated read does not rescan every same-length reference.spacr/sequencing.py:186
- barecodes_reverse_complement.reverse_complement(sequence)¶
Return the reverse complement of
sequence(N stays N).spacr/sequencing.py:1373
- graph_sequencing_stats.find_and_visualize_fraction_threshold(df, target_unique_count=5, log_x=False, log_y=False, dst=None)¶
Return the fraction threshold whose per-well unique gRNA mean is closest to
target_unique_count.The sweep plot’s view is clamped to x in [0, 0.1] and y in [0, 20], so a returned threshold above 0.1 has its marker line drawn off the visible axes even though the value itself is correct.
- Parameters:
df – one row per gRNA per well, with
fractionplusplateID,rowIDandcolumnID; any missing column raisesKeyError.target_unique_count – mean unique gRNAs per well to aim for. The answer is only the nearest point of a fixed 1000-step grid spanning 0.001 to 0.99, so an unreachable target silently saturates at one end of that grid instead of reporting that it was not met.
Noneor a string raises from the subtraction.log_x – log-scale the plot’s x axis. The hard-coded
xlim(0, 0.1)applied afterwards is then rejected by matplotlib as a non-positive limit on a log axis, so the view autoscales.log_y – the same for the y axis and
ylim(0, 20).dst – when set, writes
<dst>/results/fraction_threshold.pdf, creating the directories;Noneonly shows the figure. The sole caller always passes a path, so the default is unreachable there.
- Returns:
the chosen threshold as a
numpy.float64. A threshold that empties the table yields NaN rather than 0, so a table whose fractions are all below 0.001 makes every sweep point NaN and the fallback returns 0.99 – a value that then discards every read.
spacr/sequencing.py:1468
- graph_sequencing_stats.find_and_visualize_fraction_threshold._line_plot(df, x, y, log_x, log_y)¶
Plot columns
xandyusing the shared figure style.The returned figure and axes let the caller add its chosen threshold marker before either saving or displaying the plot.
spacr/sequencing.py:1496
- map_sequences_to_names.rev_comp(dna_sequence)¶
Return the reverse complement of
dna_sequence(N stays N).spacr/sequencing.py:125
- process_chunk._parse_record(record, label)¶
Validate and split one four-line FASTQ record.
- Parameters:
record – the record as one string of four lines.
label – how to name this record in an error message.
- Returns:
tuple
(sequence, quality).- Raises:
ValueError – when the record is not four lines, is not a FASTQ record, or pairs a sequence with a quality string of another length.
spacr/sequencing.py:444
- process_chunk._split_window(match)¶
Record every barcode the regex captured in this window.
- Parameters:
match – the regex match over one consensus window.
- Returns:
None. The captured text is appended to the lists in
extracted, one list per barcode, so that every barcode of every matched read stays at the same position.
spacr/sequencing.py:470
- process_chunk.paired_find_sequence_in_chunk_reads(r1_chunk, r2_chunk, target_sequence, offset_start, expected_end, regex)¶
Return consensus reads and their barcodes for paired-end chunks.
- Parameters:
r1_chunk – four-line FASTQ record strings for R1.
r2_chunk – the matching R2 records, paired with
r1_chunkby position only – headers are never compared.target_sequence – anchor located with
str.find(first occurrence). R2 is reverse-complemented before the search, so write the anchor in R1 orientation. A pair missing the anchor in either mate is dropped without a row, so the QCtotal_readscounts matched pairs rather than input pairs.offset_start – bases from the anchor to the window start. A resulting start below zero is clamped to the read start, not rejected, so an over-negative offset quietly shifts the window.
expected_end – window length, not an end coordinate. A window cut short by the read end is right-padded with
N(quality!) to exactly this length, so the length check always passes and a truncated read can still match withNinside a barcode – which then maps to NA and drops out of the per-well counts.regex – pattern string applied with
re.match: anchored at the window start, but bases past the last group are ignored, so an oversizedexpected_endonly adds padding.
- Returns:
the consensus sequence of every matched pair, one entry per pair, with that pair’s barcodes appended to
extracted. A chunk with no matches prints a warning and retries the last window reverse-complemented as an orientation hint.- Raises:
ValueError – when the two chunks hold different read counts.
spacr/sequencing.py:481
- process_chunk.single_find_sequence_in_chunk_reads(r1_chunk, target_sequence, offset_start, expected_end, regex)¶
Return R1 windows and their barcodes for single-end chunks.
No consensus is computed here: the R1 window is used as-is, so read quality never influences the base calls the way it does for pairs.
- Parameters:
r1_chunk – four-line FASTQ record strings for R1.
target_sequence – anchor located with
str.find(first occurrence). A read without it is dropped without a row, so the QCtotal_readscounts matched reads rather than input reads.offset_start – bases from the anchor to the window start. A resulting start below zero is clamped to the read start, not rejected.
expected_end – window length, not an end coordinate. A window cut short by the read end is right-padded with
N(quality!) to exactly this length, so a truncated read can still match withNinside a barcode – which then maps to NA and drops out of the per-well counts.regex – pattern string applied with
re.match: anchored at the window start, but bases past the last group are ignored.
- Returns:
the window of every matched read, one entry per read, with that read’s barcodes appended to
extracted. A chunk with no matches prints a warning and retries the last window reverse-complemented as an orientation hint.
spacr/sequencing.py:563