-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Overwriting images and annotations #25
Comments
You would like a method that would do something like the following? import fr.igred.omero.Client
import fr.igred.omero.repository.ImageWrapper;
import fr.igred.omero.repository.DatasetWrapper;
import fr.igred.omero.annotations.TagAnnotationWrapper;
import fr.igred.omero.annotations.FileAnnotationWrapper;
import fr.igred.omero.annotations.TableWrapper;
import fr.igred.omero.roi.ROIWrapper;
Client client = new Client();
client.connect(host, port, username, password.toCharArray(), group);
DatasetWrapper dataset = client.getDataset(datasetId);
List<Long> ids = dataset.importImage(client, path);
Long[] newIds = ids.stream().toArray(Long[]::new);
List<ImageWrapper> newImages = client.getImages(newIds);
for(ImageWrapper image : newImages) {
List<ImageWrapper> oldImages = dataset.getImages(client, image.getName());
if(!oldImages.isEmpty()) {
ImageWrapper oldImage = oldImages.get(0);
String description = oldImage.getDescription();
List<TableWrapper> tables = oldImage.getTables(client);
List<TagAnnotationWrapper> tags = oldImage.getTags(client);
List<ROIWrapper> rois = oldImage.getROIs(client);
//List<FileAnnotationWrapper> files = oldImage.getFileAnnotations(client);
//List<MapAnnotationWrapper> kvPairs = oldImage.getMapAnnotations(client);
image.setDescription(description);
image.saveAndUpdate(client);
for(TableWrapper table : tables) image.addTable(client, table);
for(TagAnnotationWrapper tag : tags) image.addTag(client, tag);
for(ROIWrapper roi : rois) image.saveROI(client, roi);
// for(FileAnnotationWrapper file : files) image.addFileAnnotation(client, file);
// for(MapAnnotationWrapper kvPair : kvPairs) image.addMapAnnotation(client, kvPair);
// Missing methods: addFileAnnotation, getMapAnnotations
client.delete(oldImage);
}
}
client.disconnect(); Currently, I think 2 methods are missing to do that, but it should be easily fixed. However, the code above has one very obvious limitation: how do you handle the case where multiple images share the same name in the dataset? In this snippet, I chose to only replace the first image found with the same name, but should it always be like that? |
Hi, |
Ok, that's what I thought, and the code above should do that. With this branch, replacing images could be done with something as simple as: import fr.igred.omero.Client
import fr.igred.omero.repository.ImageWrapper;
import fr.igred.omero.repository.DatasetWrapper;
import fr.igred.omero.roi.ROIWrapper;
Client client = new Client();
client.connect(host, port, username, password.toCharArray(), group);
DatasetWrapper dataset = client.getDataset(datasetId);
List<Long> ids = dataset.importImage(client, path);
Long[] newIds = ids.stream().toArray(Long[]::new);
List<ImageWrapper> newImages = client.getImages(newIds);
for(ImageWrapper image : newImages) {
List<ImageWrapper> oldImages = dataset.getImages(client, image.getName());
if(!oldImages.isEmpty()) {
ImageWrapper oldImage = oldImages.get(0);
String description = oldImage.getDescription();
image.setDescription(description);
image.saveAndUpdate(client);
image.copyAnnotations(client, oldImage);
List<ROIWrapper> rois = oldImage.getROIs(client);
for(ROIWrapper roi : rois) image.saveROI(client, roi);
client.delete(oldImage);
}
}
client.disconnect(); Before pulling this to the main branch, I'll have to do some tests, and maybe I'll make a specific method for images to copy description, annotations and ROIs at once. However, as I said, I'm not sure I can make a method to replace on import as the policy for this could vary from person to person: some people may want to replace all the previous images with the same name and copy all the annotations to the new image before deleting all the older ones, others may prefer to only copy data from the first image with the same name (as the code above does). If I make a function to reduce this "replace on import" to the following, would it be sufficient? import fr.igred.omero.Client
import fr.igred.omero.repository.ImageWrapper;
import fr.igred.omero.repository.DatasetWrapper;
import fr.igred.omero.roi.ROIWrapper;
Client client = new Client();
client.connect(host, port, username, password.toCharArray(), group);
DatasetWrapper dataset = client.getDataset(datasetId);
List<Long> ids = dataset.importImage(client, path);
Long[] newIds = ids.stream().toArray(Long[]::new);
List<ImageWrapper> newImages = client.getImages(newIds);
for(ImageWrapper image : newImages) {
List<ImageWrapper> oldImages = dataset.getImages(client, image.getName());
if(!oldImages.isEmpty()) {
ImageWrapper oldImage = oldImages.get(0);
image.copy(client, oldImage);
client.delete(oldImage);
}
}
client.disconnect(); Edit: |
Actually, maybe replacing ALL the images (in the dataset) that share the same name would satisfy your needs.
|
Hi, I guess it should be the same for annotations like attachments. |
* Bump version * Add methods to retrieve/add/copy annotations from/to a repository object * Add method to retrieve images from project, dataset and image name (see #24) * Add method to import file and replace images in dataset (see #25) * Add tests * Fix table name missing from getTable * Fix default namespace for MapAnnotations * Fix redundant annotations being copied
Ok. I thought PR #26 would solve this, but I forgot to include a way to replace file annotations. Moreover, the I think images that are replaced should only be "unlinked", because:
Unlinking and then only deleting if every image from the fileset is orphaned should be possible, although I haven't tried yet. For attachments, unlinking is easy too while deleting poses a similar problem: an attachment could be used by a different object somewhere else. It is a bit harder though: currently, I'm not sure how to get the number of objects linked to an annotation, besides going in HQL through every *AnnotationLink table (which is not pretty). Also, I may rename |
Yes an |
The last commit I made included a method only called "replace" which provided a boolean option to specify if the data should be unlinked or deleted.
And maybe offer a default method with less arguments that only unlinks objects. |
* Add methods to ImageWrapper: isOrphaned and getFilesetImages * Add method to count links from annotations * Add method to replace attachments * Add argument to determine if images should be deleted when replaced * Add methods to delete multiple objects at once * Add method to get images from a project using the datasets names and the images names * Add method GenericObjectWrapper#distinct to filter collections and keep distinct objects * Replace lists of unknown capacity by lists of lists and flatmap * Add tests * Refactor code to create/remove files in tests * Improve Javadoc * Replace color concatenation in tests logs by String#format() * Minor code improvements
@mcib3d Ok. I made methods to import and replace images or attachements.
If it's good for you, I can release the 5.9.1 version with these modifications. |
Hi @ppouchin , |
And maybe |
When a method is called without the policy argument, objects are only "unlinked", I guess that's the behavior you're expecting. One possible limitation that exists though is that annotation links are copied from the old images, but not removed from them, and that includes map annotations (key/value pairs). Therefore editing a value on the new image will be reflected on the old one. |
Solved with the release of 5.9.1. |
Hi,
When importing images with similar names in OMERO, there will be multiple images with the same name. One possibility is to delete the image with same name before importing.
Maybe an option "overwrite" could be welcome when importing images and adding annotations ?
Thanks.
The text was updated successfully, but these errors were encountered: