# Integrating TRUST4 outputs into anndata GEX

**URL:** <https://discourse.scverse.org/t/integrating-trust4-outputs-into-anndata-gex/3426>\
**Category:** scirpy\
**Created:** [January 15, 2025, 2:58pm UTC](https://discourse.scverse.org/t/integrating-trust4-outputs-into-anndata-gex/3426 "2025-01-15T14:58:13Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![fonseca.dfm](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.scverse.org/fonseca.dfm/32/1275_2.png) [@fonseca.dfm](https://discourse.scverse.org/u/fonseca.dfm)\
**Post date:** [January 15, 2025, 2:58pm UTC](https://discourse.scverse.org/t/integrating-trust4-outputs-into-anndata-gex/3426/1 "2025-01-15T14:58:13Z")

</div>

Hi I love this community but I am struggling to integrate scRNA vdj annotations coming out of TRUST4 with my GEX data.

I am mostly using python so I tried using dandelion (read\_airr fuction), but somehow it doesnt recognize the output of TRUST4 barcode\_airr.tsv file, as it raises a ValueError: Unable to initialize metadata due to missing keys. Please ensure either ‘umi\_count’ or ‘duplicate\_count’ is in the input data.  
Shouldn’t AIRR be a specific standardized output?

Can you help me with this? what is the best way of integrating TRUST4 into an anndata object? I tried scirpy as well, but it seems to be quite difficult to extract the TRAV/TRBV cdr3aa of pair receptors into the adata.obs

I

---

<div class="post-metadata">

**Author:** ![grst](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.scverse.org/grst/32/17_2.png) [@grst](https://discourse.scverse.org/u/grst)\
**Post date:** [January 15, 2025, 4:23pm UTC](https://discourse.scverse.org/t/integrating-trust4-outputs-into-anndata-gex/3426/2 "2025-01-15T16:23:15Z")

</div>

Hi,

it seems the [TRUST4 AIRR files](https://github.com/liulab-dfci/TRUST4/blob/master/example/TRUST_example_airr.tsv) indeed does not contain a `duplicate_count` or `umi_count` field. As per the AIRR standard, this is ok, as the field is optional. I’m still surprised it doesn’t include the field, as TRUST4 does support UMIs. Did you use the `--UMI` flag when running it?

If dandelion can’t read that file, it’s an issue on their end because it is a compliant AIRR file. The maintainer doesn’t seem to be on this discourse, but you can open an issue in their repo.

I’d expect scirpy to be able to read that file (if not, let me know, I’m the maintainer). It shouldn’t be hard to add any of the information to `adata.obs` using `scripy.get.airr_context`, see [Accessing AIRR data](https://scirpy.scverse.org/en/latest/data-structure.html#accessing-airr-data) in the documentation.

Essentially, you can add any variable you need to `.obs` temporarily using `ir.get.airr_context`:

```python
with ir.get.airr_context(adata, ["junction_aa", "v_call"], ["VJ_1", "VDJ_1"]):
    display(adata.obs)

```

**P.S.** Please indicate if you are cross-posting on different platforms: [Integration of outputs of scRNA VDJ from TRUST4 with GEX · Issue #342 · liulab-dfci/TRUST4 · GitHub](https://github.com/liulab-dfci/TRUST4/issues/342). Not doing so may lead to duplicate efforts of community members who often answer to such posts and issues in their free time.

---

<div class="post-metadata">

**Author:** ![fonseca.dfm](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.scverse.org/fonseca.dfm/32/1275_2.png) [@fonseca.dfm](https://discourse.scverse.org/u/fonseca.dfm)\
**Post date:** [January 22, 2025, 12:02pm UTC](https://discourse.scverse.org/t/integrating-trust4-outputs-into-anndata-gex/3426/3 "2025-01-22T12:02:09Z")

</div>

Hi,

thank you for your help, I really appreciate it. The TRUST4 output has a column with the --UMI, I just needed to rename it. (see [Integration of outputs of scRNA VDJ from TRUST4 with GEX · Issue #342 · liulab-dfci/TRUST4 · GitHub](https://github.com/liulab-dfci/TRUST4/issues/342)

I am new to scRNA data analysis and I am struggling to integrate my data all together. I have gex from 10x that I processed with cellRanger and I also got ab\_vdj and gd\_vdj libraries from the same dataset, which I have annotated with TRUST4.  
I processed and cleaned the gex dataset using adata and scanpy. But I am struggling to integrate the output of TRUST4, with the adata object, to do umap and clonotype analysis.

since I have two vdj datasets, do I need to concat them before using muon with vdj + gex in scirpy? Additionally I have a bit of an overlap of barcodes for the ab\_vdj and gd\_vdj and I dont know if to exclude them.

I tried ir.get.airr\_context(), but tbh I dont really understand what this function is doing… I got a table out this line of code [with ir.get.airr\_context(adata, [“junction\_aa”, “v\_call”], [“VJ\_1”, “VDJ\_1”]): display(adata.obs)] but the adata object wasnt modified.

what do you advise me to do… Any help would be good.

Thanks ,

Daniel

---

<div class="post-metadata">

**Author:** ![grst](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.scverse.org/grst/32/17_2.png) [@grst](https://discourse.scverse.org/u/grst)\
**Post date:** [January 22, 2025, 6:27pm UTC](https://discourse.scverse.org/t/integrating-trust4-outputs-into-anndata-gex/3426/4 "2025-01-22T18:27:12Z")

</div>

> since I have two vdj datasets, do I need to concat them before using muon with vdj + gex in scirpy? Additionally I have a bit of an overlap of barcodes for the ab\_vdj and gd\_vdj and I dont know if to exclude them.

You don’t need muon, but you can build a mudata object from the gex and the vdj anndata objects. An example is shown [here](https://scirpy.scverse.org/en/latest/tutorials/tutorial_io.html#combining-multiple-samples).

> Additionally I have a bit of an overlap of barcodes for the ab\_vdj and gd\_vdj and I dont know if to exclude them.

Typically I would integrate ab and gd into a single dataset and then run scirpy.tl.chain\_qc to get labels you can use for filtering. If you loaded ab and gd into separate anndata objects, you can merge them using [scirpy.pp.merge\_airr](https://scirpy.scverse.org/en/latest/generated/scirpy.pp.merge_airr.html#scirpy.pp.merge_airr):

```python
adata_airr = ir.pp.merge_airr(adata_ab, adata_gd)
mdata = MuData({"gex": adata_gex, "airr": adata_airr})
ir.tl.chain_qc(mdata)

```

> I tried ir.get.airr\_context(), but tbh I dont really understand what this function is doing… I got a table out this line of code [with ir.get.airr\_context(adata, [“junction\_aa”, “v\_call”], [“VJ\_1”, “VDJ\_1”]): display(adata.obs)] but the adata object wasnt modified.

airr\_context only temporarily adds the information to `.obs` while you are within the context manager. This is not to overload your `.obs` with tons of columns. You can use the AIRR variables within the context manager for whatever you’d like to do, e.g. plot gene usage. See an example [in the scirpy tutorial](https://scirpy.scverse.org/en/latest/tutorials/tutorial_3k_tcr.html#gene-usage).

If you really want to add the information permanently, you can use `ir.get.airr` to get a data frame and join it with `adata.obs`.
