Reading 10X Cell Ranger output directly

If for whatever reason you’ve decided to skip the reannotation/preprocessing, you can read the files directly from the Cell Ranger output folder with Dandelion’s ddl.read_10x_vdj, which accepts the *_contig_annotations.csv or all_contig_annotations.json file(s) as input. If reading with the .csv file, and the .fasta file and/or .json file(s) are in the same folder, ddl.read_10x_vdj will try to extract additional information not found in the .csv file e.g. contig sequences.

From Cell Ranger V4 onwards, there is also an airr_rearrangement.tsv file that can be used directly with Dandelion. However, doing so will miss out on the reannotation steps but that is entirely up to you.

Import dandelion module

[1]:
import os
import pandas as pd
import dandelion as ddl

# new function to setup tutorial data
from dandelion.tutorial import setup_dandelion_tutorial_bcr

setup_dandelion_tutorial_bcr()

# change directory to somewhere more workable
os.chdir("dandelion_tutorial")
# ddl.logging.print_versions()
folder_location = "sc5p_v2_hs_PBMC_10k_b"
# or file_location = 'sc5p_v2_hs_PBMC_10k/'
vdj = ddl.read_10x_vdj(folder_location, filename_prefix="filtered")
vdj
[1]:
Lazy Dandelion object with n_obs = 994 and n_contigs = 2601
    data: cell_id, is_cell_10x, sequence_id, high_confidence_10x, sequence_length_10x, locus, v_call, d_call, j_call, c_call, complete_vdj, productive, junction_aa, junction, consensus_count, umi_count, clone_id, raw_consensus_id_10x, sequence, rearrangement_status
    metadata: cell_id, clone_id, clone_id_rank, locus_VDJ, locus_VJ, v_call_VDJ, v_call_VJ, d_call_VDJ, j_call_VDJ, j_call_VJ, c_call_VDJ, c_call_VJ, junction_aa_VDJ, junction_aa_VJ, junction_VDJ, junction_VJ, umi_count_VDJ, umi_count_VJ, locus_VDJ_main, locus_VJ_main, v_call_VDJ_main, v_call_VJ_main, d_call_VDJ_main, j_call_VDJ_main, j_call_VJ_main, c_call_VDJ_main, c_call_VJ_main, junction_aa_VDJ_main, junction_aa_VJ_main, junction_VDJ_main, junction_VJ_main, umi_count_VDJ_main, umi_count_VJ_main, isotype, isotype_main, isotype_status, locus_status, chain_status, rearrangement_status_VDJ, rearrangement_status_VJ

With ddl.read_10x_airr:

[2]:
# read in the airr_rearrangement.tsv file
file_location = "sc5p_v2_hs_PBMC_10k_b/airr_rearrangement.tsv"
vdj = ddl.read_10x_airr(file_location)
vdj
[2]:
Lazy Dandelion object with n_obs = 994 and n_contigs = 2093
    data: cell_id, sequence_id, sequence, sequence_aa, productive, rev_comp, v_call, v_cigar, d_call, d_cigar, j_call, j_cigar, c_call, c_cigar, sequence_alignment, germline_alignment, junction, junction_aa, junction_length, junction_aa_length, v_sequence_start, v_sequence_end, d_sequence_start, d_sequence_end, j_sequence_start, j_sequence_end, c_sequence_start, c_sequence_end, consensus_count, umi_count, is_cell, locus, rearrangement_status
    metadata: cell_id, productive_VDJ, productive_VJ, v_call_VDJ, v_call_VJ, d_call_VDJ, j_call_VDJ, j_call_VJ, c_call_VDJ, c_call_VJ, junction_VDJ, junction_VJ, junction_aa_VDJ, junction_aa_VJ, locus_VDJ, locus_VJ, umi_count_VDJ, umi_count_VJ, productive_VDJ_main, productive_VJ_main, v_call_VDJ_main, v_call_VJ_main, d_call_VDJ_main, j_call_VDJ_main, j_call_VJ_main, c_call_VDJ_main, c_call_VJ_main, junction_VDJ_main, junction_VJ_main, junction_aa_VDJ_main, junction_aa_VJ_main, locus_VDJ_main, locus_VJ_main, umi_count_VDJ_main, umi_count_VJ_main, isotype, isotype_main, isotype_status, locus_status, chain_status, rearrangement_status_VDJ, rearrangement_status_VJ

