> For the complete documentation index, see [llms.txt](https://help.bioinsight.illumina.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://help.bioinsight.illumina.com/dragen-protein-quantification/counting-and-normalization/interpretation-of-results/site-specific-elod.md).

# Site-Specific Estimated Limit of Detection (eLOD)

## Overview

Illumina is committed to improving methods for analyzing SomaSeq Discovery data. Previously, a static Limit of Detection (LOD) that was computed during Illumina's Design Verification Testing (DVT) was provided in SOMAmer metadata. Because background signal levels can differ across sites due to environmental conditions, instrumentation, and sample handling practices, the static LOD may not accurately reflect the detection threshold at every site.

It is recommended to calculate a site-specific estimated Limit of Detection (eLOD) using blank samples from a passing Product Quality (PQ) run. The PQ run contains more blank samples than a standard run, providing sufficient statistical power to estimate the detection threshold for each SOMAmer at a given site.

## When to Calculate eLOD

It's recommended to calculate a site-specific eLOD when setting up a new instrument or site.

## How eLOD Is Calculated

For each SOMAmer, an eLOD is derived from the blank samples using the following steps:

1. Calculate the median and adjusted Median Absolute Deviation (MAD):

$$MAD\_{Adjusted} = 1.4826 \times MAD$$

The constant 1.4826 adjusts the MAD to be reflective of the standard deviation of the normal distribution.

2. Calculate the eLOD:

$$eLOD = median + 3.3 \times MAD\_{Adjusted}$$

The result is a per-SOMAmer eLOD value in RFU units.

## Calculating eLOD with SomaData/Canopy (Python)

The `calcELOD()` function is available in the [SomaData](https://github.com/SomaLogic/Canopy) package (v1.2.6).

### Usage

```python
import somadata

# load adat
pq_adat = somadata.read_adat(pq_adat_path)

# filter to blank samples
blank_stypes = ['Blank', 'Buffer']
blanks = pq_adat[pq_adat.index.get_level_values('SampleType').isin(blank_stypes)]

# compute eLOD per SOMAmer (returns pd.Series indexed by SeqId column names)
elod = blanks.apply(somadata.base.adat_math_helpers.calcELOD)

# as dataframe
elod_df = elod.to_frame(name='eLOD')
```

The result is a `pd.DataFrame` indexed by SeqId column names with a single `eLOD` column.

## Calculating eLOD with SomaDataIO (R)

The `calc_eLOD()` function is available in the [SomaDataIO](https://github.com/SomaLogic/SomaDataIO) package (v6.6.0+).

### Usage

```r
library(SomaDataIO)
library(dplyr)

# Load the PQ ADAT file
pq_adat <- read_adat("path/to/pq_run.adat")

# Filter to blank/buffer samples only
blank_samples <- pq_adat |> filter(SampleType %in% c("Blank", "Buffer"))

# Calculate site-specific eLOD
site_elod <- calc_eLOD(blank_samples)

# View results
head(site_elod)
#> # A tibble: 6 x 2
#>   SeqId           eLOD
#>   <chr>          <dbl>
#> 1 seq.10000.28    234.
#> 2 seq.10001.7     512.
#> 3 seq.10003.15    189.
#> ...
```

The function returns a tibble with two columns: `SeqId` and `eLOD`.

## Important Considerations

* **Use blank samples only.** The input data must be filtered to include only blank samples. Including calibrator, QC, or plasma/serum/CSF/MultiMatrix samples will produce incorrect eLOD values.
* **Use a passing PQ run.** The PQ run provides a larger number of blank samples than a standard run, improving the reliability of the estimate.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://help.bioinsight.illumina.com/dragen-protein-quantification/counting-and-normalization/interpretation-of-results/site-specific-elod.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
