Skip to content

Conversation

@will-moore
Copy link
Member

@will-moore will-moore commented Mar 3, 2017

Script to Select Screens, Plates, or Wells and move Annotations from Images onto their parent Wells.
See https://trello.com/c/gasafKWk/291-update-script-wellsample-well-annotation-migration

To test:

  • Add a bunch of Annotations to Images in Wells. Pick some Wells that have multiple fields.
    • Add tags, ratings, map annotations, comments etc.
  • Select Screens, Plates or Wells and run script (check that selected S/P/W are populated in dialog)
  • Choose to filter annotations by Type or Namespace. (can test this using openmicroscopy.org/omero/client/mapAnnotation for Map Annotations).
  • Test "Remove Annotations" removes annotations from Images if checked.

screen shot 2017-03-03 at 14 59 17

"""Move annotations from Images in this Well onto the Well itself."""
print "Processing Well:", well.id, well.getWellPos()
iids = [wellSample.getImage().id for wellSample in well.listChildren()]
print " Image IDs:", iids
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have remove print from all other scripts.
Could you remove it

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahhhhh! The prints for scripts provide the log for the user. If you don't have any prints then they won't know what's gone wrong or won't have any "info" on what the script has done. They are essential.
At least where I've used a log() function to do the printing, it's only a case of adding back the print statement there, but for scripts with individual print statements this will be a fair bit harder.

Copy link
Member

@jburel jburel Mar 6, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for now I will follow what has been done in the export scripts i.e. log and do a print at the end if required (that could be turned into an option)
and many of those prints are not necessary
they are helpful when debugging.
We will have to review that part in another round (analyis scripts initialize a logger that is not used)


new_links = []
for l in old_links:
print " Annotation:", l.child.id.val, l.child.__class__.__name__
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same

try:
conn.getUpdateService().saveArray(new_links)
except Exception, ex:
print "Failed to create links: ", ex.message
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same. Log error instead

return 0

if remove_anns:
print "Deleting ImageAnnotation links...", link_ids
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same

to_delete = ImageAnnotationLinkI(link_id, False)
conn.getUpdateService().deleteObject(to_delete)
except Exception, ex:
print "Failed to delete links: ", ex.message
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same

return ann_total


def runScript():
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

run_script to match the formatting used in the other script


