Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update pipelines for Cellranger 9.0.0 #1015

Open
wants to merge 4 commits into
base: devel
Choose a base branch
from
Open
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
7 changes: 6 additions & 1 deletion auto_process_ngs/tenx/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,14 @@
'SC3Pv1': 'Single Cell 3\' v1',
'SC3Pv2': 'Single Cell 3\' v2',
'SC3Pv3': 'Single Cell 3\' v3',
'SC3Pv4': 'Single Cell 3\' v4',
'SC3Pv3LT': 'Single Cell 3\' v3 LT',
'SC3Pv3HT': 'Single Cell 3\' v3 HT',
'SC5P-PE': 'Single Cell 5\' paired-end (both R1 and R2 are used for alignment)',
'SC5P-PE-v3': 'Single Cell 5\' paired-end (both R1 and R2 are used for alignment) v3',
'SC5P-R2': 'Single Cell 5\' R2-only (where only R2 is used for alignment)',
'ARC-v1': 'Single Cell Multiome (ATAC+GEX) v1', # Not documented?
'SC5P-R2-v3': 'Single Cell 5\' R2-only (where only R2 is used for alignment)',
'ARC-v1': 'Single Cell Multiome (ATAC+GEX) v1 (cannot be autodetected)'
}

# Default Cellranger version
Expand Down
13 changes: 10 additions & 3 deletions auto_process_ngs/tenx/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -568,6 +568,13 @@ def make_multi_config_template(f,reference=None,probe_set=None,
cellranger_version = DEFAULT_CELLRANGER_VERSION
else:
cellranger_version = str(cellranger_version)
# Major version
try:
cellranger_major_version = int(cellranger_version.split(".")[0])
except Exception as ex:
raise Exception(f"'{cellranger_version}': unable to extract "
f"Cellranger major version from version string: "
f"{ex}")
# Normalise and check supplied library type
if library_type.startswith("CellPlex"):
library_type = "cellplex"
Expand Down Expand Up @@ -605,14 +612,14 @@ def make_multi_config_template(f,reference=None,probe_set=None,
(probe_set if probe_set
else "/path/to/probe/set"))
fp.write("#force-cells,n\n")
if cellranger_version.startswith("7."):
if cellranger_major_version == 7:
# Cellranger 7.* targetted
if no_bam is not None:
fp.write("no-bam,%s\n" % str(no_bam).lower())
else:
fp.write("#no-bam,true|false\n")
elif cellranger_version.startswith("8."):
# Cellranger 8.* targetted
elif cellranger_major_version in (8, 9):
# Cellranger 8.* or 9.* targetted
if no_bam is not None:
fp.write("create-bam,%s\n" % str(not no_bam).lower())
else:
Expand Down
120 changes: 120 additions & 0 deletions auto_process_ngs/test/tenx/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,13 @@ def _make_mock_cellranger_800(self):
fp.write("#!/bin/bash\necho cellranger cellranger-8.0.0")
os.chmod(cellranger_800,0o775)
return cellranger_800
def _make_mock_cellranger_900(self):
# Make a fake cellranger 9.0.0 executable
cellranger_900 = os.path.join(self.wd,"cellranger")
with open(cellranger_900,'w') as fp:
fp.write("#!/bin/bash\necho cellranger cellranger-9.0.0")
os.chmod(cellranger_900,0o775)
return cellranger_900
def _make_mock_cellranger_atac_101(self):
# Make a fake cellranger-atac 1.0.1 executable
cellranger_atac_101 = os.path.join(self.wd,"cellranger-atac")
Expand Down Expand Up @@ -449,6 +456,13 @@ def test_cellranger_800(self):
self.assertEqual(cellranger_info(path=cellranger),
(cellranger,'cellranger','8.0.0'))

def test_cellranger_900(self):
"""cellranger_info: collect info for cellranger 8.0.0
"""
cellranger = self._make_mock_cellranger_900()
self.assertEqual(cellranger_info(path=cellranger),
(cellranger,'cellranger','9.0.0'))

def test_cellranger_atac_101(self):
"""cellranger_info: collect info for cellranger-atac 1.0.1
"""
Expand Down Expand Up @@ -775,6 +789,41 @@ def test_make_multi_config_template_cellplex_scrnaseq_800(self):
if not line.startswith('##')])
self.assertEqual(expected_content,actual_content)

