Skip to content

Commit

Permalink
Add code to retrieve kv-pairs
Browse files Browse the repository at this point in the history
  • Loading branch information
ppouchin committed Oct 22, 2024
1 parent e794738 commit 679558c
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 27 deletions.
8 changes: 8 additions & 0 deletions .omeroci/test-data
Original file line number Diff line number Diff line change
Expand Up @@ -126,3 +126,11 @@ MAP2=$(omero obj new MapAnnotation)
omero obj map-set "$MAP2" mapValue testKey1 testValue2
omero obj map-set "$MAP2" mapValue testKey2 30
omero obj new ImageAnnotationLink parent="$IMAGE2" child="$MAP2"

MAP3=$(omero obj new MapAnnotation)
omero obj map-set "$MAP3" mapValue key value
omero obj new ProjectAnnotationLink parent="$PROJECT2" child="$MAP3"
omero obj new DatasetAnnotationLink parent="$DATASET3" child="$MAP3"
omero obj new ScreenAnnotationLink parent="$SCREEN1" child="$MAP3"
omero obj new PlateAnnotationLink parent="$PLATE1" child="$MAP3"
omero obj new WellAnnotationLink parent="Well:1" child="$MAP3"
112 changes: 90 additions & 22 deletions src/main/java/fr/igred/ij/plugin/OMEROMacroExtension.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@