client = scripts.client(
'Move_Annotations.py',
"""Move Annotations from SPW Images to their parent Wells.""",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I won't use SPW, better to be explicit


scripts.List(
"IDs", optional=False, grouping="2",
description="List of Screen IDs or Plate IDs").ofType(rlong(0)),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

well is supported as a data_type, this need to be reflected in the description of the ids param

scripts.String(
"Annotation_Type", grouping="3",
description="Move All annotations OR just one type of annotation"
" Z below.", values=ann_types, default='All'),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's Z below?

conn = BlitzGateway(client_obj=client)

script_params = client.getInputs(unwrap=True)
print script_params
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same please remove

@jburel
Copy link
Member

jburel commented Mar 4, 2017

@jburel
Copy link
Member

jburel commented Mar 4, 2017

./omero/util_scripts/Move_Annotations.py:49:29: E128 continuation line under-indented for visual indent ./omero/util_scripts/Move_Annotations.py:123:5: N802 function name should be lowercase ./omero/util_scripts/Move_Annotations.py:184:1: E305 expected 2 blank lines after class or function definition, found 1

@jburel
Copy link
Member

jburel commented Mar 4, 2017

note that on this repo "flake8" is more "aggressive" than on the openmicroscopy repo
i.e. flake8 pycodestyle pep8-naming are installed

@mtbc
Copy link
Member

mtbc commented Mar 5, 2017

Would it be possible to avoid attempting to link when such a link already exists? Might be especially useful for trying to re-run a script after deleting old links failed.

@mtbc
Copy link
Member

mtbc commented Mar 5, 2017

If an admin runs the script would it be worth trying to preserve the ownership of the previous link?

try:
for link_id in link_ids:
to_delete = ImageAnnotationLinkI(link_id, False)
conn.getUpdateService().deleteObject(to_delete)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could delete in bulk?

@jburel
Copy link
Member

jburel commented Mar 5, 2017

@mtbc: I think we have to preserve the ownership of the links

@joshmoore
Copy link
Member

NB: This seems like code ripe for wrapping into a server-side method: "relink". cc: @mtbc

@mtbc
Copy link
Member

mtbc commented Mar 8, 2017

Certainly feasible. If it might be done enough in general to warrant server-side support, might be worth a design issue to discuss exactly what it should be able to do and what use cases should be supported.

@mtbc
Copy link
Member

mtbc commented Mar 8, 2017

I'm curious about users in read-only groups running this on others' data: what happens?

Also, can I make a plate from someone else's dataset in a read-only group? What happens then when the annotations are being moved from a same-owner link to a different-owner link (whether by the plate owner or the image owner)?

@mtbc
Copy link
Member

mtbc commented Mar 8, 2017

Would a dry-run mode be useful?

@will-moore
Copy link
Member Author

After discussion with @pwalczysko and @mtbc, we decided to only move links that you own (unless you are an Admin).
This simplifies lots of questions about whether to delete another owner's links that you have moved, how to distinguish between new links that were generated from your own links vv generated from someone else's links, whether the script should behave differently in read-write vv read-ann group etc.

Also, we now check for existing links, so we should avoid ValidationExceptions (e.g. if you run the script twice without removing annotations).

@pwalczysko
Copy link
Member

pwalczysko commented Mar 9, 2017

Remove Annotations --> Remove Annotations from Images (first thought this would mean completely remove all annotations and do nothing else (i.e. do not add them to wells). If you add ...from Images than it is clearer you are not talking about complete wipeout of the annotations.

@pwalczysko
Copy link
Member

RFE: put some helpful icons into activities which would lead you to the well with the freshly attached annotations (just like for the other scripts).
screen shot 2017-03-09 at 12 29 51

@pwalczysko
Copy link
Member

pwalczysko commented Mar 9, 2017

I don't think that this box should be ticked by default.
screen shot 2017-03-09 at 13 24 13

Especially considering that you can re-run the script a second time with the same settings, only ticking the box and the annotations will still be removed from the images.

Thus, the user will be hopefully inclined to run the script the first time, not deleting anything, when they are happy and have checked, they might want to run the script the second time with the box ticked.

@will-moore
Copy link
Member Author

@jburel What do you think to @pwalczysko's suggestion that "Remove Annotations" should not be checked by default?

@jburel
Copy link
Member

jburel commented Mar 9, 2017

I will agree with @pwalczysko
since we have moving towards "dry-run" for all actions, I will say not ticked by default too

@pwalczysko
Copy link
Member

pwalczysko commented Mar 9, 2017

Tested up till now:

  • work on my own data ony
    - checked all types of annotations (Tables are not an annotation in true sense, not tested as there is no object in the back end to manipulate)
    - checked the checkbox "Remove annotations"
    - checked filtering for Map Annotations (namespace and Type)
    - checked selecting Well and Plate (it does all wells in that Plate)
    - ToDo: Check selecting Screen with multiple Plates

  • ToDo: work as an admin on other's data (expected behaviour is: all the new links belong to the owners of the corresponding original links)

  • ToDo: work on your own data, but with somebody else annotating them as well (expected behaviour is: only your own links will be transferred, the other user's links will be left as they are)

@dominikl
Copy link
Member

dominikl commented Mar 9, 2017

Looks good, tested (locally) with Screen, Plate and Well <-> Tags, Map, File, Rating, Comment. Only own annotations get moved, unless run as admin (in which case original ownership is preserved) 👍

'File': 'FileAnnotationI',
'Comment': 'CommentAnnotationI',
'Rating': 'LongAnnotationI',
'Key-Value': 'MapAnnotationI'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This subset is basically those that the web UI will usefully display for wells?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. My assumption is that users who have added annotations via their own scripts / clients will either have given them a useful namespace that can be used to select them in the Move_Annotations script OR they can also write their own script (or update this one) to customise the task.
Although I could add extra types here, I think this adds extra complexity for users and more testing for us which is probably not justified at this stage.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair enough, thank you.


scripts.String(
"Annotation_Type", grouping="3",
description="Move All annotations OR just one type of annotation",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is "All" capitalized?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ooops - getting a touch of Title Case here. https://medium.com/@jsaito/making-a-case-for-letter-case-19d09f653c98#.h1s476nc6. I'll fix...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess it's because "All" is an option in the dropdown list

@pwalczysko
Copy link
Member

Retest in UI went fine, finished all the ToDo's from #134 (comment) as well as checked the new label on the checkbox Remove.... and the new navigation tool in the activities, which works fine.

Ready to merge after the questions of @mtbc are answered.

@will-moore
Copy link
Member Author

NB: I still need to finish the integration test for this script, and also add support for linking to Wells from the 'Browse' button in the Activities panel.

@jburel
Copy link
Member

jburel commented Mar 13, 2017

one RFE: Support for plate acquisition in the type

try:
for link_id in link_ids:
to_delete = ImageAnnotationLinkI(link_id, False)
conn.getUpdateService().deleteObject(to_delete)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you should not use the deprecated method, use delete2 instead

@jburel
Copy link
Member

jburel commented Mar 14, 2017

./omero/util_scripts/Move_Annotations.py:24:1: F401 'omero.model.ImageAnnotationLinkI' imported but unused

@jburel
Copy link
Member

jburel commented Mar 15, 2017

https://trello.com/c/TNJk38iN/36-move-annotation-rfe to capture suggestions

@jburel
Copy link
Member

jburel commented Mar 16, 2017

Thanks for making the changes.
2 failures with the test currently

@jburel jburel merged commit 4994916 into ome:develop Mar 17, 2017
@jburel jburel added this to the 5.3.0 milestone Mar 29, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants