Improper CombineObject Merging in Cellprofiler

Hello,

I am counting cells in multiple channels (brightfield and RFP) using IdentifyPrimaryObjects for each channel and combining them into a single, larger object set using CombineObjects for further classification (live vs. dead). It seems that the CombineObjects module does not add all unique objects from the “object set to combine” to the “initial object set”–only some objects are added instead of all unique objects.

In the attached pipeline, the CombineObjects #22 does not merge ALL unique Brightfield_Filtered objects into the DeadCells objects. Some objects are merged but not others and I’m not sure what is causing this issue. Could you provide any insight into why this is occuring? I am a newer user and it’s possible I’m using the module incorrectly. I haven’t found any other topics reporting this issue.

Thank you for your time,
Matt

EdgeDetection.cpproj (84.8 KB)
H7_02_4_2_Bright Field_023.tif (7.6 MB) H7_02_2_2_RFP_023.tif (7.6 MB) H7_02_1_2_GFP_023.tif (7.6 MB)

In taking a look at this pipeline, I think there may be a bug in our CombineObjects module (IIUC the documentation correctly). CellProfiler code experts like @DStirling should probably chime in:

When I use discard, merge, or segment mode: it seems like objects from the second object set that don’t overlap with the first object are not included in the final set. These objects are included w/ preserve mode.

Discard mode w/ DeadCells as first object
Screen Shot 2021-03-04 at 11.51.00 AM

Discard mode w/ Brightfield_Filtered as first object

I don’t understand this behavior. I would predict that objects from the Second Set would only be excluded from the CombinedSet if they overlap w/ objects from the First Set. Is this a misunderstanding on my part or a bug?

I’ve been investigating this, and it is indeed a bug. When combining objects we renumber the second set to give them unique label numbers, but in this case the object arrays are typed as int8, meaning that label numbers above 127 overflow and wrap around to -128. This causes them to get lost as negative object labels aren’t valid.

This should be straightforward to fix in the next version, I just want to make sure that CellProfiler is actually supposed to be storing objects in int8 arrays - if so then we can just check the type before trying to renumber in CombineObjects.

@mposkus Thanks so much for reporting this, the attached pipeline was very helpful!

Thank you both so much for your quick responses and diagnosis! I greatly appreciate it. Do you suggest any workarounds in the meantime so I can use my pipeline? Perhaps this is something I could modify locally as to not have to wait for the next release (assuming it is a simple fix)?

Are you running from source or downloaded from the website, @mposkus ?

If from source, then sure, as soon as the changes are made you can pull them; if from built, that isn’t something I’d recommend.

If your objects are always as well separated as they are in the screenshot, my workaround would be doing this how we used to do it in the “old days” before CombineObjects, which is 1) run both object sets through ConvertObjectToImage in binary mode 2) ImageMath to add the binary images 3) a new IdentifyPrimaryObjects to find the combined object set, with declumping off if the objects are always well separated, otherwise you need to re-declump and may possibly end up with SLIGHTLY different objects than you did initially, but likely very close to the original set.

1 Like

I was running from the packaged version downloaded from the website, but now I’ve switched to source so I can update as soon as the bug fix is published. I’ll try out your workaround–thanks for the suggestion!

There is a preliminary pull request with a branch you can check out now; we still need to clean it up a bit but the functionality should work. Please let us know if it does not in your hands!

It seems to work flawlessly. Thank you (and all others involved) for resolving this issue!

1 Like