Reduce annotations-invasion assay/tumor margins

Hi, I have used the following method ( to score postively stained lymphocytes in the different regions. (Many thanks for providing me with the script! It worked very well)

I am wondering if I can reduce the annotation tumor center border (black) with 500µm whereby my tumor will consist out of several bands of 500µm in width without having to repeat the cell dedetection/classification steps? Thus further subdividing the tumor center in 500 µm bands, and assess the numer of positive and negative cells in eacht band. Hereby I can check if there is a gradient in the positivity of the cells in each band.

Thanks in advance!
Kind regards,

You should be able to handle smaller regions much more easily. Just type in a negative number in the Expand Annotations function:
Unlike the expanding annotations, it doesn’t need to play any coding tricks to remove the interior. Keep selecting the new annotation and run as many times as you want.

Note that it will make any holes in the annotation smaller as well!

If you want separated regions, though, for counting, You will want to use Pete’s script, but make your first, central annotation first. So use the above command to create a -1500um annotation, and then expand outward 3 times from there using the script.

As @Research_Associate writers, you can expand with a negative value (i.e. contract/erode). Note that in v0.2.0-m2 this should work better/faster than before…

There is also a new experimental command Analyze → Calculate features → Distance to annotations (experimental) that you might want to explore at some point. This should calculate the distance between the centroid of any cell and any classified annotations.

(I haven’t had time to document all the new things yet… that one is also sufficiently recent to be in m2 but not m1…)

Yes, that has been so nice! Already found a few people interested in using that, especially once you create an inverse annotation and then select THAT annotation to find the distance from the surface of the tumor/islet/etc.

Good! I’m still wondering if ‘inside’ distances should be negative values representing the distance to the boundary, rather than 0…

Either. Include a checkbox!

Thank you both for the info!

I have an additional question, I have used the Expand Annotations function, but as you can see on the picture I am working with “cut” of the stumor. Is it possible to create a “bands” as marked in the second pitcture


I have nothing for that one.

I modified the create annotations plugin to first create the the outer margin and then create the inner margin from expanding the outer margin and intercepting it on the original annotation. That way I got rid of inner margin in the borders when no outer margin was present. This is a bit computation heavy, but I see no reason why it should not work to nest several such steps within each other.

1 Like

Correction, I have a super hacky and currently manual process. It is entirely possible that it is scriptable, but I will hold off on looking into that until I am sure I have the result down.

More or less my starting region, with a whitespace border.
To begin with, I create an inverse annotation to my region of interest, and then delete the original region of interest. If you are using 0.2.0 you do not need to delete the region of interest as you can CTRL+SHIFT draw inside of locked annotations.

With the only the inverse annotation left, I can CTRL+SHIFT brush tool an edge to the annotation where I want it to be considered for the expansion. Be as careful as you like with this part, I clearly was not!

Once done with the drawing, Select the outer, inverse region, and make inverse again. This restores the original region that was outlined. Select the hand-drawn thin strip of region, and expand it. Select the expansion and expand it again. Repeat as needed.

Use this script to split your annotations into contiguous parts, which will result in a lot of duplicate annotations. Delete the duplicates.

And that is what I ended up with. You would definitely want to be a bit more careful than I was with the first annotation.

Another way I thought of doing this afterwards might be more programmatic in the future. I made a 10um expansion on the original annotation, eliminated the whitespace part of the expansion, and then did another 1um expansion to get an inner rim. I duplicated the original annotation then intersected the duplicate with the 1um expansion, which resulted in:

Which sounds very much like what Tkilvaer just posted! Only it wasn’t within the parent annotation, so I’ll need to look into that.

Actually, correction, Tkilvaer’s idea should work better, just using the intersect for the whole process!

Ok, even better. Here is a script that I think, so far, does what you are looking for.


Important parts about the script:

  1. Do have a simple tissue detection made to limit the borders.
  2. Make an inverse area, delete the original tissue, and use CTRL+SHIFT BRUSH TOOL ONLY to create the border of your tumor touching the simple tissue detection edge. You can use the wand tool for the interior of the tumor, but any little pixel that is missed by the wand tool defining the whitespace border of the tumor will result in an expansion. Brush tool them all away.
  3. Invert the inverted tissue detection to get the original tissue back, and then delete the inverted annotation.
  4. Have fun. You may want to play with the coloring or naming around line 115.
1 Like

Many thanks! I tried it on one of my images but I get an error (Error at line 102:…) when running the script.
But maybe I did something wrong.
I tried the script on already analyzed images (cell detection, classification of cells within the tumor border). I have made an inverse annotation of my tumor border, deleted the orginal tumor border annotation, used to brushing tool to create interiour border of the tumor. And then I have inverted the inversed one again and I got my original tumor border back. I have deleted the inverted annotation. Then I selected the ‘new’ orginal tumor border and run the script.

Can you help me?

What is the error?

Also, I think you might have followed slightly different steps. I created an inverse annotation to the whole tissue annotation first, and used that to create the tumor annotation. So you also need to make sure you uninvert the whole tissue annotation. The script expects:

  1. Your tumor annotation to be selected
  2. A whole tissue annotation (with the Tumor as a child annotation) to use as the “edge” in order to avoid expanding into whitespace.

I have not yet tried it out with cells already existing, will check to see if that causes problems a bit later, have to run :slight_smile:

And just to check, it did seem to work with cell detection already existing.

For clarity, just before you run the script, your setup should look like this, roughly:

The full tissue annotation creates the boundary for the different layers, and the second annotation (with the cells) is the tumor. The tumor annotation border is completely pressed up against the annotation defining the edge of the tissue.

Updated this script based on code from @Tkilvaer so that it works for both 0.2.0m2 and previous versions.

Now updated for M6 and includes a central or “remaining tumor” area.