def test_make_multi_config_template_cellplex_900(self):
"""
make_multi_config_template: check CellPlex template (9.0.0)
"""
expected_content = """[gene-expression]
reference,/data/mm10_transcriptome
#force-cells,n
create-bam,true
#cmo-set,/path/to/custom/cmo/reference

#[feature]
#reference,/path/to/feature/reference

[libraries]
fastq_id,fastqs,lanes,physical_library_id,feature_types,subsample_rate
PJB_CML,/runs/novaseq_50/fastqs,any,PJB_CML,[Gene Expression|Multiplexing Capture],
PJB_GEX,/runs/novaseq_50/fastqs,any,PJB_GEX,[Gene Expression|Multiplexing Capture],

[samples]
sample_id,cmo_ids,description
MULTIPLEXED_SAMPLE,CMO1|CMO2|...,DESCRIPTION
"""
out_file = os.path.join(self.wd,"10x_multi_config.csv")
make_multi_config_template(out_file,
reference="/data/mm10_transcriptome",
fastq_dir="/runs/novaseq_50/fastqs",
samples=("PJB_CML","PJB_GEX"),
library_type="CellPlex",
cellranger_version="9.0.0")
self.assertTrue(os.path.exists(out_file))
with open(out_file,'rt') as fp:
actual_content = '\n'.join([line for line in fp.read().split('\n')
if not line.startswith('##')])
self.assertEqual(expected_content,actual_content)

def test_make_multi_config_template_flex_700(self):
"""
make_multi_config_template: check Flex template (7.1.0)
Expand Down Expand Up @@ -849,6 +898,43 @@ def test_make_multi_config_template_flex_800(self):
if not line.startswith('##')])
self.assertEqual(expected_content,actual_content)

def test_make_multi_config_template_flex_900(self):
"""
make_multi_config_template: check Flex template (9.0.0)
"""
expected_content = """[gene-expression]
reference,/data/mm10_transcriptome
probe-set,/data/mm10_probe_set.csv
#force-cells,n
create-bam,false
#cmo-set,/path/to/custom/cmo/reference

#[feature]
#reference,/path/to/feature/reference

[libraries]
fastq_id,fastqs,lanes,physical_library_id,feature_types,subsample_rate
PJB_Flex,/runs/novaseq_50/fastqs,any,PJB_Flex,[Gene Expression|Antibody Capture],

[samples]
sample_id,probe_barcode_ids,description
MULTIPLEXED_SAMPLE,BC001|BC002|...,DESCRIPTION
"""
out_file = os.path.join(self.wd,"10x_multi_config.csv")
make_multi_config_template(out_file,
reference="/data/mm10_transcriptome",
probe_set="/data/mm10_probe_set.csv",
fastq_dir="/runs/novaseq_50/fastqs",
samples=("PJB_Flex",),
no_bam=True,
library_type="Flex",
cellranger_version="9.0.0")
self.assertTrue(os.path.exists(out_file))
with open(out_file,'rt') as fp:
actual_content = '\n'.join([line for line in fp.read().split('\n')
if not line.startswith('##')])
self.assertEqual(expected_content,actual_content)

def test_make_multi_config_template_immune_profiling_710(self):
"""
make_multi_config_template: check Single Cell Immune Profiling template (7.0.0)
Expand Down Expand Up @@ -917,6 +1003,40 @@ def test_make_multi_config_template_immune_profiling_800(self):
if not line.startswith('##')])
self.assertEqual(expected_content,actual_content)

def test_make_multi_config_template_immune_profiling_900(self):
"""
make_multi_config_template: check Single Cell Immune Profiling template (9.0.0)
"""
expected_content = """[gene-expression]
reference,/data/mm10_transcriptome
#force-cells,n
create-bam,true
#cmo-set,/path/to/custom/cmo/reference

#[feature]
#reference,/path/to/feature/reference

#[vdj]
#reference,/path/to/vdj/reference

[libraries]
fastq_id,fastqs,lanes,physical_library_id,feature_types,subsample_rate
PJB_CML,/runs/novaseq_50/fastqs,any,PJB_CML,[Gene Expression|Antibody Capture|VDJ-B|VDJ-T],
PJB_GEX,/runs/novaseq_50/fastqs,any,PJB_GEX,[Gene Expression|Antibody Capture|VDJ-B|VDJ-T],
"""
out_file = os.path.join(self.wd,"10x_multi_config.csv")
make_multi_config_template(out_file,
reference="/data/mm10_transcriptome",
fastq_dir="/runs/novaseq_50/fastqs",
samples=("PJB_CML","PJB_GEX"),
library_type="Single Cell Immune Profiling",
cellranger_version="9.0.0")
self.assertTrue(os.path.exists(out_file))
with open(out_file,'rt') as fp:
actual_content = '\n'.join([line for line in fp.read().split('\n')
if not line.startswith('##')])
self.assertEqual(expected_content,actual_content)

def test_make_multi_config_template_unsupported_library(self):
"""
make_multi_config_template: exception for unsupported library type
Expand Down