imaging1/4 Jupyter Notebook

sc-imaging

Here, you will learn how to structure, featurize, and make a large imaging collection queryable for large-scale machine learning:

  1. Load and annotate a Collection of microscopy images (sc-imaging/4)

  2. Generate single-cell images (sc-imaging2/4)

  3. Featurize single-cell images (sc-imaging3/4)

  4. Train model to identify autophagy positive cells (sc-imaging4/4)

First, we load and annotate a collection of microscopy images in TIFF format that was previously uploaded.

The images used here were acquired as part of a study on autophagy, a cellular process during which cells recycle their components in autophagosomes. The study tracked genetic determinants of autophagy through fluorescence microscopy of human U2OS cells.

# pip install 'lamindb[jupyter,bionty]'
!lamin init --storage ./test-sc-imaging --modules bionty
Hide code cell output
 initialized lamindb: testuser1/test-sc-imaging
import lamindb as ln
import bionty as bt
from tifffile import imread
import matplotlib.pyplot as plt

ln.track()
Hide code cell output
 connected lamindb: testuser1/test-sc-imaging
 created Transform('F5ZxoLZwqwqZ0000'), started new Run('GJwXLLhJ...') at 2025-03-31 12:38:56 UTC
 notebook imports: bionty==1.2.1 lamindb==1.3.1 matplotlib==3.10.1 tifffile==2025.3.30

All image metadata is stored in an already ingested .csv file on the scportrait/examples instance.

metadata_files = (
    ln.Artifact.using("scportrait/examples")
    .get(key="input_data_imaging_usecase/metadata_files.csv")
    .load()
)

metadata_files.head(2)
Hide code cell output
 completing transfer to track Artifact('jdjwcUB0') as input
 mapped records: 
 transferred records: Artifact(uid='jdjwcUB0w1QAHAYm0000'), Storage(uid='r7YUayXjktSb')
