Bayer-Group / paquo

PAthological QUpath Obsession - QuPath and Python conversations
GNU General Public License v3.0
103 stars 16 forks source link

Are detection measurements writable? #95

Closed choosehappy closed 1 year ago

choosehappy commented 1 year ago

I want to do something like this:

alldets =[det for det in qpimg.hierarchy.detections]  #e.g., cell detection

for det in alldets:
    feat = np.random.uniform(size=(5,1)) # this would be replaced by some image analysis code to produce a feature vector
    for key,val in enumerate(feat):
        det.measurements[f'feat_{key}']=val[0] #save the feature vector back into the measurements

This looks to work:

>>>det.measurements
Measurements({'feat_0': 0.8531321287155151, 'feat_1': 0.0879729762673378, 'feat_2': 0.9763356447219849, 'feat_3': 0.29371482133865356, 'feat_4': 0.41111141443252563, 'feat_5': 0.8154646158218384})

but isn't reflected back in the project file I've opened my project in append mode:

qp=QuPathProject(projname, mode='a')

and have trie det.measurements.update(), and a series of other things, but the modification time on the project file doesn't change, and the results arent reflected in QuPath

Is this functionality there?

Thanks!

ap-- commented 1 year ago

Hi Andrew,

This is probably a bug. Can you try the following to see if it fixes the issue:

alldets = qpimg.hierarchy.detections

for det in alldets:
    feat = np.random.uniform(size=(5, 1))
    for key, val in enumerate(feat):
        det.measurements[f'feat_{key}'] = val[0]

        # manually trigger the currently missing update 
        det._update_callback(det)

If this fixes the issue for you, I will work on a patch and a new paquo release.

Cheers, Andreas

choosehappy commented 1 year ago

Hey! Long time

hmmm sorry that fix doesn't seem to work

let me put together the smallest possible package and stick it online

choosehappy commented 1 year ago

Here you go:

https://www.dropbox.com/s/m5m4dy82sv9mabq/paquo_measurement_test.7z?dl=0

choosehappy commented 1 year ago

Brief update

copying detections also doesn't result in a save

I've created a minimal version of that but unfortunately you'll need to provide your own image : )

https://www.dropbox.com/s/z7c29c7hgbm2a08/paquo_measurement_add_test.7z?dl=1

but the code is fairly straightforward:


projname='smalltestproj'
projname_out='smalltestproj_out'

import os
os.environ["PAQUO_QUPATH_DIR"] = r"C:\Users\ajanowc\AppData\Local\QuPath-0.4.3"
from tqdm.autonotebook import tqdm
import numpy as np

import paquo
from paquo.projects import QuPathProject
from paquo.images import QuPathImageType

qp=QuPathProject(projname, mode='r')
qpout=QuPathProject(projname_out, mode='a')

qpimg=qp.images[0]

qpimgout = qpout.add_image(qpimg.image_name,image_type=QuPathImageType.BRIGHTFIELD_H_E,)

alldets =[det for det in qpimg.hierarchy.detections]

for det in tqdm(alldets):
    feat = np.random.uniform(size=(5, 1))
    measurements = {f'feat_{key}':val for key,val in enumerate(feat)}
    qpimgout.hierarchy.add_detection(roi=det.roi,measurements=measurements)
ap-- commented 1 year ago

I added a test and crated a patch to fix the issue. I'll prepare a release soon.

ap-- commented 1 year ago

The new release is on its way, and will be ready when the CI finishes.

One thing I noticed: In your code you use QuPathProject without the context manager. So you might have to call qpout.save() at the end of your script.

Let me know if this solves the issue 😃

choosehappy commented 1 year ago

Yea!! That totally works, so cool, thanks!

usrsbn commented 1 year ago

Hi Andreas,

I just wanted to mention this for completeness: The above is not an issue in version 0.5.1 which I'm still running.

ap-- commented 1 year ago

@usrsbn thank you for your comment! interesting... 🤔

Could you provide an example code snippet that works for you and report your OS, python-version and qupath-version?

usrsbn commented 1 year ago

Sure. Actually it's almost the same code as Andrew's just like this:

with QuPathProject(projname, mode='r') as qp:
    with QuPathProject(projname_out, mode='a') as qpout:
        qpimg = qp.images[0]
        qpimgout = qpout.add_image(qpimg.uri.split(":")[1], image_type=QuPathImageType.BRIGHTFIELD_H_E)

        alldets = [det for det in qpimg.hierarchy.detections]

        for det in tqdm(alldets):
            feat = np.random.uniform(size=(5, 1))
            measurements = {f'feat_{key}': val for key, val in enumerate(feat)}
            qpimgout.hierarchy.add_detection(roi=det.roi, measurements=measurements)

But works also in the way he proposed above with a qpout.save()as you mentioned.

My versions are: Kubuntu 22.04 Python 3.10.6 QuPath version: 0.3.2

ap-- commented 1 year ago

@usrsbn i tried reproducing this with QuPath-0.3.2 and paquo-0.5.1 on my mac and I think when you create a new project and "update" (='create new detections with') measurements via add_image and use the contextmanager for QuPathProject, this bug does not occur.

But the bug initially described in this issue "measurements are not updated if you try to do it via the dict interface .measurements" is present: https://github.com/bayer-science-for-a-better-life/paquo/blob/8446f27011a8da6efd36cb423471eec6960d3e69/paquo/tests/test_pathobjects.py#L199-L208

The above test fails on QuPath-0.3.2 paquo-0.5.1