If you are using non-10x data e.g. Parse Bioscience Evercode, BD Rhapsody, you can use ddl.read_parse_airr and ddl.read_bd_airr respectively. If you are using other sources of single-cell AIRR data that provides standard AIRR formatted files e.g. SeekGene Biosciences, or just a standard AIRR file, you can use ddl.read_airr directly.

We will continue with the rest of the filtering part of the analysis to show how it slots smoothly with the rest of the workflow.

Import modules for use with scanpy

[3]:
import scanpy as sc
import warnings

warnings.filterwarnings("ignore")
sc.logging.print_header()
[3]:

Import the transcriptome data

[4]:
adata = sc.read_10x_h5(
    "sc5p_v2_hs_PBMC_10k_b/filtered_feature_bc_matrix.h5", gex_only=True
)
adata.obs["sample_id"] = "sc5p_v2_hs_PBMC_10k_b"
adata.var_names_make_unique()
adata
[4]:
AnnData object with n_obs × n_vars = 10553 × 36601
    obs: 'sample_id'
    var: 'gene_ids', 'feature_types', 'genome', 'pattern', 'read', 'sequence'

Run QC on the transcriptome data.

[5]:
ddl.pp.recipe_scanpy_qc(adata)
adata
OMP: Info #276: omp_set_nested routine deprecated, please use omp_set_max_active_levels instead.
[5]:
AnnData object with n_obs × n_vars = 10553 × 36601
    obs: 'sample_id', 'n_genes', 'n_genes_by_counts', 'total_counts', 'total_counts_mt', 'pct_counts_mt', 'scrublet_score', 'is_doublet', 'filter_rna'
    var: 'gene_ids', 'feature_types', 'genome', 'pattern', 'read', 'sequence'

Run the filtering of bcr data. Note that I’m using the DandelionPolars object as input rather than the pandas dataframe (yes both types of input will works. In fact, a file path to the .tsv will work too).

[6]:
# The function will return both objects.
vdj, adata = ddl.pp.check_contigs(vdj, adata)
Filtering contigs...
Marking ambiguous contigs...
Initializing DandelionPolars object...

Check the output V(D)J table

The vdj table is returned as a DandelionPolars class object in the .data slot; if a file was provided for filter_bcr above, a new file will be created in the same folder with the filtered prefix. Note that this V(D)J table is indexed based on contigs (sequence_id).

[7]:
vdj
[7]:
Lazy Dandelion object with n_obs = 984 and n_contigs = 2028
    data: cell_id, sequence_id, sequence, sequence_aa, productive, rev_comp, v_call, v_cigar, d_call, d_cigar, j_call, j_cigar, c_call, c_cigar, sequence_alignment, germline_alignment, junction, junction_aa, junction_length, junction_aa_length, v_sequence_start, v_sequence_end, d_sequence_start, d_sequence_end, j_sequence_start, j_sequence_end, c_sequence_start, c_sequence_end, consensus_count, umi_count, is_cell, locus, rearrangement_status, extra, ambiguous
    metadata: cell_id, productive_VDJ, productive_VJ, v_call_VDJ, v_call_VJ, d_call_VDJ, j_call_VDJ, j_call_VJ, c_call_VDJ, c_call_VJ, junction_VDJ, junction_VJ, junction_aa_VDJ, junction_aa_VJ, locus_VDJ, locus_VJ, umi_count_VDJ, umi_count_VJ, productive_VDJ_main, productive_VJ_main, v_call_VDJ_main, v_call_VJ_main, d_call_VDJ_main, j_call_VDJ_main, j_call_VJ_main, c_call_VDJ_main, c_call_VJ_main, junction_VDJ_main, junction_VJ_main, junction_aa_VDJ_main, junction_aa_VJ_main, locus_VDJ_main, locus_VJ_main, umi_count_VDJ_main, umi_count_VJ_main, isotype, isotype_main, isotype_status, locus_status, chain_status, rearrangement_status_VDJ, rearrangement_status_VJ

Check the AnnData object as well

And the AnnData object is indexed based on cells.

