Skip to content

Preprocessing · step 1

Data import#

  1. Data import
  2. Quality control
  3. Bridging
  4. Sample metadata

Use this when you have an NPX file, the data file that Olink's software exports (.csv, .txt, .xlsx or .parquet), and want it as a table in Python.

import signatomics.olink as so

data = so.read_npx(so.example_file())      # your own file: so.read_npx("my_npx_file.csv")

so.example_file() gives the path to a small, synthetic NPX file that comes with signatomics: one Target 96 plate with 40 samples, 8 controls and 92 assays. The values are synthetic, so you can follow every lesson without data of your own. Real data appears in Examples.

On the synthetic example file

Reading report
  file: example_plate1.csv
  file type: .csv
  layout: long format (one row per sample and assay)
  control samples: 8 (marked in SampleType); apply_qc removes them
  result: 4416 rows = (40 samples + 8 controls) x 92 assays

The plate holds 40 samples and 8 controls, each measured on 92 assays: one row per sample and assay, so 48 × 92 = 4416 rows. This is the long format, the layout every step of signatomics uses. The controls are Olink's own (negative, plate and sample controls); quality control removes them.

an NPX file (here: wide format) sample IL8 IL6 QC Warning Plate S15.13.2PASSP1 S24.80.7WARNP1 S35.63.5PASSP1 LOD0.91.1 Missing freq.0.000.33 read_npx long format: one row per sample and assay SampleIDAssayNPXLODMissingFreqQC_WarningPlateID S1IL85.10.90.00PASSP1 S1IL63.21.10.33PASSP1 S2IL84.80.90.00WARNP1 S2IL60.71.10.33WARNP1 … 6 rows: 3 samples × 2 assays
Whatever the NPX file looks like (long or wide format; .csv, .txt, .xlsx or .parquet), every function works on the same table in long format, with Olink's column names. In blue: one measurement. In the wide file its details sit in different places; in long format they share one row. All other Olink columns (OlinkID, UniProt, Panel, ...) are kept. Values are synthetic.
My file looks different. What does the report tell me?

When a file needs fixing, the report lists each change. Three examples from real NPX files:

Report line Meaning
columns renamed to the names signatomics uses: PlateLOD -> LOD the detection-limit column had another name; it is renamed LOD, so every step finds it
NPX: 184 cells said No Data, read as missing values 184 measurements held the text "No Data"; they become empty values
MissingFreq (missing frequency): percentages ("12%") read as fractions (0.12) the MissingFreq column, the share of samples below the LOD for each assay, was written as a percentage; it becomes a fraction
My file calls its columns something else, for example Patient instead of SampleID. What do I do?

signatomics looks for Olink's column names (SampleID, Assay, NPX, ...) and recognises the usual variants. When a needed column is missing, the message lists your columns and suggests a fix to copy:

my_npx_file.csv: the columns signatomics needs are missing.
  Needed: SampleID (the sample ID), Assay or OlinkID (the protein), NPX (the value)
  Your file has: Patient, Protein, Value, Plate
  Did you mean: read_npx("my_npx_file.csv", column_map={'Patient': 'SampleID', 'Protein': 'Assay', 'Value': 'NPX'})

Optional columns (LOD, PlateID, QC_Warning) that are missing get a line in the reading report, with what each is needed for.

Which NPX files have been tested?

Public NPX files from the PRIDE affinity proteomics archive of Target 48, Target 96, Explore 384, Explore 3072, Explore HT and Reveal; long .csv files (commas or semicolons, decimal points or commas), .xlsx and .parquet; and older wide files from NPX Manager. Where a file deviates (a sample-ID column holding something else, numbers damaged by a spreadsheet), the report says so.

Check yourself: why does each sample get 92 rows?

Each measurement carries its own details: its plate, its QC status, and the LOD and MissingFreq of that assay on that plate. One row per sample and assay keeps them together. The table turns into one row per sample at the end of preprocessing, in the analysis table.

Every option: read_npx in Functions.