import fr.igred.omero.Client;
import fr.igred.omero.GenericObjectWrapper;
import fr.igred.omero.annotations.GenericAnnotationWrapper;
import fr.igred.omero.annotations.MapAnnotationWrapper;
import fr.igred.omero.annotations.TableWrapper;
import fr.igred.omero.annotations.TagAnnotationWrapper;
import fr.igred.omero.exception.AccessException;
Expand Down Expand Up @@ -82,6 +84,7 @@ public class OMEROMacroExtension implements PlugIn, MacroExtension {
private static final String PLATE = "plate";
private static final String WELL = "well";
private static final String TAG = "tag";
private static final String MAP = "kv-pair";
private static final String INVALID = "Invalid type";

private static final String ERROR_POSSIBLE_VALUES = "%s: %s. Possible values are: %s";
Expand Down Expand Up @@ -309,6 +312,12 @@ private GenericObjectWrapper<?> getObject(String type, long id) {
} catch (OMEROServerError | ServiceException e) {
IJ.error("Could not retrieve tag: " + e.getMessage());
}
} else if (MAP.equals(singularType)) {
try {
object = client.getMapAnnotation(id);
} catch (ServiceException | ExecutionException | AccessException e) {
IJ.error("Could not retrieve tag: " + e.getMessage());
}
} else {
object = getRepositoryObject(type, id);
}
Expand Down Expand Up @@ -361,35 +370,35 @@ private GenericRepositoryObjectWrapper<?> getRepositoryObject(String type, long
/**
* Lists the objects of the specified type linked to a tag.
*
* @param type The object type.
* @param id The tag id.
* @param type The object type.
* @param annotation The annotation.
*
* @return A list of GenericObjectWrappers.
*/
private List<? extends GenericObjectWrapper<?>> listForTag(String type, long id)
private List<? extends GenericObjectWrapper<?>> listForAnnotation(String type,
GenericAnnotationWrapper<?> annotation)
throws ServiceException, OMEROServerError, AccessException, ExecutionException {
String singularType = singularType(type);

List<? extends GenericObjectWrapper<?>> objects = new ArrayList<>(0);
TagAnnotationWrapper tag = client.getTag(id);
switch (singularType) {
case PROJECT:
objects = tag.getProjects(client);
objects = annotation.getProjects(client);
break;
case DATASET:
objects = tag.getDatasets(client);
objects = annotation.getDatasets(client);
break;
case IMAGE:
objects = tag.getImages(client);
objects = annotation.getImages(client);
break;
case SCREEN:
objects = tag.getScreens(client);
objects = annotation.getScreens(client);
break;
case PLATE:
objects = tag.getPlates(client);
objects = annotation.getPlates(client);
break;
case WELL:
objects = tag.getWells(client);
objects = annotation.getWells(client);
break;
default:
String msg = String.format(ERROR_POSSIBLE_VALUES,
Expand Down Expand Up @@ -425,8 +434,11 @@ private List<? extends GenericObjectWrapper<?>> listForProject(String type, long
case TAG:
objects = project.getTags(client);
break;
case MAP:
objects = project.getMapAnnotations(client);
break;
default:
IJ.error(String.format(ERROR_POSSIBLE_VALUES, INVALID, type, "datasets, images or tags."));
IJ.error(String.format(ERROR_POSSIBLE_VALUES, INVALID, type, "datasets, images, tags or kv-pairs."));
}
return objects;
}
Expand All @@ -453,8 +465,11 @@ private List<? extends GenericObjectWrapper<?>> listForDataset(String type, long
case TAG:
objects = dataset.getTags(client);
break;
case MAP:
objects = dataset.getMapAnnotations(client);
break;
default:
IJ.error(String.format(ERROR_POSSIBLE_VALUES, INVALID, type, "images or tags."));
IJ.error(String.format(ERROR_POSSIBLE_VALUES, INVALID, type, "images, tags or kv-pairs."));
}
return objects;
}
Expand Down Expand Up @@ -488,8 +503,11 @@ private List<? extends GenericObjectWrapper<?>> listForScreen(String type, long
case TAG:
objects = screen.getTags(client);
break;
case MAP:
objects = screen.getMapAnnotations(client);
break;
default:
IJ.error(String.format(ERROR_POSSIBLE_VALUES, INVALID, type, "plates, wells, images or tags."));
IJ.error(String.format(ERROR_POSSIBLE_VALUES, INVALID, type, "plates, wells, images, tags or kv-pairs."));
}
return objects;
}
Expand Down Expand Up @@ -520,8 +538,11 @@ private List<? extends GenericObjectWrapper<?>> listForPlate(String type, long i
case TAG:
objects = plate.getTags(client);
break;
case MAP:
objects = plate.getMapAnnotations(client);
break;
default:
IJ.error(String.format(ERROR_POSSIBLE_VALUES, INVALID, type, "wells, images or tags."));
IJ.error(String.format(ERROR_POSSIBLE_VALUES, INVALID, type, "wells, images, tags or kv-pairs."));
}
return objects;
}
Expand Down Expand Up @@ -549,8 +570,11 @@ private List<? extends GenericObjectWrapper<?>> listForWell(String type, long id
case TAG:
objects = well.getTags(client);
break;
case MAP:
objects = well.getMapAnnotations(client);
break;
default:
IJ.error(String.format(ERROR_POSSIBLE_VALUES, INVALID, type, "images or tags."));
IJ.error(String.format(ERROR_POSSIBLE_VALUES, INVALID, type, "images, tags or kv-pairs."));
break;
}
return objects;
Expand Down Expand Up @@ -941,6 +965,10 @@ public String list(String type) {
List<TagAnnotationWrapper> tags = client.getTags();
results = listToIDs(filterUser(tags));
break;
case MAP:
List<MapAnnotationWrapper> maps = client.getMapAnnotations();
results = listToIDs(filterUser(maps));
break;
default:
String msg = String.format(ERROR_POSSIBLE_VALUES, INVALID, type,
"projects, datasets, images, screens, plates, wells or tags.");
Expand Down Expand Up @@ -998,6 +1026,10 @@ public String list(String type, String name) {
List<TagAnnotationWrapper> tags = client.getTags(name);
results = listToIDs(filterUser(tags));
break;
case MAP:
List<MapAnnotationWrapper> maps = client.getMapAnnotations(name);
results = listToIDs(filterUser(maps));
break;
default:
String msg = String.format(ERROR_POSSIBLE_VALUES, INVALID, type,
"projects, datasets, images, screens, plates, wells or tags.");
Expand Down Expand Up @@ -1031,8 +1063,13 @@ public String list(String type, String parent, long id) {
case DATASET:
objects = listForDataset(type, id);
break;
case MAP:
MapAnnotationWrapper map = client.getMapAnnotation(id);
objects = listForAnnotation(type, map);
break;
case TAG:
objects = listForTag(type, id);
TagAnnotationWrapper tag = client.getTag(id);
objects = listForAnnotation(type, tag);
break;
case SCREEN:
objects = listForScreen(type, id);
Expand Down Expand Up @@ -1107,16 +1144,28 @@ public void link(String type1, long id1, String type2, long id2) {
Long datasetId = map.get(DATASET);
Long imageId = map.get(IMAGE);
Long tagId = map.get(TAG);
Long mapId = map.get(MAP);

if (tagId != null && mapId != null) {
IJ.error(String.format("Cannot link %s and %s", type1, type2));
}

try {
// Link tag to repository object
// Link annotation to repository object
if (TAG.equals(t1) ^ TAG.equals(t2)) {
String obj = TAG.equals(t1) ? t2 : t1;

GenericRepositoryObjectWrapper<?> object = getRepositoryObject(obj, map.get(obj));
if (object != null) {
object.addTag(client, tagId);
}
} else if (MAP.equals(t1) ^ MAP.equals(t2)) {
String obj = MAP.equals(t1) ? t2 : t1;

GenericRepositoryObjectWrapper<?> object = getRepositoryObject(obj, map.get(obj));
if (object != null) {
object.link(client, client.getMapAnnotation(mapId));
}
} else if (datasetId == null || (projectId == null && imageId == null)) {
IJ.error(String.format("Cannot link %s and %s", type1, type2));
} else { // Or link dataset to image or project
Expand Down Expand Up @@ -1153,25 +1202,38 @@ public void unlink(String type1, long id1, String type2, long id2) {
Long datasetId = map.get(DATASET);
Long imageId = map.get(IMAGE);
Long tagId = map.get(TAG);
Long mapId = map.get(MAP);

boolean linkAnnotations = tagId != null && mapId != null;
boolean tagObject = TAG.equals(t1) ^ TAG.equals(t2) && !linkAnnotations;
boolean mapObject = MAP.equals(t1) ^ MAP.equals(t2) && !linkAnnotations;
boolean linkDataset = datasetId != null && (projectId != null || imageId != null);

try {
// Unlink tag from repository object
if (TAG.equals(t1) ^ TAG.equals(t2)) {
// Unlink annotation from repository object
if (tagObject) {
String obj = TAG.equals(t1) ? t2 : t1;

GenericRepositoryObjectWrapper<?> object = getRepositoryObject(obj, map.get(obj));
if (object != null) {
object.unlink(client, client.getTag(tagId));
}
} else if (datasetId == null || (projectId == null && imageId == null)) {
IJ.error(String.format("Cannot unlink %s and %s", type1, type2));
} else { // Or unlink dataset from image or project
} else if (mapObject) {
String obj = MAP.equals(t1) ? t2 : t1;

GenericRepositoryObjectWrapper<?> object = getRepositoryObject(obj, map.get(obj));
if (object != null) {
object.unlink(client, client.getMapAnnotation(mapId));
}
} else if (linkDataset) { // Or unlink dataset from image or project
DatasetWrapper dataset = client.getDataset(datasetId);
if (projectId != null) {
client.getProject(projectId).removeDataset(client, dataset);
} else {
dataset.removeImage(client, client.getImage(imageId));
}
} else {
IJ.error(String.format("Cannot unlink %s and %s", type1, type2));
}
} catch (ServiceException | AccessException | ExecutionException | OMEROServerError e) {
IJ.error(String.format("Cannot unlink %s and %s: %s", type1, type2, e.getMessage()));
Expand All @@ -1198,6 +1260,12 @@ public String getName(String type, long id) {
name = ((GenericRepositoryObjectWrapper<?>) object).getName();
} else if (object instanceof TagAnnotationWrapper) {
name = ((TagAnnotationWrapper) object).getName();
} else if (object instanceof MapAnnotationWrapper) {
MapAnnotationWrapper map = (MapAnnotationWrapper) object;
name = map.getContentAsEntryList()
.stream()
.map(e -> e.getKey() + "\t" + e.getValue())
.collect(Collectors.joining(String.format("%n")));
}
return name;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@ void testListInvalidArgs() {
"hello;plate;2",
"hello;well;2",
"hello;tag;2",
"hello;kv-pair;2",
"hello;TestDatasetImport;",
"hello;;",})
void testListInvalidType(String type1, String type2, Double id) {
Expand Down
28 changes: 23 additions & 5 deletions src/test/java/fr/igred/ij/plugin/OMEROExtensionTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,9 @@ void testListForUser(String user, double output) {
"list;plates;1,2,3",
"list;wells;1,2,3,4,5",
"list;tags;1,2,3",
"list;tag;1,2,3",})
"list;tag;1,2,3",
"list;kv-pairs;4,5,6",
"list;kv-pair;4,5,6",})
void testListAll(String extension, String type, String output) {
Object[] args = {type, null, null};
String result = ext.handleExtension(extension, args);
Expand All @@ -135,7 +137,9 @@ void testListAll(String extension, String type, String output) {
"list;screen;TestScreen;1",
"list;plate;Plate Name 0;1,2",
"list;tags;tag2;2",
"list;tag;tag2;2",})
"list;tag;tag2;2",
"list;kv-pairs;testKey1;4,5",
"list;kv-pair;testKey1;4,5",})
void testListByName(String extension, String type, String name, String output) {
Object[] args = {type, name, null};
String result = ext.handleExtension(extension, args);
Expand All @@ -161,9 +165,16 @@ void testListByName(String extension, String type, String name, String output) {
"list;screens;tag;1.0;1",
"list;plates;tag;1.0;1",
"list;wells;tag;1.0;1",
"list;tags;project;2.0;1",
"list;tags;dataset;3.0;1",
"list;tags;screen;1.0;1",
"list;tags;plate;1.0;1",
"list;tags;well;1.0;1",
"list;kv-pairs;project;2.0;6",
"list;kv-pairs;dataset;3.0;6",
"list;kv-pairs;screen;1.0;6",
"list;kv-pairs;plate;1.0;6",
"list;kv-pairs;well;1.0;6",
"list;plates;screen;2.0;2,3",
"list;wells;screen;2.0;2,3,4,5",
"list;images;screen;1.0;5,6",
Expand All @@ -174,7 +185,8 @@ void testListFrom(String extension, String type, String parent, double id, Strin
Object[] args = {type, parent, id};
String result = ext.handleExtension(extension, args);

String sortedIds = Arrays.stream(result.split(",")).map(Long::parseLong).sorted()
String sortedIds = Arrays.stream(result.split(","))
.map(Long::parseLong).sorted()
.map(String::valueOf)
.collect(Collectors.joining(","));

Expand All @@ -192,7 +204,8 @@ void testListFrom(String extension, String type, String parent, double id, Strin
"getName;screen;1.0;TestScreen",
"getName;plate;2.0;Plate Name 0",
"getName;well;1.0;Well A-1",
"getName;tag;1.0;tag1",})
"getName;tag;1.0;tag1",
"getName;kv-pair;6.0;key\tvalue",})
void testGetName(String extension, String type, double id, String output) {
Object[] args = {type, id};
String result = ext.handleExtension(extension, args);
Expand Down Expand Up @@ -239,11 +252,16 @@ void testCreateAndLinkTag() {


@ParameterizedTest
@CsvSource(delimiter = ';', value = {"tag;1.0;project;2.0",
@CsvSource(delimiter = ';', value = {"project;2.0;tag;1.0",
"tag;1.0;dataset;3.0",
"tag;1.0;screen;1.0",
"tag;1.0;plate;1.0",
"tag;1.0;well;1.0",
"project;2.0;kv-pair;6.0",
"kv-pair;6.0;dataset;3.0",
"kv-pair;6.0;screen;1.0",
"kv-pair;6.0;plate;1.0",
"kv-pair;6.0;well;1.0",
"dataset;3.0;project;2.0",
"image;1.0;dataset;1.0",})
void testUnlinkThenLink(String type1, double id1, String type2, double id2) {
Expand Down

0 comments on commit 679558c

Please sign in to comment.