[8]:
adata
[8]:
AnnData object with n_obs × n_vars = 10553 × 36601
    obs: 'sample_id', 'n_genes', 'n_genes_by_counts', 'total_counts', 'total_counts_mt', 'pct_counts_mt', 'scrublet_score', 'is_doublet', 'filter_rna', 'has_contig', 'productive_VDJ', 'productive_VJ', 'v_call_VDJ', 'v_call_VJ', 'd_call_VDJ', 'j_call_VDJ', 'j_call_VJ', 'c_call_VDJ', 'c_call_VJ', 'junction_VDJ', 'junction_VJ', 'junction_aa_VDJ', 'junction_aa_VJ', 'locus_VDJ', 'locus_VJ', 'umi_count_VDJ', 'umi_count_VJ', 'productive_VDJ_main', 'productive_VJ_main', 'v_call_VDJ_main', 'v_call_VJ_main', 'd_call_VDJ_main', 'j_call_VDJ_main', 'j_call_VJ_main', 'c_call_VDJ_main', 'c_call_VJ_main', 'junction_VDJ_main', 'junction_VJ_main', 'junction_aa_VDJ_main', 'junction_aa_VJ_main', 'locus_VDJ_main', 'locus_VJ_main', 'umi_count_VDJ_main', 'umi_count_VJ_main', 'isotype', 'isotype_main', 'isotype_status', 'locus_status', 'chain_status', 'rearrangement_status_VDJ', 'rearrangement_status_VJ'
    var: 'gene_ids', 'feature_types', 'genome', 'pattern', 'read', 'sequence'

The number of cells that actually has a matching BCR can be tabluated.

[9]:
pd.crosstab(adata.obs["has_contig"], adata.obs["chain_status"])
[9]:
chain_status Extra pair Orphan VDJ Orphan VJ Single pair
has_contig
True 81 5 16 882

Now actually filter the AnnData object and run through a standard workflow starting by filtering genes and normalizing the data

Because the ‘filtered’ AnnData object was returned as a filtered but otherwise unprocessed object, we still need to normalize and run through the usual process here. The following is just a standard scanpy workflow.

[10]:
adata = adata[
    adata.obs["filter_rna"] == "False"
]  # from ddl.pp.recipe_scanpy_qc
# filter genes
sc.pp.filter_genes(adata, min_cells=3)
# Normalize the counts
sc.pp.normalize_total(adata, target_sum=1e4)
# Logarithmize the data
sc.pp.log1p(adata)
# Stash the normalised counts
adata.raw = adata

Identify highly-variable genes

[11]:
sc.pp.highly_variable_genes(adata, min_mean=0.0125, max_mean=3, min_disp=0.5)
sc.pl.highly_variable_genes(adata)
../../_images/notebooks_polars_1b_dandelion_noreannotation-10x_data_polars_24_0.png

Filter the genes to only those marked as highly-variable

[12]:
adata = adata[:, adata.var.highly_variable]

Regress out effects of total counts per cell and the percentage of mitochondrial genes expressed. Scale the data to unit variance.

[13]:
sc.pp.regress_out(adata, ["total_counts", "pct_counts_mt"])
sc.pp.scale(adata, max_value=10)

Run PCA

[14]:
sc.tl.pca(adata, svd_solver="arpack")
sc.pl.pca_variance_ratio(adata, log=True, n_pcs=50)
../../_images/notebooks_polars_1b_dandelion_noreannotation-10x_data_polars_30_0.png

Computing the neighborhood graph, umap and clusters

[15]:
# Computing the neighborhood graph
sc.pp.neighbors(adata)
# Embedding the neighborhood graph
sc.tl.umap(adata)
# Clustering the neighborhood graph
sc.tl.leiden(adata)

Visualizing the clusters and whether or not there’s a corresponding BCR

[16]:
sc.pl.umap(adata, color=["leiden", "chain_status"])
../../_images/notebooks_polars_1b_dandelion_noreannotation-10x_data_polars_34_0.png

Visualizing some B cell genes

[17]:
sc.pl.umap(adata, color=["IGHM", "JCHAIN"])
../../_images/notebooks_polars_1b_dandelion_noreannotation-10x_data_polars_36_0.png

Save AnnData

We can save this AnnData object for now.

