From 116c70e936c2387ab0df68adcc86fd4d15410676 Mon Sep 17 00:00:00 2001 From: Tom Burke Date: Wed, 6 Apr 2022 11:33:21 +0200 Subject: [PATCH 1/7] Rewrite to json from bson Change to API, removal of most class arguments. Removal of bson/mongo dep, add gson dep. Update to tests --- labeling.iml | 2 +- pom.xml | 10 +- .../labeling/DefaultLabelingIOService.java | 338 +++++++------- .../imglib2/labeling/LabelingIOService.java | 59 +-- .../labeling/codecs/ImgLabelingCodec.java | 410 ----------------- .../labeling/codecs/LabelingMappingCodec.java | 424 ------------------ .../labeling/data/ImgLabelingContainer.java | 70 --- .../labeling/data/LabelingContainer.java | 89 ---- .../imglib2/labeling/data/LabelingData.java | 95 ++++ .../imglib2/labeling/utils/LabelingUtil.java | 15 +- .../net/imglib2/labeling/LabelingIOTest.java | 103 ++--- .../labeling/tutorials/E01_LoadLabeling.java | 30 +- .../labeling/tutorials/E02_SaveLabeling.java | 7 +- .../labeling/tutorials/ExampleCodec.java | 67 --- src/test/resources/labeling/example1.bson | Bin 421 -> 0 bytes src/test/resources/labeling/example1.tif | Bin 198 -> 0 bytes src/test/resources/labeling/example1_sav.bson | Bin 325 -> 0 bytes .../resources/labeling/example1_sav.lbl.json | 1 + src/test/resources/labeling/example1_sav.tif | Bin 1447 -> 1852 bytes .../labeling/labelSaveTestComplex.bson | Bin 342 -> 0 bytes .../labeling/labelSaveTestComplex.lbl.json | 1 + .../labeling/labelSaveTestComplex.tif | Bin 549 -> 769 bytes .../labelSaveTestComplexFunction.bson | Bin 269 -> 0 bytes .../labeling/labelSaveTestComplexFunction.tif | Bin 571 -> 0 bytes .../labeling/labelSaveTestSimple.bson | Bin 236 -> 0 bytes .../labeling/labelSaveTestSimple.lbl.json | 1 + .../labeling/labelSaveTestSimple.tif | Bin 456 -> 438 bytes .../labeling/labelSaveTestSimpleMeta.lbl.json | 1 + .../labeling/labelSaveTestSimpleMeta.tif | Bin 0 -> 426 bytes src/test/resources/labeling/test.lbl.json | 1 + src/test/resources/labeling/test.tif | Bin 0 -> 198 bytes src/test/resources/labeling/test2.lbl.json | 1 + src/test/resources/labeling/test2.tif | Bin 0 -> 807 bytes 33 files changed, 329 insertions(+), 1396 deletions(-) delete mode 100644 src/main/java/net/imglib2/labeling/codecs/ImgLabelingCodec.java delete mode 100644 src/main/java/net/imglib2/labeling/codecs/LabelingMappingCodec.java delete mode 100644 src/main/java/net/imglib2/labeling/data/ImgLabelingContainer.java delete mode 100644 src/main/java/net/imglib2/labeling/data/LabelingContainer.java create mode 100644 src/main/java/net/imglib2/labeling/data/LabelingData.java delete mode 100644 src/test/java/net/imglib2/labeling/tutorials/ExampleCodec.java delete mode 100644 src/test/resources/labeling/example1.bson delete mode 100644 src/test/resources/labeling/example1.tif delete mode 100644 src/test/resources/labeling/example1_sav.bson create mode 100644 src/test/resources/labeling/example1_sav.lbl.json delete mode 100644 src/test/resources/labeling/labelSaveTestComplex.bson create mode 100644 src/test/resources/labeling/labelSaveTestComplex.lbl.json delete mode 100644 src/test/resources/labeling/labelSaveTestComplexFunction.bson delete mode 100644 src/test/resources/labeling/labelSaveTestComplexFunction.tif delete mode 100644 src/test/resources/labeling/labelSaveTestSimple.bson create mode 100644 src/test/resources/labeling/labelSaveTestSimple.lbl.json create mode 100644 src/test/resources/labeling/labelSaveTestSimpleMeta.lbl.json create mode 100644 src/test/resources/labeling/labelSaveTestSimpleMeta.tif create mode 100644 src/test/resources/labeling/test.lbl.json create mode 100644 src/test/resources/labeling/test.tif create mode 100644 src/test/resources/labeling/test2.lbl.json create mode 100644 src/test/resources/labeling/test2.tif diff --git a/labeling.iml b/labeling.iml index 85e31e9..a23b9c1 100644 --- a/labeling.iml +++ b/labeling.iml @@ -19,7 +19,7 @@ - + diff --git a/pom.xml b/pom.xml index 5259e64..fb58005 100644 --- a/pom.xml +++ b/pom.xml @@ -110,14 +110,18 @@ - org.mongodb - bson - 4.2.3 + com.google.code.gson + gson + ${gson.version} io.scif scifio + + org.scijava + scijava-common + diff --git a/src/main/java/net/imglib2/labeling/DefaultLabelingIOService.java b/src/main/java/net/imglib2/labeling/DefaultLabelingIOService.java index 2536e02..6dbda27 100644 --- a/src/main/java/net/imglib2/labeling/DefaultLabelingIOService.java +++ b/src/main/java/net/imglib2/labeling/DefaultLabelingIOService.java @@ -33,243 +33,237 @@ */ package net.imglib2.labeling; +import com.google.gson.Gson; import io.scif.services.DatasetIOService; import net.imagej.ImageJService; +import net.imglib2.RandomAccessibleInterval; import net.imglib2.img.Img; import net.imglib2.img.ImgView; -import net.imglib2.labeling.codecs.ImgLabelingCodec; -import net.imglib2.labeling.codecs.LabelingMappingCodec; import net.imglib2.labeling.data.Container; +import net.imglib2.labeling.data.LabelingData; import net.imglib2.labeling.utils.LabelingUtil; import net.imglib2.roi.labeling.ImgLabeling; +import net.imglib2.roi.labeling.LabelingMapping; import net.imglib2.type.numeric.IntegerType; -import org.bson.BsonBinaryReader; -import org.bson.BsonBinaryWriter; -import org.bson.BsonReader; -import org.bson.codecs.*; -import org.bson.codecs.configuration.CodecProvider; -import org.bson.codecs.configuration.CodecRegistries; -import org.bson.codecs.configuration.CodecRegistry; -import org.bson.io.BasicOutputBuffer; import org.scijava.Context; import org.scijava.plugin.Parameter; import org.scijava.plugin.Plugin; import org.scijava.service.AbstractService; -import java.io.File; +import java.io.FileWriter; import java.io.IOException; -import java.io.RandomAccessFile; -import java.nio.MappedByteBuffer; -import java.nio.channels.FileChannel; -import java.nio.file.Path; +import java.io.Reader; +import java.io.Writer; +import java.nio.file.Files; import java.nio.file.Paths; +import java.util.*; import java.util.function.LongFunction; import java.util.function.ToLongFunction; +import static net.imglib2.labeling.utils.LabelingUtil.TIF_ENDING; + @Plugin(type = ImageJService.class) public class DefaultLabelingIOService extends AbstractService implements LabelingIOService { - CodecRegistry registry = CodecRegistries.fromProviders(new BsonValueCodecProvider(), new DocumentCodecProvider() - , new ValueCodecProvider(), new MapCodecProvider()); @Parameter private Context context; @Parameter private DatasetIOService datasetIOService; + private Gson gson; @Override public void initialize() { - addCodecs(new BsonArrayCodec(registry)); + gson = new Gson(); } - public > ImgLabeling load(String file) throws IOException { - ImgLabelingCodec imgLabelingCodec = new ImgLabelingCodec.Builder().setIndexImg(LabelingUtil.getFilePathWithExtension(file, LabelingUtil.TIF_ENDING, "")) - .setCodecRegistry(registry).setFile(Paths.get(file)).setDatasetIOService(datasetIOService).build(); - RandomAccessFile aFile = new RandomAccessFile(LabelingUtil.getFilePathWithExtension(file, LabelingUtil.BSON_ENDING, Paths.get(file).getParent().toString()), "r"); - FileChannel inChannel = aFile.getChannel(); - MappedByteBuffer buffer = inChannel.map(FileChannel.MapMode.READ_ONLY, 0, inChannel.size()); - BsonReader bsonReader = new BsonBinaryReader(buffer); - ImgLabeling imgLabeling = imgLabelingCodec.decode(bsonReader, DecoderContext.builder().build()); - return imgLabeling; - } @Override - public > ImgLabeling load(String file, Class clazz, Codec... codecs) throws IOException { - addCodecs(codecs); - ImgLabelingCodec imgLabelingCodec = new ImgLabelingCodec.Builder().setIndexImg(LabelingUtil.getFilePathWithExtension(file, LabelingUtil.TIF_ENDING, "")) - .setClazz(clazz).setCodecRegistry(registry).setFile(Paths.get(file)).setDatasetIOService(datasetIOService).build(); - RandomAccessFile aFile = new RandomAccessFile(LabelingUtil.getFilePathWithExtension(file, LabelingUtil.BSON_ENDING, Paths.get(file).getParent().toString()), "r"); - FileChannel inChannel = aFile.getChannel(); - MappedByteBuffer buffer = inChannel.map(FileChannel.MapMode.READ_ONLY, 0, inChannel.size()); - BsonReader bsonReader = new BsonBinaryReader(buffer); - ImgLabeling imgLabeling = imgLabelingCodec.decode(bsonReader, DecoderContext.builder().build()); - return imgLabeling; - } + public > ImgLabeling load(String file) throws IOException { + String path = LabelingUtil.getFilePathWithExtension(file, LabelingUtil.LBL_ENDING, Paths.get(file).getParent().toString()); + Reader reader = Files.newBufferedReader(Paths.get(path)); + LabelingData labelingData = gson.fromJson(reader, LabelingData.class); + int version = labelingData.getVersion(); + int numSets = labelingData.getNumSets(); + int numSources = labelingData.getNumSources(); + String indexImg = labelingData.getIndexImg(); + List> labelSets = readLabelsets(labelingData, numSets); + RandomAccessibleInterval img = null; + try { + img = (Img) datasetIOService.open(LabelingUtil.getFilePathWithExtension(indexImg, TIF_ENDING, Paths.get(file).getParent().toString())).getImgPlus().getImg(); + } catch (IOException e) { + e.printStackTrace(); + } - @Override - public > void save(ImgLabeling imgLabeling, String file) throws IOException { - ImgLabelingCodec imgLabelingCodec = new ImgLabelingCodec.Builder().setIndexImg(LabelingUtil.getFilePathWithExtension(file, LabelingUtil.TIF_ENDING, Paths.get(file).getParent().toString())).setCodecRegistry(registry).build(); - saveLabeling(imgLabeling, file, imgLabelingCodec); + return ImgLabeling.fromImageAndLabelSets(img, labelSets); } @Override - public > void save(ImgLabeling imgLabeling, String file, Class clazz, Codec... codecs) throws IOException { - addCodecs(codecs); - ImgLabelingCodec imgLabelingCodec = new ImgLabelingCodec.Builder().setIndexImg(LabelingUtil.getFilePathWithExtension(file, LabelingUtil.TIF_ENDING, Paths.get(file).getParent().toString())).setClazz(clazz).setCodecRegistry(registry).build(); - saveLabeling(imgLabeling, file, imgLabelingCodec); - } + public > ImgLabeling load(String file, Class clazz) throws IOException { + String path = LabelingUtil.getFilePathWithExtension(file, LabelingUtil.LBL_ENDING, Paths.get(file).getParent().toString()); + Reader reader = Files.newBufferedReader(Paths.get(path)); + LabelingData labelingData = gson.fromJson(reader, LabelingData.class); + int version = labelingData.getVersion(); + int numSets = labelingData.getNumSets(); + int numSources = labelingData.getNumSources(); + String indexImg = labelingData.getIndexImg(); + List> labelSets = readLabelsets(labelingData, numSets); + RandomAccessibleInterval img = null; + try { + img = (Img) datasetIOService.open(LabelingUtil.getFilePathWithExtension(indexImg, TIF_ENDING, Paths.get(file).getParent().toString())).getImgPlus().getImg(); + } catch (IOException e) { + e.printStackTrace(); + } - private > void saveLabeling(ImgLabeling imgLabeling, String file, ImgLabelingCodec imgLabelingCodec) { - imgLabelingCodec.setIndexImg(LabelingUtil.getFilePathWithExtension(file, LabelingUtil.TIF_ENDING, "")); - BasicOutputBuffer outputBuffer = new BasicOutputBuffer(); - BsonBinaryWriter writer = new BsonBinaryWriter(outputBuffer); - imgLabelingCodec.encode(writer, imgLabeling, EncoderContext.builder().isEncodingCollectibleDocument(false).build()); - LabelingUtil.writeToFile(outputBuffer, new File(LabelingUtil.getFilePathWithExtension(file, LabelingUtil.BSON_ENDING, Paths.get(file).getParent().toString()))); - final Img img = ImgView.wrap(imgLabeling.getIndexImg(), null); - LabelingUtil.saveAsTiff(context, LabelingUtil.getFilePathWithExtension(file, LabelingUtil.TIF_ENDING, Paths.get(file).getParent().toString()), img); + return ImgLabeling.fromImageAndLabelSets(img, labelSets); } @Override - public > Container loadWithMetadata(String file, Class metadataClazz, Codec... codecs) throws IOException { - addCodecs(codecs); - LabelingMappingCodec labelingMappingCodec = new LabelingMappingCodec.Builder() - .setIndexImg(LabelingUtil.getFilePathWithExtension(file, LabelingUtil.TIF_ENDING, "")) - .setMetadataClazz(metadataClazz) - .setFile(Paths.get(file)).setDatasetIOService(datasetIOService) - .setCodecRegistry(registry).build(); - RandomAccessFile aFile = new RandomAccessFile(LabelingUtil.getFilePathWithExtension(file, LabelingUtil.BSON_ENDING, Paths.get(file).getParent().toString()), "r"); - FileChannel inChannel = aFile.getChannel(); - MappedByteBuffer buffer = inChannel.map(FileChannel.MapMode.READ_ONLY, 0, inChannel.size()); - BsonReader bsonReader = new BsonBinaryReader(buffer); - Container container = labelingMappingCodec.decode(bsonReader, DecoderContext.builder().build()); + public > Container loadWithMetadata(String file, Class metadataClazz) throws IOException { + String path = LabelingUtil.getFilePathWithExtension(file, LabelingUtil.LBL_ENDING, Paths.get(file).getParent().toString()); + Reader reader = Files.newBufferedReader(Paths.get(path)); + LabelingData labelingData = gson.fromJson(reader, LabelingData.class); + int version = labelingData.getVersion(); + int numSets = labelingData.getNumSets(); + int numSources = labelingData.getNumSources(); + String indexImg = labelingData.getIndexImg(); + List> labelSets = readLabelsets(labelingData, numSets); + RandomAccessibleInterval img = null; + try { + img = (Img) datasetIOService.open(LabelingUtil.getFilePathWithExtension(indexImg, TIF_ENDING, Paths.get(file).getParent().toString())).getImgPlus().getImg(); + } catch (IOException e) { + e.printStackTrace(); + } + Container container = new Container<>(); + container.setImgLabeling(ImgLabeling.fromImageAndLabelSets(img, labelSets)); + S metadata = gson.fromJson(gson.toJson(labelingData.getMetadata()), metadataClazz); + container.setMetadata(metadata); return container; - } - @Override - public > Container loadWithMetadata(String file, Class clazz, Class metadataClazz, Codec... codecs) throws IOException { - addCodecs(codecs); - LabelingMappingCodec labelingMappingCodec = new LabelingMappingCodec.Builder() - .setIndexImg(LabelingUtil.getFilePathWithExtension(file, LabelingUtil.TIF_ENDING, "")) - .setClazz(clazz).setMetadataClazz(metadataClazz) - .setFile(Paths.get(file)).setDatasetIOService(datasetIOService) - .setCodecRegistry(registry).build(); - RandomAccessFile aFile = new RandomAccessFile(LabelingUtil.getFilePathWithExtension(file, LabelingUtil.BSON_ENDING, Paths.get(file).getParent().toString()), "r"); - FileChannel inChannel = aFile.getChannel(); - MappedByteBuffer buffer = inChannel.map(FileChannel.MapMode.READ_ONLY, 0, inChannel.size()); - BsonReader bsonReader = new BsonBinaryReader(buffer); - Container container = labelingMappingCodec.decode(bsonReader, DecoderContext.builder().build()); - return container; - - } @Override - public > Container loadWithMetadata(String file, LongFunction idToLabel, Class metadataClazz, Codec... codecs) throws IOException { - addCodecs(codecs); - LabelingMappingCodec labelingMappingCodec = new LabelingMappingCodec.Builder() - .setMetadataClazz(metadataClazz) - .setFile(Paths.get(file)).setDatasetIOService(datasetIOService) - .setCodecRegistry(registry).setIdToLabel(idToLabel).build(); - Path labelingFile = Paths.get(file); - RandomAccessFile aFile = new RandomAccessFile(LabelingUtil.getFilePathWithExtension(file, LabelingUtil.BSON_ENDING, labelingFile.getParent().toString()), "r"); - FileChannel inChannel = aFile.getChannel(); - MappedByteBuffer buffer = inChannel.map(FileChannel.MapMode.READ_ONLY, 0, inChannel.size()); - BsonReader bsonReader = new BsonBinaryReader(buffer); - - Container container = labelingMappingCodec.decode(bsonReader, DecoderContext.builder().build()); + public > Container loadWithMetadata(String file, LongFunction idToLabel, Class metadataClazz) throws IOException { + String path = LabelingUtil.getFilePathWithExtension(file, LabelingUtil.LBL_ENDING, Paths.get(file).getParent().toString()); + Reader reader = Files.newBufferedReader(Paths.get(path)); + LabelingData labelingData = gson.fromJson(reader, LabelingData.class); + int version = labelingData.getVersion(); + int numSets = labelingData.getNumSets(); + int numSources = labelingData.getNumSources(); + String indexImg = labelingData.getIndexImg(); + List> labelSets = new ArrayList>(labelingData.getLabelSets().values()); + RandomAccessibleInterval img = null; + try { + img = (Img) datasetIOService.open(LabelingUtil.getFilePathWithExtension(indexImg, TIF_ENDING, Paths.get(file).getParent().toString())).getImgPlus().getImg(); + } catch (IOException e) { + e.printStackTrace(); + } + Container container = new Container<>(); + container.setImgLabeling(ImgLabeling.fromImageAndLabelSets(img, labelSets)); + S metadata = gson.fromJson(gson.toJson(labelingData.getMetadata()), metadataClazz); + container.setMetadata(metadata); return container; - } @Override - public > void saveWithMetaData(Container container, String file, Class metadataClazz, Codec... codecs) { - addCodecs(codecs); - LabelingMappingCodec labelingMappingCodec = new LabelingMappingCodec.Builder() - .setIndexImg(LabelingUtil.getFilePathWithExtension(file, LabelingUtil.TIF_ENDING, Paths.get(file).getParent().toString())) - .setMetadataClazz(metadataClazz) - .setFile(Paths.get(file)).setDatasetIOService(datasetIOService) - .setCodecRegistry(registry).build(); - labelingMappingCodec.setIndexImg(LabelingUtil.getFilePathWithExtension(file, LabelingUtil.TIF_ENDING, "")); - BasicOutputBuffer outputBuffer = new BasicOutputBuffer(); - BsonBinaryWriter writer = new BsonBinaryWriter(outputBuffer); - labelingMappingCodec.encode(writer, container, EncoderContext.builder().isEncodingCollectibleDocument(false).build()); - LabelingUtil.writeToFile(outputBuffer, new File(LabelingUtil.getFilePathWithExtension(file, LabelingUtil.BSON_ENDING, Paths.get(file).getParent().toString()))); - final Img img = ImgView.wrap(container.getImgLabeling().getIndexImg(), null); + public > void save(ImgLabeling imgLabeling, String file) throws IOException { + LabelingMapping labelingMapping = imgLabeling.getMapping(); + LabelingData labelingData = createBasicLabelingData(file, labelingMapping); + if (!labelingMapping.getLabels().isEmpty()) { + createLabelsets(labelingMapping, labelingData); + } + final Img img = ImgView.wrap(imgLabeling.getIndexImg(), null); LabelingUtil.saveAsTiff(context, LabelingUtil.getFilePathWithExtension(file, LabelingUtil.TIF_ENDING, Paths.get(file).getParent().toString()), img); - + writeLabelingFile(file, labelingData); } @Override - public > void saveWithMetaData(Container container, String file, Class clazz, Class metadataClazz, Codec... codecs) { - addCodecs(codecs); - LabelingMappingCodec labelingMappingCodec = new LabelingMappingCodec.Builder() - .setIndexImg(LabelingUtil.getFilePathWithExtension(file, LabelingUtil.TIF_ENDING, Paths.get(file).getParent().toString())) - .setClazz(clazz).setMetadataClazz(metadataClazz) - .setFile(Paths.get(file)).setDatasetIOService(datasetIOService) - .setCodecRegistry(registry).build(); - labelingMappingCodec.setIndexImg(LabelingUtil.getFilePathWithExtension(file, LabelingUtil.TIF_ENDING, "")); - BasicOutputBuffer outputBuffer = new BasicOutputBuffer(); - BsonBinaryWriter writer = new BsonBinaryWriter(outputBuffer); - labelingMappingCodec.encode(writer, container, EncoderContext.builder().isEncodingCollectibleDocument(false).build()); - LabelingUtil.writeToFile(outputBuffer, new File(LabelingUtil.getFilePathWithExtension(file, LabelingUtil.BSON_ENDING, Paths.get(file).getParent().toString()))); - final Img img = ImgView.wrap(container.getImgLabeling().getIndexImg(), null); - LabelingUtil.saveAsTiff(context, LabelingUtil.getFilePathWithExtension(file, LabelingUtil.TIF_ENDING, Paths.get(file).getParent().toString()), img); + public > void saveWithMetaData(ImgLabeling imgLabeling, String file, S metadata) throws IOException { + LabelingMapping labelingMapping = imgLabeling.getMapping(); + LabelingData labelingData = createBasicLabelingData(file, labelingMapping); + labelingData.setMetadata(metadata); + if (!labelingMapping.getLabels().isEmpty()) { + createLabelsets(labelingMapping, labelingData); + } + final Img img = ImgView.wrap(imgLabeling.getIndexImg(), null); + LabelingUtil.saveAsTiff(context, LabelingUtil.getFilePathWithExtension(file, LabelingUtil.TIF_ENDING, Paths.get(file).getParent().toString()), img); + writeLabelingFile(file, labelingData); } @Override - public > void saveWithMetaData(Container container, String file, ToLongFunction labelToId, Class metadataClazz, Codec... codecs) { - addCodecs(codecs); - LabelingMappingCodec labelingMappingCodec = new LabelingMappingCodec.Builder() - .setMetadataClazz(metadataClazz) - .setFile(Paths.get(file)).setDatasetIOService(datasetIOService) - .setCodecRegistry(registry).setLabelToId(labelToId).build(); - labelingMappingCodec.setIndexImg(LabelingUtil.getFilePathWithExtension(file, LabelingUtil.TIF_ENDING, "")); - BasicOutputBuffer outputBuffer = new BasicOutputBuffer(); - BsonBinaryWriter writer = new BsonBinaryWriter(outputBuffer); - labelingMappingCodec.encode(writer, container, EncoderContext.builder().isEncodingCollectibleDocument(false).build()); - LabelingUtil.writeToFile(outputBuffer, new File(LabelingUtil.getFilePathWithExtension(file, LabelingUtil.BSON_ENDING, Paths.get(file).getParent().toString()))); - final Img img = ImgView.wrap(container.getImgLabeling().getIndexImg(), null); - LabelingUtil.saveAsTiff(context, LabelingUtil.getFilePathWithExtension(file, LabelingUtil.TIF_ENDING, Paths.get(file).getParent().toString()), img); + public > void saveWithMetaData(ImgLabeling imgLabeling, String file, ToLongFunction labelToId, S metadata) throws IOException { + LabelingMapping labelingMapping = imgLabeling.getMapping(); + LabelingData labelingData = createBasicLabelingData(file, labelingMapping); + labelingData.setMetadata(metadata); + //TODO: add function transformation + final Img img = ImgView.wrap(imgLabeling.getIndexImg(), null); + LabelingUtil.saveAsTiff(context, LabelingUtil.getFilePathWithExtension(file, LabelingUtil.TIF_ENDING, Paths.get(file).getParent().toString()), img); + writeLabelingFile(file, labelingData); } - private CodecRegistry getRegistry() { - return registry; + private void createLabelsets(LabelingMapping labelingMapping, LabelingData labelingData) { + if(labelingMapping.getLabels().stream().findFirst().get() instanceof Integer){ + Map> labels = new HashMap<>(); + for (int i = 0; i < labelingMapping.numSets(); i++) { + labels.put(Integer.toString(i), (Set) labelingMapping.labelsAtIndex(i)); + } + labelingData.setLabelSets(labels); + }else{ + Map> labels = new HashMap<>(); + Map map = new HashMap<>(); + for (int i = 0; i < labelingMapping.numSets(); i++) { + Set labelset = new HashSet<>(); + for(T value : labelingMapping.labelsAtIndex(i)){ + if(!map.containsValue(value)){ + map.put(map.size()+1, value); + } + int mappedInteger = map.entrySet().stream().filter(entry -> value.equals(entry.getValue())) + .map(Map.Entry::getKey).findFirst().get(); + labelset.add(mappedInteger); + } + labels.put(Integer.toString(i), labelset); + } + labelingData.setLabelMapping(map); + labelingData.setLabelSets(labels); + } } - /** - * Overwrites the complete CodecRegistry. - * - * @param registry the registry to override the existing one - */ - private void setRegistry(CodecRegistry registry) { - this.registry = registry; + private List> readLabelsets(LabelingData labelingData, int numSets) { + List> labelSets; + if(labelingData.getLabelMapping()==null || labelingData.getLabelMapping().isEmpty()){ + labelSets = new ArrayList<>(); + for(Set set : labelingData.getLabelSets().values()){ + Set labelSet = new HashSet<>(); + set.stream().map(v->((Number)v).intValue()).forEach(v -> labelSet.add((T) v)); + labelSets.add(labelSet); + } + }else{ + labelSets = new ArrayList<>(); + for(int i = 0; i< numSets; i++){ + Set set = new HashSet<>(); + for(int j : (Set) labelingData.getLabelSets().get(Integer.toString(i))){ + set.add((T) labelingData.getLabelMapping().get(Integer.toString(j))); + } + labelSets.add(set); + } + } + return labelSets; } - /** - * Adds the codecs contained in one or more {@link CodecRegistry} to the current registry. - * - * @param registries a number of registries to merge into the existing one - */ - private void addCodecRegistries(CodecRegistry... registries) { - this.registry = CodecRegistries.fromRegistries(getRegistry(), CodecRegistries.fromRegistries(registries)); + private LabelingData createBasicLabelingData(String file, LabelingMapping labelingMapping) { + LabelingData labelingData = new LabelingData(); + labelingData.setVersion(LabelingUtil.VERSION); + labelingData.setNumSets(labelingMapping.numSets()); + labelingData.setNumSources(1); + labelingData.setIndexImg(LabelingUtil.getFilePathWithExtension(file, LabelingUtil.TIF_ENDING, null)); + return labelingData; } - /** - * Adds the codecs contained in one or more {@link CodecProvider} to the current registry. - * - * @param providers a number of providers to merge into the existing registry - */ - private void addCodecProviders(CodecProvider... providers) { - this.registry = CodecRegistries.fromRegistries(getRegistry(), CodecRegistries.fromProviders(providers)); + private void writeLabelingFile(String file, LabelingData labelingData) throws IOException { + Writer writer = new FileWriter(LabelingUtil.getFilePathWithExtension(file, LabelingUtil.LBL_ENDING, Paths.get(file).getParent().toString())); + gson.toJson(labelingData, writer); + writer.flush(); + writer.close(); } - /** - * Adds one or more {@link Codec} to the current registry. - * - * @param codecs a number of codecs to merge into the existing registry - */ - @SafeVarargs - public final void addCodecs(Codec... codecs) { - this.registry = CodecRegistries.fromRegistries(getRegistry(), CodecRegistries.fromCodecs(codecs)); - } } diff --git a/src/main/java/net/imglib2/labeling/LabelingIOService.java b/src/main/java/net/imglib2/labeling/LabelingIOService.java index e31fc6e..5af1e24 100644 --- a/src/main/java/net/imglib2/labeling/LabelingIOService.java +++ b/src/main/java/net/imglib2/labeling/LabelingIOService.java @@ -34,11 +34,9 @@ package net.imglib2.labeling; import net.imagej.ImageJService; -import net.imglib2.labeling.codecs.LabelingMappingCodec; import net.imglib2.labeling.data.Container; import net.imglib2.roi.labeling.ImgLabeling; import net.imglib2.type.numeric.IntegerType; -import org.bson.codecs.Codec; import java.io.IOException; import java.util.function.LongFunction; @@ -48,7 +46,7 @@ * A service to easily access a load/save functionality for BSON-based labeling data files. * Basic support for primitive types and BSON standard types is already included. For non-primitive types, * a codec must be set and the class must be given as an argument to the methods. - * Examples for Codecs can be found at {@link LabelingMappingCodec}. + * * * @author Tom Burke */ @@ -56,19 +54,15 @@ public interface LabelingIOService extends ImageJService { > ImgLabeling load(String file) throws IOException; - > ImgLabeling load(String file, Class clazz, Codec... codecs) throws IOException; + > ImgLabeling load(String file, Class clazz) throws IOException; > void save(ImgLabeling imgLabeling, String file) throws IOException; - > void save(ImgLabeling imgLabeling, String file, Class clazz, Codec... codecs) throws IOException; - - /** * Load a labeling container from the given file path as string. * The file path must point to the bson file containing the labeling data. * * @param file The path to the file - * @param codecs One or more codecs necessary to convert the data to clazz. * @param metadataClazz the metadata class * @param the label value * @param IntegerType for the pixel value @@ -76,24 +70,7 @@ public interface LabelingIOService extends ImageJService { * @throws IOException on file read fail * @return a container object holding the ImgLabeling (as well as an optional source mapping) */ - > Container loadWithMetadata(String file, Class metadataClazz, Codec... codecs) throws IOException; - - - /** - * Load a labeling container from the given file path as string. - * The file path must point to the bson file containing the labeling data. - * - * @param file The path to the file - * @param clazz The class to convert the contains of the file to - * @param metadataClazz the metadata class - * @param codecs One or more codecs necessary to convert the data to clazz. - * @param the label value - * @param IntegerType for the pixel value - * @param Class of the meta data - * @throws IOException on file read fail - * @return a container object holding the ImgLabeling (as well as an optional source mapping) - */ - > Container loadWithMetadata(String file, Class clazz, Class metadataClazz, Codec... codecs) throws IOException; + > Container loadWithMetadata(String file, Class metadataClazz) throws IOException; /** * Load a labeling container from the given file path as string. @@ -102,57 +79,37 @@ public interface LabelingIOService extends ImageJService { * @param file The path to the file * @param idToLabel a function transforming the label of type T into something else * @param metadataClazz the metadata class - * @param codecs One or more codecs necessary to convert the data to clazz. * @param the label value * @param IntegerType for the pixel value * @param Class of the meta data * @throws IOException on file read fail * @return a container object holding the ImgLabeling (as well as an optional source mapping) */ - > Container loadWithMetadata(String file, LongFunction idToLabel, Class metadataClazz, Codec... codecs) throws IOException; - - /** - * Save an ImgLabelingContainer in the file-path, transforming it into a bson file and an image. - * The path must contain the filename (ending does not matter). - * - * @param codecs one or more codecs to convert clazz into something bsonifyable - * @param container the container with the ImgLabeling and a metadata object - * @param file the path pointing to the file, including the filename - * @param metadataClazz the metadata class - * @param the label value - * @param IntegerType for the pixel value - * @param Class of the meta data - */ - > void saveWithMetaData(Container container, String file, Class metadataClazz, Codec... codecs); + > Container loadWithMetadata(String file, LongFunction idToLabel, Class metadataClazz) throws IOException; /** * Save an ImgLabelingContainer in the file-path, transforming it into a bson file and an image. * The path must contain the filename (ending does not matter). * - * @param clazz the class of the type T that is contained in the labeling - * @param codecs one or more codecs to convert clazz into something bsonifyable - * @param container the container with the ImgLabeling and a metadata object + * @param imgLabeling the imglabeling object that needs to be serialized * @param file the path pointing to the file, including the filename - * @param metadataClazz the metadata class * @param the label value * @param IntegerType for the pixel value * @param Class of the meta data */ - > void saveWithMetaData(Container container, String file, Class clazz, Class metadataClazz, Codec... codecs); + > void saveWithMetaData(ImgLabeling imgLabeling, String file, S metadata) throws IOException; /** * Save an ImgLabelingContainer in the file-path, transforming it into a bson file and an image. * The path must contain the filename (ending does not matter). * + * @param imgLabeling the imglabeling object that needs to be serialized * @param labelToId a function to convert the type T to a long value. - * @param container the container with the ImgLabeling and a metadata object - * @param codecs one or more codecs to convert clazz into something bsonifyable * @param file the path pointing to the file, including the filename - * @param metadataClazz the metadata class * @param the label value * @param IntegerType for the pixel value * @param Class of the meta data */ - > void saveWithMetaData(Container container, String file, ToLongFunction labelToId, Class metadataClazz, Codec... codecs); + > void saveWithMetaData(ImgLabeling imgLabeling, String file, ToLongFunction labelToId, S metadata) throws IOException; } diff --git a/src/main/java/net/imglib2/labeling/codecs/ImgLabelingCodec.java b/src/main/java/net/imglib2/labeling/codecs/ImgLabelingCodec.java deleted file mode 100644 index 8031322..0000000 --- a/src/main/java/net/imglib2/labeling/codecs/ImgLabelingCodec.java +++ /dev/null @@ -1,410 +0,0 @@ -/*- - * #%L - * ImgLib2: a general-purpose, multidimensional image processing library. - * %% - * Copyright (C) 2020 - 2021 Tobias Pietzsch, Stephan Preibisch, Stephan Saalfeld, - * John Bogovic, Albert Cardona, Barry DeZonia, Christian Dietz, Jan Funke, - * Aivar Grislis, Jonathan Hale, Grant Harris, Stefan Helfrich, Mark Hiner, - * Martin Horn, Steffen Jaensch, Lee Kamentsky, Larry Lindsey, Melissa Linkert, - * Mark Longair, Brian Northan, Nick Perry, Curtis Rueden, Johannes Schindelin, - * Jean-Yves Tinevez and Michael Zinsmaier. - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package net.imglib2.labeling.codecs; - -import io.scif.services.DatasetIOService; -import net.imglib2.RandomAccessibleInterval; -import net.imglib2.img.Img; -import net.imglib2.labeling.data.LabelingContainer; -import net.imglib2.labeling.utils.LabelingUtil; -import net.imglib2.roi.labeling.ImgLabeling; -import net.imglib2.roi.labeling.LabelingMapping; -import net.imglib2.type.logic.BoolType; -import net.imglib2.type.numeric.IntegerType; -import net.imglib2.type.numeric.integer.IntType; -import net.imglib2.type.numeric.integer.LongType; -import org.bson.BsonArray; -import org.bson.BsonReader; -import org.bson.BsonType; -import org.bson.BsonWriter; -import org.bson.codecs.Codec; -import org.bson.codecs.DecoderContext; -import org.bson.codecs.EncoderContext; -import org.bson.codecs.configuration.CodecRegistry; - -import java.io.IOException; -import java.nio.file.Path; -import java.util.*; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.LongFunction; -import java.util.function.ToLongFunction; -import java.util.stream.Collectors; - -import static net.imglib2.labeling.utils.LabelingUtil.TIF_ENDING; - -/** - * A codec (encoder/decoder) for the ImgLabeling class to and from the BSON (binary JSON) data type. - * The resulting data structure consists of the number of sets, a mapping from complex type to integer - * as well as the actual label sets. The Codec class is used in the LabelingIO class and handles - * the basic structure. For non-primitive label types, an additional codec must be written. - * V1 Data structure: - * // @formatter:off - * { - * version: int32 - * numSets: int32 - * indexImg: String - * mapping: { //may be empty - * "1": {//encoded type} - * ... - * } - * labelSets:{ - * labelSet_n: [...] - * ... - * } - * } - * // @formatter:on - * - * @author Tom Burke - */ -public class ImgLabelingCodec> implements Codec> { - private final static int VERSION = 1; - private static final Set WRAPPER_TYPES = new HashSet(Arrays.asList(IntType.class, LongType.class, BoolType.class, - Boolean.class, Character.class, Byte.class, Short.class, Integer.class, Long.class, Float.class, Double.class, Void.class, String.class)); - private final Class clazz; - private CodecRegistry codecRegistry; - private String indexImg; - private LongFunction idToLabel; - private ToLongFunction labelToId; - private DatasetIOService datasetIOService; - private Path file; - - private ImgLabelingCodec(final Builder builder) { - this.clazz = builder.clazz; - this.codecRegistry = builder.codecRegistry; - this.indexImg = builder.indexImg; - this.idToLabel = builder.idToLabel; - this.labelToId = builder.labelToId; - this.datasetIOService = builder.datasetIOService; - this.file = builder.file; - - } - - public static boolean isWrapperType(Class clazz) { - return WRAPPER_TYPES.contains(clazz); - } - - @Override - public ImgLabeling decode(BsonReader reader, DecoderContext decoderContext) { - LabelingMapping labelingMapping = new LabelingMapping<>(new IntType()); - String path = this.file.getParent().toString(); - reader.readStartDocument(); - int version = reader.readInt32("version"); - int numSets = reader.readInt32("numSets"); - int numSources = reader.readInt32("numSources"); - this.indexImg = reader.readString("indexImg"); - - Map mapping = readMapping(reader, decoderContext, clazz); - List> labelSets = readLabelSets(reader, decoderContext, numSets, numSources, mapping); - RandomAccessibleInterval img = null; - try { - img = (Img) datasetIOService.open(LabelingUtil.getFilePathWithExtension(indexImg, TIF_ENDING, path)).getImgPlus().getImg(); - } catch (IOException e) { - e.printStackTrace(); - } - return ImgLabeling.fromImageAndLabelSets(img, labelSets); - } - - private List> readLabelSets(BsonReader reader, DecoderContext decoderContext, int numSets, int numSources, Map mapping) { - LabelingContainer container = new LabelingContainer<>(); - List> labelSets = new ArrayList<>(); - reader.readStartDocument(); - for (int i = 0; i < numSets; i++) { - Set labelSet; - BsonType bsonType = reader.readBsonType(); - if (bsonType == BsonType.DOCUMENT) { - reader.readStartDocument(); - labelSet = readLabelSet(reader, decoderContext, mapping); - reader.readEndDocument(); - } else { - labelSet = readLabelSet(reader, decoderContext, mapping); - } - labelSets.add(labelSet); - } - reader.readEndDocument(); - container.setLabelSets(labelSets); - return labelSets; - } - - private Set readLabelSet(BsonReader reader, DecoderContext decoderContext, Map mapping) { - BsonArray bsonValues = getCodecRegistry().get(BsonArray.class).decode(reader, decoderContext); - Set labelSet = bsonValues.stream().map(v -> { - if (v.isInt32()) - return v.asInt32().intValue(); - else - return v.asInt64().intValue(); - }).map(v -> { - if (getIdToLabel() != null) - return getIdToLabel().apply(v); - else if (!mapping.isEmpty()) - return mapping.get(v); - else - return v; - }).collect(Collectors.toSet()); - - - return (Set) labelSet; - } - - @Override - public void encode(BsonWriter writer, ImgLabeling value, EncoderContext encoderContext) { - LabelingMapping labelingMapping = value.getMapping(); - writer.writeStartDocument(); - writer.writeInt32("version", VERSION); - writer.writeInt32("numSets", labelingMapping.numSets()); - writer.writeInt32("numSources", 1); - writer.writeString("indexImg", indexImg); - Optional first = labelingMapping.getLabels().stream().findFirst(); - if (first.isPresent() && !isWrapperType(first.get().getClass())) { - if (clazz == null) { - writer.writeStartDocument("labelMapping"); - writer.writeEndDocument(); - writer.writeStartDocument("labelSets"); - for (int i = 0; i < labelingMapping.numSets(); i++) { - Set labelSet = labelingMapping.labelsAtIndex(i); - writer.writeStartArray(Integer.toString(i)); - labelSet.forEach(v -> writeValue(labelToId.applyAsLong(v), writer, encoderContext)); - writer.writeEndArray(); - } - writer.writeEndDocument(); - } else { - AtomicInteger count = new AtomicInteger(); - HashMap map = new HashMap<>(); - writer.writeStartDocument("labelMapping"); - labelingMapping.getLabels().forEach(v -> { - map.put(v, count.get()); - writer.writeName(String.valueOf(count.getAndIncrement())); - Codec codec = (Codec) codecRegistry.get(v.getClass()); - encoderContext.encodeWithChildContext(codec, writer, v); - }); - writer.writeEndDocument(); - writer.writeStartDocument("labelSets"); - for (int i = 0; i < labelingMapping.numSets(); i++) { - Set labelSet = labelingMapping.labelsAtIndex(i); - writer.writeStartArray(Integer.toString(i)); - labelSet.forEach(v -> writeValue(map.get(v), writer, encoderContext)); - writer.writeEndArray(); - } - writer.writeEndDocument(); - } - } else { - writer.writeStartDocument("labelMapping"); - writer.writeEndDocument(); - writer.writeStartDocument("labelSets"); - for (int i = 0; i < labelingMapping.numSets(); i++) { - Set labelSet = labelingMapping.labelsAtIndex(i); - writer.writeStartArray(Integer.toString(i)); - labelSet.forEach(v -> writeValue(v, writer, encoderContext)); - writer.writeEndArray(); - } - writer.writeEndDocument(); - } - writer.writeEndDocument(); - } - - private Map readMapping(BsonReader reader, DecoderContext decoderContext, Class clazz) { - Map mapping = new HashMap<>(); - reader.readStartDocument(); - while (reader.readBsonType() != BsonType.END_OF_DOCUMENT) { - int key = Integer.parseInt(reader.readName()); - Codec c = codecRegistry.get(clazz); - T value = c.decode(reader, decoderContext); - mapping.put(key, value); - } - - reader.readEndDocument(); - return mapping; - } - - private void writeValue(Object v, BsonWriter writer, EncoderContext encoderContext) { - if (v instanceof IntType) { - writer.writeInt32(((IntType) v).get()); - } else if (v instanceof LongType) { - writer.writeInt64(((LongType) v).get()); - } else if (v instanceof BoolType) { - writer.writeBoolean(((BoolType) v).get()); - } else if (v instanceof Integer) { - writer.writeInt32((Integer) v); - } else if (v instanceof Long) { - writer.writeInt64((Long) v); - } else if (v instanceof Float) { - writer.writeDouble((Float) v); - } else if (v instanceof Double) { - writer.writeDouble((Double) v); - } else if (v instanceof Character) { - writer.writeString(String.valueOf(v)); - } else if (v instanceof Byte) { - writer.writeInt32(((Byte) v).intValue()); - } else if (v instanceof Short) { - writer.writeInt32(((Short) v).intValue()); - } else if (v instanceof Boolean) { - writer.writeBoolean((Boolean) v); - } else if (v instanceof String) { - writer.writeString(((String) v).intern()); - } else { - System.out.println("Type not supported. Type: " + v.getClass().getSimpleName()); - } - - } - - @Override - public Class> getEncoderClass() { - return (Class>) ImgLabeling.fromImageAndLabels(null, null).getClass(); - } - - public Class getClazz() { - return clazz; - } - - public CodecRegistry getCodecRegistry() { - return codecRegistry; - } - - public void setCodecRegistry(CodecRegistry codecRegistry) { - this.codecRegistry = codecRegistry; - } - - public String getIndexImg() { - return indexImg; - } - - public void setIndexImg(final String indexImg) { - this.indexImg = indexImg; - } - - public LongFunction getIdToLabel() { - return idToLabel; - } - - public void setIdToLabel(final LongFunction idToLabel) { - this.idToLabel = idToLabel; - } - - public ToLongFunction getLabelToId() { - return labelToId; - } - - public void setLabelToId(final ToLongFunction labelToId) { - this.labelToId = labelToId; - } - - public static final class Builder> { - - private Path file; - - private DatasetIOService datasetIOService; - - private Class clazz = null; - - private CodecRegistry codecRegistry = null; - - private String indexImg = null; - - private LongFunction idToLabel = null; - - private ToLongFunction labelToId = null; - - /** - * Set either a class and include a codec for that class - * or provide functions for encoding {@link #setLabelToId} - * and decoding {@link #setIdToLabel}. - * - * @param clazz the class that represents a label - * @return a Builder for a LabelingMappingCodec - */ - public Builder setClazz(final Class clazz) { - this.clazz = clazz; - return this; - } - - public Builder setCodecRegistry(final CodecRegistry codecRegistry) { - this.codecRegistry = codecRegistry; - return this; - } - - public Builder setIndexImg(final String indexImg) { - this.indexImg = indexImg; - return this; - } - - /** - * Set either this function for decoding or provide a class through {@link #setClazz} - * and codec through the registry {@link #setCodecRegistry} - * - * @param idToLabel the decoding labeling function - * @return a Builder for a LabelingMappingCodec - */ - public Builder setIdToLabel(final LongFunction idToLabel) { - this.idToLabel = idToLabel; - return this; - } - - /** - * Set either this function for encoding or provide a class through {@link #setClazz} - * and codec through the registry {@link #setCodecRegistry} - * - * @param labelToId the encoding labeling function - * @return a Builder for a LabelingMappingCodec - */ - public Builder setLabelToId(final ToLongFunction labelToId) { - this.labelToId = labelToId; - return this; - } - - /** - * - * @param file the fully qualified path to the file - * @return a Builder for a LabelingMappingCodec - */ - public Builder setFile(Path file) { - this.file = file; - return this; - } - - /** - * Set the datasetIO Service to use. Can be accessed through the current context. - * @param datasetIOService a scijava dataetIOService gotten through the context - * @return a Builder for a LabelingMappingCodec - */ - public Builder setDatasetIOService(DatasetIOService datasetIOService) { - this.datasetIOService = datasetIOService; - return this; - } - - public ImgLabelingCodec build() { - return new ImgLabelingCodec(this); - } - - } - -} diff --git a/src/main/java/net/imglib2/labeling/codecs/LabelingMappingCodec.java b/src/main/java/net/imglib2/labeling/codecs/LabelingMappingCodec.java deleted file mode 100644 index 2bae052..0000000 --- a/src/main/java/net/imglib2/labeling/codecs/LabelingMappingCodec.java +++ /dev/null @@ -1,424 +0,0 @@ -/*- - * #%L - * ImgLib2: a general-purpose, multidimensional image processing library. - * %% - * Copyright (C) 2020 - 2021 Tobias Pietzsch, Stephan Preibisch, Stephan Saalfeld, - * John Bogovic, Albert Cardona, Barry DeZonia, Christian Dietz, Jan Funke, - * Aivar Grislis, Jonathan Hale, Grant Harris, Stefan Helfrich, Mark Hiner, - * Martin Horn, Steffen Jaensch, Lee Kamentsky, Larry Lindsey, Melissa Linkert, - * Mark Longair, Brian Northan, Nick Perry, Curtis Rueden, Johannes Schindelin, - * Jean-Yves Tinevez and Michael Zinsmaier. - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package net.imglib2.labeling.codecs; - -import io.scif.services.DatasetIOService; -import net.imglib2.RandomAccessibleInterval; -import net.imglib2.img.Img; -import net.imglib2.labeling.data.Container; -import net.imglib2.labeling.utils.LabelingUtil; -import net.imglib2.roi.labeling.ImgLabeling; -import net.imglib2.roi.labeling.LabelingMapping; -import net.imglib2.type.logic.BoolType; -import net.imglib2.type.numeric.IntegerType; -import net.imglib2.type.numeric.integer.IntType; -import net.imglib2.type.numeric.integer.LongType; -import org.bson.*; -import org.bson.codecs.Codec; -import org.bson.codecs.DecoderContext; -import org.bson.codecs.EncoderContext; -import org.bson.codecs.configuration.CodecRegistry; - -import java.io.IOException; -import java.nio.file.Path; -import java.util.*; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.LongFunction; -import java.util.function.ToLongFunction; -import java.util.stream.Collectors; - -import static net.imglib2.labeling.utils.LabelingUtil.TIF_ENDING; - -/** - * A codec (encoder/decoder) for the LabelingMapping class to and from the BSON (binary JSON) data type. - * The resulting data structure consists of the number of sets, a mapping from complex type to integer - * as well as the actual label sets. The Codec class is used in the LabelingIO class and handles - * the basic structure. For non-primitive label types, an additional codec must be written. - * V1 Data structure: - * // @formatter:off - * { - * version: int32 - * numSets: int32 - * indexImg: String - * mapping: { //may be empty - * "1": {//encoded type} - * ... - * } - * labelSets:{ - * labelSet_n: [...] - * ... - * } - * } - * // @formatter:on - * - * @author Tom Burke - */ -public class LabelingMappingCodec> implements Codec> { - private final static int VERSION = 1; - private static final Set WRAPPER_TYPES = new HashSet(Arrays.asList(IntType.class, LongType.class, BoolType.class, - Boolean.class, Character.class, Byte.class, Short.class, Integer.class, Long.class, Float.class, Double.class, Void.class, String.class)); - private final Class clazz; - private final Class metadataClazz; - private CodecRegistry codecRegistry; - private String indexImg; - private LongFunction idToLabel; - private ToLongFunction labelToId; - private DatasetIOService datasetIOService; - private Path file; - - private LabelingMappingCodec(final Builder builder) { - this.clazz = builder.clazz; - this.metadataClazz = builder.metadataClazz; - this.codecRegistry = builder.codecRegistry; - this.indexImg = builder.indexImg; - this.idToLabel = builder.idToLabel; - this.labelToId = builder.labelToId; - this.datasetIOService = builder.datasetIOService; - this.file = builder.file; - } - - public static boolean isWrapperType(Class clazz) { - return WRAPPER_TYPES.contains(clazz); - } - - @Override - public Container decode(BsonReader reader, DecoderContext decoderContext) { - LabelingMapping labelingMapping = new LabelingMapping<>(new IntType()); - String path = this.file.getParent().toString(); - reader.readStartDocument(); - int version = reader.readInt32("version"); - int numSets = reader.readInt32("numSets"); - int numSources = reader.readInt32("numSources"); - this.indexImg = reader.readString("indexImg"); - - - RandomAccessibleInterval img = null; - try { - img = (Img) datasetIOService.open(LabelingUtil.getFilePathWithExtension(indexImg, TIF_ENDING, path)).getImgPlus().getImg(); - } catch (IOException e) { - e.printStackTrace(); - } - Map mapping = readMapping(reader, decoderContext, clazz); - Container container = readLabelSetsContainer(reader, decoderContext, numSets, numSources, mapping, img); - return container; - } - - private Container readLabelSetsContainer(BsonReader reader, DecoderContext decoderContext, int numSets, int numSources, Map mapping, RandomAccessibleInterval img) { - Container container = new Container<>(); - List> labelSets = new ArrayList<>(); - reader.readStartDocument(); - for (int i = 0; i < numSets; i++) { - Set labelSet; - BsonType bsonType = reader.readBsonType(); - if (bsonType == BsonType.DOCUMENT) { - reader.readStartDocument(); - labelSet = readLabelSet(reader, decoderContext, mapping); - reader.readEndDocument(); - } else { - labelSet = readLabelSet(reader, decoderContext, mapping); - } - labelSets.add(labelSet); - } - reader.readEndDocument(); - container.setImgLabeling(ImgLabeling.fromImageAndLabelSets(img, labelSets)); - S metadata = getCodecRegistry().get(metadataClazz).decode(reader,decoderContext); - container.setMetadata(metadata); - return container; - } - - private Set readLabelSet(BsonReader reader, DecoderContext decoderContext, Map mapping) { - BsonArray bsonValues = getCodecRegistry().get(BsonArray.class).decode(reader, decoderContext); - Set labelSet = bsonValues.stream().map(v -> { - if (v.isInt32()) - return v.asInt32().intValue(); - else - return v.asInt64().intValue(); - }).map(v -> { - if (getIdToLabel() != null) - return getIdToLabel().apply(v); - else if (!mapping.isEmpty()) - return mapping.get(v); - else - return v; - }).collect(Collectors.toSet()); - - - return (Set) labelSet; - } - - @Override - public void encode(BsonWriter writer, Container value, EncoderContext encoderContext) { - writer.writeStartDocument(); - writer.writeInt32("version", VERSION); - writer.writeInt32("numSets", value.getImgLabeling().getMapping().numSets()); - writer.writeInt32("numSources", 1); - writer.writeString("indexImg", indexImg); - Optional first = value.getImgLabeling().getMapping().getLabels().stream().findFirst(); - if (first.isPresent() && !isWrapperType(first.get().getClass())) { - if (clazz == null) { - writer.writeStartDocument("labelMapping"); - writer.writeEndDocument(); - writer.writeStartDocument("labelSets"); - for (int i = 0; i < value.getImgLabeling().getMapping().numSets(); i++) { - Set labelSet = value.getImgLabeling().getMapping().labelsAtIndex(i); - writer.writeStartArray(Integer.toString(i)); - labelSet.forEach(v -> writeValue(labelToId.applyAsLong(v), writer, encoderContext)); - writer.writeEndArray(); - } - writer.writeEndDocument(); - } else { - AtomicInteger count = new AtomicInteger(); - HashMap map = new HashMap<>(); - writer.writeStartDocument("labelMapping"); - value.getImgLabeling().getMapping().getLabels().forEach(v -> { - map.put(v, count.get()); - writer.writeName(String.valueOf(count.getAndIncrement())); - Codec codec = (Codec) codecRegistry.get(v.getClass()); - encoderContext.encodeWithChildContext(codec, writer, v); - }); - writer.writeEndDocument(); - writer.writeStartDocument("labelSets"); - for (int i = 0; i < value.getImgLabeling().getMapping().numSets(); i++) { - Set labelSet = value.getImgLabeling().getMapping().labelsAtIndex(i); - writer.writeStartArray(Integer.toString(i)); - labelSet.forEach(v -> writeValue(map.get(v), writer, encoderContext)); - writer.writeEndArray(); - } - writer.writeEndDocument(); - } - } else { - writer.writeStartDocument("labelMapping"); - writer.writeEndDocument(); - writer.writeStartDocument("labelSets"); - for (int i = 0; i < value.getImgLabeling().getMapping().numSets(); i++) { - Set labelSet = value.getImgLabeling().getMapping().labelsAtIndex(i); - writer.writeStartArray(Integer.toString(i)); - labelSet.forEach(v -> writeValue(v, writer, encoderContext)); - writer.writeEndArray(); - } - writer.writeEndDocument(); - } - writer.writeName("metadata"); - getCodecRegistry().get(metadataClazz).encode(writer, value.getMetadata(), encoderContext); - writer.writeEndDocument(); - } - - private Map readMapping(BsonReader reader, DecoderContext decoderContext, Class clazz) { - Map mapping = new HashMap<>(); - reader.readStartDocument(); - while (reader.readBsonType() != BsonType.END_OF_DOCUMENT) { - int key = Integer.parseInt(reader.readName()); - Codec c = codecRegistry.get(clazz); - T value = c.decode(reader, decoderContext); - mapping.put(key, value); - } - - reader.readEndDocument(); - return mapping; - } - - private void writeValue(Object v, BsonWriter writer, EncoderContext encoderContext) { - if (v instanceof IntType) { - writer.writeInt32(((IntType) v).get()); - } else if (v instanceof LongType) { - writer.writeInt64(((LongType) v).get()); - } else if (v instanceof BoolType) { - writer.writeBoolean(((BoolType) v).get()); - } else if (v instanceof Integer) { - writer.writeInt32((Integer) v); - } else if (v instanceof Long) { - writer.writeInt64((Long) v); - } else if (v instanceof Float) { - writer.writeDouble((Float) v); - } else if (v instanceof Double) { - writer.writeDouble((Double) v); - } else if (v instanceof Character) { - writer.writeString(String.valueOf(v)); - } else if (v instanceof Byte) { - writer.writeInt32(((Byte) v).intValue()); - } else if (v instanceof Short) { - writer.writeInt32(((Short) v).intValue()); - } else if (v instanceof Boolean) { - writer.writeBoolean((Boolean) v); - } else if (v instanceof String) { - writer.writeString(((String) v).intern()); - } else { - System.out.println("Type not supported. Type: " + v.getClass().getSimpleName()); - } - - } - - @Override - public Class > getEncoderClass() { - return (Class >) new Container ().getClass(); - } - - public Class getClazz() { - return clazz; - } - - public CodecRegistry getCodecRegistry() { - return codecRegistry; - } - - public void setCodecRegistry(CodecRegistry codecRegistry) { - this.codecRegistry = codecRegistry; - } - - public String getIndexImg() { - return indexImg; - } - - public void setIndexImg(final String indexImg) { - this.indexImg = indexImg; - } - - public LongFunction getIdToLabel() { - return idToLabel; - } - - public void setIdToLabel(final LongFunction idToLabel) { - this.idToLabel = idToLabel; - } - - public ToLongFunction getLabelToId() { - return labelToId; - } - - public void setLabelToId(final ToLongFunction labelToId) { - this.labelToId = labelToId; - } - - public static final class Builder> { - - private Class metadataClazz; - - private Path file; - - private DatasetIOService datasetIOService; - - private Class clazz = null; - - private CodecRegistry codecRegistry = null; - - private String indexImg = null; - - private LongFunction idToLabel = null; - - private ToLongFunction labelToId = null; - - /** - * Set either a class and include a codec for that class - * or provide functions for encoding {@link #setLabelToId} - * and decoding {@link #setIdToLabel}. - * - * @param clazz the class that represents a label - * @return a Builder for a LabelingMappingCodec - */ - public Builder setClazz(final Class clazz) { - this.clazz = clazz; - return this; - } - - public Builder setCodecRegistry(final CodecRegistry codecRegistry) { - this.codecRegistry = codecRegistry; - return this; - } - - public Builder setIndexImg(final String indexImg) { - this.indexImg = indexImg; - return this; - } - - /** - * Set either this function for decoding or provide a class through {@link #setClazz} - * and codec through the registry {@link #setCodecRegistry} - * - * @param idToLabel the decoding labeling function - * @return a Builder for a LabelingMappingCodec - */ - public Builder setIdToLabel(final LongFunction idToLabel) { - this.idToLabel = idToLabel; - return this; - } - - /** - * Set either this function for encoding or provide a class through {@link #setClazz} - * and codec through the registry {@link #setCodecRegistry} - * - * @param labelToId the encoding labeling function - * @return a Builder for a LabelingMappingCodec - */ - public Builder setLabelToId(final ToLongFunction labelToId) { - this.labelToId = labelToId; - return this; - } - - /** - * - * @param file the fully qualified path to the file - * @return a Builder for a LabelingMappingCodec - */ - public Builder setFile(Path file) { - this.file = file; - return this; - } - - /** - * Set the datasetIO Service to use. Can be accessed through the current context. - * @param datasetIOService the datasetIO Service to use - * @return a Builder for a LabelingMappingCodec - */ - public Builder setDatasetIOService(DatasetIOService datasetIOService) { - this.datasetIOService = datasetIOService; - return this; - } - - /** - * the class of the metadata that is contained in the file. also needs a codec to decode - * @param metadataClazz the metadata class to use - * @return a Builder for a LabelingMappingCodec - */ - public Builder setMetadataClazz(Class metadataClazz) { - this.metadataClazz = metadataClazz; - return this; - } - - public LabelingMappingCodec build() { - return new LabelingMappingCodec<>(this); - } - - } - -} diff --git a/src/main/java/net/imglib2/labeling/data/ImgLabelingContainer.java b/src/main/java/net/imglib2/labeling/data/ImgLabelingContainer.java deleted file mode 100644 index 43e7234..0000000 --- a/src/main/java/net/imglib2/labeling/data/ImgLabelingContainer.java +++ /dev/null @@ -1,70 +0,0 @@ -/*- - * #%L - * ImgLib2: a general-purpose, multidimensional image processing library. - * %% - * Copyright (C) 2020 - 2021 Tobias Pietzsch, Stephan Preibisch, Stephan Saalfeld, - * John Bogovic, Albert Cardona, Barry DeZonia, Christian Dietz, Jan Funke, - * Aivar Grislis, Jonathan Hale, Grant Harris, Stefan Helfrich, Mark Hiner, - * Martin Horn, Steffen Jaensch, Lee Kamentsky, Larry Lindsey, Melissa Linkert, - * Mark Longair, Brian Northan, Nick Perry, Curtis Rueden, Johannes Schindelin, - * Jean-Yves Tinevez and Michael Zinsmaier. - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package net.imglib2.labeling.data; - -import net.imglib2.roi.labeling.ImgLabeling; -import net.imglib2.type.numeric.IntegerType; - -import java.util.Map; -import java.util.Set; - -public class ImgLabelingContainer> { - - ImgLabeling imgLabeling; - Map> sourceToLabel; - - public ImgLabelingContainer(ImgLabeling imgLabeling, Map> sourceToLabel) { - this.imgLabeling = imgLabeling; - this.sourceToLabel = sourceToLabel; - } - - public ImgLabelingContainer() { - } - - public ImgLabeling getImgLabeling() { - return imgLabeling; - } - - public void setImgLabeling(ImgLabeling imgLabeling) { - this.imgLabeling = imgLabeling; - } - - public Map> getSourceToLabel() { - return sourceToLabel; - } - - public void setSourceToLabel(Map> sourceToLabel) { - this.sourceToLabel = sourceToLabel; - } -} diff --git a/src/main/java/net/imglib2/labeling/data/LabelingContainer.java b/src/main/java/net/imglib2/labeling/data/LabelingContainer.java deleted file mode 100644 index aeb1970..0000000 --- a/src/main/java/net/imglib2/labeling/data/LabelingContainer.java +++ /dev/null @@ -1,89 +0,0 @@ -/*- - * #%L - * ImgLib2: a general-purpose, multidimensional image processing library. - * %% - * Copyright (C) 2020 - 2021 Tobias Pietzsch, Stephan Preibisch, Stephan Saalfeld, - * John Bogovic, Albert Cardona, Barry DeZonia, Christian Dietz, Jan Funke, - * Aivar Grislis, Jonathan Hale, Grant Harris, Stefan Helfrich, Mark Hiner, - * Martin Horn, Steffen Jaensch, Lee Kamentsky, Larry Lindsey, Melissa Linkert, - * Mark Longair, Brian Northan, Nick Perry, Curtis Rueden, Johannes Schindelin, - * Jean-Yves Tinevez and Michael Zinsmaier. - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package net.imglib2.labeling.data; - -import net.imglib2.roi.labeling.LabelingMapping; - -import java.util.*; - -public class LabelingContainer { - - List> labelSets; - Map> sourceToLabel = new HashMap<>(); - LabelingMapping labelingMapping; - - - public LabelingContainer(List> labelSets, Map> sourceToLabel, LabelingMapping labelingMapping) { - this.labelSets = labelSets; - this.sourceToLabel = sourceToLabel; - this.labelingMapping = labelingMapping; - } - - public LabelingContainer() { - - } - - public void addLabelToSource(String source, T label) { - sourceToLabel.putIfAbsent(source, new HashSet<>()); - sourceToLabel.get(source).add(label); - } - - public List> getLabelSets() { - return labelSets; - } - - public void setLabelSets(List> labelSets) { - if (labelingMapping != null) - labelingMapping.setLabelSets(labelSets); - this.labelSets = labelSets; - } - - public Map> getSourceToLabel() { - return sourceToLabel; - } - - public void setSourceToLabel(Map> sourceToLabel) { - this.sourceToLabel = sourceToLabel; - } - - public LabelingMapping getLabelingMapping() { - return labelingMapping; - } - - public void setLabelingMapping(LabelingMapping labelingMapping) { - this.labelingMapping = labelingMapping; - if (labelSets != null) - labelingMapping.setLabelSets(labelSets); - } -} diff --git a/src/main/java/net/imglib2/labeling/data/LabelingData.java b/src/main/java/net/imglib2/labeling/data/LabelingData.java new file mode 100644 index 0000000..49fbe2d --- /dev/null +++ b/src/main/java/net/imglib2/labeling/data/LabelingData.java @@ -0,0 +1,95 @@ +package net.imglib2.labeling.data; + +import com.google.gson.Gson; + +import java.util.Map; +import java.util.Objects; +import java.util.Set; + +public class LabelingData { + + private int version = 3; + private int numSets = 0; + private int numSources = 0; + private String indexImg; + private Map labelMapping; + private Map> labelSets; + private S metadata; + + public int getVersion() { + return this.version; + } + + public void setVersion(int version) { + this.version = version; + } + + public int getNumSets() { + return this.numSets; + } + + public void setNumSets(int numSets) { + this.numSets = numSets; + } + + public int getNumSources() { + return this.numSources; + } + + public void setNumSources(int numSources) { + this.numSources = numSources; + } + + public String getIndexImg() { + return this.indexImg; + } + + public void setIndexImg(String indexImg) { + this.indexImg = indexImg; + } + + public Map getLabelMapping() { + return this.labelMapping; + } + + public void setLabelMapping(Map labelMapping) { + this.labelMapping = labelMapping; + } + + public Map> getLabelSets() { + return this.labelSets; + } + + public void setLabelSets(Map> labelSets) { + this.labelSets = labelSets; + } + + public S getMetadata() { + return this.metadata; + } + + public void setMetadata(S metadata) { + this.metadata = metadata; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || this.getClass() != o.getClass()) return false; + LabelingData that = (LabelingData) o; + return this.numSets == that.numSets && this.indexImg.equals(that.indexImg) && this.labelSets.equals(that.labelSets); + } + + @Override + public int hashCode() { + return Objects.hash(this.numSets, this.indexImg, this.labelSets); + } + + public String toJson(){ + return new Gson().toJson(this); + } + + public LabelingData fromJson(String json){ + return new Gson().fromJson(json, this.getClass()); + } +} \ No newline at end of file diff --git a/src/main/java/net/imglib2/labeling/utils/LabelingUtil.java b/src/main/java/net/imglib2/labeling/utils/LabelingUtil.java index 8a82682..b79a0f0 100644 --- a/src/main/java/net/imglib2/labeling/utils/LabelingUtil.java +++ b/src/main/java/net/imglib2/labeling/utils/LabelingUtil.java @@ -40,19 +40,16 @@ import net.imglib2.exception.IncompatibleTypeException; import net.imglib2.img.ImgView; import net.imglib2.type.numeric.RealType; -import org.bson.io.BasicOutputBuffer; import org.scijava.Context; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; import java.nio.file.Paths; public class LabelingUtil { - public static final String BSON_ENDING = ".bson"; + public static final String LBL_ENDING = ".lbl.json"; public static final String TIF_ENDING = ".tif"; + public final static int VERSION = 3; /** * @param context the scijava context used in the project @@ -71,14 +68,6 @@ public static > void saveAsTiff(final Context context, } } - public static void writeToFile(BasicOutputBuffer outputBuffer, File file) { - try (FileOutputStream fileOutputStream = new FileOutputStream(file)) { - outputBuffer.pipe(fileOutputStream); - } catch (IOException e) { - e.printStackTrace(); - } - } - public static String getFilePathWithExtension(final String filename, final String extension, String path) { path = (path == null) ? "" : path; String actualFilename = Paths.get(filename).getFileName().toString(); diff --git a/src/test/java/net/imglib2/labeling/LabelingIOTest.java b/src/test/java/net/imglib2/labeling/LabelingIOTest.java index 6420f37..78fece4 100644 --- a/src/test/java/net/imglib2/labeling/LabelingIOTest.java +++ b/src/test/java/net/imglib2/labeling/LabelingIOTest.java @@ -35,16 +35,10 @@ import net.imglib2.img.Img; import net.imglib2.img.array.ArrayImgs; -import net.imglib2.labeling.codecs.LabelingMappingCodec; import net.imglib2.labeling.data.Container; import net.imglib2.roi.labeling.ImgLabeling; import net.imglib2.type.numeric.integer.IntType; import net.imglib2.type.numeric.integer.UnsignedByteType; -import org.bson.BsonReader; -import org.bson.BsonWriter; -import org.bson.codecs.Codec; -import org.bson.codecs.DecoderContext; -import org.bson.codecs.EncoderContext; import org.junit.Assert; import org.junit.Before; import org.junit.Test; @@ -64,25 +58,33 @@ public void beforeTests() { } @Test - public void test() throws IOException { + public void testEquality() throws IOException { LabelingIOService labelingIOService = context.getService(LabelingIOService.class); - ImgLabeling imgLabeling = labelingIOService.load("src/test/resources/labeling/example1.bson"); - labelingIOService.save(imgLabeling, "src/test/resources/labeling/example1_sav.bson"); + ImgLabeling imgLabeling = labelingIOService.load("src/test/resources/labeling/labelSaveTestSimple"); + labelingIOService.save(imgLabeling, "src/test/resources/labeling/example1_sav"); + ImgLabeling imgLabeling2 = labelingIOService.load("src/test/resources/labeling/example1_sav"); + Assert.assertEquals(imgLabeling.getMapping().getLabels(),imgLabeling2.getMapping().getLabels()); } @Test - public void saveLabelingWithMetadataPrimitiveTest() { + public void testEquality2() throws IOException { + LabelingIOService labelingIOService = context.getService(LabelingIOService.class); + ImgLabeling imgLabeling = labelingIOService.load("src/test/resources/labeling/test"); + labelingIOService.save(imgLabeling, "src/test/resources/labeling/test2"); + ImgLabeling imgLabeling2 = labelingIOService.load("src/test/resources/labeling/test2"); + Assert.assertEquals(imgLabeling.getMapping().getLabels(),imgLabeling2.getMapping().getLabels()); + } + + @Test + public void saveLabelingWithMetadataPrimitiveTest() throws IOException { ImgLabeling labeling = getSimpleImgLabeling(); - Container container = new Container(); - container.setImgLabeling(labeling); - container.setMetadata(new Example("a",2.0,1)); - context.getService(LabelingIOService.class).saveWithMetaData(container, new File("src/test/resources/labeling/labelSaveTestSimple.tif").getAbsolutePath(), Example.class, new ExampleCodec()); + context.getService(LabelingIOService.class).saveWithMetaData(labeling, new File("src/test/resources/labeling/labelSaveTestSimple.tif").getAbsolutePath(), new Example("a",2.0,1)); } @Test public void loadLabelingWithMetadataPrimitiveTest() throws IOException { - Container container = context.getService(LabelingIOService.class).loadWithMetadata("src/test/resources/labeling/labelSaveTestSimple.bson", Example.class, new ExampleCodec()); + Container container = context.getService(LabelingIOService.class).loadWithMetadata("src/test/resources/labeling/labelSaveTestSimpleMeta.tif", Example.class); ImgLabeling mapping = container.getImgLabeling(); Example e = container.getMetadata(); Assert.assertNotNull(e); @@ -90,23 +92,20 @@ public void loadLabelingWithMetadataPrimitiveTest() throws IOException { } @Test - public void saveLabelingWithMetadataComplexWithCodecTest() { + public void saveLabelingWithMetadataComplexTest() throws IOException { ImgLabeling labeling = getComplexImgLabeling(); LabelingIOService labelingIOService = context.getService(LabelingIOService.class); - Container container = new Container(); - container.setImgLabeling(labeling); - container.setMetadata(new Example("a",2.0,1)); - labelingIOService.saveWithMetaData(container, new File("src/test/resources/labeling/labelSaveTestComplex.tif").getAbsolutePath(), Example.class, Example.class, new ExampleCodec()); + labelingIOService.saveWithMetaData(labeling, new File("src/test/resources/labeling/labelSaveTestComplex.tif").getAbsolutePath(), new Example("a",2.0,1)); } @Test public void loadLabelingWithMetadataComplexWithCodecTest() throws IOException { LabelingIOService labelingIOService = context.getService(LabelingIOService.class); - Container container = labelingIOService.loadWithMetadata("src/test/resources/labeling/labelSaveTestComplex.bson", Example.class, Example.class, new ExampleCodec()); - ImgLabeling mapping = container.getImgLabeling(); - Example e = container.getMetadata(); - Assert.assertNotNull(e); - Assert.assertEquals(getComplexImgLabeling().getMapping().getLabels(), mapping.getMapping().getLabels()); +// Container container = labelingIOService.loadWithMetadata("src/test/resources/labeling/labelSaveTestComplex.bson", Example.class, Example.class, new ExampleCodec()); +// ImgLabeling mapping = container.getImgLabeling(); +// Example e = container.getMetadata(); +// Assert.assertNotNull(e); +// Assert.assertEquals(getComplexImgLabeling().getMapping().getLabels(), mapping.getMapping().getLabels()); } @Test @@ -119,8 +118,8 @@ public void saveLabelingWithMetadataComplexWithFunctionTest() { Container container = new Container(); container.setImgLabeling(labeling); container.setMetadata(new Example("a",2.0,1)); - labelingIOService.saveWithMetaData(container, new File("src/test/resources/labeling/labelSaveTestComplexFunction.tif").getAbsolutePath(), - mapping::get, Example.class, new ExampleCodec()); +// labelingIOService.saveWithMetaData(container, new File("src/test/resources/labeling/labelSaveTestComplexFunction.tif").getAbsolutePath(), +// mapping::get, Example.class, new ExampleCodec()); } @Test @@ -130,20 +129,12 @@ public void loadLabelingWithMetadataComplexWithFunctionTest() throws IOException Map map = new HashMap<>(); AtomicLong atomicLong = new AtomicLong(0); labels.forEach(label -> map.put(atomicLong.getAndIncrement(), label)); - Container container = labelingIOService.loadWithMetadata("src/test/resources/labeling/labelSaveTestComplexFunction.bson", map::get, - Example.class, new ExampleCodec()); - Example metadata = container.getMetadata(); - Assert.assertNotNull(metadata); - Assert.assertEquals(new Example("a",2.0,1), metadata); - Assert.assertEquals(labels, container.getImgLabeling().getMapping().getLabels()); - } - - @Test - public void encoderClassTest() { - LabelingMappingCodec labelingMappingCodec = new LabelingMappingCodec.Builder<>().build(); - Class c = labelingMappingCodec.getEncoderClass(); - - Assert.assertEquals(Container.class, c); +// Container container = labelingIOService.loadWithMetadata("src/test/resources/labeling/labelSaveTestComplexFunction.bson", map::get, +// Example.class, new ExampleCodec()); +// Example metadata = container.getMetadata(); +// Assert.assertNotNull(metadata); +// Assert.assertEquals(new Example("a",2.0,1), metadata); +// Assert.assertEquals(labels, container.getImgLabeling().getMapping().getLabels()); } private ImgLabeling getSimpleImgLabeling() { @@ -151,7 +142,7 @@ private ImgLabeling getSimpleImgLabeling() { Integer[] values2 = new Integer[]{1}; Integer[] values3 = new Integer[]{1, 13, 42}; // setup - Img indexImg = ArrayImgs.unsignedBytes(new byte[]{1, 0, 2}, 3); + Img indexImg = ArrayImgs.unsignedBytes(new byte[]{1, 0, 2}, 1); List> labelSets = Arrays.asList(asSet(), asSet(values1), asSet(values2), asSet(values3)); return ImgLabeling.fromImageAndLabelSets(indexImg, labelSets); } @@ -161,7 +152,7 @@ private ImgLabeling getComplexImgLabeling() { Example[] values2 = new Example[]{new Example("a", 1.0, 1)}; Example[] values3 = new Example[]{new Example("b", 2.24121, 2), new Example("a", 1.0, 1), new Example("a", 1.0, 3)}; // setup - Img indexImg = ArrayImgs.ints(new int[]{1, 0, 2}, 3); + Img indexImg = ArrayImgs.ints(new int[]{1, 0, 2}, 1); List> labelSets = Arrays.asList(asSet(), asSet(values1), asSet(values2), asSet(values3)); return ImgLabeling.fromImageAndLabelSets(indexImg, labelSets); } @@ -171,32 +162,6 @@ private Set asSet(T... values) { return new TreeSet<>(Arrays.asList(values)); } - private static class ExampleCodec implements Codec { - - @Override - public Example decode(BsonReader reader, DecoderContext decoderContext) { - reader.readStartDocument(); - String a = reader.readString("a"); - double b = reader.readDouble("b"); - int c = reader.readInt32("c"); - reader.readEndDocument(); - return new Example(a, b, c); - } - - @Override - public void encode(BsonWriter writer, Example value, EncoderContext encoderContext) { - writer.writeStartDocument(); - writer.writeString("a", value.a); - writer.writeDouble("b", value.b); - writer.writeInt32("c", value.c); - writer.writeEndDocument(); - } - - @Override - public Class getEncoderClass() { - return Example.class; - } - } private static class Example implements Comparable { diff --git a/src/test/java/net/imglib2/labeling/tutorials/E01_LoadLabeling.java b/src/test/java/net/imglib2/labeling/tutorials/E01_LoadLabeling.java index 70c1252..bc3d3d9 100644 --- a/src/test/java/net/imglib2/labeling/tutorials/E01_LoadLabeling.java +++ b/src/test/java/net/imglib2/labeling/tutorials/E01_LoadLabeling.java @@ -36,7 +36,6 @@ import net.imglib2.img.Img; import net.imglib2.img.array.ArrayImgs; import net.imglib2.labeling.LabelingIOService; -import net.imglib2.labeling.data.Container; import net.imglib2.roi.labeling.ImgLabeling; import net.imglib2.type.numeric.integer.IntType; import net.imglib2.type.numeric.integer.UnsignedByteType; @@ -67,22 +66,7 @@ public void loadBasicLabeling() throws IOException { // the container contains an ImgLabeling of that type as well as an optional sourcemap // the sourcemap is a mapping of a source img to a list of labels that where contained in it and added to // the ImgLabeling - ImgLabeling imgLabeling = labelingIOService.load("src/test/resources/labeling/labelSaveTestSimple.bson"); - Assert.assertNotNull(imgLabeling); - Assert.assertNotNull(imgLabeling.getIndexImg()); - Assert.assertFalse(imgLabeling.getMapping().getLabels().isEmpty()); - - } - - @Test - public void loadBasicLabeling2() throws IOException { - // get the LabelingIO service from the context - LabelingIOService labelingIOService = context.getService(LabelingIOService.class); - // load a bson file with IntType labels - // the container contains an ImgLabeling of that type as well as an optional sourcemap - // the sourcemap is a mapping of a source img to a list of labels that where contained in it and added to - // the ImgLabeling - ImgLabeling imgLabeling = labelingIOService.load("src/test/resources/labeling/example1.bson"); + ImgLabeling imgLabeling = labelingIOService.load("src/test/resources/labeling/labelSaveTestSimple.lbl.json"); Assert.assertNotNull(imgLabeling); Assert.assertNotNull(imgLabeling.getIndexImg()); Assert.assertFalse(imgLabeling.getMapping().getLabels().isEmpty()); @@ -101,18 +85,18 @@ public void loadFunctionBasedLabeling() throws IOException { AtomicLong atomicLong = new AtomicLong(0); labels.forEach(label -> map.put(atomicLong.getAndIncrement(), label)); //get the ImgLabeling with Example.class from our mapping through the map.get() function - Container container = labelingIOService.loadWithMetadata("src/test/resources/labeling/labelSaveTestComplexFunction.bson", map::get, Example.class, new ExampleCodec()); - ImgLabeling mapping = container.getImgLabeling(); - Assert.assertNotNull(mapping); +// Container container = labelingIOService.loadWithMetadata("src/test/resources/labeling/labelSaveTestComplexFunction.bson", map::get, Example.class, new ExampleCodec()); +// ImgLabeling mapping = container.getImgLabeling(); +// Assert.assertNotNull(mapping); } @Test public void loadClassBasedLabeling() throws IOException { // get the LabelingIO service from the context LabelingIOService labelingIOService = context.getService(LabelingIOService.class); - Container container = labelingIOService.loadWithMetadata("src/test/resources/labeling/labelSaveTestComplex.bson", Example.class, Example.class, new ExampleCodec()); - ImgLabeling mapping = container.getImgLabeling(); - Assert.assertNotNull(mapping); +// Container container = labelingIOService.loadWithMetadata("src/test/resources/labeling/labelSaveTestComplex.bson", Example.class, Example.class, new ExampleCodec()); +// ImgLabeling mapping = container.getImgLabeling(); +// Assert.assertNotNull(mapping); } diff --git a/src/test/java/net/imglib2/labeling/tutorials/E02_SaveLabeling.java b/src/test/java/net/imglib2/labeling/tutorials/E02_SaveLabeling.java index d92e48f..d446a53 100644 --- a/src/test/java/net/imglib2/labeling/tutorials/E02_SaveLabeling.java +++ b/src/test/java/net/imglib2/labeling/tutorials/E02_SaveLabeling.java @@ -40,7 +40,6 @@ import net.imglib2.roi.labeling.ImgLabeling; import net.imglib2.type.numeric.integer.IntType; import net.imglib2.type.numeric.integer.UnsignedByteType; -import org.bson.codecs.MapCodec; import org.junit.Before; import org.junit.Test; import org.scijava.Context; @@ -73,13 +72,13 @@ public void saveLabelingTest2() throws IOException { ImgLabeling labeling = getComplexImgLabeling(); // get the LabelingIO service from the context LabelingIOService labelingIOService = context.getService(LabelingIOService.class); - labelingIOService.save(labeling, new File("src/test/resources/labeling/labelSaveTestSimple.tif").getAbsolutePath(), Example.class, new ExampleCodec()); + labelingIOService.save(labeling, new File("src/test/resources/labeling/labelSaveTestComplex.tif").getAbsolutePath()); } @Test - public void saveLabelingWithMetaDataTest() { + public void saveLabelingWithMetaDataTest() throws IOException { ImgLabeling labeling = getSimpleImgLabeling(); Container container = new Container<>(); container.setImgLabeling(labeling); @@ -94,7 +93,7 @@ public void saveLabelingWithMetaDataTest() { // get the LabelingIO service from the context LabelingIOService labelingIOService = context.getService(LabelingIOService.class); - labelingIOService.saveWithMetaData(container, new File("src/test/resources/labeling/labelSaveTestSimple.tif").getAbsolutePath(), Map.class, new MapCodec()); + labelingIOService.saveWithMetaData(labeling, new File("src/test/resources/labeling/labelSaveTestSimpleMeta.tif").getAbsolutePath(), sources); } diff --git a/src/test/java/net/imglib2/labeling/tutorials/ExampleCodec.java b/src/test/java/net/imglib2/labeling/tutorials/ExampleCodec.java deleted file mode 100644 index d44506d..0000000 --- a/src/test/java/net/imglib2/labeling/tutorials/ExampleCodec.java +++ /dev/null @@ -1,67 +0,0 @@ -/*- - * #%L - * ImgLib2: a general-purpose, multidimensional image processing library. - * %% - * Copyright (C) 2020 - 2021 Tobias Pietzsch, Stephan Preibisch, Stephan Saalfeld, - * John Bogovic, Albert Cardona, Barry DeZonia, Christian Dietz, Jan Funke, - * Aivar Grislis, Jonathan Hale, Grant Harris, Stefan Helfrich, Mark Hiner, - * Martin Horn, Steffen Jaensch, Lee Kamentsky, Larry Lindsey, Melissa Linkert, - * Mark Longair, Brian Northan, Nick Perry, Curtis Rueden, Johannes Schindelin, - * Jean-Yves Tinevez and Michael Zinsmaier. - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ -package net.imglib2.labeling.tutorials; - -import org.bson.BsonReader; -import org.bson.BsonWriter; -import org.bson.codecs.Codec; -import org.bson.codecs.DecoderContext; -import org.bson.codecs.EncoderContext; - -class ExampleCodec implements Codec { - - @Override - public Example decode(BsonReader reader, DecoderContext decoderContext) { - reader.readStartDocument(); - String a = reader.readString("a"); - double b = reader.readDouble("b"); - int c = reader.readInt32("c"); - reader.readEndDocument(); - return new Example(a, b, c); - } - - @Override - public void encode(BsonWriter writer, Example value, EncoderContext encoderContext) { - writer.writeStartDocument(); - writer.writeString("a", value.a); - writer.writeDouble("b", value.b); - writer.writeInt32("c", value.c); - writer.writeEndDocument(); - } - - @Override - public Class getEncoderClass() { - return Example.class; - } -} diff --git a/src/test/resources/labeling/example1.bson b/src/test/resources/labeling/example1.bson deleted file mode 100644 index bc39e37c82cdc8f660091901a19b627e0f95524c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 421 zcmZ9IO%8%U427REE=)8bapxfngTGgBVPfJ5P%9yUkq8(rEI#F7{DzrWaf qxaL~&E#_bLd)ht1Z}w-Jf5HoUJrDG+P@YJOtea+{OSPjc;mop diff --git a/src/test/resources/labeling/example1_sav.bson b/src/test/resources/labeling/example1_sav.bson deleted file mode 100644 index 6bbb9f08581dfb5212fc2ac5a953cfee1f30511f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 325 zcmZ9GO%8%E5QU#m7w&4@c?d)C_W~|lxbgs|Y9&pe5DJ8=dK=r~5aO=y`(9_}JOg;A zYO6~F_Xam@aZ`=OfP5m{J1-@6 diff --git a/src/test/resources/labeling/example1_sav.lbl.json b/src/test/resources/labeling/example1_sav.lbl.json new file mode 100644 index 0000000..73e4588 --- /dev/null +++ b/src/test/resources/labeling/example1_sav.lbl.json @@ -0,0 +1 @@ +{"version":3,"numSets":4,"numSources":1,"indexImg":"example1_sav.tif","labelSets":{"0":[],"1":[42,13],"2":[1],"3":[42,13,1]}} \ No newline at end of file diff --git a/src/test/resources/labeling/example1_sav.tif b/src/test/resources/labeling/example1_sav.tif index 746da4b08a1a342327e662307c710e50b500097c..f828cc82f42f62f496972721a2de425d0718e96f 100644 GIT binary patch delta 58 wcmZ3^y@zi@5u*^hB?AN7cLoM_b|4mKU|?Y0+`_2LviUh<1EVM-0~00!067^4!vFvP delta 31 jcmdnPx14)J5u*@mIs*f1IS{u4@pJ|T27%2jjLIwka-#+@ diff --git a/src/test/resources/labeling/labelSaveTestComplex.bson b/src/test/resources/labeling/labelSaveTestComplex.bson deleted file mode 100644 index 650d8968494b830ef1963fbf988b93883293f696..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 342 zcmaKnF>ZrE5Jf-ix^uCTtE6%tDFSi;M@p3iVbq zLFH}!{+Xw*Ki>gh4z%ma#)1DZZeOS5JLrGY>~}eJ{W2_FLC4Q}iznVzHlr%F2ij2Q zKbpF&==kc(AEEj%H(}CRQw200;^<-WRi0Fd-=Vd zgLh7mWM+m|a>1Idjxdw4jJ?Dr$9;s G5|0~UDK#Si diff --git a/src/test/resources/labeling/labelSaveTestComplex.lbl.json b/src/test/resources/labeling/labelSaveTestComplex.lbl.json new file mode 100644 index 0000000..3580c47 --- /dev/null +++ b/src/test/resources/labeling/labelSaveTestComplex.lbl.json @@ -0,0 +1 @@ +{"version":3,"numSets":4,"numSources":1,"indexImg":"labelSaveTestComplex.tif","labelMapping":{"1":{"a":"a","b":1.0,"c":1},"2":{"a":"b","b":2.24121,"c":2},"3":{"a":"a","b":1.0,"c":3}},"labelSets":{"0":[],"1":[1,2],"2":[1],"3":[1,2,3]}} \ No newline at end of file diff --git a/src/test/resources/labeling/labelSaveTestComplex.tif b/src/test/resources/labeling/labelSaveTestComplex.tif index 5debdd2e766756007f75de7b49566c31a9207b46..8a5b67641be5b8dc8aa04d141e87fbd5d8052711 100644 GIT binary patch delta 52 scmZ3=(#SR;mhtPxxZ{kI*D_WBF*_sUb#sZX*h6axv1IjJ>z2YiN25y0mWB#mWyNpLmI` zle)&vRTjw~s2yd=EVC2`N8{v|@e`*ASIjbShc_x diff --git a/src/test/resources/labeling/labelSaveTestComplexFunction.tif b/src/test/resources/labeling/labelSaveTestComplexFunction.tif deleted file mode 100644 index 5e705443ec55b14bf61fbb57fa2aa3db32985926..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 571 zcmdUr!Ait15Qb-3btQ=CK?U{TQKYO}*K1CKu!qHkz34I4xGkn>X;P@SeG1vL59D+B z7*4Wn=_?pW^5xGznaRxOa03AQaD)ImM6^MO*fU}Pq1UhIGHjV#xHsTK2*~qI^9PT+ z*x(jV2AYpKC<4#$~I!>@=1Sv&Y#JpN#M0 z@q~#+8vY!;FeUZMriM?Wn3+TT#fW3=W}hkhR$BUunNIlb)B{~ z*4$jI@b|$elGzq1c8oH?c9Ik)7KjX+*_{SKTyU82uOzcDh(8JU= KmT*^DF4ZpvG$^wG diff --git a/src/test/resources/labeling/labelSaveTestSimple.lbl.json b/src/test/resources/labeling/labelSaveTestSimple.lbl.json new file mode 100644 index 0000000..ca0afa4 --- /dev/null +++ b/src/test/resources/labeling/labelSaveTestSimple.lbl.json @@ -0,0 +1 @@ +{"version":3,"numSets":4,"numSources":1,"indexImg":"labelSaveTestSimple.tif","labelSets":{"0":[],"1":[13,42],"2":[1],"3":[13,42,1]}} \ No newline at end of file diff --git a/src/test/resources/labeling/labelSaveTestSimple.tif b/src/test/resources/labeling/labelSaveTestSimple.tif index 6dcd290437f4c4ab762403edc61eae3ed9e311d1..3251ad51a4608e0debc2dbaf46f05cf5f1ce06b2 100644 GIT binary patch delta 40 ecmX@Xyp4H6EaT>haW#yF6K@|8XJlYv#DW3f;s+rB delta 58 ecmdnSe1dsGEaTCMaW#wv6K@~UWME<>4gmmY9tTzc diff --git a/src/test/resources/labeling/labelSaveTestSimpleMeta.lbl.json b/src/test/resources/labeling/labelSaveTestSimpleMeta.lbl.json new file mode 100644 index 0000000..9414e64 --- /dev/null +++ b/src/test/resources/labeling/labelSaveTestSimpleMeta.lbl.json @@ -0,0 +1 @@ +{"version":3,"numSets":4,"numSources":1,"indexImg":"labelSaveTestSimpleMeta.tif","labelSets":{"0":[],"1":[13,42],"2":[1],"3":[13,42,1]},"metadata":{"one":1,"two":2,"three":3}} \ No newline at end of file diff --git a/src/test/resources/labeling/labelSaveTestSimpleMeta.tif b/src/test/resources/labeling/labelSaveTestSimpleMeta.tif new file mode 100644 index 0000000000000000000000000000000000000000..36efd7192fcf054a31e755a06fb822087dc566e8 GIT binary patch literal 426 zcmaiwy-ve05XbKlpp^#%10VqpfKU|Gf`P>o5>khXN?l+y#xxdAQpJua6FdcC?Zn&g z96SaWw+Y#he7>L0|NGEQCU6b_L)b%rEh2IdBX*1!K^)>k`iwVBD%|PuE<~hRk$vNS zn~Ps~(9;~YaX>ukIL2ex4)p;`Jn8raPkXs%8>UH+hh77sH=O-xs0Pfg$2a3!F-k9a z%9&hhC+?DaW_2<5nG+WYXHH2=VV;f>GFBJHJ5kiuCe6hj=sDHZ)GW0XSIp#c-l&<% zWKn3_ptDAW*i$9*0NLw8SI$fIEPPdKmY0uOs4`!a&UhVqgcc0o^W&ZN`_uaMz_j$} G-}4K#k3#?P04*|O5Xn`(b%Xc8~^>g|dG@dBjZTSP}5c5g; z!b888&cXtZTFmk0OvL_%S>Xxn`11kZ@O0zXc-Go`(Rlh3jC`*>avwNr>aIIIvzzhl z_)ZQ7qi7HbwbWMLhY!N&Y+fy_9EBrcV`Zou4Td2})LBwlnbpRG?j;^6PIWm=mfFbc zE0LsX?r;$=RF-MutTjpOYtN-hy;-~#y0n#wUu0F*TBP}tmT{gIxlJnVoA@4r{;~5- z`UME+20@<+y)CWZS5*IjX8per5q>akIPR)W&bPB0l9L;v6VIIIne#kzo@dVU%z2(U R&ok$F<~+}w=b7_c`42RMM-Tu2 literal 0 HcmV?d00001 From 04802ec570ec43b1f8ba7967813902eb50f3b421 Mon Sep 17 00:00:00 2001 From: Tom Burke Date: Wed, 6 Apr 2022 19:51:08 +0200 Subject: [PATCH 2/7] Do some DRY cleanup * Reactivate tests * Method refactoring --- pom.xml | 5 +- .../labeling/DefaultLabelingIOService.java | 164 +++++------------- .../imglib2/labeling/LabelingIOService.java | 59 +++---- .../net/imglib2/labeling/data/Container.java | 4 +- .../imglib2/labeling/data/LabelingData.java | 4 +- .../imglib2/labeling/utils/LabelingUtil.java | 16 +- .../net/imglib2/labeling/LabelingIOTest.java | 51 ++---- .../labeling/tutorials/E01_LoadLabeling.java | 56 +----- .../labeling/tutorials/E02_SaveLabeling.java | 6 +- .../imglib2/labeling/tutorials/Example.java | 4 +- src/test/resources/labeling/example1_sav.tif | Bin 1852 -> 1861 bytes .../labeling/labelSaveTestComplex.tif | Bin 769 -> 817 bytes .../labelSaveTestComplexMeta.lbl.json | 1 + .../labeling/labelSaveTestComplexMeta.tif | Bin 0 -> 399 bytes .../labeling/labelSaveTestSimple.tif | Bin 438 -> 450 bytes .../labeling/labelSaveTestSimpleMeta.tif | Bin 426 -> 435 bytes src/test/resources/labeling/test.lbl.json | 28 ++- src/test/resources/labeling/test2.tif | Bin 807 -> 999 bytes 18 files changed, 140 insertions(+), 258 deletions(-) create mode 100644 src/test/resources/labeling/labelSaveTestComplexMeta.lbl.json create mode 100644 src/test/resources/labeling/labelSaveTestComplexMeta.tif diff --git a/pom.xml b/pom.xml index fb58005..110f2d0 100644 --- a/pom.xml +++ b/pom.xml @@ -1,12 +1,13 @@ - + 4.0.0 org.scijava pom-scijava 30.0.0 - + net.imglib2 diff --git a/src/main/java/net/imglib2/labeling/DefaultLabelingIOService.java b/src/main/java/net/imglib2/labeling/DefaultLabelingIOService.java index 6dbda27..cbb5813 100644 --- a/src/main/java/net/imglib2/labeling/DefaultLabelingIOService.java +++ b/src/main/java/net/imglib2/labeling/DefaultLabelingIOService.java @@ -11,13 +11,13 @@ * %% * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -49,6 +49,7 @@ import org.scijava.plugin.Parameter; import org.scijava.plugin.Plugin; import org.scijava.service.AbstractService; +import sun.reflect.generics.reflectiveObjects.NotImplementedException; import java.io.FileWriter; import java.io.IOException; @@ -68,154 +69,85 @@ public class DefaultLabelingIOService extends AbstractService implements Labelin private Context context; @Parameter private DatasetIOService datasetIOService; - private Gson gson; - - @Override - public void initialize() { - gson = new Gson(); - } - + private Gson gson = new Gson(); @Override public > ImgLabeling load(String file) throws IOException { - String path = LabelingUtil.getFilePathWithExtension(file, LabelingUtil.LBL_ENDING, Paths.get(file).getParent().toString()); - Reader reader = Files.newBufferedReader(Paths.get(path)); - LabelingData labelingData = gson.fromJson(reader, LabelingData.class); - int version = labelingData.getVersion(); - int numSets = labelingData.getNumSets(); - int numSources = labelingData.getNumSources(); - String indexImg = labelingData.getIndexImg(); - List> labelSets = readLabelsets(labelingData, numSets); - RandomAccessibleInterval img = null; - try { - img = (Img) datasetIOService.open(LabelingUtil.getFilePathWithExtension(indexImg, TIF_ENDING, Paths.get(file).getParent().toString())).getImgPlus().getImg(); - } catch (IOException e) { - e.printStackTrace(); - } - - return ImgLabeling.fromImageAndLabelSets(img, labelSets); - } - - @Override - public > ImgLabeling load(String file, Class clazz) throws IOException { - String path = LabelingUtil.getFilePathWithExtension(file, LabelingUtil.LBL_ENDING, Paths.get(file).getParent().toString()); - Reader reader = Files.newBufferedReader(Paths.get(path)); - LabelingData labelingData = gson.fromJson(reader, LabelingData.class); - int version = labelingData.getVersion(); - int numSets = labelingData.getNumSets(); - int numSources = labelingData.getNumSources(); - String indexImg = labelingData.getIndexImg(); - List> labelSets = readLabelsets(labelingData, numSets); - RandomAccessibleInterval img = null; - try { - img = (Img) datasetIOService.open(LabelingUtil.getFilePathWithExtension(indexImg, TIF_ENDING, Paths.get(file).getParent().toString())).getImgPlus().getImg(); - } catch (IOException e) { - e.printStackTrace(); - } - - return ImgLabeling.fromImageAndLabelSets(img, labelSets); + return getImgLabeling(file); } @Override public > Container loadWithMetadata(String file, Class metadataClazz) throws IOException { - String path = LabelingUtil.getFilePathWithExtension(file, LabelingUtil.LBL_ENDING, Paths.get(file).getParent().toString()); - Reader reader = Files.newBufferedReader(Paths.get(path)); - LabelingData labelingData = gson.fromJson(reader, LabelingData.class); - int version = labelingData.getVersion(); - int numSets = labelingData.getNumSets(); - int numSources = labelingData.getNumSources(); - String indexImg = labelingData.getIndexImg(); - List> labelSets = readLabelsets(labelingData, numSets); - RandomAccessibleInterval img = null; - try { - img = (Img) datasetIOService.open(LabelingUtil.getFilePathWithExtension(indexImg, TIF_ENDING, Paths.get(file).getParent().toString())).getImgPlus().getImg(); - } catch (IOException e) { - e.printStackTrace(); - } + LabelingData labelingData = readLabelingDataFromJson(file); Container container = new Container<>(); - container.setImgLabeling(ImgLabeling.fromImageAndLabelSets(img, labelSets)); + container.setImgLabeling(getImgLabeling(file)); S metadata = gson.fromJson(gson.toJson(labelingData.getMetadata()), metadataClazz); container.setMetadata(metadata); return container; } - @Override - public > Container loadWithMetadata(String file, LongFunction idToLabel, Class metadataClazz) throws IOException { - String path = LabelingUtil.getFilePathWithExtension(file, LabelingUtil.LBL_ENDING, Paths.get(file).getParent().toString()); - Reader reader = Files.newBufferedReader(Paths.get(path)); - LabelingData labelingData = gson.fromJson(reader, LabelingData.class); - int version = labelingData.getVersion(); - int numSets = labelingData.getNumSets(); - int numSources = labelingData.getNumSources(); - String indexImg = labelingData.getIndexImg(); - List> labelSets = new ArrayList>(labelingData.getLabelSets().values()); - RandomAccessibleInterval img = null; - try { - img = (Img) datasetIOService.open(LabelingUtil.getFilePathWithExtension(indexImg, TIF_ENDING, Paths.get(file).getParent().toString())).getImgPlus().getImg(); - } catch (IOException e) { - e.printStackTrace(); - } - Container container = new Container<>(); - container.setImgLabeling(ImgLabeling.fromImageAndLabelSets(img, labelSets)); - S metadata = gson.fromJson(gson.toJson(labelingData.getMetadata()), metadataClazz); - container.setMetadata(metadata); - return container; + public > Container loadWithMetadata(String file, LongFunction idToLabel, Class metadataClazz) { + throw new NotImplementedException(); } @Override public > void save(ImgLabeling imgLabeling, String file) throws IOException { - LabelingMapping labelingMapping = imgLabeling.getMapping(); - LabelingData labelingData = createBasicLabelingData(file, labelingMapping); - if (!labelingMapping.getLabels().isEmpty()) { - createLabelsets(labelingMapping, labelingData); - } - final Img img = ImgView.wrap(imgLabeling.getIndexImg(), null); - LabelingUtil.saveAsTiff(context, LabelingUtil.getFilePathWithExtension(file, LabelingUtil.TIF_ENDING, Paths.get(file).getParent().toString()), img); - writeLabelingFile(file, labelingData); + saveWithMetaData(imgLabeling, file, null); } @Override - public > void saveWithMetaData(ImgLabeling imgLabeling, String file, S metadata) throws IOException { + public > void saveWithMetaData(ImgLabeling imgLabeling, String file, S metadata) throws IOException { LabelingMapping labelingMapping = imgLabeling.getMapping(); LabelingData labelingData = createBasicLabelingData(file, labelingMapping); - labelingData.setMetadata(metadata); if (!labelingMapping.getLabels().isEmpty()) { createLabelsets(labelingMapping, labelingData); } + labelingData.setMetadata(metadata); final Img img = ImgView.wrap(imgLabeling.getIndexImg(), null); LabelingUtil.saveAsTiff(context, LabelingUtil.getFilePathWithExtension(file, LabelingUtil.TIF_ENDING, Paths.get(file).getParent().toString()), img); writeLabelingFile(file, labelingData); } @Override - public > void saveWithMetaData(ImgLabeling imgLabeling, String file, ToLongFunction labelToId, S metadata) throws IOException { - LabelingMapping labelingMapping = imgLabeling.getMapping(); - LabelingData labelingData = createBasicLabelingData(file, labelingMapping); - labelingData.setMetadata(metadata); + public > void saveWithMetaData(ImgLabeling imgLabeling, String file, ToLongFunction labelToId, S metadata) throws IOException { + throw new NotImplementedException(); + } - //TODO: add function transformation - final Img img = ImgView.wrap(imgLabeling.getIndexImg(), null); - LabelingUtil.saveAsTiff(context, LabelingUtil.getFilePathWithExtension(file, LabelingUtil.TIF_ENDING, Paths.get(file).getParent().toString()), img); - writeLabelingFile(file, labelingData); + private > ImgLabeling getImgLabeling(String file) throws IOException { + return buildImgLabelingAndImage(file, readLabelingDataFromJson(file)); + } + + private LabelingData readLabelingDataFromJson(String file) throws IOException { + String path = LabelingUtil.getFilePathWithExtension(file, LabelingUtil.LBL_ENDING, Paths.get(file).getParent().toString()); + Reader reader = Files.newBufferedReader(Paths.get(path)); + return gson.fromJson(reader, LabelingData.class); + } + + private > ImgLabeling buildImgLabelingAndImage(String file, LabelingData labelingData) throws IOException { + int numSets = labelingData.getNumSets(); + String indexImg = labelingData.getIndexImg(); + List> labelSets = readLabelsets(labelingData, numSets); + RandomAccessibleInterval img = (Img) datasetIOService.open(LabelingUtil.getFilePathWithExtension(indexImg, TIF_ENDING, Paths.get(file).getParent().toString())).getImgPlus().getImg(); + return ImgLabeling.fromImageAndLabelSets(img, labelSets); } - private void createLabelsets(LabelingMapping labelingMapping, LabelingData labelingData) { - if(labelingMapping.getLabels().stream().findFirst().get() instanceof Integer){ + private void createLabelsets(LabelingMapping labelingMapping, LabelingData labelingData) { + if (labelingMapping.getLabels().stream().findFirst().get() instanceof Integer) { Map> labels = new HashMap<>(); for (int i = 0; i < labelingMapping.numSets(); i++) { labels.put(Integer.toString(i), (Set) labelingMapping.labelsAtIndex(i)); } labelingData.setLabelSets(labels); - }else{ + } else { Map> labels = new HashMap<>(); Map map = new HashMap<>(); for (int i = 0; i < labelingMapping.numSets(); i++) { Set labelset = new HashSet<>(); - for(T value : labelingMapping.labelsAtIndex(i)){ - if(!map.containsValue(value)){ - map.put(map.size()+1, value); + for (T value : labelingMapping.labelsAtIndex(i)) { + if (!map.containsValue(value)) { + map.put(map.size() + 1, value); } int mappedInteger = map.entrySet().stream().filter(entry -> value.equals(entry.getValue())) .map(Map.Entry::getKey).findFirst().get(); @@ -228,21 +160,21 @@ private void createLabelsets(LabelingMapping labelingMapping, LabelingD } } - private List> readLabelsets(LabelingData labelingData, int numSets) { + private List> readLabelsets(LabelingData labelingData, int numSets) { List> labelSets; - if(labelingData.getLabelMapping()==null || labelingData.getLabelMapping().isEmpty()){ + if (labelingData.getLabelMapping() == null || labelingData.getLabelMapping().isEmpty()) { labelSets = new ArrayList<>(); - for(Set set : labelingData.getLabelSets().values()){ + for (Set set : labelingData.getLabelSets().values()) { Set labelSet = new HashSet<>(); - set.stream().map(v->((Number)v).intValue()).forEach(v -> labelSet.add((T) v)); + set.stream().map(v -> ((Number) v).intValue()).forEach(v -> labelSet.add((T) v)); labelSets.add(labelSet); } - }else{ + } else { labelSets = new ArrayList<>(); - for(int i = 0; i< numSets; i++){ + for (int i = 0; i < numSets; i++) { Set set = new HashSet<>(); - for(int j : (Set) labelingData.getLabelSets().get(Integer.toString(i))){ - set.add((T) labelingData.getLabelMapping().get(Integer.toString(j))); + for (int j : labelingData.getLabelSets().get(Integer.toString(i))) { + set.add((T) labelingData.getLabelMapping().get(j)); } labelSets.add(set); } @@ -250,8 +182,8 @@ private List> readLabelsets(LabelingData labelingData, int nu return labelSets; } - private LabelingData createBasicLabelingData(String file, LabelingMapping labelingMapping) { - LabelingData labelingData = new LabelingData(); + private LabelingData createBasicLabelingData(String file, LabelingMapping labelingMapping) { + LabelingData labelingData = new LabelingData(); labelingData.setVersion(LabelingUtil.VERSION); labelingData.setNumSets(labelingMapping.numSets()); labelingData.setNumSources(1); @@ -259,7 +191,7 @@ private LabelingData createBasicLabelingData(String file, LabelingMa return labelingData; } - private void writeLabelingFile(String file, LabelingData labelingData) throws IOException { + private void writeLabelingFile(String file, LabelingData labelingData) throws IOException { Writer writer = new FileWriter(LabelingUtil.getFilePathWithExtension(file, LabelingUtil.LBL_ENDING, Paths.get(file).getParent().toString())); gson.toJson(labelingData, writer); writer.flush(); diff --git a/src/main/java/net/imglib2/labeling/LabelingIOService.java b/src/main/java/net/imglib2/labeling/LabelingIOService.java index 5af1e24..bf7f7cb 100644 --- a/src/main/java/net/imglib2/labeling/LabelingIOService.java +++ b/src/main/java/net/imglib2/labeling/LabelingIOService.java @@ -11,13 +11,13 @@ * %% * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -47,28 +47,25 @@ * Basic support for primitive types and BSON standard types is already included. For non-primitive types, * a codec must be set and the class must be given as an argument to the methods. * - * * @author Tom Burke */ public interface LabelingIOService extends ImageJService { - > ImgLabeling load(String file) throws IOException; - - > ImgLabeling load(String file, Class clazz) throws IOException; + > ImgLabeling load(String file) throws IOException; - > void save(ImgLabeling imgLabeling, String file) throws IOException; + > void save(ImgLabeling imgLabeling, String file) throws IOException; /** * Load a labeling container from the given file path as string. * The file path must point to the bson file containing the labeling data. * - * @param file The path to the file + * @param file The path to the file * @param metadataClazz the metadata class - * @param the label value - * @param IntegerType for the pixel value - * @param Class of the meta data - * @throws IOException on file read fail + * @param the label value + * @param IntegerType for the pixel value + * @param Class of the meta data * @return a container object holding the ImgLabeling (as well as an optional source mapping) + * @throws IOException on file read fail */ > Container loadWithMetadata(String file, Class metadataClazz) throws IOException; @@ -76,14 +73,14 @@ public interface LabelingIOService extends ImageJService { * Load a labeling container from the given file path as string. * The file path must point to the bson file containing the labeling data. * - * @param file The path to the file - * @param idToLabel a function transforming the label of type T into something else + * @param file The path to the file + * @param idToLabel a function transforming the label of type T into something else * @param metadataClazz the metadata class - * @param the label value - * @param IntegerType for the pixel value - * @param Class of the meta data - * @throws IOException on file read fail + * @param the label value + * @param IntegerType for the pixel value + * @param Class of the meta data * @return a container object holding the ImgLabeling (as well as an optional source mapping) + * @throws IOException on file read fail */ > Container loadWithMetadata(String file, LongFunction idToLabel, Class metadataClazz) throws IOException; @@ -91,25 +88,25 @@ public interface LabelingIOService extends ImageJService { * Save an ImgLabelingContainer in the file-path, transforming it into a bson file and an image. * The path must contain the filename (ending does not matter). * - * @param imgLabeling the imglabeling object that needs to be serialized - * @param file the path pointing to the file, including the filename - * @param the label value - * @param IntegerType for the pixel value - * @param Class of the meta data + * @param imgLabeling the imglabeling object that needs to be serialized + * @param file the path pointing to the file, including the filename + * @param the label value + * @param IntegerType for the pixel value + * @param Class of the meta data */ - > void saveWithMetaData(ImgLabeling imgLabeling, String file, S metadata) throws IOException; + > void saveWithMetaData(ImgLabeling imgLabeling, String file, S metadata) throws IOException; /** * Save an ImgLabelingContainer in the file-path, transforming it into a bson file and an image. * The path must contain the filename (ending does not matter). * - * @param imgLabeling the imglabeling object that needs to be serialized - * @param labelToId a function to convert the type T to a long value. - * @param file the path pointing to the file, including the filename - * @param the label value - * @param IntegerType for the pixel value - * @param Class of the meta data + * @param imgLabeling the imglabeling object that needs to be serialized + * @param labelToId a function to convert the type T to a long value. + * @param file the path pointing to the file, including the filename + * @param the label value + * @param IntegerType for the pixel value + * @param Class of the meta data */ - > void saveWithMetaData(ImgLabeling imgLabeling, String file, ToLongFunction labelToId, S metadata) throws IOException; + > void saveWithMetaData(ImgLabeling imgLabeling, String file, ToLongFunction labelToId, S metadata) throws IOException; } diff --git a/src/main/java/net/imglib2/labeling/data/Container.java b/src/main/java/net/imglib2/labeling/data/Container.java index 948aa18..b4f3c75 100644 --- a/src/main/java/net/imglib2/labeling/data/Container.java +++ b/src/main/java/net/imglib2/labeling/data/Container.java @@ -11,13 +11,13 @@ * %% * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE diff --git a/src/main/java/net/imglib2/labeling/data/LabelingData.java b/src/main/java/net/imglib2/labeling/data/LabelingData.java index 49fbe2d..c989965 100644 --- a/src/main/java/net/imglib2/labeling/data/LabelingData.java +++ b/src/main/java/net/imglib2/labeling/data/LabelingData.java @@ -85,11 +85,11 @@ public int hashCode() { return Objects.hash(this.numSets, this.indexImg, this.labelSets); } - public String toJson(){ + public String toJson() { return new Gson().toJson(this); } - public LabelingData fromJson(String json){ + public LabelingData fromJson(String json) { return new Gson().fromJson(json, this.getClass()); } } \ No newline at end of file diff --git a/src/main/java/net/imglib2/labeling/utils/LabelingUtil.java b/src/main/java/net/imglib2/labeling/utils/LabelingUtil.java index b79a0f0..bf22f30 100644 --- a/src/main/java/net/imglib2/labeling/utils/LabelingUtil.java +++ b/src/main/java/net/imglib2/labeling/utils/LabelingUtil.java @@ -11,13 +11,13 @@ * %% * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -52,14 +52,14 @@ public class LabelingUtil { public final static int VERSION = 3; /** - * @param context the scijava context used in the project - * @param filename the filename of the Img to save - * @param rai the img - * @param the pixel value + * @param context the scijava context used in the project + * @param filename the filename of the Img to save + * @param rai the img + * @param the pixel value */ public static > void saveAsTiff(final Context context, - final String filename, - final RandomAccessibleInterval rai) { + final String filename, + final RandomAccessibleInterval rai) { try { new ImgSaver(context).saveImg(filename, ImgView.wrap(rai, null), new SCIFIOConfig().writerSetFailIfOverwriting(false)); diff --git a/src/test/java/net/imglib2/labeling/LabelingIOTest.java b/src/test/java/net/imglib2/labeling/LabelingIOTest.java index 78fece4..19befce 100644 --- a/src/test/java/net/imglib2/labeling/LabelingIOTest.java +++ b/src/test/java/net/imglib2/labeling/LabelingIOTest.java @@ -11,13 +11,13 @@ * %% * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -63,7 +63,7 @@ public void testEquality() throws IOException { ImgLabeling imgLabeling = labelingIOService.load("src/test/resources/labeling/labelSaveTestSimple"); labelingIOService.save(imgLabeling, "src/test/resources/labeling/example1_sav"); ImgLabeling imgLabeling2 = labelingIOService.load("src/test/resources/labeling/example1_sav"); - Assert.assertEquals(imgLabeling.getMapping().getLabels(),imgLabeling2.getMapping().getLabels()); + Assert.assertEquals(imgLabeling.getMapping().getLabels(), imgLabeling2.getMapping().getLabels()); } @Test @@ -72,13 +72,13 @@ public void testEquality2() throws IOException { ImgLabeling imgLabeling = labelingIOService.load("src/test/resources/labeling/test"); labelingIOService.save(imgLabeling, "src/test/resources/labeling/test2"); ImgLabeling imgLabeling2 = labelingIOService.load("src/test/resources/labeling/test2"); - Assert.assertEquals(imgLabeling.getMapping().getLabels(),imgLabeling2.getMapping().getLabels()); + Assert.assertEquals(imgLabeling.getMapping().getLabels(), imgLabeling2.getMapping().getLabels()); } @Test public void saveLabelingWithMetadataPrimitiveTest() throws IOException { ImgLabeling labeling = getSimpleImgLabeling(); - context.getService(LabelingIOService.class).saveWithMetaData(labeling, new File("src/test/resources/labeling/labelSaveTestSimple.tif").getAbsolutePath(), new Example("a",2.0,1)); + context.getService(LabelingIOService.class).saveWithMetaData(labeling, new File("src/test/resources/labeling/labelSaveTestSimple.tif").getAbsolutePath(), new Example("a", 2.0, 1)); } @@ -95,46 +95,17 @@ public void loadLabelingWithMetadataPrimitiveTest() throws IOException { public void saveLabelingWithMetadataComplexTest() throws IOException { ImgLabeling labeling = getComplexImgLabeling(); LabelingIOService labelingIOService = context.getService(LabelingIOService.class); - labelingIOService.saveWithMetaData(labeling, new File("src/test/resources/labeling/labelSaveTestComplex.tif").getAbsolutePath(), new Example("a",2.0,1)); + labelingIOService.saveWithMetaData(labeling, new File("src/test/resources/labeling/labelSaveTestComplexMeta.tif").getAbsolutePath(), new Example("a", 2.0, 1)); } @Test public void loadLabelingWithMetadataComplexWithCodecTest() throws IOException { LabelingIOService labelingIOService = context.getService(LabelingIOService.class); -// Container container = labelingIOService.loadWithMetadata("src/test/resources/labeling/labelSaveTestComplex.bson", Example.class, Example.class, new ExampleCodec()); -// ImgLabeling mapping = container.getImgLabeling(); -// Example e = container.getMetadata(); -// Assert.assertNotNull(e); -// Assert.assertEquals(getComplexImgLabeling().getMapping().getLabels(), mapping.getMapping().getLabels()); - } - - @Test - public void saveLabelingWithMetadataComplexWithFunctionTest() { - ImgLabeling labeling = getComplexImgLabeling(); - LabelingIOService labelingIOService = context.getService(LabelingIOService.class); - Map mapping = new HashMap<>(); - AtomicLong atomicLong = new AtomicLong(0); - labeling.getMapping().getLabels().forEach(label -> mapping.put(label, atomicLong.getAndIncrement())); - Container container = new Container(); - container.setImgLabeling(labeling); - container.setMetadata(new Example("a",2.0,1)); -// labelingIOService.saveWithMetaData(container, new File("src/test/resources/labeling/labelSaveTestComplexFunction.tif").getAbsolutePath(), -// mapping::get, Example.class, new ExampleCodec()); - } - - @Test - public void loadLabelingWithMetadataComplexWithFunctionTest() throws IOException { - Set labels = getComplexImgLabeling().getMapping().getLabels(); - LabelingIOService labelingIOService = context.getService(LabelingIOService.class); - Map map = new HashMap<>(); - AtomicLong atomicLong = new AtomicLong(0); - labels.forEach(label -> map.put(atomicLong.getAndIncrement(), label)); -// Container container = labelingIOService.loadWithMetadata("src/test/resources/labeling/labelSaveTestComplexFunction.bson", map::get, -// Example.class, new ExampleCodec()); -// Example metadata = container.getMetadata(); -// Assert.assertNotNull(metadata); -// Assert.assertEquals(new Example("a",2.0,1), metadata); -// Assert.assertEquals(labels, container.getImgLabeling().getMapping().getLabels()); + Container container = labelingIOService.loadWithMetadata("src/test/resources/labeling/labelSaveTestComplexMeta", Example.class); + ImgLabeling mapping = container.getImgLabeling(); + Example e = container.getMetadata(); + Assert.assertNotNull(e); + Assert.assertEquals(getComplexImgLabeling().getMapping().getLabels(), mapping.getMapping().getLabels()); } private ImgLabeling getSimpleImgLabeling() { diff --git a/src/test/java/net/imglib2/labeling/tutorials/E01_LoadLabeling.java b/src/test/java/net/imglib2/labeling/tutorials/E01_LoadLabeling.java index bc3d3d9..f819736 100644 --- a/src/test/java/net/imglib2/labeling/tutorials/E01_LoadLabeling.java +++ b/src/test/java/net/imglib2/labeling/tutorials/E01_LoadLabeling.java @@ -11,13 +11,13 @@ * %% * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -33,20 +33,16 @@ */ package net.imglib2.labeling.tutorials; -import net.imglib2.img.Img; -import net.imglib2.img.array.ArrayImgs; import net.imglib2.labeling.LabelingIOService; +import net.imglib2.labeling.data.Container; import net.imglib2.roi.labeling.ImgLabeling; import net.imglib2.type.numeric.integer.IntType; -import net.imglib2.type.numeric.integer.UnsignedByteType; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.scijava.Context; import java.io.IOException; -import java.util.*; -import java.util.concurrent.atomic.AtomicLong; public class E01_LoadLabeling { @@ -73,53 +69,13 @@ public void loadBasicLabeling() throws IOException { } - @Test - public void loadFunctionBasedLabeling() throws IOException { - // get the LabelingIO service from the context - LabelingIOService labelingIOService = context.getService(LabelingIOService.class); - // creating a mapping for label value to class - // this could be the case when your label is actually a more complex data structure which contains more - // information. in this case, the user takes care of the mapping from label(id) to data structure - List labels = getComplexImgLabeling(); - Map map = new HashMap<>(); - AtomicLong atomicLong = new AtomicLong(0); - labels.forEach(label -> map.put(atomicLong.getAndIncrement(), label)); - //get the ImgLabeling with Example.class from our mapping through the map.get() function -// Container container = labelingIOService.loadWithMetadata("src/test/resources/labeling/labelSaveTestComplexFunction.bson", map::get, Example.class, new ExampleCodec()); -// ImgLabeling mapping = container.getImgLabeling(); -// Assert.assertNotNull(mapping); - } - @Test public void loadClassBasedLabeling() throws IOException { // get the LabelingIO service from the context LabelingIOService labelingIOService = context.getService(LabelingIOService.class); -// Container container = labelingIOService.loadWithMetadata("src/test/resources/labeling/labelSaveTestComplex.bson", Example.class, Example.class, new ExampleCodec()); -// ImgLabeling mapping = container.getImgLabeling(); -// Assert.assertNotNull(mapping); + Container container = labelingIOService.loadWithMetadata("src/test/resources/labeling/labelSaveTestComplex", Example.class); + ImgLabeling mapping = container.getImgLabeling(); + Assert.assertNotNull(mapping); } - - /* - Utility classes and functions start here - */ - - private List getComplexImgLabeling() { - Example[] values1 = new Example[]{new Example("a", 1.0, 1), new Example("b", 2.24121, 2)}; - Example[] values2 = new Example[]{new Example("a", 1.0, 1)}; - Example[] values3 = new Example[]{new Example("b", 2.24121, 2), new Example("a", 1.0, 1), new Example("a", 1.0, 3)}; - // setup - - Img indexImg = ArrayImgs.unsignedBytes(new byte[]{1, 3, 2}, 1); - List labelSets = Arrays.asList(new Example(), new Example("a", 1.0, 1), new Example("b", 2.24121, 2) - , new Example("b", 2.24121, 2), new Example("a", 1.0, 3)); - return labelSets; - } - - @SuppressWarnings("unchecked") - private Set asSet(T... values) { - return new TreeSet<>(Arrays.asList(values)); - } - - } diff --git a/src/test/java/net/imglib2/labeling/tutorials/E02_SaveLabeling.java b/src/test/java/net/imglib2/labeling/tutorials/E02_SaveLabeling.java index d446a53..f1be4eb 100644 --- a/src/test/java/net/imglib2/labeling/tutorials/E02_SaveLabeling.java +++ b/src/test/java/net/imglib2/labeling/tutorials/E02_SaveLabeling.java @@ -11,13 +11,13 @@ * %% * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -76,7 +76,6 @@ public void saveLabelingTest2() throws IOException { } - @Test public void saveLabelingWithMetaDataTest() throws IOException { ImgLabeling labeling = getSimpleImgLabeling(); @@ -97,7 +96,6 @@ public void saveLabelingWithMetaDataTest() throws IOException { } - private ImgLabeling getSimpleImgLabeling() { Integer[] values1 = new Integer[]{42, 13}; Integer[] values2 = new Integer[]{1}; diff --git a/src/test/java/net/imglib2/labeling/tutorials/Example.java b/src/test/java/net/imglib2/labeling/tutorials/Example.java index 246c132..9034aad 100644 --- a/src/test/java/net/imglib2/labeling/tutorials/Example.java +++ b/src/test/java/net/imglib2/labeling/tutorials/Example.java @@ -11,13 +11,13 @@ * %% * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE diff --git a/src/test/resources/labeling/example1_sav.tif b/src/test/resources/labeling/example1_sav.tif index f828cc82f42f62f496972721a2de425d0718e96f..9d0c7d5b16e7f55e8052b3c9dbe387bc57e20908 100644 GIT binary patch delta 24 bcmdnPca(2KF(aeX<`TvetelJtOb`SBT9*Y3 delta 14 VcmX@gw})>-F(aep<`TvetN diff --git a/src/test/resources/labeling/labelSaveTestComplex.tif b/src/test/resources/labeling/labelSaveTestComplex.tif index 8a5b67641be5b8dc8aa04d141e87fbd5d8052711..bfe4644f9d5b1fa68e35315923f354f7edb9f6fa 100644 GIT binary patch delta 21 dcmZo<+sHN{hKX5qW87k<$#a>wC$C{r1prEq2CM)8 delta 13 UcmdnU*2p#?hKcFx#<;~y03i|t*Z=?k diff --git a/src/test/resources/labeling/labelSaveTestComplexMeta.lbl.json b/src/test/resources/labeling/labelSaveTestComplexMeta.lbl.json new file mode 100644 index 0000000..099ce33 --- /dev/null +++ b/src/test/resources/labeling/labelSaveTestComplexMeta.lbl.json @@ -0,0 +1 @@ +{"version":3,"numSets":4,"numSources":1,"indexImg":"labelSaveTestComplexMeta.tif","labelMapping":{"1":{"a":"a","b":1.0,"c":1},"2":{"a":"b","b":2.24121,"c":2},"3":{"a":"a","b":1.0,"c":3}},"labelSets":{"0":[],"1":[1,2],"2":[1],"3":[1,2,3]},"metadata":{"a":"a","b":2.0,"c":1}} \ No newline at end of file diff --git a/src/test/resources/labeling/labelSaveTestComplexMeta.tif b/src/test/resources/labeling/labelSaveTestComplexMeta.tif new file mode 100644 index 0000000000000000000000000000000000000000..51632b1e0cc62aae994ecb6cf449ba7f5659e3b0 GIT binary patch literal 399 zcmYk2u};G<5QguXLXigq10WR!MueiM23AiZ>H?z)rm=9GD0ZZgrU;|XW7 zQBFL@Ps}L0@tG4m=FFwikj#@=Ou=fay%V-JCT=(OOvja~R=QC}+}<#q%S~%%X(p{z zrbTCT8no9+<^i(zQdQ2&^iBAxRxB@Glt_!bES&Z#GzmQzz}M#%Ao}g||HSR=;p6`R DmyJUR literal 0 HcmV?d00001 diff --git a/src/test/resources/labeling/labelSaveTestSimple.tif b/src/test/resources/labeling/labelSaveTestSimple.tif index 3251ad51a4608e0debc2dbaf46f05cf5f1ce06b2..b718913e1be213b712215edb746f5401fe50126d 100644 GIT binary patch delta 21 dcmdnSe295MEaU!-aS@D@*D-RiFfuYQ0RU6t1?B(% delta 12 TcmX@ayp4H6EaT>laS@CFADaY- diff --git a/src/test/resources/labeling/labelSaveTestSimpleMeta.tif b/src/test/resources/labeling/labelSaveTestSimpleMeta.tif index 36efd7192fcf054a31e755a06fb822087dc566e8..4d44f3127c411eb77b0cac0d36120d1f2677c029 100644 GIT binary patch delta 16 YcmZ3*yqS4IEaQfaaXyTb=P_~u05jhOnE(I) delta 12 TcmdnYyoz~3EaUQxaXyRy9vcKz diff --git a/src/test/resources/labeling/test.lbl.json b/src/test/resources/labeling/test.lbl.json index 8f12a34..94be7ea 100644 --- a/src/test/resources/labeling/test.lbl.json +++ b/src/test/resources/labeling/test.lbl.json @@ -1 +1,27 @@ -{"version": 2, "numSets": 5, "numSources": 4, "indexImg": "test.tif", "labelMapping": {}, "labelSets": {"0": [], "2": [1, 2], "4": [2, 3], "1": [1, 4], "3": [3, 4]}, "metadata": {}} \ No newline at end of file +{ + "version": 2, + "numSets": 5, + "numSources": 4, + "indexImg": "test.tif", + "labelMapping": {}, + "labelSets": { + "0": [], + "2": [ + 1, + 2 + ], + "4": [ + 2, + 3 + ], + "1": [ + 1, + 4 + ], + "3": [ + 3, + 4 + ] + }, + "metadata": {} +} \ No newline at end of file diff --git a/src/test/resources/labeling/test2.tif b/src/test/resources/labeling/test2.tif index cf3d526e613bdfeed933833740bb2bcaace851a4..3591c0cc649bc0bba60598a9e53885af681d9e3a 100644 GIT binary patch delta 31 kcmZ3^_MCk~5hEY-as~$G?Ld4Sh_7#MU|h~P`8neO0Fu}V>;M1& delta 27 hcmaFPzMO4C5hEYda|Q;c?+gsg>_9BOxq)#xBLHf#2Co1B From 3648413d2a9026eb85713ea44ffd5e6ea57415ec Mon Sep 17 00:00:00 2001 From: Tom Burke Date: Mon, 11 Apr 2022 13:53:11 +0200 Subject: [PATCH 3/7] Add Type token as an argument Add TypeToken wrapper to circumvent gson dependency in implementing projects --- .../labeling/DefaultLabelingIOService.java | 49 ++++++++++-------- .../imglib2/labeling/LabelingIOService.java | 5 +- .../imglib2/labeling/data/LabelingData.java | 5 ++ .../labeling/data/TypeTokenWrapper.java | 7 +++ .../net/imglib2/labeling/LabelingIOTest.java | 34 +++++++++--- .../labeling/tutorials/E01_LoadLabeling.java | 10 +++- src/test/resources/labeling/example1_sav.tif | Bin 1861 -> 1888 bytes .../labeling/labelSaveTestComplex.tif | Bin 817 -> 889 bytes .../labeling/labelSaveTestComplexMeta.tif | Bin 399 -> 435 bytes .../labeling/labelSaveTestSimple.lbl.json | 2 +- .../labeling/labelSaveTestSimple.tif | Bin 450 -> 477 bytes .../labeling/labelSaveTestSimpleMeta.tif | Bin 435 -> 453 bytes src/test/resources/labeling/test2.tif | Bin 999 -> 1575 bytes 13 files changed, 78 insertions(+), 34 deletions(-) create mode 100644 src/main/java/net/imglib2/labeling/data/TypeTokenWrapper.java diff --git a/src/main/java/net/imglib2/labeling/DefaultLabelingIOService.java b/src/main/java/net/imglib2/labeling/DefaultLabelingIOService.java index cbb5813..79287ec 100644 --- a/src/main/java/net/imglib2/labeling/DefaultLabelingIOService.java +++ b/src/main/java/net/imglib2/labeling/DefaultLabelingIOService.java @@ -34,6 +34,7 @@ package net.imglib2.labeling; import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; import io.scif.services.DatasetIOService; import net.imagej.ImageJService; import net.imglib2.RandomAccessibleInterval; @@ -55,6 +56,7 @@ import java.io.IOException; import java.io.Reader; import java.io.Writer; +import java.lang.reflect.Type; import java.nio.file.Files; import java.nio.file.Paths; import java.util.*; @@ -69,19 +71,19 @@ public class DefaultLabelingIOService extends AbstractService implements Labelin private Context context; @Parameter private DatasetIOService datasetIOService; - private Gson gson = new Gson(); + private final Gson gson = new Gson(); @Override - public > ImgLabeling load(String file) throws IOException { - return getImgLabeling(file); + public > ImgLabeling load(String file, Type typeToken) throws IOException { + return this.getImgLabeling(file, typeToken); } @Override - public > Container loadWithMetadata(String file, Class metadataClazz) throws IOException { - LabelingData labelingData = readLabelingDataFromJson(file); - Container container = new Container<>(); - container.setImgLabeling(getImgLabeling(file)); - S metadata = gson.fromJson(gson.toJson(labelingData.getMetadata()), metadataClazz); + public > Container loadWithMetadata(String file, Class metadataClazz, Type typeToken) throws IOException { + LabelingData labelingData = this.readLabelingDataFromJson(file, typeToken); + Container container = new Container<>(); + container.setImgLabeling(this.getImgLabeling(file, typeToken)); + S metadata = this.gson.fromJson(this.gson.toJson(labelingData.getMetadata()), metadataClazz); container.setMetadata(metadata); return container; } @@ -93,21 +95,21 @@ public > Container loadWithMetadata(Stri @Override public > void save(ImgLabeling imgLabeling, String file) throws IOException { - saveWithMetaData(imgLabeling, file, null); + this.saveWithMetaData(imgLabeling, file, null); } @Override public > void saveWithMetaData(ImgLabeling imgLabeling, String file, S metadata) throws IOException { LabelingMapping labelingMapping = imgLabeling.getMapping(); - LabelingData labelingData = createBasicLabelingData(file, labelingMapping); + LabelingData labelingData = this.createBasicLabelingData(file, labelingMapping); if (!labelingMapping.getLabels().isEmpty()) { - createLabelsets(labelingMapping, labelingData); + this.createLabelsets(labelingMapping, labelingData); } labelingData.setMetadata(metadata); final Img img = ImgView.wrap(imgLabeling.getIndexImg(), null); - LabelingUtil.saveAsTiff(context, LabelingUtil.getFilePathWithExtension(file, LabelingUtil.TIF_ENDING, Paths.get(file).getParent().toString()), img); - writeLabelingFile(file, labelingData); + LabelingUtil.saveAsTiff(this.context, LabelingUtil.getFilePathWithExtension(file, LabelingUtil.TIF_ENDING, Paths.get(file).getParent().toString()), img); + this.writeLabelingFile(file, labelingData); } @Override @@ -115,21 +117,23 @@ public > void saveWithMetaData(ImgLabeling throw new NotImplementedException(); } - private > ImgLabeling getImgLabeling(String file) throws IOException { - return buildImgLabelingAndImage(file, readLabelingDataFromJson(file)); + private > ImgLabeling getImgLabeling(String file, Type typeToken) throws IOException { + return this.buildImgLabelingAndImage(file, this.readLabelingDataFromJson(file, typeToken)); } - private LabelingData readLabelingDataFromJson(String file) throws IOException { + private LabelingData readLabelingDataFromJson(String file, Type typeToken) throws IOException { String path = LabelingUtil.getFilePathWithExtension(file, LabelingUtil.LBL_ENDING, Paths.get(file).getParent().toString()); Reader reader = Files.newBufferedReader(Paths.get(path)); - return gson.fromJson(reader, LabelingData.class); + LabelingData labelingData = this.gson.fromJson(reader, typeToken); + return labelingData; } - private > ImgLabeling buildImgLabelingAndImage(String file, LabelingData labelingData) throws IOException { + private > ImgLabeling buildImgLabelingAndImage(String file, LabelingData labelingData) throws IOException { int numSets = labelingData.getNumSets(); String indexImg = labelingData.getIndexImg(); - List> labelSets = readLabelsets(labelingData, numSets); - RandomAccessibleInterval img = (Img) datasetIOService.open(LabelingUtil.getFilePathWithExtension(indexImg, TIF_ENDING, Paths.get(file).getParent().toString())).getImgPlus().getImg(); + List> labelSets = this.readLabelsets(labelingData, numSets); + RandomAccessibleInterval img = (Img) this.datasetIOService.open(LabelingUtil.getFilePathWithExtension + (indexImg, TIF_ENDING, Paths.get(file).getParent().toString())).getImgPlus().getImg(); return ImgLabeling.fromImageAndLabelSets(img, labelSets); } @@ -183,7 +187,7 @@ private List> readLabelsets(LabelingData labelingData, int n } private LabelingData createBasicLabelingData(String file, LabelingMapping labelingMapping) { - LabelingData labelingData = new LabelingData(); + LabelingData labelingData = new LabelingData<>(); labelingData.setVersion(LabelingUtil.VERSION); labelingData.setNumSets(labelingMapping.numSets()); labelingData.setNumSources(1); @@ -193,7 +197,8 @@ private LabelingData createBasicLabelingData(String file, LabelingM private void writeLabelingFile(String file, LabelingData labelingData) throws IOException { Writer writer = new FileWriter(LabelingUtil.getFilePathWithExtension(file, LabelingUtil.LBL_ENDING, Paths.get(file).getParent().toString())); - gson.toJson(labelingData, writer); + Type labelingDataType = new TypeToken>() {}.getType(); + this.gson.toJson(labelingData, labelingDataType, writer); writer.flush(); writer.close(); } diff --git a/src/main/java/net/imglib2/labeling/LabelingIOService.java b/src/main/java/net/imglib2/labeling/LabelingIOService.java index bf7f7cb..bf774b5 100644 --- a/src/main/java/net/imglib2/labeling/LabelingIOService.java +++ b/src/main/java/net/imglib2/labeling/LabelingIOService.java @@ -39,6 +39,7 @@ import net.imglib2.type.numeric.IntegerType; import java.io.IOException; +import java.lang.reflect.Type; import java.util.function.LongFunction; import java.util.function.ToLongFunction; @@ -51,7 +52,7 @@ */ public interface LabelingIOService extends ImageJService { - > ImgLabeling load(String file) throws IOException; + > ImgLabeling load(String file, Type typeToken) throws IOException; > void save(ImgLabeling imgLabeling, String file) throws IOException; @@ -67,7 +68,7 @@ public interface LabelingIOService extends ImageJService { * @return a container object holding the ImgLabeling (as well as an optional source mapping) * @throws IOException on file read fail */ - > Container loadWithMetadata(String file, Class metadataClazz) throws IOException; + > Container loadWithMetadata(String file, Class metadataClazz, Type typeToken) throws IOException; /** * Load a labeling container from the given file path as string. diff --git a/src/main/java/net/imglib2/labeling/data/LabelingData.java b/src/main/java/net/imglib2/labeling/data/LabelingData.java index c989965..57fdc89 100644 --- a/src/main/java/net/imglib2/labeling/data/LabelingData.java +++ b/src/main/java/net/imglib2/labeling/data/LabelingData.java @@ -92,4 +92,9 @@ public String toJson() { public LabelingData fromJson(String json) { return new Gson().fromJson(json, this.getClass()); } + + @Override + public String toString() { + return this.toJson(); + } } \ No newline at end of file diff --git a/src/main/java/net/imglib2/labeling/data/TypeTokenWrapper.java b/src/main/java/net/imglib2/labeling/data/TypeTokenWrapper.java new file mode 100644 index 0000000..630feda --- /dev/null +++ b/src/main/java/net/imglib2/labeling/data/TypeTokenWrapper.java @@ -0,0 +1,7 @@ +package net.imglib2.labeling.data; + +import com.google.gson.reflect.TypeToken; + +public class TypeTokenWrapper extends TypeToken { + +} diff --git a/src/test/java/net/imglib2/labeling/LabelingIOTest.java b/src/test/java/net/imglib2/labeling/LabelingIOTest.java index 19befce..a3f5fe5 100644 --- a/src/test/java/net/imglib2/labeling/LabelingIOTest.java +++ b/src/test/java/net/imglib2/labeling/LabelingIOTest.java @@ -33,9 +33,13 @@ */ package net.imglib2.labeling; +import com.google.gson.GsonBuilder; +import com.google.gson.reflect.TypeToken; import net.imglib2.img.Img; import net.imglib2.img.array.ArrayImgs; import net.imglib2.labeling.data.Container; +import net.imglib2.labeling.data.LabelingData; +import net.imglib2.labeling.data.TypeTokenWrapper; import net.imglib2.roi.labeling.ImgLabeling; import net.imglib2.type.numeric.integer.IntType; import net.imglib2.type.numeric.integer.UnsignedByteType; @@ -46,8 +50,11 @@ import java.io.File; import java.io.IOException; +import java.io.Reader; +import java.lang.reflect.Type; +import java.nio.file.Files; +import java.nio.file.Paths; import java.util.*; -import java.util.concurrent.atomic.AtomicLong; public class LabelingIOTest { Context context; @@ -60,18 +67,20 @@ public void beforeTests() { @Test public void testEquality() throws IOException { LabelingIOService labelingIOService = context.getService(LabelingIOService.class); - ImgLabeling imgLabeling = labelingIOService.load("src/test/resources/labeling/labelSaveTestSimple"); + Type type = new TypeTokenWrapper>() {}.getType(); + ImgLabeling imgLabeling = labelingIOService.load("src/test/resources/labeling/labelSaveTestSimple",type); labelingIOService.save(imgLabeling, "src/test/resources/labeling/example1_sav"); - ImgLabeling imgLabeling2 = labelingIOService.load("src/test/resources/labeling/example1_sav"); + ImgLabeling imgLabeling2 = labelingIOService.load("src/test/resources/labeling/example1_sav", type); Assert.assertEquals(imgLabeling.getMapping().getLabels(), imgLabeling2.getMapping().getLabels()); } @Test public void testEquality2() throws IOException { LabelingIOService labelingIOService = context.getService(LabelingIOService.class); - ImgLabeling imgLabeling = labelingIOService.load("src/test/resources/labeling/test"); + Type type = new TypeTokenWrapper>() {}.getType(); + ImgLabeling imgLabeling = labelingIOService.load("src/test/resources/labeling/test", type); labelingIOService.save(imgLabeling, "src/test/resources/labeling/test2"); - ImgLabeling imgLabeling2 = labelingIOService.load("src/test/resources/labeling/test2"); + ImgLabeling imgLabeling2 = labelingIOService.load("src/test/resources/labeling/test2", type); Assert.assertEquals(imgLabeling.getMapping().getLabels(), imgLabeling2.getMapping().getLabels()); } @@ -84,7 +93,7 @@ public void saveLabelingWithMetadataPrimitiveTest() throws IOException { @Test public void loadLabelingWithMetadataPrimitiveTest() throws IOException { - Container container = context.getService(LabelingIOService.class).loadWithMetadata("src/test/resources/labeling/labelSaveTestSimpleMeta.tif", Example.class); + Container container = context.getService(LabelingIOService.class).loadWithMetadata("src/test/resources/labeling/labelSaveTestSimpleMeta.tif", Example.class , new TypeTokenWrapper>() {}.getType()); ImgLabeling mapping = container.getImgLabeling(); Example e = container.getMetadata(); Assert.assertNotNull(e); @@ -101,11 +110,21 @@ public void saveLabelingWithMetadataComplexTest() throws IOException { @Test public void loadLabelingWithMetadataComplexWithCodecTest() throws IOException { LabelingIOService labelingIOService = context.getService(LabelingIOService.class); - Container container = labelingIOService.loadWithMetadata("src/test/resources/labeling/labelSaveTestComplexMeta", Example.class); + Container container = labelingIOService.loadWithMetadata("src/test/resources/labeling/labelSaveTestComplexMeta", Example.class, new TypeTokenWrapper>() {}.getType()); ImgLabeling mapping = container.getImgLabeling(); Example e = container.getMetadata(); Assert.assertNotNull(e); Assert.assertEquals(getComplexImgLabeling().getMapping().getLabels(), mapping.getMapping().getLabels()); + + + } + + @Test + public void t() throws IOException { + GsonBuilder builder = new GsonBuilder(); + Type labelingDataType = new TypeToken>() {}.getType(); + Reader reader = Files.newBufferedReader(Paths.get("src/test/resources/labeling/labelSaveTestComplexMeta.lbl.json")); + LabelingData labelingData = builder.create().fromJson(reader, labelingDataType); } private ImgLabeling getSimpleImgLabeling() { @@ -128,6 +147,7 @@ private ImgLabeling getComplexImgLabeling() { return ImgLabeling.fromImageAndLabelSets(indexImg, labelSets); } + @SuppressWarnings("unchecked") private Set asSet(T... values) { return new TreeSet<>(Arrays.asList(values)); diff --git a/src/test/java/net/imglib2/labeling/tutorials/E01_LoadLabeling.java b/src/test/java/net/imglib2/labeling/tutorials/E01_LoadLabeling.java index f819736..fa7aa46 100644 --- a/src/test/java/net/imglib2/labeling/tutorials/E01_LoadLabeling.java +++ b/src/test/java/net/imglib2/labeling/tutorials/E01_LoadLabeling.java @@ -35,6 +35,8 @@ import net.imglib2.labeling.LabelingIOService; import net.imglib2.labeling.data.Container; +import net.imglib2.labeling.data.LabelingData; +import net.imglib2.labeling.data.TypeTokenWrapper; import net.imglib2.roi.labeling.ImgLabeling; import net.imglib2.type.numeric.integer.IntType; import org.junit.Assert; @@ -43,6 +45,7 @@ import org.scijava.Context; import java.io.IOException; +import java.lang.reflect.Type; public class E01_LoadLabeling { @@ -62,7 +65,9 @@ public void loadBasicLabeling() throws IOException { // the container contains an ImgLabeling of that type as well as an optional sourcemap // the sourcemap is a mapping of a source img to a list of labels that where contained in it and added to // the ImgLabeling - ImgLabeling imgLabeling = labelingIOService.load("src/test/resources/labeling/labelSaveTestSimple.lbl.json"); + Type type = new TypeTokenWrapper>() {}.getType(); + + ImgLabeling imgLabeling = labelingIOService.load("src/test/resources/labeling/labelSaveTestSimple.lbl.json", type); Assert.assertNotNull(imgLabeling); Assert.assertNotNull(imgLabeling.getIndexImg()); Assert.assertFalse(imgLabeling.getMapping().getLabels().isEmpty()); @@ -73,7 +78,8 @@ public void loadBasicLabeling() throws IOException { public void loadClassBasedLabeling() throws IOException { // get the LabelingIO service from the context LabelingIOService labelingIOService = context.getService(LabelingIOService.class); - Container container = labelingIOService.loadWithMetadata("src/test/resources/labeling/labelSaveTestComplex", Example.class); + Type type = new TypeTokenWrapper>() {}.getType(); + Container container = labelingIOService.loadWithMetadata("src/test/resources/labeling/labelSaveTestComplex", Example.class, type); ImgLabeling mapping = container.getImgLabeling(); Assert.assertNotNull(mapping); } diff --git a/src/test/resources/labeling/example1_sav.tif b/src/test/resources/labeling/example1_sav.tif index 9d0c7d5b16e7f55e8052b3c9dbe387bc57e20908..48243646cb3e9e5ac203ebcc1f27f4ba71860909 100644 GIT binary patch delta 41 jcmX@g_keFhF(YH_<`Tw>tds58S;ZI_86b#>kpY1K(p?5e delta 14 VcmaFBca(2KF(aeX<`Tw>tNYI73Di1_lO3LKpzNCj?Xg delta 12 TcmdnY+|N8Ama%(doFO9s97_ZP diff --git a/src/test/resources/labeling/labelSaveTestSimple.lbl.json b/src/test/resources/labeling/labelSaveTestSimple.lbl.json index ca0afa4..9214b88 100644 --- a/src/test/resources/labeling/labelSaveTestSimple.lbl.json +++ b/src/test/resources/labeling/labelSaveTestSimple.lbl.json @@ -1 +1 @@ -{"version":3,"numSets":4,"numSources":1,"indexImg":"labelSaveTestSimple.tif","labelSets":{"0":[],"1":[13,42],"2":[1],"3":[13,42,1]}} \ No newline at end of file +{"version":3,"numSets":4,"numSources":1,"indexImg":"labelSaveTestSimple.tif","labelSets":{"0":[],"1":[13,42],"2":[1],"3":[13,42,1]},"metadata":{"a":"a","b":2.0,"c":1}} \ No newline at end of file diff --git a/src/test/resources/labeling/labelSaveTestSimple.tif b/src/test/resources/labeling/labelSaveTestSimple.tif index b718913e1be213b712215edb746f5401fe50126d..05d297f803af9cd46b7318160c3bb24ba790af3d 100644 GIT binary patch delta 45 hcmX@ae3yAbEaRPtamtL08=D*$r5Qnhfe8gexd7+u1}*>q delta 17 Ycmcc1e295MEaU!(amtL$8=D*$0Xu;O-2eap diff --git a/src/test/resources/labeling/labelSaveTestSimpleMeta.tif b/src/test/resources/labeling/labelSaveTestSimpleMeta.tif index 4d44f3127c411eb77b0cac0d36120d1f2677c029..33688ee9872ce0a8e063be7a2a51aac4ddc9c17b 100644 GIT binary patch delta 16 YcmdnYe3W@YEaRb#aiNTp=P?Qa05(ho*Z=?k delta 12 TcmX@gyqS4IEaQfaaiNR=AB+To diff --git a/src/test/resources/labeling/test2.tif b/src/test/resources/labeling/test2.tif index 3591c0cc649bc0bba60598a9e53885af681d9e3a..6dcdc466808e82ee24e6c9cae032ce5aba608b1e 100644 GIT binary patch delta 35 pcmaFPzMN-65hEY#a|Q<1?+grV>_9BOxq&gAY4LMLrpeD49RRQ@3CaKf delta 27 gcmZ3^^PGJ{5hEY-as~$G?Ld4Sh_7#MU`%HM0B&vvcmMzZ From 8bf32b6e636768b74bc548baa913ecd6ab21d610 Mon Sep 17 00:00:00 2001 From: Gabriel Selzer Date: Mon, 18 Apr 2022 14:45:36 -0500 Subject: [PATCH 4/7] Extract list instantiation Can all be done on one line. --- .../java/net/imglib2/labeling/DefaultLabelingIOService.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/java/net/imglib2/labeling/DefaultLabelingIOService.java b/src/main/java/net/imglib2/labeling/DefaultLabelingIOService.java index 79287ec..0a01f05 100644 --- a/src/main/java/net/imglib2/labeling/DefaultLabelingIOService.java +++ b/src/main/java/net/imglib2/labeling/DefaultLabelingIOService.java @@ -165,16 +165,14 @@ private void createLabelsets(LabelingMapping labelingMapping, Labeling } private List> readLabelsets(LabelingData labelingData, int numSets) { - List> labelSets; + List> labelSets = new ArrayList<>(); if (labelingData.getLabelMapping() == null || labelingData.getLabelMapping().isEmpty()) { - labelSets = new ArrayList<>(); for (Set set : labelingData.getLabelSets().values()) { Set labelSet = new HashSet<>(); set.stream().map(v -> ((Number) v).intValue()).forEach(v -> labelSet.add((T) v)); labelSets.add(labelSet); } } else { - labelSets = new ArrayList<>(); for (int i = 0; i < numSets; i++) { Set set = new HashSet<>(); for (int j : labelingData.getLabelSets().get(Integer.toString(i))) { From b94719c52896035b9df0f9b16eb4295a33286fa1 Mon Sep 17 00:00:00 2001 From: Gabriel Selzer Date: Wed, 20 Apr 2022 11:16:06 -0500 Subject: [PATCH 5/7] Replace NotImplementedException --- .../java/net/imglib2/labeling/DefaultLabelingIOService.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/java/net/imglib2/labeling/DefaultLabelingIOService.java b/src/main/java/net/imglib2/labeling/DefaultLabelingIOService.java index 0a01f05..7282fc2 100644 --- a/src/main/java/net/imglib2/labeling/DefaultLabelingIOService.java +++ b/src/main/java/net/imglib2/labeling/DefaultLabelingIOService.java @@ -50,7 +50,6 @@ import org.scijava.plugin.Parameter; import org.scijava.plugin.Plugin; import org.scijava.service.AbstractService; -import sun.reflect.generics.reflectiveObjects.NotImplementedException; import java.io.FileWriter; import java.io.IOException; @@ -90,7 +89,7 @@ public > Container loadWithMetadata(Stri @Override public > Container loadWithMetadata(String file, LongFunction idToLabel, Class metadataClazz) { - throw new NotImplementedException(); + throw new UnsupportedOperationException(); } @Override @@ -114,7 +113,7 @@ public > void saveWithMetaData(ImgLabeling @Override public > void saveWithMetaData(ImgLabeling imgLabeling, String file, ToLongFunction labelToId, S metadata) throws IOException { - throw new NotImplementedException(); + throw new UnsupportedOperationException(); } private > ImgLabeling getImgLabeling(String file, Type typeToken) throws IOException { From 693788a5aed2a3b6ff3910659af50fc67e0dff6d Mon Sep 17 00:00:00 2001 From: Gabriel Selzer Date: Wed, 20 Apr 2022 12:55:20 -0500 Subject: [PATCH 6/7] Replace Types with Classes for TypeVariables This prevents vacuous type parameters! --- .../labeling/DefaultLabelingIOService.java | 27 ++++++++++--------- .../imglib2/labeling/LabelingIOService.java | 7 +++-- .../net/imglib2/labeling/LabelingIOTest.java | 21 ++++++--------- .../labeling/tutorials/E01_LoadLabeling.java | 6 ++--- 4 files changed, 28 insertions(+), 33 deletions(-) diff --git a/src/main/java/net/imglib2/labeling/DefaultLabelingIOService.java b/src/main/java/net/imglib2/labeling/DefaultLabelingIOService.java index 7282fc2..88284b8 100644 --- a/src/main/java/net/imglib2/labeling/DefaultLabelingIOService.java +++ b/src/main/java/net/imglib2/labeling/DefaultLabelingIOService.java @@ -42,6 +42,7 @@ import net.imglib2.img.ImgView; import net.imglib2.labeling.data.Container; import net.imglib2.labeling.data.LabelingData; +import net.imglib2.labeling.data.TypeTokenWrapper; import net.imglib2.labeling.utils.LabelingUtil; import net.imglib2.roi.labeling.ImgLabeling; import net.imglib2.roi.labeling.LabelingMapping; @@ -73,16 +74,16 @@ public class DefaultLabelingIOService extends AbstractService implements Labelin private final Gson gson = new Gson(); @Override - public > ImgLabeling load(String file, Type typeToken) throws IOException { - return this.getImgLabeling(file, typeToken); + public > ImgLabeling load(String file, Class labelType, Class backingType) throws IOException { + return this.getImgLabeling(file, labelType, backingType); } @Override - public > Container loadWithMetadata(String file, Class metadataClazz, Type typeToken) throws IOException { - LabelingData labelingData = this.readLabelingDataFromJson(file, typeToken); + public > Container loadWithMetadata(String file, Class metadataType, Class labelType, Class backingType) throws IOException { + LabelingData labelingData = this.readLabelingDataFromJson(file, labelType, metadataType); Container container = new Container<>(); - container.setImgLabeling(this.getImgLabeling(file, typeToken)); - S metadata = this.gson.fromJson(this.gson.toJson(labelingData.getMetadata()), metadataClazz); + container.setImgLabeling(this.getImgLabeling(file, labelType, backingType)); + S metadata = this.gson.fromJson(this.gson.toJson(labelingData.getMetadata()), metadataType); container.setMetadata(metadata); return container; } @@ -116,18 +117,20 @@ public > void saveWithMetaData(ImgLabeling throw new UnsupportedOperationException(); } - private > ImgLabeling getImgLabeling(String file, Type typeToken) throws IOException { - return this.buildImgLabelingAndImage(file, this.readLabelingDataFromJson(file, typeToken)); + private > ImgLabeling getImgLabeling(String file, Class labelType, Class backingType) throws IOException { + return this.buildImgLabelingAndImage(file, this.readLabelingDataFromJson(file, labelType, Object.class), backingType); } - private LabelingData readLabelingDataFromJson(String file, Type typeToken) throws IOException { + private LabelingData readLabelingDataFromJson(String file, Class labelType, Class metadataType) throws IOException { String path = LabelingUtil.getFilePathWithExtension(file, LabelingUtil.LBL_ENDING, Paths.get(file).getParent().toString()); Reader reader = Files.newBufferedReader(Paths.get(path)); - LabelingData labelingData = this.gson.fromJson(reader, typeToken); - return labelingData; + Type type = TypeToken // + .getParameterized(LabelingData.class, labelType, metadataType) // + .getType(); + return this.gson.fromJson(reader, type); } - private > ImgLabeling buildImgLabelingAndImage(String file, LabelingData labelingData) throws IOException { + private > ImgLabeling buildImgLabelingAndImage(String file, LabelingData labelingData, Class backingType) throws IOException { int numSets = labelingData.getNumSets(); String indexImg = labelingData.getIndexImg(); List> labelSets = this.readLabelsets(labelingData, numSets); diff --git a/src/main/java/net/imglib2/labeling/LabelingIOService.java b/src/main/java/net/imglib2/labeling/LabelingIOService.java index bf774b5..3e00183 100644 --- a/src/main/java/net/imglib2/labeling/LabelingIOService.java +++ b/src/main/java/net/imglib2/labeling/LabelingIOService.java @@ -39,7 +39,6 @@ import net.imglib2.type.numeric.IntegerType; import java.io.IOException; -import java.lang.reflect.Type; import java.util.function.LongFunction; import java.util.function.ToLongFunction; @@ -52,7 +51,7 @@ */ public interface LabelingIOService extends ImageJService { - > ImgLabeling load(String file, Type typeToken) throws IOException; + > ImgLabeling load(String file, Class labelType, Class backingType) throws IOException; > void save(ImgLabeling imgLabeling, String file) throws IOException; @@ -61,14 +60,14 @@ public interface LabelingIOService extends ImageJService { * The file path must point to the bson file containing the labeling data. * * @param file The path to the file - * @param metadataClazz the metadata class + * @param metadataType the metadata class * @param the label value * @param IntegerType for the pixel value * @param Class of the meta data * @return a container object holding the ImgLabeling (as well as an optional source mapping) * @throws IOException on file read fail */ - > Container loadWithMetadata(String file, Class metadataClazz, Type typeToken) throws IOException; + > Container loadWithMetadata(String file, Class metadataType, Class labelType, Class backingType) throws IOException; /** * Load a labeling container from the given file path as string. diff --git a/src/test/java/net/imglib2/labeling/LabelingIOTest.java b/src/test/java/net/imglib2/labeling/LabelingIOTest.java index a3f5fe5..80bfa31 100644 --- a/src/test/java/net/imglib2/labeling/LabelingIOTest.java +++ b/src/test/java/net/imglib2/labeling/LabelingIOTest.java @@ -39,7 +39,6 @@ import net.imglib2.img.array.ArrayImgs; import net.imglib2.labeling.data.Container; import net.imglib2.labeling.data.LabelingData; -import net.imglib2.labeling.data.TypeTokenWrapper; import net.imglib2.roi.labeling.ImgLabeling; import net.imglib2.type.numeric.integer.IntType; import net.imglib2.type.numeric.integer.UnsignedByteType; @@ -67,20 +66,18 @@ public void beforeTests() { @Test public void testEquality() throws IOException { LabelingIOService labelingIOService = context.getService(LabelingIOService.class); - Type type = new TypeTokenWrapper>() {}.getType(); - ImgLabeling imgLabeling = labelingIOService.load("src/test/resources/labeling/labelSaveTestSimple",type); + ImgLabeling imgLabeling = labelingIOService.load("src/test/resources/labeling/labelSaveTestSimple", Integer.class, IntType.class); labelingIOService.save(imgLabeling, "src/test/resources/labeling/example1_sav"); - ImgLabeling imgLabeling2 = labelingIOService.load("src/test/resources/labeling/example1_sav", type); + ImgLabeling imgLabeling2 = labelingIOService.load("src/test/resources/labeling/example1_sav", Integer.class, IntType.class); Assert.assertEquals(imgLabeling.getMapping().getLabels(), imgLabeling2.getMapping().getLabels()); } @Test public void testEquality2() throws IOException { LabelingIOService labelingIOService = context.getService(LabelingIOService.class); - Type type = new TypeTokenWrapper>() {}.getType(); - ImgLabeling imgLabeling = labelingIOService.load("src/test/resources/labeling/test", type); + ImgLabeling imgLabeling = labelingIOService.load("src/test/resources/labeling/test", Integer.class, IntType.class); labelingIOService.save(imgLabeling, "src/test/resources/labeling/test2"); - ImgLabeling imgLabeling2 = labelingIOService.load("src/test/resources/labeling/test2", type); + ImgLabeling imgLabeling2 = labelingIOService.load("src/test/resources/labeling/test2", Integer.class, IntType.class); Assert.assertEquals(imgLabeling.getMapping().getLabels(), imgLabeling2.getMapping().getLabels()); } @@ -90,10 +87,10 @@ public void saveLabelingWithMetadataPrimitiveTest() throws IOException { context.getService(LabelingIOService.class).saveWithMetaData(labeling, new File("src/test/resources/labeling/labelSaveTestSimple.tif").getAbsolutePath(), new Example("a", 2.0, 1)); } - @Test public void loadLabelingWithMetadataPrimitiveTest() throws IOException { - Container container = context.getService(LabelingIOService.class).loadWithMetadata("src/test/resources/labeling/labelSaveTestSimpleMeta.tif", Example.class , new TypeTokenWrapper>() {}.getType()); + Container + container = context.getService(LabelingIOService.class).loadWithMetadata("src/test/resources/labeling/labelSaveTestSimpleMeta.tif", Example.class, Integer.class, IntType.class); ImgLabeling mapping = container.getImgLabeling(); Example e = container.getMetadata(); Assert.assertNotNull(e); @@ -110,20 +107,18 @@ public void saveLabelingWithMetadataComplexTest() throws IOException { @Test public void loadLabelingWithMetadataComplexWithCodecTest() throws IOException { LabelingIOService labelingIOService = context.getService(LabelingIOService.class); - Container container = labelingIOService.loadWithMetadata("src/test/resources/labeling/labelSaveTestComplexMeta", Example.class, new TypeTokenWrapper>() {}.getType()); + Container container = labelingIOService.loadWithMetadata("src/test/resources/labeling/labelSaveTestComplexMeta", Example.class, Example.class, IntType.class); ImgLabeling mapping = container.getImgLabeling(); Example e = container.getMetadata(); Assert.assertNotNull(e); Assert.assertEquals(getComplexImgLabeling().getMapping().getLabels(), mapping.getMapping().getLabels()); - - } @Test public void t() throws IOException { GsonBuilder builder = new GsonBuilder(); - Type labelingDataType = new TypeToken>() {}.getType(); Reader reader = Files.newBufferedReader(Paths.get("src/test/resources/labeling/labelSaveTestComplexMeta.lbl.json")); + Type labelingDataType = new TypeToken>() {}.getType(); LabelingData labelingData = builder.create().fromJson(reader, labelingDataType); } diff --git a/src/test/java/net/imglib2/labeling/tutorials/E01_LoadLabeling.java b/src/test/java/net/imglib2/labeling/tutorials/E01_LoadLabeling.java index fa7aa46..0747968 100644 --- a/src/test/java/net/imglib2/labeling/tutorials/E01_LoadLabeling.java +++ b/src/test/java/net/imglib2/labeling/tutorials/E01_LoadLabeling.java @@ -65,9 +65,8 @@ public void loadBasicLabeling() throws IOException { // the container contains an ImgLabeling of that type as well as an optional sourcemap // the sourcemap is a mapping of a source img to a list of labels that where contained in it and added to // the ImgLabeling - Type type = new TypeTokenWrapper>() {}.getType(); - ImgLabeling imgLabeling = labelingIOService.load("src/test/resources/labeling/labelSaveTestSimple.lbl.json", type); + ImgLabeling imgLabeling = labelingIOService.load("src/test/resources/labeling/labelSaveTestSimple.lbl.json", Integer.class, IntType.class); Assert.assertNotNull(imgLabeling); Assert.assertNotNull(imgLabeling.getIndexImg()); Assert.assertFalse(imgLabeling.getMapping().getLabels().isEmpty()); @@ -78,8 +77,7 @@ public void loadBasicLabeling() throws IOException { public void loadClassBasedLabeling() throws IOException { // get the LabelingIO service from the context LabelingIOService labelingIOService = context.getService(LabelingIOService.class); - Type type = new TypeTokenWrapper>() {}.getType(); - Container container = labelingIOService.loadWithMetadata("src/test/resources/labeling/labelSaveTestComplex", Example.class, type); + Container container = labelingIOService.loadWithMetadata("src/test/resources/labeling/labelSaveTestComplex", Example.class, Example.class, IntType.class); ImgLabeling mapping = container.getImgLabeling(); Assert.assertNotNull(mapping); } From b658367d7f98ad3531c00f528bffbdb4fb8135f3 Mon Sep 17 00:00:00 2001 From: Gabriel Selzer Date: Wed, 20 Apr 2022 13:14:58 -0500 Subject: [PATCH 7/7] Ensure empty label sets don't throw exceptions --- .../java/net/imglib2/labeling/DefaultLabelingIOService.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/imglib2/labeling/DefaultLabelingIOService.java b/src/main/java/net/imglib2/labeling/DefaultLabelingIOService.java index 88284b8..f99b376 100644 --- a/src/main/java/net/imglib2/labeling/DefaultLabelingIOService.java +++ b/src/main/java/net/imglib2/labeling/DefaultLabelingIOService.java @@ -140,7 +140,8 @@ private > ImgLabeling buildImgLabelingAndIm } private void createLabelsets(LabelingMapping labelingMapping, LabelingData labelingData) { - if (labelingMapping.getLabels().stream().findFirst().get() instanceof Integer) { + Optional optional = labelingMapping.getLabels().stream().findFirst(); + if (optional.isPresent() && optional.get() instanceof Integer) { Map> labels = new HashMap<>(); for (int i = 0; i < labelingMapping.numSets(); i++) { labels.put(Integer.toString(i), (Set) labelingMapping.labelsAtIndex(i));