image_path genotype stimulation cell_line cell_line_clone channel FOV magnification microscope imaged structure resolution
0 input_data_imaging_usecase/images/Timepoint001... WT 14h Torin-1 U2OS U2OS lcklip-mNeon mCherryLC3B clone 1 Alexa488 FOV1 20X Opera Phenix LckLip-mNeon 0.597976
1 input_data_imaging_usecase/images/Timepoint001... WT 14h Torin-1 U2OS U2OS lcklip-mNeon mCherryLC3B clone 1 Alexa488 FOV2 20X Opera Phenix LckLip-mNeon 0.597976
metadata_files.apply(lambda col: col.unique())
Hide code cell output
image_path          [input_data_imaging_usecase/images/Timepoint00...
genotype                                                 [WT, EI24KO]
stimulation                                  [14h Torin-1, untreated]
cell_line                                                      [U2OS]
cell_line_clone     [U2OS lcklip-mNeon mCherryLC3B clone 1, U2OS l...
channel                                     [Alexa488, DAPI, mCherry]
FOV                                                      [FOV1, FOV2]
magnification                                                   [20X]
microscope                                             [Opera Phenix]
imaged structure                    [LckLip-mNeon, DNA, mCherry-LC3B]
resolution                                              [0.597976081]
dtype: object

All images are of the same cell line (U2OS), which have been imaged on an Opera Phenix microscope at 20X magnification. To induce autophagy, the cells have either been treated with Torin-1, a small molecule that mimics starvation, for 14 hours, or left untreated as a control.

To visualize the process of autophagosome formation, the U2OS cells have been genetically engineered to express fluorescently tagged proteins. LC3B is a marker of autophagosomes, allowing us to visualize their formation in the mCherry channel. LckLip is a membrane-targeted fluorescent protein, which helps outline the cellular boundaries of individual cells in the Alexa488 channel. Furthermore, the cells’ DNA was stained using Hoechst, which we can visualize in the DAPI channel to identify the nuclei of individual cells.

These three structures are visualized in three separate image channels:

Channel

Imaged Structure

1

DNA

2

Autophagosomes

3

Plasma Membrane

In addition to expressing fluorescently tagged proteins, some of the cells have had the EI24 gene knocked out, leading to two different genotypes: WT (wild-type) cells and EI24KO (knockout) cells. For each genotype, two different clonal cell lines were analyzed, with multiple fields of view (FOVs) captured per condition.

To enable queries on our images, we annotate them with the corresponding metadata.

autophagy_imaging_schema = ln.Schema(
    name="Autophagy imaging schema",
    features=[
        ln.Feature(name="genotype", dtype=ln.ULabel.name).save(),
        ln.Feature(name="stimulation", dtype=ln.ULabel.name).save(),
        ln.Feature(name="cell_line", dtype=bt.CellLine.name).save(),
        ln.Feature(name="cell_line_clone", dtype=ln.ULabel.name).save(),
        ln.Feature(name="channel", dtype=ln.ULabel.name).save(),
        ln.Feature(name="FOV", dtype=ln.ULabel.name).save(),
        ln.Feature(name="magnification", dtype=ln.ULabel.name).save(),
        ln.Feature(name="microscope", dtype=ln.ULabel.name).save(),
        ln.Feature(name="imaged structure", dtype=ln.ULabel.name).save(),
        ln.Feature(
            name="resolution", dtype=float, description="conversion factor for px to µm"
        ).save(),
    ],
    coerce_dtype=True,
).save()
curator = ln.curators.DataFrameCurator(metadata_files, autophagy_imaging_schema)
try:
    curator.validate()
except ln.core.exceptions.ValidationError as e:
    print(e)
Hide code cell output
 Created a ULabel type: ULabel(uid='VALtgZ0i', name='Genotype', is_type=True, space_id=1, created_by_id=1, run_id=1, created_at=2025-03-31 12:39:08 UTC)
 Created a ULabel type: ULabel(uid='kRvlsAid', name='Stimulation', is_type=True, space_id=1, created_by_id=1, run_id=1, created_at=2025-03-31 12:39:08 UTC)
 saving validated records of 'cell_line'
 added 1 record from public with CellLine.name for "cell_line": 'U-2 OS cell'
 Created a ULabel type: ULabel(uid='tdxysm0S', name='CellLineClone', is_type=True, space_id=1, created_by_id=1, run_id=1, created_at=2025-03-31 12:39:09 UTC)
 Created a ULabel type: ULabel(uid='5lFdItkI', name='Channel', is_type=True, space_id=1, created_by_id=1, run_id=1, created_at=2025-03-31 12:39:09 UTC)
 Created a ULabel type: ULabel(uid='U7Et1HXL', name='Fov', is_type=True, space_id=1, created_by_id=1, run_id=1, created_at=2025-03-31 12:39:09 UTC)
 Created a ULabel type: ULabel(uid='yf0Kcq16', name='Magnification', is_type=True, space_id=1, created_by_id=1, run_id=1, created_at=2025-03-31 12:39:09 UTC)
 Created a ULabel type: ULabel(uid='9qnjMAao', name='Microscope', is_type=True, space_id=1, created_by_id=1, run_id=1, created_at=2025-03-31 12:39:09 UTC)
 Created a ULabel type: ULabel(uid='HBBe0Oit', name='Imaged structure', is_type=True, space_id=1, created_by_id=1, run_id=1, created_at=2025-03-31 12:39:09 UTC)
 mapping "genotype" on ULabel.name
!   2 terms are not validated: 'WT', 'EI24KO'
    → fix typos, remove non-existent values, or save terms via .add_new_from("genotype")
 mapping "stimulation" on ULabel.name
!   2 terms are not validated: '14h Torin-1', 'untreated'
    → fix typos, remove non-existent values, or save terms via .add_new_from("stimulation")
 mapping "cell_line" on CellLine.name
!   1 term is not validated: 'U2OS'
    1 synonym found: "U2OS" → "U-2 OS cell"
    → curate synonyms via .standardize("cell_line")
 mapping "cell_line_clone" on ULabel.name
!   4 terms are not validated: 'U2OS lcklip-mNeon mCherryLC3B clone 1', 'U2OS lcklip-mNeon mCherryLC3B clone 2', 'U2OS lcklip-mNeon mCherryLC3B EI24 KO clone 1', 'U2OS lcklip-mNeon mCherryLC3B EI24 KO clone 2'
    → fix typos, remove non-existent values, or save terms via .add_new_from("cell_line_clone")
 mapping "channel" on ULabel.name
!   3 terms are not validated: 'Alexa488', 'DAPI', 'mCherry'
    → fix typos, remove non-existent values, or save terms via .add_new_from("channel")
 mapping "FOV" on ULabel.name
!   2 terms are not validated: 'FOV1', 'FOV2'
    → fix typos, remove non-existent values, or save terms via .add_new_from("FOV")
 mapping "magnification" on ULabel.name
!   1 term is not validated: '20X'
    → fix typos, remove non-existent values, or save terms via .add_new_from("magnification")
 mapping "microscope" on ULabel.name
!   1 term is not validated: 'Opera Phenix'
    → fix typos, remove non-existent values, or save terms via .add_new_from("microscope")
 mapping "imaged structure" on ULabel.name
!   3 terms are not validated: 'LckLip-mNeon', 'DNA', 'mCherry-LC3B'
    → fix typos, remove non-existent values, or save terms via .add_new_from("imaged structure")
3 terms are not validated: 'LckLip-mNeon', 'DNA', 'mCherry-LC3B'
    → fix typos, remove non-existent values, or save terms via .add_new_from("imaged structure")

Add and standardize missing terms:

curator.cat.standardize("cell_line")
curator.cat.add_new_from("all")
curator.validate()
Hide code cell output
 standardized 1 synonym in "cell_line": "U2OS" → "U-2 OS cell"
 added 2 records with ULabel.name for "genotype": 'WT', 'EI24KO'
 added 2 records with ULabel.name for "stimulation": 'untreated', '14h Torin-1'
 added 4 records with ULabel.name for "cell_line_clone": 'U2OS lcklip-mNeon mCherryLC3B clone 1', 'U2OS lcklip-mNeon mCherryLC3B EI24 KO clone 2', 'U2OS lcklip-mNeon mCherryLC3B EI24 KO clone 1', 'U2OS lcklip-mNeon mCherryLC3B clone 2'
! records with similar names exist! did you mean to load one of them?
uid name is_type description reference reference_type space_id type_id run_id created_at created_by_id _aux _branch_code
id
13 7QQ6ogf5 U2OS lcklip-mNeon mCherryLC3B clone 1 False None None None 1 None 1 2025-03-31 12:39:10.028000+00:00 1 None 1
14 FIZCs34L U2OS lcklip-mNeon mCherryLC3B EI24 KO clone 2 False None None None 1 None 1 2025-03-31 12:39:10.028000+00:00 1 None 1
15 cW0GsYzh U2OS lcklip-mNeon mCherryLC3B EI24 KO clone 1 False None None None 1 None 1 2025-03-31 12:39:10.028000+00:00 1 None 1
 added 3 records with ULabel.name for "channel": 'mCherry', 'Alexa488', 'DAPI'
 added 2 records with ULabel.name for "FOV": 'FOV1', 'FOV2'
 added 1 record with ULabel.name for "magnification": '20X'
 added 1 record with ULabel.name for "microscope": 'Opera Phenix'
! records with similar names exist! did you mean to load one of them?
uid name is_type description reference reference_type space_id type_id run_id created_at created_by_id _aux _branch_code
id
13 7QQ6ogf5 U2OS lcklip-mNeon mCherryLC3B clone 1 False None None None 1 None 1 2025-03-31 12:39:10.028000+00:00 1 None 1
14 FIZCs34L U2OS lcklip-mNeon mCherryLC3B EI24 KO clone 2 False None None None 1 None 1 2025-03-31 12:39:10.028000+00:00 1 None 1
15 cW0GsYzh U2OS lcklip-mNeon mCherryLC3B EI24 KO clone 1 False None None None 1 None 1 2025-03-31 12:39:10.028000+00:00 1 None 1
 added 3 records with ULabel.name for "imaged structure": 'LckLip-mNeon', 'DNA', 'mCherry-LC3B'
 "genotype" is validated against ULabel.name
 "stimulation" is validated against ULabel.name
 "cell_line" is validated against CellLine.name
 "cell_line_clone" is validated against ULabel.name
 "channel" is validated against ULabel.name
 "FOV" is validated against ULabel.name
 "magnification" is validated against ULabel.name
 "microscope" is validated against ULabel.name
 "imaged structure" is validated against ULabel.name

Add all images to our lamindb instance to annotate all relevant metadata.

# Create study feature and associated label
ln.Feature(name="study", dtype=ln.ULabel).save()
ln.ULabel(name="autophagy imaging").save()

# loop through all Artifacts and add feature values
artifacts = []
for _, row in metadata_files.iterrows():
    artifact = (
        ln.Artifact.using("scportrait/examples")
        .filter(key__icontains=row["image_path"])
        .one()
    )
    artifact.save()
    artifact.cell_lines.add(bt.CellLine.filter(name=row.cell_line).one())

    artifact.features.add_values(
        {
            "genotype": row.genotype,
            "stimulation": row.stimulation,
            "cell_line_clone": row.cell_line_clone,
            "channel": row.channel,
            "imaged structure": row["imaged structure"],
            "study": "autophagy imaging",
            "FOV": row.FOV,
            "magnification": row.magnification,
            "microscope": row.microscope,
            "resolution": row.resolution,
        }
    )

    artifacts.append(artifact)
Hide code cell output
 mapped records: 
 transferred records: Artifact(uid='Md4OouMExlWS2YfZ0000'), CellLine(uid='4oLoqaUP'), ULabel(uid='9hHptuyb'), ULabel(uid='A2945i5P'), ULabel(uid='KH1brNUW'), ULabel(uid='XKI9Mx33'), ULabel(uid='CrR7fgIZ'), ULabel(uid='QrU6fxsG'), ULabel(uid='PKiCEP1h'), ULabel(uid='HRRTqARL'), ULabel(uid='e82fx2wm')
 mapped records: CellLine(uid='4oLoqaUP'), ULabel(uid='9hHptuyb'), ULabel(uid='A2945i5P'), ULabel(uid='KH1brNUW'), ULabel(uid='XKI9Mx33'), ULabel(uid='QrU6fxsG'), ULabel(uid='PKiCEP1h'), ULabel(uid='HRRTqARL'), ULabel(uid='e82fx2wm')
 transferred records: Artifact(uid='KKbVRkOjQ1jdA2fx0000'), ULabel(uid='1KPobNqK')
 mapped records: CellLine(uid='4oLoqaUP'), ULabel(uid='9hHptuyb'), ULabel(uid='A2945i5P'), ULabel(uid='KH1brNUW'), ULabel(uid='CrR7fgIZ'), ULabel(uid='PKiCEP1h'), ULabel(uid='HRRTqARL'), ULabel(uid='e82fx2wm')
 transferred records: Artifact(uid='CiQYTBNZrj0CPejK0000'), ULabel(uid='HK8F1lVS'), ULabel(uid='xhpmj7p7')
 mapped records: CellLine(uid='4oLoqaUP'), ULabel(uid='HK8F1lVS'), ULabel(uid='9hHptuyb'), ULabel(uid='A2945i5P'), ULabel(uid='KH1brNUW'), ULabel(uid='1KPobNqK'), ULabel(uid='xhpmj7p7'), ULabel(uid='PKiCEP1h'), ULabel(uid='HRRTqARL'), ULabel(uid='e82fx2wm')
 transferred records: Artifact(uid='W6tzE7JNiM80Ruho0000')
 mapped records: CellLine(uid='4oLoqaUP'), ULabel(uid='9hHptuyb'), ULabel(uid='A2945i5P'), ULabel(uid='KH1brNUW'), ULabel(uid='CrR7fgIZ'), ULabel(uid='PKiCEP1h'), ULabel(uid='HRRTqARL'), ULabel(uid='e82fx2wm')
 transferred records: Artifact(uid='YGiNq6DPfIEjtt9j0000'), ULabel(uid='AyafKoQw'), ULabel(uid='xHqZKcIG')
 mapped records: CellLine(uid='4oLoqaUP'), ULabel(uid='9hHptuyb'), ULabel(uid='A2945i5P'), ULabel(uid='KH1brNUW'), ULabel(uid='AyafKoQw'), ULabel(uid='1KPobNqK'), ULabel(uid='xHqZKcIG'), ULabel(uid='PKiCEP1h'), ULabel(uid='HRRTqARL'), ULabel(uid='e82fx2wm')
 transferred records: Artifact(uid='uuh41FAHEz0ASL2N0000')
 mapped records: CellLine(uid='4oLoqaUP'), ULabel(uid='9hHptuyb'), ULabel(uid='KH1brNUW'), ULabel(uid='XKI9Mx33'), ULabel(uid='CrR7fgIZ'), ULabel(uid='QrU6fxsG'), ULabel(uid='PKiCEP1h'), ULabel(uid='HRRTqARL'), ULabel(uid='e82fx2wm')
 transferred records: Artifact(uid='Gtwi9Pcyx8maQEWB0000'), ULabel(uid='EgihgpJC')
 mapped records: CellLine(uid='4oLoqaUP'), ULabel(uid='9hHptuyb'), ULabel(uid='EgihgpJC'), ULabel(uid='KH1brNUW'), ULabel(uid='XKI9Mx33'), ULabel(uid='1KPobNqK'), ULabel(uid='QrU6fxsG'), ULabel(uid='PKiCEP1h'), ULabel(uid='HRRTqARL'), ULabel(uid='e82fx2wm')
 transferred records: Artifact(uid='nSZhAypqiNZ2Ylbe0000')
 mapped records: CellLine(uid='4oLoqaUP'), ULabel(uid='HK8F1lVS'), ULabel(uid='9hHptuyb'), ULabel(uid='EgihgpJC'), ULabel(uid='KH1brNUW'), ULabel(uid='CrR7fgIZ'), ULabel(uid='xhpmj7p7'), ULabel(uid='PKiCEP1h'), ULabel(uid='HRRTqARL'), ULabel(uid='e82fx2wm')
 transferred records: Artifact(uid='sHHpiiFYWsIXMZNV0000')
 mapped records: CellLine(uid='4oLoqaUP'), ULabel(uid='HK8F1lVS'), ULabel(uid='9hHptuyb'), ULabel(uid='EgihgpJC'), ULabel(uid='KH1brNUW'), ULabel(uid='1KPobNqK'), ULabel(uid='xhpmj7p7'), ULabel(uid='PKiCEP1h'), ULabel(uid='HRRTqARL'), ULabel(uid='e82fx2wm')
 transferred records: Artifact(uid='jzqxtoduIJ3hCbB40000')
 mapped records: CellLine(uid='4oLoqaUP'), ULabel(uid='9hHptuyb'), ULabel(uid='EgihgpJC'), ULabel(uid='KH1brNUW'), ULabel(uid='AyafKoQw'), ULabel(uid='CrR7fgIZ'), ULabel(uid='xHqZKcIG'), ULabel(uid='PKiCEP1h'), ULabel(uid='HRRTqARL'), ULabel(uid='e82fx2wm')
 transferred records: Artifact(uid='hNMkrIHce1XrLZHY0000')
 mapped records: CellLine(uid='4oLoqaUP'), ULabel(uid='9hHptuyb'), ULabel(uid='EgihgpJC'), ULabel(uid='KH1brNUW'), ULabel(uid='AyafKoQw'), ULabel(uid='1KPobNqK'), ULabel(uid='xHqZKcIG'), ULabel(uid='PKiCEP1h'), ULabel(uid='HRRTqARL'), ULabel(uid='e82fx2wm')
 transferred records: Artifact(uid='M06liaIzh2OVEuJ40000')
 mapped records: CellLine(uid='4oLoqaUP'), ULabel(uid='9hHptuyb'), ULabel(uid='A2945i5P'), ULabel(uid='XKI9Mx33'), ULabel(uid='CrR7fgIZ'), ULabel(uid='QrU6fxsG'), ULabel(uid='PKiCEP1h'), ULabel(uid='HRRTqARL'), ULabel(uid='e82fx2wm')
 transferred records: Artifact(uid='yiIMSAddDWgLgki70000'), ULabel(uid='GadMJgvN')
 mapped records: CellLine(uid='4oLoqaUP'), ULabel(uid='9hHptuyb'), ULabel(uid='A2945i5P'), ULabel(uid='GadMJgvN'), ULabel(uid='XKI9Mx33'), ULabel(uid='1KPobNqK'), ULabel(uid='QrU6fxsG'), ULabel(uid='PKiCEP1h'), ULabel(uid='HRRTqARL'), ULabel(uid='e82fx2wm')
 transferred records: Artifact(uid='2ie2Kjzn1O7UYhuq0000')
 mapped records: CellLine(uid='4oLoqaUP'), ULabel(uid='HK8F1lVS'), ULabel(uid='9hHptuyb'), ULabel(uid='A2945i5P'), ULabel(uid='GadMJgvN'), ULabel(uid='CrR7fgIZ'), ULabel(uid='xhpmj7p7'), ULabel(uid='PKiCEP1h'), ULabel(uid='HRRTqARL'), ULabel(uid='e82fx2wm')
 transferred records: Artifact(uid='DEzw4QQAsjVZ010b0000')
 mapped records: CellLine(uid='4oLoqaUP'), ULabel(uid='HK8F1lVS'), ULabel(uid='9hHptuyb'), ULabel(uid='A2945i5P'), ULabel(uid='GadMJgvN'), ULabel(uid='1KPobNqK'), ULabel(uid='xhpmj7p7'), ULabel(uid='PKiCEP1h'), ULabel(uid='HRRTqARL'), ULabel(uid='e82fx2wm')
 transferred records: Artifact(uid='fOQSb7JCK67aeN6a0000')
 mapped records: CellLine(uid='4oLoqaUP'), ULabel(uid='9hHptuyb'), ULabel(uid='A2945i5P'), ULabel(uid='GadMJgvN'), ULabel(uid='AyafKoQw'), ULabel(uid='CrR7fgIZ'), ULabel(uid='xHqZKcIG'), ULabel(uid='PKiCEP1h'), ULabel(uid='HRRTqARL'), ULabel(uid='e82fx2wm')
 transferred records: Artifact(uid='hbVyCGFARHU91Kax0000')
 mapped records: CellLine(uid='4oLoqaUP'), ULabel(uid='9hHptuyb'), ULabel(uid='A2945i5P'), ULabel(uid='GadMJgvN'), ULabel(uid='AyafKoQw'), ULabel(uid='1KPobNqK'), ULabel(uid='xHqZKcIG'), ULabel(uid='PKiCEP1h'), ULabel(uid='HRRTqARL'), ULabel(uid='e82fx2wm')
 transferred records: Artifact(uid='qHQpdWcFu7FzF6l50000')
 mapped records: CellLine(uid='4oLoqaUP'), ULabel(uid='9hHptuyb'), ULabel(uid='EgihgpJC'), ULabel(uid='GadMJgvN'), ULabel(uid='XKI9Mx33'), ULabel(uid='CrR7fgIZ'), ULabel(uid='QrU6fxsG'), ULabel(uid='PKiCEP1h'), ULabel(uid='HRRTqARL'), ULabel(uid='e82fx2wm')
 transferred records: Artifact(uid='mXWwV1x42Jz9RoSO0000')
 mapped records: CellLine(uid='4oLoqaUP'), ULabel(uid='9hHptuyb'), ULabel(uid='EgihgpJC'), ULabel(uid='GadMJgvN'), ULabel(uid='XKI9Mx33'), ULabel(uid='1KPobNqK'), ULabel(uid='QrU6fxsG'), ULabel(uid='PKiCEP1h'), ULabel(uid='HRRTqARL'), ULabel(uid='e82fx2wm')
 transferred records: Artifact(uid='Ov8FnKzHMNY0XVJa0000')
 mapped records: CellLine(uid='4oLoqaUP'), ULabel(uid='HK8F1lVS'), ULabel(uid='9hHptuyb'), ULabel(uid='EgihgpJC'), ULabel(uid='GadMJgvN'), ULabel(uid='CrR7fgIZ'), ULabel(uid='xhpmj7p7'), ULabel(uid='PKiCEP1h'), ULabel(uid='HRRTqARL'), ULabel(uid='e82fx2wm')
 transferred records: Artifact(uid='gj0HHnoVpEqbaUJb0000')
 mapped records: CellLine(uid='4oLoqaUP'), ULabel(uid='HK8F1lVS'), ULabel(uid='9hHptuyb'), ULabel(uid='EgihgpJC'), ULabel(uid='GadMJgvN'), ULabel(uid='1KPobNqK'), ULabel(uid='xhpmj7p7'), ULabel(uid='PKiCEP1h'), ULabel(uid='HRRTqARL'), ULabel(uid='e82fx2wm')
 transferred records: Artifact(uid='Lwk8shsYe0V5bMgd0000')
 mapped records: CellLine(uid='4oLoqaUP'), ULabel(uid='9hHptuyb'), ULabel(uid='EgihgpJC'), ULabel(uid='GadMJgvN'), ULabel(uid='AyafKoQw'), ULabel(uid='CrR7fgIZ'), ULabel(uid='xHqZKcIG'), ULabel(uid='PKiCEP1h'), ULabel(uid='HRRTqARL'), ULabel(uid='e82fx2wm')
 transferred records: Artifact(uid='1XnEyqVt6UGXCTmV0000')
 mapped records: CellLine(uid='4oLoqaUP'), ULabel(uid='9hHptuyb'), ULabel(uid='EgihgpJC'), ULabel(uid='GadMJgvN'), ULabel(uid='AyafKoQw'), ULabel(uid='1KPobNqK'), ULabel(uid='xHqZKcIG'), ULabel(uid='PKiCEP1h'), ULabel(uid='HRRTqARL'), ULabel(uid='e82fx2wm')
 transferred records: Artifact(uid='YuyVn060M4FxATPz0000')
 mapped records: CellLine(uid='4oLoqaUP'), ULabel(uid='A2945i5P'), ULabel(uid='XKI9Mx33'), ULabel(uid='CrR7fgIZ'), ULabel(uid='QrU6fxsG'), ULabel(uid='PKiCEP1h'), ULabel(uid='HRRTqARL'), ULabel(uid='e82fx2wm')
 transferred records: Artifact(uid='jVytS8AyAHmHkYR30000'), ULabel(uid='Aj8KGwbh'), ULabel(uid='JIbWVXma')
 mapped records: CellLine(uid='4oLoqaUP'), ULabel(uid='Aj8KGwbh'), ULabel(uid='A2945i5P'), ULabel(uid='JIbWVXma'), ULabel(uid='XKI9Mx33'), ULabel(uid='1KPobNqK'), ULabel(uid='QrU6fxsG'), ULabel(uid='PKiCEP1h'), ULabel(uid='HRRTqARL'), ULabel(uid='e82fx2wm')
 transferred records: Artifact(uid='vCVbKkzz4CnJPPKF0000')
 mapped records: CellLine(uid='4oLoqaUP'), ULabel(uid='HK8F1lVS'), ULabel(uid='Aj8KGwbh'), ULabel(uid='A2945i5P'), ULabel(uid='JIbWVXma'), ULabel(uid='CrR7fgIZ'), ULabel(uid='xhpmj7p7'), ULabel(uid='PKiCEP1h'), ULabel(uid='HRRTqARL'), ULabel(uid='e82fx2wm')
 transferred records: Artifact(uid='cw4F6bUB9zuMthCY0000')
 mapped records: CellLine(uid='4oLoqaUP'), ULabel(uid='HK8F1lVS'), ULabel(uid='Aj8KGwbh'), ULabel(uid='A2945i5P'), ULabel(uid='JIbWVXma'), ULabel(uid='1KPobNqK'), ULabel(uid='xhpmj7p7'), ULabel(uid='PKiCEP1h'), ULabel(uid='HRRTqARL'), ULabel(uid='e82fx2wm')
 transferred records: Artifact(uid='5kMhlcDNek4RMeQF0000')
 mapped records: CellLine(uid='4oLoqaUP'), ULabel(uid='Aj8KGwbh'), ULabel(uid='A2945i5P'), ULabel(uid='JIbWVXma'), ULabel(uid='AyafKoQw'), ULabel(uid='CrR7fgIZ'), ULabel(uid='xHqZKcIG'), ULabel(uid='PKiCEP1h'), ULabel(uid='HRRTqARL'), ULabel(uid='e82fx2wm')
 transferred records: Artifact(uid='7TZGXvbA0JLL68hR0000')
 mapped records: CellLine(uid='4oLoqaUP'), ULabel(uid='Aj8KGwbh'), ULabel(uid='A2945i5P'), ULabel(uid='JIbWVXma'), ULabel(uid='AyafKoQw'), ULabel(uid='1KPobNqK'), ULabel(uid='xHqZKcIG'), ULabel(uid='PKiCEP1h'), ULabel(uid='HRRTqARL'), ULabel(uid='e82fx2wm')
 transferred records: Artifact(uid='9BmbViqMmlVhpfS00000')
 mapped records: CellLine(uid='4oLoqaUP'), ULabel(uid='Aj8KGwbh'), ULabel(uid='EgihgpJC'), ULabel(uid='JIbWVXma'), ULabel(uid='XKI9Mx33'), ULabel(uid='CrR7fgIZ'), ULabel(uid='QrU6fxsG'), ULabel(uid='PKiCEP1h'), ULabel(uid='HRRTqARL'), ULabel(uid='e82fx2wm')
 transferred records: Artifact(uid='ThuJnRAhqkp54kyU0000')
 mapped records: CellLine(uid='4oLoqaUP'), ULabel(uid='Aj8KGwbh'), ULabel(uid='EgihgpJC'), ULabel(uid='JIbWVXma'), ULabel(uid='XKI9Mx33'), ULabel(uid='1KPobNqK'), ULabel(uid='QrU6fxsG'), ULabel(uid='PKiCEP1h'), ULabel(uid='HRRTqARL'), ULabel(uid='e82fx2wm')
 transferred records: Artifact(uid='h4EKWveW36LIzXez0000')
 mapped records: CellLine(uid='4oLoqaUP'), ULabel(uid='HK8F1lVS'), ULabel(uid='Aj8KGwbh'), ULabel(uid='EgihgpJC'), ULabel(uid='JIbWVXma'), ULabel(uid='CrR7fgIZ'), ULabel(uid='xhpmj7p7'), ULabel(uid='PKiCEP1h'), ULabel(uid='HRRTqARL'), ULabel(uid='e82fx2wm')
 transferred records: Artifact(uid='PquYNyshQTDd24Vw0000')
 mapped records: CellLine(uid='4oLoqaUP'), ULabel(uid='HK8F1lVS'), ULabel(uid='Aj8KGwbh'), ULabel(uid='EgihgpJC'), ULabel(uid='JIbWVXma'), ULabel(uid='1KPobNqK'), ULabel(uid='xhpmj7p7'), ULabel(uid='PKiCEP1h'), ULabel(uid='HRRTqARL'), ULabel(uid='e82fx2wm')
 transferred records: Artifact(uid='fdem35nw5ztUnEIM0000')
 mapped records: CellLine(uid='4oLoqaUP'), ULabel(uid='Aj8KGwbh'), ULabel(uid='EgihgpJC'), ULabel(uid='JIbWVXma'), ULabel(uid='AyafKoQw'), ULabel(uid='CrR7fgIZ'), ULabel(uid='xHqZKcIG'), ULabel(uid='PKiCEP1h'), ULabel(uid='HRRTqARL'), ULabel(uid='e82fx2wm')
 transferred records: Artifact(uid='8SFUmW0RhBNySxBO0000')
 mapped records: CellLine(uid='4oLoqaUP'), ULabel(uid='Aj8KGwbh'), ULabel(uid='EgihgpJC'), ULabel(uid='JIbWVXma'), ULabel(uid='AyafKoQw'), ULabel(uid='1KPobNqK'), ULabel(uid='xHqZKcIG'), ULabel(uid='PKiCEP1h'), ULabel(uid='HRRTqARL'), ULabel(uid='e82fx2wm')
 transferred records: Artifact(uid='VkmKLUCaMsYFCuGE0000')
 mapped records: CellLine(uid='4oLoqaUP'), ULabel(uid='Aj8KGwbh'), ULabel(uid='A2945i5P'), ULabel(uid='XKI9Mx33'), ULabel(uid='CrR7fgIZ'), ULabel(uid='QrU6fxsG'), ULabel(uid='PKiCEP1h'), ULabel(uid='HRRTqARL'), ULabel(uid='e82fx2wm')
 transferred records: Artifact(uid='OS0wBE7bviIlW7qj0000'), ULabel(uid='joRCMMWX')
 mapped records: CellLine(uid='4oLoqaUP'), ULabel(uid='Aj8KGwbh'), ULabel(uid='A2945i5P'), ULabel(uid='joRCMMWX'), ULabel(uid='XKI9Mx33'), ULabel(uid='1KPobNqK'), ULabel(uid='QrU6fxsG'), ULabel(uid='PKiCEP1h'), ULabel(uid='HRRTqARL'), ULabel(uid='e82fx2wm')
 transferred records: Artifact(uid='9ZVngbl0JUS0XdZ70000')
 mapped records: CellLine(uid='4oLoqaUP'), ULabel(uid='HK8F1lVS'), ULabel(uid='Aj8KGwbh'), ULabel(uid='A2945i5P'), ULabel(uid='joRCMMWX'), ULabel(uid='CrR7fgIZ'), ULabel(uid='xhpmj7p7'), ULabel(uid='PKiCEP1h'), ULabel(uid='HRRTqARL'), ULabel(uid='e82fx2wm')
 transferred records: Artifact(uid='ixOpuSTsyrPXdYuA0000')
 mapped records: CellLine(uid='4oLoqaUP'), ULabel(uid='HK8F1lVS'), ULabel(uid='Aj8KGwbh'), ULabel(uid='A2945i5P'), ULabel(uid='joRCMMWX'), ULabel(uid='1KPobNqK'), ULabel(uid='xhpmj7p7'), ULabel(uid='PKiCEP1h'), ULabel(uid='HRRTqARL'), ULabel(uid='e82fx2wm')
 transferred records: Artifact(uid='IzP3IAwIhmM7OORD0000')
 mapped records: CellLine(uid='4oLoqaUP'), ULabel(uid='Aj8KGwbh'), ULabel(uid='A2945i5P'), ULabel(uid='joRCMMWX'), ULabel(uid='AyafKoQw'), ULabel(uid='CrR7fgIZ'), ULabel(uid='xHqZKcIG'), ULabel(uid='PKiCEP1h'), ULabel(uid='HRRTqARL'), ULabel(uid='e82fx2wm')
 transferred records: Artifact(uid='6uMjKAk1aYlAV7Cf0000')
 mapped records: CellLine(uid='4oLoqaUP'), ULabel(uid='Aj8KGwbh'), ULabel(uid='A2945i5P'), ULabel(uid='joRCMMWX'), ULabel(uid='AyafKoQw'), ULabel(uid='1KPobNqK'), ULabel(uid='xHqZKcIG'), ULabel(uid='PKiCEP1h'), ULabel(uid='HRRTqARL'), ULabel(uid='e82fx2wm')
 transferred records: Artifact(uid='RRVS8qVx3VSw02Xu0000')
 mapped records: CellLine(uid='4oLoqaUP'), ULabel(uid='Aj8KGwbh'), ULabel(uid='EgihgpJC'), ULabel(uid='joRCMMWX'), ULabel(uid='XKI9Mx33'), ULabel(uid='CrR7fgIZ'), ULabel(uid='QrU6fxsG'), ULabel(uid='PKiCEP1h'), ULabel(uid='HRRTqARL'), ULabel(uid='e82fx2wm')
 transferred records: Artifact(uid='QDPX1ljp0eCMz80o0000')
 mapped records: CellLine(uid='4oLoqaUP'), ULabel(uid='Aj8KGwbh'), ULabel(uid='EgihgpJC'), ULabel(uid='joRCMMWX'), ULabel(uid='XKI9Mx33'), ULabel(uid='1KPobNqK'), ULabel(uid='QrU6fxsG'), ULabel(uid='PKiCEP1h'), ULabel(uid='HRRTqARL'), ULabel(uid='e82fx2wm')
 transferred records: Artifact(uid='Oww4y0yYuR8pxV9q0000')
 mapped records: CellLine(uid='4oLoqaUP'), ULabel(uid='HK8F1lVS'), ULabel(uid='Aj8KGwbh'), ULabel(uid='EgihgpJC'), ULabel(uid='joRCMMWX'), ULabel(uid='CrR7fgIZ'), ULabel(uid='xhpmj7p7'), ULabel(uid='PKiCEP1h'), ULabel(uid='HRRTqARL'), ULabel(uid='e82fx2wm')
 transferred records: Artifact(uid='Cvamog4G3a2XYGM80000')
 mapped records: CellLine(uid='4oLoqaUP'), ULabel(uid='HK8F1lVS'), ULabel(uid='Aj8KGwbh'), ULabel(uid='EgihgpJC'), ULabel(uid='joRCMMWX'), ULabel(uid='1KPobNqK'), ULabel(uid='xhpmj7p7'), ULabel(uid='PKiCEP1h'), ULabel(uid='HRRTqARL'), ULabel(uid='e82fx2wm')
 transferred records: Artifact(uid='AhBvnNKg5yJcG6LU0000')
 mapped records: CellLine(uid='4oLoqaUP'), ULabel(uid='Aj8KGwbh'), ULabel(uid='EgihgpJC'), ULabel(uid='joRCMMWX'), ULabel(uid='AyafKoQw'), ULabel(uid='CrR7fgIZ'), ULabel(uid='xHqZKcIG'), ULabel(uid='PKiCEP1h'), ULabel(uid='HRRTqARL'), ULabel(uid='e82fx2wm')
 transferred records: Artifact(uid='6uUjyphUD4D1Hixc0000')
 mapped records: CellLine(uid='4oLoqaUP'), ULabel(uid='Aj8KGwbh'), ULabel(uid='EgihgpJC'), ULabel(uid='joRCMMWX'), ULabel(uid='AyafKoQw'), ULabel(uid='1KPobNqK'), ULabel(uid='xHqZKcIG'), ULabel(uid='PKiCEP1h'), ULabel(uid='HRRTqARL'), ULabel(uid='e82fx2wm')
 transferred records: Artifact(uid='AVRTVX9gEu4LrTAP0000')
artifacts[0].describe()
Artifact .tif
├── General
│   ├── .uid = 'Md4OouMExlWS2YfZ0000'
│   ├── .key = 'input_data_imaging_usecase/images/Timepoint001_Row01_Well01_Alexa488_zstack001_r003_c005.tif'
│   ├── .size = 2333056
│   ├── .hash = '0aoXxT857VvKAGo9UQo-8g'
│   ├── .path = s3://lamin-eu-central-1/r7YUayXjktSb/.lamindb/Md4OouMExlWS2YfZ0000.tif
│   ├── .created_by = testuser1 (Test User1)
│   ├── .created_at = 2025-03-07 13:51:25
│   └── .transform = 'Transfer from `scportrait/examples`'
├── Linked features
│   └── FOV                         cat[ULabel.name]           FOV1                                     
cell_line_clone             cat[ULabel.name]           U2OS lcklip-mNeon mCherryLC3B clone 1    
channel                     cat[ULabel.name]           Alexa488                                 
genotype                    cat[ULabel.name]           WT                                       
imaged structure            cat[ULabel.name]           LckLip-mNeon                             
magnification               cat[ULabel.name]           20X                                      
microscope                  cat[ULabel.name]           Opera Phenix                             
stimulation                 cat[ULabel.name]           14h Torin-1                              
study                       cat[ULabel]                autophagy imaging                        
resolution                  float                      0.597976081                              
└── Labels
    └── .cell_lines                 bionty.CellLine            U-2 OS cell, U2OS                        
        .ulabels                    ULabel                     WT, 14h Torin-1, U2OS lcklip-mNeon mCher…

In addition, we create a Collection to hold all Artifact that belong to this specific imaging study.

collection = ln.Collection(
    artifacts,
    key="Annotated autophagy imaging raw images",
    description="annotated microscopy images of cells stained for autophagy markers",
)
collection.save()
Hide code cell output
 adding artifact ids [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49] as inputs for run 1
Collection(uid='V2RcE5dPOw6pBuuy0000', is_latest=True, key='Annotated autophagy imaging raw images', description='annotated microscopy images of cells stained for autophagy markers', hash='6L85RD5Q83sQ7ZwaNOIMNw', space_id=1, created_by_id=1, run_id=1, created_at=2025-03-31 12:44:39 UTC)

Let’s look at some example images where we match images from the same clone, stimulation condition, and FOV to ensure correct channel alignment.

FOV_example_images = (
    metadata_files.sort_values(by=["cell_line_clone", "stimulation", "FOV"])
    .head(3)
    .reset_index(drop=True)
)

fig, axs = plt.subplots(1, 3, figsize=(15, 5))
for idx, row in FOV_example_images.iterrows():
    path = ln.Artifact.using("scportrait/examples").get(key=row["image_path"]).cache()
    image = imread(path)
    axs[idx].imshow(image)
    axs[idx].set_title(f"{row['imaged structure']}")
    axs[idx].axis("off")

FOV_example_images = (
    metadata_files.sort_values(by=["cell_line_clone", "stimulation", "FOV"])
    .tail(3)
    .reset_index(drop=True)
)

fig, axs = plt.subplots(1, 3, figsize=(15, 5))
for idx, row in FOV_example_images.iterrows():
    path = ln.Artifact.using("scportrait/examples").get(key=row["image_path"]).cache()
    image = imread(path)
    axs[idx].imshow(image)
    axs[idx].set_title(f"{row['imaged structure']}")
    axs[idx].axis("off")
 completing transfer to track Artifact('jVytS8Ay') as input
 mapped records: Artifact(uid='jVytS8AyAHmHkYR30000'), CellLine(uid='4oLoqaUP'), ULabel(uid='Aj8KGwbh'), ULabel(uid='A2945i5P'), ULabel(uid='JIbWVXma'), ULabel(uid='XKI9Mx33'), ULabel(uid='CrR7fgIZ'), ULabel(uid='QrU6fxsG'), ULabel(uid='PKiCEP1h'), ULabel(uid='HRRTqARL'), ULabel(uid='e82fx2wm')
 transferred records: 
 adding artifact ids [26] as inputs for run 1, adding parent transform 2
 completing transfer to track Artifact('cw4F6bUB') as input
 mapped records: Artifact(uid='cw4F6bUB9zuMthCY0000'), CellLine(uid='4oLoqaUP'), ULabel(uid='HK8F1lVS'), ULabel(uid='Aj8KGwbh'), ULabel(uid='A2945i5P'), ULabel(uid='JIbWVXma'), ULabel(uid='CrR7fgIZ'), ULabel(uid='xhpmj7p7'), ULabel(uid='PKiCEP1h'), ULabel(uid='HRRTqARL'), ULabel(uid='e82fx2wm')
 transferred records: 
 adding artifact ids [28] as inputs for run 1, adding parent transform 2
 completing transfer to track Artifact('7TZGXvbA') as input
 mapped records: Artifact(uid='7TZGXvbA0JLL68hR0000'), CellLine(uid='4oLoqaUP'), ULabel(uid='Aj8KGwbh'), ULabel(uid='A2945i5P'), ULabel(uid='JIbWVXma'), ULabel(uid='AyafKoQw'), ULabel(uid='CrR7fgIZ'), ULabel(uid='xHqZKcIG'), ULabel(uid='PKiCEP1h'), ULabel(uid='HRRTqARL'), ULabel(uid='e82fx2wm')
 transferred records: 
 adding artifact ids [30] as inputs for run 1, adding parent transform 2
 completing transfer to track Artifact('Ov8FnKzH') as input
 mapped records: Artifact(uid='Ov8FnKzHMNY0XVJa0000'), CellLine(uid='4oLoqaUP'), ULabel(uid='9hHptuyb'), ULabel(uid='EgihgpJC'), ULabel(uid='GadMJgvN'), ULabel(uid='XKI9Mx33'), ULabel(uid='1KPobNqK'), ULabel(uid='QrU6fxsG'), ULabel(uid='PKiCEP1h'), ULabel(uid='HRRTqARL'), ULabel(uid='e82fx2wm')
 transferred records: 
 adding artifact ids [21] as inputs for run 1, adding parent transform 2
 completing transfer to track Artifact('Lwk8shsY') as input
 mapped records: Artifact(uid='Lwk8shsYe0V5bMgd0000'), CellLine(uid='4oLoqaUP'), ULabel(uid='HK8F1lVS'), ULabel(uid='9hHptuyb'), ULabel(uid='EgihgpJC'), ULabel(uid='GadMJgvN'), ULabel(uid='1KPobNqK'), ULabel(uid='xhpmj7p7'), ULabel(uid='PKiCEP1h'), ULabel(uid='HRRTqARL'), ULabel(uid='e82fx2wm')
 transferred records: 
 adding artifact ids [23] as inputs for run 1, adding parent transform 2
 completing transfer to track Artifact('YuyVn060') as input
 mapped records: Artifact(uid='YuyVn060M4FxATPz0000'), CellLine(uid='4oLoqaUP'), ULabel(uid='9hHptuyb'), ULabel(uid='EgihgpJC'), ULabel(uid='GadMJgvN'), ULabel(uid='AyafKoQw'), ULabel(uid='1KPobNqK'), ULabel(uid='xHqZKcIG'), ULabel(uid='PKiCEP1h'), ULabel(uid='HRRTqARL'), ULabel(uid='e82fx2wm')
 transferred records: 
 adding artifact ids [25] as inputs for run 1, adding parent transform 2
_images/e882e04f95fae870ff1e602447afd500a8a6a8091cc0de5e6d2b4cc1e1b621ee.png _images/f028ad5302e1ee100eb448a6b6a0c1b99b0f532ef8b0e1a10ea1144ab532119a.png
ln.finish()
Hide code cell output
 finished Run('GJwXLLhJ') after 6m at 2025-03-31 12:45:38 UTC