[18]:
adata.write("adata2.h5ad", compression="gzip")

Save DandelionPolars

To save the vdj object, we have two options - either save the .data and .metadata slots with pandas’ functions.

Polars backend update

Since vdj.data is a Polars DataFrame in the polars backend, the pandas .to_csv() method is no longer available. Use Polars’ .write_csv() instead (note the parameter is separator=, not sep=).

[19]:
vdj.data.collect().write_csv("filtered_vdj_table2.tsv", separator="\t")
[20]:
vdj.write_h5ddl("dandelion_results2.h5ddl")

Concatenating multiple bcr objects

It is quite common that one might be trying to analyse data from multiple samples. In that case, dandelion has a concat function to merge the data.

We will simulate a second object but reading in the same file.

[21]:
vdj1 = ddl.read_10x_vdj(folder_location, filename_prefix="filtered")
vdj2 = ddl.read_10x_vdj(folder_location, filename_prefix="filtered")

Before you merge the objects, make sure that the “cell_id” and “sequence_id” are distinct so that you can distinguish them later

[22]:
vdj1.add_cell_prefix("run1_")
vdj2.add_cell_prefix("run2_")
[23]:
vdj_merged = ddl.tl.concat([vdj1, vdj2])
vdj_merged
[23]:
Lazy Dandelion object with n_obs = 1988 and n_contigs = 5202
    data: cell_id, is_cell_10x, sequence_id, high_confidence_10x, sequence_length_10x, locus, v_call, d_call, j_call, c_call, complete_vdj, productive, junction_aa, junction, consensus_count, umi_count, clone_id, raw_consensus_id_10x, sequence, rearrangement_status
    metadata: cell_id, clone_id, clone_id_rank, locus_VDJ, locus_VJ, v_call_VDJ, v_call_VJ, d_call_VDJ, j_call_VDJ, j_call_VJ, c_call_VDJ, c_call_VJ, junction_aa_VDJ, junction_aa_VJ, junction_VDJ, junction_VJ, umi_count_VDJ, umi_count_VJ, locus_VDJ_main, locus_VJ_main, v_call_VDJ_main, v_call_VJ_main, d_call_VDJ_main, j_call_VDJ_main, j_call_VJ_main, c_call_VDJ_main, c_call_VJ_main, junction_aa_VDJ_main, junction_aa_VJ_main, junction_VDJ_main, junction_VJ_main, umi_count_VDJ_main, umi_count_VJ_main, isotype, isotype_main, isotype_status, locus_status, chain_status, rearrangement_status_VDJ, rearrangement_status_VJ
[24]:
vdj_merged.data.collect()
[24]:
shape: (5_202, 20)
cell_idis_cell_10xsequence_idhigh_confidence_10xsequence_length_10xlocusv_calld_callj_callc_callcomplete_vdjproductivejunction_aajunctionconsensus_countumi_countclone_idraw_consensus_id_10xsequencerearrangement_status
strboolstrbooli64strstrstrstrstrboolboolstrstri64i64strstrstrstr
"run1_AAACCTGTCATATCGG-1"true"run1_AAACCTGTCATATCGG-1_contig…true556"IGK""IGKV1-8"null"IGKJ4""IGKC"truetrue"CQQYDELPVTF""TGTCAACAATATGACGAACTTCCCGTCACT…913968"clonotype9""clonotype9_consensus_1""TGGGGAGGAGTCAGTCCCAACCAGGACACG…"Standard"
"run1_AAACCTGTCATATCGG-1"true"run1_AAACCTGTCATATCGG-1_contig…true802"IGK"nullnull"IGKJ1"nullfalsefalsenullnull887"clonotype9"null"GGCTGCTATCTTCTCTTTCTCTCAAGGAAG…"Unknown"
"run1_AAACCTGTCCGTTGTC-1"true"run1_AAACCTGTCCGTTGTC-1_contig…true565"IGH""IGHV1-69D""IGHD3-22""IGHJ3""IGHM"truetrue"CATTYYYDSSGYYQNDAFDIW""TGTGCGACTACGTATTACTATGATAGTAGT…416151"clonotype10""clonotype10_consensus_2""ATCACATAACAACCACATTCCTCCTCTAAA…"Standard"
"run1_AAACCTGTCCGTTGTC-1"true"run1_AAACCTGTCCGTTGTC-1_contig…true551"IGK""IGKV1-8"null"IGKJ1""IGKC"truetrue"CQQYYSYPRTF""TGTCAACAGTATTATAGTTACCCTCGGACG…567943"clonotype10""clonotype10_consensus_1""AGGAGTCAGACCCTGTCAGGACACAGCATA…"Standard"
"run1_AAACCTGTCGAGAACG-1"true"run1_AAACCTGTCGAGAACG-1_contig…true642"IGL""IGLV5-45"null"IGLJ3""IGLC3"truetrue"CMIWHSSAWVV""TGTATGATTTGGCACAGCAGCGCTTGGGTG…1316090"clonotype11""clonotype11_consensus_1""ACTGTGGGGGTAAGAGGTTGTGTCCACCAT…"Standard"
"run2_TTTGGTTTCAGTGTTG-1"true"run2_TTTGGTTTCAGTGTTG-1_contig…true640"IGL""IGLV2-23"null"IGLJ2""IGLC2"truetrue"CCSYAGSSTFEVF""TGCTGCTCATATGCAGGTAGTAGCACTTTC…649758"clonotype983""clonotype983_consensus_1""GGGGTCACAAGAGGCAGCGCTCTCGGGACG…"Standard"
"run2_TTTGGTTTCAGTGTTG-1"true"run2_TTTGGTTTCAGTGTTG-1_contig…true517"IGH""IGHV2-5"null"IGHJ4""IGHM"truetrue"CAHRFEYFDYW""TGTGCACACAGGTTTGAGTACTTTGACTAC…353033"clonotype983""clonotype983_consensus_2""ATATTTCGTATCTGGGGAGTGACTCCTGTG…"Standard"
"run2_TTTGGTTTCGGTGTCG-1"true"run2_TTTGGTTTCGGTGTCG-1_contig…true568"IGK""IGKV3-11"null"IGKJ4""IGKC"truetrue"CQQRSNWPRLTF""TGTCAGCAGCGTAGCAACTGGCCTAGGCTC…305822"clonotype984""clonotype984_consensus_2""GGGAGAGCCCTGGGGAGGAACTGCTCAGTT…"Standard"
"run2_TTTGGTTTCGGTGTCG-1"true"run2_TTTGGTTTCGGTGTCG-1_contig…true571"IGH""IGHV3-21"null"IGHJ2""IGHM"truetrue"CARDPGDYVEIEWYFDLW""TGTGCGAGAGATCCCGGTGACTACGTAGAA…102612"clonotype984""clonotype984_consensus_1""GAGAGAGGAGCCTTAGCCCTGGATTCCAAG…"Standard"
"run2_TTTGGTTTCGGTGTCG-1"true"run2_TTTGGTTTCGGTGTCG-1_contig…true362"IGH"nullnull"IGHJ6""IGHD"falsefalsenullnull1992"clonotype984"null"GGGACTTCCCAGGCCGACAGTGGTCTGGCT…"Unknown"
[25]:
vdj_merged.metadata.collect()
[25]:
shape: (1_988, 40)
cell_idclone_idclone_id_ranklocus_VDJlocus_VJv_call_VDJv_call_VJd_call_VDJj_call_VDJj_call_VJc_call_VDJc_call_VJjunction_aa_VDJjunction_aa_VJjunction_VDJjunction_VJumi_count_VDJumi_count_VJlocus_VDJ_mainlocus_VJ_mainv_call_VDJ_mainv_call_VJ_maind_call_VDJ_mainj_call_VDJ_mainj_call_VJ_mainc_call_VDJ_mainc_call_VJ_mainjunction_aa_VDJ_mainjunction_aa_VJ_mainjunction_VDJ_mainjunction_VJ_mainumi_count_VDJ_mainumi_count_VJ_mainisotypeisotype_mainisotype_statuslocus_statuschain_statusrearrangement_status_VDJrearrangement_status_VJ
strstrcatstrstrstrstrstrstrstrstrstrstrstrstrstri64i64strstrstrstrstrstrstrstrstrstrstrstrstrf64f64strstrstrstrstrstrstr
"run1_AAACCTGTCATATCGG-1""clonotype9""306"null"IGK"null"IGKV1-8"nullnull"IGKJ4"null"IGKC"null"CQQYDELPVTF"null"TGTCAACAATATGACGAACTTCCCGTCACT…068null"IGK"null"IGKV1-8"nullnull"IGKJ4"null"IGKC"null"CQQYDELPVTF"null"TGTCAACAATATGACGAACTTCCCGTCACT…null68.0nullnullnull"Orphan IGK""Orphan VJ"null"Standard"
"run1_AAACCTGTCCGTTGTC-1""clonotype10""360""IGH""IGK""IGHV1-69D""IGKV1-8""IGHD3-22""IGHJ3""IGKJ1""IGHM""IGKC""CATTYYYDSSGYYQNDAFDIW""CQQYYSYPRTF""TGTGCGACTACGTATTACTATGATAGTAGT…"TGTCAACAGTATTATAGTTACCCTCGGACG…5143"IGH""IGK""IGHV1-69D""IGKV1-8""IGHD3-22""IGHJ3""IGKJ1""IGHM""IGKC""CATTYYYDSSGYYQNDAFDIW""CQQYYSYPRTF""TGTGCGACTACGTATTACTATGATAGTAGT…"TGTCAACAGTATTATAGTTACCCTCGGACG…51.043.0"IgM""IgM""IgM""IGH + IGK""Single pair""Standard""Standard"
"run1_AAACCTGTCGAGAACG-1""clonotype11""837""IGH""IGL""IGHV1-2""IGLV5-45"null"IGHJ3""IGLJ3""IGHM""IGLC3""CAREIEGDGVFEIW""CMIWHSSAWVV""TGTGCGAGAGAGATAGAGGGGGACGGTGTT…"TGTATGATTTGGCACAGCAGCGCTTGGGTG…4790"IGH""IGL""IGHV1-2""IGLV5-45"null"IGHJ3""IGLJ3""IGHM""IGLC3""CAREIEGDGVFEIW""CMIWHSSAWVV""TGTGCGAGAGAGATAGAGGGGGACGGTGTT…"TGTATGATTTGGCACAGCAGCGCTTGGGTG…47.090.0"IgM""IgM""IgM""IGH + IGL""Single pair""Standard""Standard"
"run1_AAACCTGTCTTGAGAC-1""clonotype12""562""IGH""IGK""IGHV5-51""IGKV1D-8"null"IGHJ3""IGKJ2""IGHM""IGKC""CARHIRGNRFGNDAFDIW""CQQYYSFPYTF""TGTGCGAGACATATCCGTGGGAACAGATTT…"TGTCAACAGTATTATAGTTTCCCGTACACT…8022"IGH""IGK""IGHV5-51""IGKV1D-8"null"IGHJ3""IGKJ2""IGHM""IGKC""CARHIRGNRFGNDAFDIW""CQQYYSFPYTF""TGTGCGAGACATATCCGTGGGAACAGATTT…"TGTCAACAGTATTATAGTTTCCCGTACACT…80.022.0"IgM""IgM""IgM""IGH + IGK""Single pair""Standard""Standard"
"run1_AAACGGGAGCGACGTA-1""clonotype13""796""IGH""IGL""IGHV4-59""IGLV3-19"null"IGHJ3""IGLJ2""IGHM""IGLC2""CARVGYRAAAGTDAFDIW""CNSRDSSGNHVVF""TGTGCGAGAGTAGGCTATAGAGCAGCAGCT…"TGTAACTCCCGGGACAGCAGTGGTAACCAT…1814"IGH""IGL""IGHV4-59""IGLV3-19"null"IGHJ3""IGLJ2""IGHM""IGLC2""CARVGYRAAAGTDAFDIW""CNSRDSSGNHVVF""TGTGCGAGAGTAGGCTATAGAGCAGCAGCT…"TGTAACTCCCGGGACAGCAGTGGTAACCAT…18.014.0"IgM""IgM""IgM""IGH + IGL""Single pair""Standard""Standard"
"run2_TTTGCGCTCTAACGGT-1""clonotype980""907""IGH""IGL""IGHV3-43""IGLV2-8"null"IGHJ6""IGLJ3""IGHM""IGLC2""CARVSGSYQYNYYYGMDVW""CGSFAGSNIWVF""TGTGCAAGAGTAAGTGGGAGCTACCAATAT…"TGCGGCTCATTTGCAGGCAGCAACATTTGG…46163"IGH""IGL""IGHV3-43""IGLV2-8"null"IGHJ6""IGLJ3""IGHM""IGLC2""CARVSGSYQYNYYYGMDVW""CGSFAGSNIWVF""TGTGCAAGAGTAAGTGGGAGCTACCAATAT…"TGCGGCTCATTTGCAGGCAGCAACATTTGG…46.0163.0"IgM""IgM""IgM""IGH + IGL""Single pair""Standard""Standard"
"run2_TTTGGTTGTAGCCTAT-1""clonotype981""737""IGH""IGK""IGHV4-39""IGKV6-21"null"IGHJ2""IGKJ4""IGHM""IGKC""CARLWVFLTMVRGPDFDLW""CHQSSSLPLTF""TGTGCGAGACTTTGGGTATTTCTTACTATG…"TGTCATCAGAGTAGTAGTTTACCGCTCACT…56"IGH""IGK""IGHV4-39""IGKV6-21"null"IGHJ2""IGKJ4""IGHM""IGKC""CARLWVFLTMVRGPDFDLW""CHQSSSLPLTF""TGTGCGAGACTTTGGGTATTTCTTACTATG…"TGTCATCAGAGTAGTAGTTTACCGCTCACT…5.06.0"IgM""IgM""IgM""IGH + IGK""Single pair""Standard""Standard"
"run2_TTTGGTTTCAGAGCTT-1""clonotype982""275""IGH""IGK""IGHV7-4-1""IGKV3-11""IGHD3-10""IGHJ4""IGKJ5""IGHM""IGKC""CARVFRRYGSGSYYNLW""CQQRSNWLTF""TGTGCGAGAGTTTTTAGACGCTATGGTTCG…"TGTCAGCAGCGTAGCAACTGGCTCACCTTC"7373"IGH""IGK""IGHV7-4-1""IGKV3-11""IGHD3-10""IGHJ4""IGKJ5""IGHM""IGKC""CARVFRRYGSGSYYNLW""CQQRSNWLTF""TGTGCGAGAGTTTTTAGACGCTATGGTTCG…"TGTCAGCAGCGTAGCAACTGGCTCACCTTC"73.073.0"IgM""IgM""IgM""IGH + IGK""Single pair""Standard""Standard"
"run2_TTTGGTTTCAGTGTTG-1""clonotype983""199""IGH""IGL""IGHV2-5""IGLV2-23"null"IGHJ4""IGLJ2""IGHM""IGLC2""CAHRFEYFDYW""CCSYAGSSTFEVF""TGTGCACACAGGTTTGAGTACTTTGACTAC…"TGCTGCTCATATGCAGGTAGTAGCACTTTC…3358"IGH""IGL""IGHV2-5""IGLV2-23"null"IGHJ4""IGLJ2""IGHM""IGLC2""CAHRFEYFDYW""CCSYAGSSTFEVF""TGTGCACACAGGTTTGAGTACTTTGACTAC…"TGCTGCTCATATGCAGGTAGTAGCACTTTC…33.058.0"IgM""IgM""IgM""IGH + IGL""Single pair""Standard""Standard"
"run2_TTTGGTTTCGGTGTCG-1""clonotype984""31""IGH""IGK""IGHV3-21""IGKV3-11"null"IGHJ2""IGKJ4""IGHM""IGKC""CARDPGDYVEIEWYFDLW""CQQRSNWPRLTF""TGTGCGAGAGATCCCGGTGACTACGTAGAA…"TGTCAGCAGCGTAGCAACTGGCCTAGGCTC…1222"IGH""IGK""IGHV3-21""IGKV3-11"null"IGHJ2""IGKJ4""IGHM""IGKC""CARDPGDYVEIEWYFDLW""CQQRSNWPRLTF""TGTGCGAGAGATCCCGGTGACTACGTAGAA…"TGTCAGCAGCGTAGCAACTGGCCTAGGCTC…12.022.0"IgM""IgM""IgM""IGH + IGK""Single pair""Standard""Standard"