results;
+ try {
+ results = queryInterface.query(query);
+ } catch (QueryException e) {
+ logger.error("Could not complete query:", e);
+ return null;
+ }
+
+ for (SearchResult first : results) {
+ if (first != null) {
+ return first.getURI();
+ }
+ }
+ return null;
+ }
+
+ private StorageInputStream retrieveInputStream(URI uri) {
+ return PluginController.getInstance().resolveURI(uri).iterator().next();
+ }
+
+}
diff --git a/dicoogle_web_api.yaml b/dicoogle_web_api.yaml
index 97c795d9d..cbfaaafe1 100644
--- a/dicoogle_web_api.yaml
+++ b/dicoogle_web_api.yaml
@@ -19,7 +19,7 @@ info:
- Dicoogle Javadoc
- Dicoogle Javascript Client
- version: 3.1.0
+ version: 3.3.1
title: Dicoogle
contact:
name: Support
@@ -47,6 +47,8 @@ tags:
description: Management related services
- name: Misc
description: Misc related services
+ - name: Machine Learning
+ description: Machine learning services
paths:
/login:
post:
@@ -1031,6 +1033,323 @@ paths:
$ref: "#/components/schemas/Version"
"400":
description: Invalid supplied parameters
+ /roi:
+ get:
+ tags:
+ - Misc
+ summary: Retrieve a rectangular region of a WSI
+ operationId: getImageROI
+ parameters:
+ - in: query
+ name: uid
+ description: SOPInstanceUID
+ required: true
+ schema:
+ type: string
+ - in: query
+ name: x
+ description: left coordinate of the top left corner of the ROI in relation to the SOPInstanceUID provided
+ required: true
+ schema:
+ type: number
+ - in: query
+ name: y
+ description: top coordinate of the top left corner of the ROI in relation to the SOPInstanceUID provided
+ required: true
+ schema:
+ type: number
+ - in: query
+ name: width
+ description: Width of the ROI in pixels
+ required: true
+ schema:
+ type: number
+ - in: query
+ name: height
+ description: Height of the ROI in pixels
+ required: true
+ schema:
+ type: number
+ responses:
+ "200":
+ description: Successful operation
+ content:
+ image/jpeg:
+ schema:
+ type: string
+ format: binary
+ "400":
+ description: Invalid supplied parameters
+ "404":
+ description: SOPInstanceUID provided does not exist
+ post:
+ tags:
+ - Misc
+ summary: Retrieve an arbitrary region of a WSI
+ operationId: postImageROI
+ requestBody:
+ description: Describes the region to extract
+ required: true
+ content:
+ application/json:
+ schema:
+ type: object
+ properties:
+ uid:
+ type: string
+ description: SOPInstanceUID
+ type:
+ type: string
+ enum: [RECTANGLE, ELLIPSE, POLYGON, POLYLINE, POINT]
+ points:
+ type: array
+ items:
+ type: object
+ description: A list of points that defines the shape to extract
+ properties:
+ x:
+ type: number
+ y:
+ type: number
+ responses:
+ "200":
+ description: Successful operation
+ content:
+ image/jpeg:
+ schema:
+ type: string
+ format: binary
+ "400":
+ description: Invalid supplied parameters
+ "404":
+ description: SOPInstanceUID provided does not exist
+ /ml/datastore:
+ post:
+ tags:
+ - Machine Learning
+ summary: Datastore endpoint for machine learning providers, used to upload images and labels to services
+ operationId: mlDatastore
+ requestBody:
+ description: Describes the data to upload to the provider
+ required: true
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/DatastoreRequest'
+ responses:
+ '200':
+ description: The datastore request was successfully processed and sent to the provider
+ '400':
+ description: Malformed request
+ /ml/infer/single:
+ post:
+ tags:
+ - Machine Learning
+ summary: Infer endpoint for a single object, image or DICOM object (series or sop instance). It has split functionality for WSI images.
+ operationId: mlInferSingle
+ parameters:
+ - in: query
+ name: provider
+ description: The name of the provider, e.g "MONAI"
+ required: true
+ schema:
+ type: string
+ - in: query
+ name: modelID
+ description: Model identifier that will perform the inference
+ required: true
+ schema:
+ type: string
+ - in: query
+ name: wsi
+ description: Flag to identify WSI requests. Defaults to false.
+ required: false
+ schema:
+ type: boolean
+ default: false
+ - in: query
+ name: level
+ description:
+ The DIM level. Required if wsi is false
+ required: false
+ schema:
+ type: string
+ enum: [PATIENT, STUDY, SERIES, INSTANCE]
+ - in: query
+ name: uid
+ description: The unique identifier of the DIM object. Required if wsi is false
+ required: false
+ schema:
+ type: string
+ responses:
+ '200':
+ description: The datastore request was successully processed and sent to the provider
+ content:
+ application/dicom:
+ schema:
+ type: string
+ format: binary
+ description: A DICOMSeg file
+ multipart/form-data:
+ schema:
+ type: object
+ properties:
+ params:
+ type: object
+ description: Extra information the inference might return
+ dicomseg:
+ type: string
+ format: binary
+ description: DICOMSeg file containing the segmentations returned by the inference
+ application/json:
+ schema:
+ $ref: '#/components/schemas/MLInference'
+ '400':
+ description: Malformed request
+ /ml/infer/bulk:
+ post:
+ tags:
+ - Machine Learning
+ summary: Infer endpoint for a bulk of objects, images or DICOM objects (series or sop instance)
+ operationId: mlInferBulk
+ responses:
+ '501':
+ description: Not implemented
+ /ml/train:
+ post:
+ tags:
+ - Machine Learning
+ summary: Request a training task
+ operationId: mlTrain
+ requestBody:
+ required: true
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/TrainRequest'
+ responses:
+ '200':
+ description: The training request was successfully processed and sent to the provider
+ '400':
+ description: Malformed request
+ delete:
+ tags:
+ - Machine Learning
+ summary: Cancel a training
+ operationId: mlCancelTrain
+ requestBody:
+ required: true
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/TrainRequest'
+ responses:
+ '200':
+ description: The training request was successfully cancelled
+ '400':
+ description: Malformed request
+ /ml/model/list:
+ get:
+ tags:
+ - Machine Learning
+ summary: Get a list of models from all providers or a specific one
+ operationId: mlModelList
+ parameters:
+ - in: query
+ name: provider
+ description: The name of the provider to request the models from. If specified, only models from this provider are returned.
+ required: false
+ schema:
+ type: string
+ responses:
+ '200':
+ description: The list of providers
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/MLProvider'
+ '400':
+ description: Malformed request
+ /ml/model/info:
+ get:
+ tags:
+ - Machine Learning
+ summary: Get training info a model
+ operationId: mlModelInfo
+ parameters:
+ - in: query
+ name: provider
+ description: The name of the provider, e.g "MONAI"
+ required: true
+ schema:
+ type: string
+ - in: query
+ name: modelID
+ description: Model identifier
+ required: true
+ schema:
+ type: string
+ responses:
+ '200':
+ description: The training information of the specified model
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/MLModelTrainInfo'
+ '400':
+ description: Malformed request
+ /ml/cache:
+ post:
+ tags:
+ - Machine Learning
+ summary: Cache DICOM objects on a provider
+ operationId: mlCache
+ parameters:
+ - in: query
+ name: provider
+ description: The name of the provider, e.g "MONAI"
+ required: true
+ schema:
+ type: string
+ requestBody:
+ description: Contains the DICOM files to cache
+ required: true
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/DICOMDataset'
+ responses:
+ '200':
+ description: The cache request was successfully processed and sent to the provider
+ '400':
+ description: Malformed request
+ /ml/provider/methods:
+ get:
+ tags:
+ - Machine Learning
+ summary: Retrieves the implemented methods of the machine learning interface from a provider
+ operationId: mlCache
+ parameters:
+ - in: query
+ name: provider
+ description: The name of the provider, e.g "MONAI"
+ required: true
+ schema:
+ type: string
+ responses:
+ '200':
+ description: A list of the implemented methods
+ content:
+ application/json:
+ schema:
+ type: array
+ items:
+ type: string
+ '400':
+ description: Malformed request
+
components:
securitySchemes:
dicoogle_auth:
@@ -1434,3 +1753,93 @@ components:
type: array
items:
type: string
+ DatastoreRequest:
+ type: object
+ properties:
+ provider:
+ type: string
+ description: Provider name
+ example: MONAI
+ dataType:
+ type: string
+ enum: [CSV, IMAGE, DICOM]
+ dimLevel:
+ type: string
+ enum: [PATIENT, STUDY, SERIES, INSTANCE]
+ uids:
+ type: array
+ items:
+ type: string
+ dataset:
+ type: object
+ description: A map where keys represent SOPInstances and the values are annotations to upload
+ DICOMDataset:
+ type: object
+ properties:
+ level:
+ type: string
+ enum: [PATIENT, STUDY, SERIES, INSTANCE]
+ dimUIDs:
+ type: array
+ items:
+ type: string
+ TrainRequest:
+ type: object
+ properties:
+ provider:
+ type: string
+ description: Provider name
+ example: MONAI
+ modelID:
+ type: string
+ description: Model identifier
+ example: spleen_model
+ MLInference:
+ type: object
+ properties:
+ metrics:
+ type: object
+ description: A key-value dictionary of extra metrics the inference might return
+ version:
+ type: string
+ description: Version of the model that generated this inference
+ annotations:
+ type: array
+ description: A list of annotations
+ items:
+ type: object
+ MLProvider:
+ type: object
+ properties:
+ name:
+ type: string
+ description: The name of this provider
+ models:
+ type: array
+ items:
+ type: object
+ description: A list of models that belongs to this provider
+ datasets:
+ type: array
+ items:
+ type: object
+ description: A list of datasets that belongs to this provider
+ MLModelTrainInfo:
+ type: object
+ properties:
+ modifiedTime:
+ type: string
+ startTime:
+ type: string
+ currentEpoch:
+ type: number
+ totalEpochs:
+ type: number
+ bestMetric:
+ type: number
+ description: Numerical value of the best metric identifier by the best metric key.
+ bestMetricKey:
+ type: string
+ metrics:
+ type: object
+ description: A key-value containing the training metrics of the model, such as accuracy, precision, f1-score, etc.
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 12eeed323..621f657c9 100644
--- a/pom.xml
+++ b/pom.xml
@@ -3,7 +3,7 @@
4.0.0
pt.ua.ieeta
dicoogle-all
- 3.4.1-SNAPSHOT
+ 3.5.0-1-SNAPSHOT
pom
dicoogle-all
diff --git a/sdk/pom.xml b/sdk/pom.xml
index b234fb6f2..828bab10f 100644
--- a/sdk/pom.xml
+++ b/sdk/pom.xml
@@ -10,7 +10,7 @@
pt.ua.ieeta
dicoogle-all
- 3.4.1-SNAPSHOT
+ 3.5.0-1-SNAPSHOT
../pom.xml
diff --git a/sdk/src/main/java/pt/ua/dicoogle/sdk/PluginBase.java b/sdk/src/main/java/pt/ua/dicoogle/sdk/PluginBase.java
index a3132387e..62ce1ad8f 100644
--- a/sdk/src/main/java/pt/ua/dicoogle/sdk/PluginBase.java
+++ b/sdk/src/main/java/pt/ua/dicoogle/sdk/PluginBase.java
@@ -18,6 +18,7 @@
*/
package pt.ua.dicoogle.sdk;
+import pt.ua.dicoogle.sdk.mlprovider.MLProviderInterface;
import pt.ua.dicoogle.sdk.settings.ConfigurationHolder;
import java.util.ArrayList;
@@ -39,6 +40,7 @@ public abstract class PluginBase implements PluginSet, PlatformCommunicatorInter
protected List queryPlugins = new ArrayList<>();
protected List jettyPlugins = new ArrayList<>();
protected List storagePlugins = new ArrayList<>();
+ protected List mlPlugins = new ArrayList<>();
protected List services = new ArrayList<>();
protected ConfigurationHolder settings = null;
@@ -82,6 +84,11 @@ public Collection getStoragePlugins() {
return storagePlugins;
}
+ @Override
+ public Collection getMLPlugins() {
+ return mlPlugins;
+ }
+
@Override
public void setPlatformProxy(DicooglePlatformInterface core) {
this.platform = core;
diff --git a/sdk/src/main/java/pt/ua/dicoogle/sdk/PluginSet.java b/sdk/src/main/java/pt/ua/dicoogle/sdk/PluginSet.java
index d58f268dd..3db10404b 100644
--- a/sdk/src/main/java/pt/ua/dicoogle/sdk/PluginSet.java
+++ b/sdk/src/main/java/pt/ua/dicoogle/sdk/PluginSet.java
@@ -25,6 +25,7 @@
import org.restlet.resource.ServerResource;
+import pt.ua.dicoogle.sdk.mlprovider.MLProviderInterface;
import pt.ua.dicoogle.sdk.settings.ConfigurationHolder;
/**
@@ -97,6 +98,16 @@ public default Collection extends JettyPluginInterface> getJettyPlugins() {
return Collections.EMPTY_LIST;
}
+ /**
+ * Obtains a collection of MachineLearningProvider plugins, so as to integrate Machine Learning providers in Dicoogle.
+ * This collection must be immutable.
+ * @return a collection of MachineLearningProvider plugins to the core application
+ * @see MLProviderInterface
+ */
+ public default Collection extends MLProviderInterface> getMLPlugins() {
+ return Collections.EMPTY_LIST;
+ }
+
/**
* Defines the plugin's settings. This method will be called once after the plugin set was instantiated
* with plugin-scoped settings. Dicoogle users can modify these settings by accessing the XML file with
diff --git a/sdk/src/main/java/pt/ua/dicoogle/sdk/datastructs/UnindexReport.java b/sdk/src/main/java/pt/ua/dicoogle/sdk/datastructs/UnindexReport.java
index 34ebcc952..a928efd5b 100644
--- a/sdk/src/main/java/pt/ua/dicoogle/sdk/datastructs/UnindexReport.java
+++ b/sdk/src/main/java/pt/ua/dicoogle/sdk/datastructs/UnindexReport.java
@@ -152,8 +152,6 @@ public long notUnindexedFileCount() {
* for reasons other than the files not being found.
*/
public long failedFileCount() {
- return this.failures.stream()
- .mapToLong(f -> f.urisAffected.size())
- .sum();
+ return this.failures.stream().mapToLong(f -> f.urisAffected.size()).sum();
}
}
diff --git a/sdk/src/main/java/pt/ua/dicoogle/sdk/datastructs/dim/BulkAnnotation.java b/sdk/src/main/java/pt/ua/dicoogle/sdk/datastructs/dim/BulkAnnotation.java
new file mode 100644
index 000000000..510dc60b7
--- /dev/null
+++ b/sdk/src/main/java/pt/ua/dicoogle/sdk/datastructs/dim/BulkAnnotation.java
@@ -0,0 +1,198 @@
+/**
+ * Copyright (C) 2014 Universidade de Aveiro, DETI/IEETA, Bioinformatics Group - http://bioinformatics.ua.pt/
+ *
+ * This file is part of Dicoogle/dicoogle-sdk.
+ *
+ * Dicoogle/dicoogle-sdk is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Dicoogle/dicoogle-sdk is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Dicoogle. If not, see .
+ */
+package pt.ua.dicoogle.sdk.datastructs.dim;
+
+import pt.ua.dicoogle.sdk.mlprovider.MLlabel;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * A bulk annotation object denotes a group of annotations from a DICOM file generated by third-party services like AI algorithms.
+ * It follows the supplement 222 of the DICOM standard.
+ * Annotations in a bulk annotation object share common attributes such as shape type, label, pixel origin, etc.
+ * Check the module C.37.1.2 Microscopy Bulk Simple Annotations for more information on annotation bulks.
+ * This object only maps certain parts of the standard, not the whole of it, as it is quite extensive.
+ * For ease of use, this object maps annotations as a list of lists.
+ * The standard stores all the annotations on a single list and uses a secondary list of indices to delimit the annotations.
+ */
+public class BulkAnnotation {
+
+ /**
+ * Denotes the pixel origin of the annotations contained in this bulk.
+ */
+ public enum PixelOrigin {
+ /**
+ * Coordinates of this annotation are related to the frame (image section)
+ */
+ FRAME,
+ /**
+ * Coordinates of this annotation are related to the Frame Matrix (whole image)
+ */
+ VOLUME
+ }
+
+ /**
+ * Denotes the type of annotations contained in this bulk.
+ */
+ public enum AnnotationType {
+ RECTANGLE, ELLIPSE, POLYGON, POLYLINE, POINT
+ }
+
+ /**
+ * Denotes the type of coordinates contained in this bulk
+ */
+ public enum CoordinateType {
+ /**
+ * For image relative coordinates
+ */
+ TWO_DIMENSIONAL,
+ /**
+ * For coordinates in a Cartesian system defined by a frame of reference
+ */
+ THREE_DIMENSIONAL
+ }
+
+ private PixelOrigin pixelOrigin;
+
+ private CoordinateType coordinateType;
+
+ private AnnotationType annotationType;
+
+ private MLlabel label;
+
+ private List> annotations;
+
+ public BulkAnnotation(AnnotationType type, PixelOrigin origin) {
+ this.annotationType = type;
+ this.pixelOrigin = origin;
+ this.annotations = new ArrayList<>();
+ }
+
+ public BulkAnnotation(AnnotationType type, PixelOrigin origin, List> annotations) {
+ this(type, origin);
+ this.annotations = annotations;
+ }
+
+ public PixelOrigin getPixelOrigin() {
+ return pixelOrigin;
+ }
+
+ public void setPixelOrigin(PixelOrigin pixelOrigin) {
+ this.pixelOrigin = pixelOrigin;
+ }
+
+ public CoordinateType getCoordinateType() {
+ return coordinateType;
+ }
+
+ public void setCoordinateType(CoordinateType coordinateType) {
+ this.coordinateType = coordinateType;
+ }
+
+ public AnnotationType getAnnotationType() {
+ return annotationType;
+ }
+
+ public void setAnnotationType(AnnotationType annotationType) {
+ this.annotationType = annotationType;
+ }
+
+ public MLlabel getLabel() {
+ return label;
+ }
+
+ public void setLabel(MLlabel label) {
+ this.label = label;
+ }
+
+ public List> getAnnotations() {
+ return annotations;
+ }
+
+ public void setAnnotations(List> annotations) {
+ this.annotations = annotations;
+ }
+
+ public void addAnnotation(List annotation) {
+ this.annotations.add(annotation);
+ }
+
+ public List getBoundingBox(List points) {
+ return BulkAnnotation.getBoundingBox(this.annotationType, points);
+ }
+
+ /**
+ * Calculate the bounding box of an annotation from this bulk.
+ * @return a list of 4 points, representing a rectangle that contains the provided annotation.
+ */
+ public static List getBoundingBox(AnnotationType type, List points) {
+
+ double minX = Double.MAX_VALUE;
+ double minY = Double.MAX_VALUE;
+ double maxX = Double.MIN_VALUE;
+ double maxY = Double.MIN_VALUE;
+
+ switch (type) {
+ case RECTANGLE:
+ return points; // In case of rectangles, annotations are already coded as the corners of the rectangle
+ case POLYGON:
+ case POLYLINE:
+ for (Point2D p : points) {
+ if (p.getX() > maxX)
+ maxX = p.getX();
+ if (p.getX() < minX)
+ minX = p.getX();
+
+ if (p.getY() > maxY)
+ maxY = p.getY();
+ if (p.getY() < minY)
+ minY = p.getY();
+ }
+ break;
+ case ELLIPSE:
+ minX = points.get(0).getX();
+ maxX = points.get(1).getX();
+ minY = points.get(2).getY();
+ maxY = points.get(3).getY();
+ break;
+ }
+
+ Point2D tl = new Point2D(minX, minY);
+ Point2D tr = new Point2D(maxX, minY);
+ Point2D bl = new Point2D(minX, maxY);
+ Point2D br = new Point2D(maxX, maxY);
+
+ return Arrays.asList(tl, tr, bl, br);
+ }
+
+ /**
+ * Given a list of points from this bulk, calculate its area.
+ * @param points
+ * @return
+ */
+ public double getArea(List points) {
+ List bbox = this.getBoundingBox(points);
+ double width = bbox.get(1).getX() - bbox.get(0).getX();
+ double height = bbox.get(0).getY() - bbox.get(2).getY();
+ return Math.abs(width * height);
+ }
+
+}
diff --git a/sdk/src/main/java/pt/ua/dicoogle/sdk/datastructs/dim/ImageROI.java b/sdk/src/main/java/pt/ua/dicoogle/sdk/datastructs/dim/ImageROI.java
new file mode 100644
index 000000000..c8a860ad3
--- /dev/null
+++ b/sdk/src/main/java/pt/ua/dicoogle/sdk/datastructs/dim/ImageROI.java
@@ -0,0 +1,153 @@
+/**
+ * Copyright (C) 2014 Universidade de Aveiro, DETI/IEETA, Bioinformatics Group - http://bioinformatics.ua.pt/
+ *
+ * This file is part of Dicoogle/dicoogle-sdk.
+ *
+ * Dicoogle/dicoogle-sdk is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Dicoogle/dicoogle-sdk is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Dicoogle. If not, see .
+ */
+package pt.ua.dicoogle.sdk.datastructs.dim;
+
+import java.net.URI;
+import java.util.Objects;
+
+/**
+ * This object defines an Image ROI.
+ * The ROI has an x and y position that identify its origin in the source image.
+ * The SOPInstanceUID defines where this ROI was extracted from.
+ */
+public class ImageROI {
+
+ /** Not in use **/
+ public enum FileType {
+ JPEG(".jpg", "image/jpeg"), PNG(".png", "image/png");
+
+ private final String extension;
+ private final String mimeType;
+
+ private FileType(String s, String mimeType) {
+ this.extension = s;
+ this.mimeType = mimeType;
+ }
+
+ public String getExtension() {
+ return extension;
+ }
+
+ public String getMimeType() {
+ return mimeType;
+ }
+ }
+
+ private double x;
+
+ private double y;
+
+ private double width;
+
+ private double height;
+
+ private String sopInstanceUID;
+
+ private URI uriROI;
+
+ private FileType fileType;
+
+ public ImageROI(String sopInstanceUID, int x, int y, int width, int height) {
+ this.x = x;
+ this.y = y;
+ this.width = width;
+ this.height = height;
+ }
+
+ public ImageROI(String sopInstanceUID, double x, double y, double width, double height, URI roi) {
+ this.x = x;
+ this.y = y;
+ this.width = width;
+ this.height = height;
+ this.uriROI = roi;
+ }
+
+ public double getX() {
+ return x;
+ }
+
+ public void setX(double x) {
+ this.x = x;
+ }
+
+ public double getY() {
+ return y;
+ }
+
+ public void setY(double y) {
+ this.y = y;
+ }
+
+ public String getSopInstanceUID() {
+ return sopInstanceUID;
+ }
+
+ public void setSopInstanceUID(String sopInstanceUID) {
+ this.sopInstanceUID = sopInstanceUID;
+ }
+
+ public double getWidth() {
+ return width;
+ }
+
+ public void setWidth(int width) {
+ this.width = width;
+ }
+
+ public double getHeight() {
+ return height;
+ }
+
+ public void setHeight(int height) {
+ this.height = height;
+ }
+
+ public URI getUriROI() {
+ return uriROI;
+ }
+
+ public void setUriROI(URI uriROI) {
+ this.uriROI = uriROI;
+ }
+
+ public FileType getFileType() {
+ return fileType;
+ }
+
+ public void setFileType(FileType fileType) {
+ this.fileType = fileType;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o)
+ return true;
+ if (o == null || getClass() != o.getClass())
+ return false;
+ ImageROI imageROI = (ImageROI) o;
+ return Double.compare(imageROI.x, x) == 0 && Double.compare(imageROI.y, y) == 0 && width == imageROI.width
+ && height == imageROI.height && Objects.equals(sopInstanceUID, imageROI.sopInstanceUID)
+ && Objects.equals(uriROI, imageROI.uriROI);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(x, y, width, height, sopInstanceUID, uriROI);
+ }
+}
diff --git a/sdk/src/main/java/pt/ua/dicoogle/sdk/datastructs/dim/Point2D.java b/sdk/src/main/java/pt/ua/dicoogle/sdk/datastructs/dim/Point2D.java
new file mode 100644
index 000000000..6871bf65e
--- /dev/null
+++ b/sdk/src/main/java/pt/ua/dicoogle/sdk/datastructs/dim/Point2D.java
@@ -0,0 +1,63 @@
+/**
+ * Copyright (C) 2014 Universidade de Aveiro, DETI/IEETA, Bioinformatics Group - http://bioinformatics.ua.pt/
+ *
+ * This file is part of Dicoogle/dicoogle-sdk.
+ *
+ * Dicoogle/dicoogle-sdk is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Dicoogle/dicoogle-sdk is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Dicoogle. If not, see .
+ */
+package pt.ua.dicoogle.sdk.datastructs.dim;
+
+/**
+ * A point in pixel coordinates, to be used to identify coordinates in pixel space.
+ */
+public class Point2D {
+
+ private double x;
+ private double y;
+
+ public Point2D() {
+ x = 0;
+ y = 0;
+ }
+
+ public Point2D(int x, int y) {
+ this.x = x;
+ this.y = y;
+ }
+
+ public Point2D(double x, double y) {
+ this.x = x;
+ this.y = y;
+ }
+
+ public double getX() {
+ return x;
+ }
+
+ public void setX(double x) {
+ this.x = x;
+ }
+
+ public double getY() {
+ return y;
+ }
+
+ public void setY(double y) {
+ this.y = y;
+ }
+
+ public double distance(Point2D otherPoint) {
+ return Math.sqrt(Math.pow(this.x - otherPoint.getX(), 2) + Math.pow(this.y - otherPoint.getY(), 2));
+ }
+}
diff --git a/sdk/src/main/java/pt/ua/dicoogle/sdk/datastructs/wsi/WSIFrame.java b/sdk/src/main/java/pt/ua/dicoogle/sdk/datastructs/wsi/WSIFrame.java
new file mode 100644
index 000000000..a9b1c681b
--- /dev/null
+++ b/sdk/src/main/java/pt/ua/dicoogle/sdk/datastructs/wsi/WSIFrame.java
@@ -0,0 +1,89 @@
+/**
+ * Copyright (C) 2014 Universidade de Aveiro, DETI/IEETA, Bioinformatics Group - http://bioinformatics.ua.pt/
+ *
+ * This file is part of Dicoogle/dicoogle-sdk.
+ *
+ * Dicoogle/dicoogle-sdk is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Dicoogle/dicoogle-sdk is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Dicoogle. If not, see .
+ */
+package pt.ua.dicoogle.sdk.datastructs.wsi;
+
+public class WSIFrame {
+
+ private int width;
+ private int height;
+ private int x;
+ private int y;
+ private int frameIndex;
+
+ /**
+ * Construct a WSI frame.
+ * @param width the width of the frame
+ * @param height the height of the frame
+ * @param x the x coordinate of this frame in the frame matrix
+ * @param y the y coordinate of this frame in the frame matrix
+ * @param frameIndex the index of the frame that uniquely identifies this frame in the WSI
+ */
+ public WSIFrame(int width, int height, int x, int y, int frameIndex) {
+ this.width = width;
+ this.height = height;
+ this.x = x;
+ this.y = y;
+ this.frameIndex = frameIndex;
+ }
+
+ public WSIFrame(int width, int height) {
+ this.width = width;
+ this.height = height;
+ }
+
+ public int getWidth() {
+ return width;
+ }
+
+ public void setWidth(int width) {
+ this.width = width;
+ }
+
+ public int getHeight() {
+ return height;
+ }
+
+ public void setHeight(int height) {
+ this.height = height;
+ }
+
+ public int getX() {
+ return x;
+ }
+
+ public void setX(int x) {
+ this.x = x;
+ }
+
+ public int getY() {
+ return y;
+ }
+
+ public void setY(int y) {
+ this.y = y;
+ }
+
+ public int getFrameIndex() {
+ return frameIndex;
+ }
+
+ public void setFrameIndex(int frameIndex) {
+ this.frameIndex = frameIndex;
+ }
+}
diff --git a/sdk/src/main/java/pt/ua/dicoogle/sdk/mlprovider/ImageEntry.java b/sdk/src/main/java/pt/ua/dicoogle/sdk/mlprovider/ImageEntry.java
new file mode 100644
index 000000000..2b53ec5d2
--- /dev/null
+++ b/sdk/src/main/java/pt/ua/dicoogle/sdk/mlprovider/ImageEntry.java
@@ -0,0 +1,72 @@
+/**
+ * Copyright (C) 2014 Universidade de Aveiro, DETI/IEETA, Bioinformatics Group - http://bioinformatics.ua.pt/
+ *
+ * This file is part of Dicoogle/dicoogle-sdk.
+ *
+ * Dicoogle/dicoogle-sdk is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Dicoogle/dicoogle-sdk is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Dicoogle. If not, see .
+ */
+package pt.ua.dicoogle.sdk.mlprovider;
+
+import org.dcm4che2.data.DicomObject;
+
+import java.net.URI;
+import java.util.Objects;
+
+/**
+ * This object is used in {@see MLImageDataset} to map the image objects.
+ * Each entry is defined by a physical file and a set of DICOM metadata containing information such as
+ * the transfer syntax of the image, and other relevant information to process this image.
+ */
+public class ImageEntry {
+
+ private DicomObject object;
+
+ private URI file;
+
+ public ImageEntry(DicomObject object, URI file) {
+ this.object = object;
+ this.file = file;
+ }
+
+ public DicomObject getObject() {
+ return object;
+ }
+
+ public void setObject(DicomObject object) {
+ this.object = object;
+ }
+
+ public URI getFile() {
+ return file;
+ }
+
+ public void setFile(URI file) {
+ this.file = file;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o)
+ return true;
+ if (o == null || getClass() != o.getClass())
+ return false;
+ ImageEntry that = (ImageEntry) o;
+ return object.equals(that.object) && file.equals(that.file);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(file);
+ }
+}
diff --git a/sdk/src/main/java/pt/ua/dicoogle/sdk/mlprovider/MLDataType.java b/sdk/src/main/java/pt/ua/dicoogle/sdk/mlprovider/MLDataType.java
new file mode 100644
index 000000000..7862d3130
--- /dev/null
+++ b/sdk/src/main/java/pt/ua/dicoogle/sdk/mlprovider/MLDataType.java
@@ -0,0 +1,40 @@
+/**
+ * Copyright (C) 2014 Universidade de Aveiro, DETI/IEETA, Bioinformatics Group - http://bioinformatics.ua.pt/
+ *
+ * This file is part of Dicoogle/dicoogle-sdk.
+ *
+ * Dicoogle/dicoogle-sdk is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Dicoogle/dicoogle-sdk is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Dicoogle. If not, see .
+ */
+package pt.ua.dicoogle.sdk.mlprovider;
+
+/**
+ * This enum maps the supported data types used in the MLProviderInterface.
+ * Data in this context always refers to data objects, labelled or unlabelled, used throughout the ML pipeline,
+ * for example in training or inference jobs.
+ * The data types listed here are not exhaustive, meaning future releases and iterations might add or remove new data types.
+ */
+public enum MLDataType {
+ /**
+ * CSV data objects refers to data that can be mapped in a tabular format.
+ */
+ CSV,
+ /**
+ * IMAGE data objects refer explicitly to pixel data objects.
+ */
+ IMAGE,
+ /**
+ * DICOM data objects refer to one: Study, Series or Instance.
+ */
+ DICOM
+}
diff --git a/sdk/src/main/java/pt/ua/dicoogle/sdk/mlprovider/MLDataset.java b/sdk/src/main/java/pt/ua/dicoogle/sdk/mlprovider/MLDataset.java
new file mode 100644
index 000000000..69faf0aae
--- /dev/null
+++ b/sdk/src/main/java/pt/ua/dicoogle/sdk/mlprovider/MLDataset.java
@@ -0,0 +1,51 @@
+/**
+ * Copyright (C) 2014 Universidade de Aveiro, DETI/IEETA, Bioinformatics Group - http://bioinformatics.ua.pt/
+ *
+ * This file is part of Dicoogle/dicoogle-sdk.
+ *
+ * Dicoogle/dicoogle-sdk is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Dicoogle/dicoogle-sdk is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Dicoogle. If not, see .
+ */
+package pt.ua.dicoogle.sdk.mlprovider;
+
+/**
+ * ML dataset objects map a collection of labelled data, to be used in the training and generation of models.
+ * ML datasets have a type, defined by {@see MLDataType} and an identifier, to be used by the providers to internally manage this dataset.
+ * This data object is used in datastore requests to construct annotated datasets.
+ */
+public abstract class MLDataset {
+
+ protected String name;
+ protected MLDataType dataType;
+
+ public MLDataset(String name, MLDataType dataType) {
+ this.name = name;
+ this.dataType = dataType;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public MLDataType getDataType() {
+ return dataType;
+ }
+
+ public void setDataType(MLDataType dataType) {
+ this.dataType = dataType;
+ }
+}
diff --git a/sdk/src/main/java/pt/ua/dicoogle/sdk/mlprovider/MLDicomDataset.java b/sdk/src/main/java/pt/ua/dicoogle/sdk/mlprovider/MLDicomDataset.java
new file mode 100644
index 000000000..006e298cc
--- /dev/null
+++ b/sdk/src/main/java/pt/ua/dicoogle/sdk/mlprovider/MLDicomDataset.java
@@ -0,0 +1,61 @@
+/**
+ * Copyright (C) 2014 Universidade de Aveiro, DETI/IEETA, Bioinformatics Group - http://bioinformatics.ua.pt/
+ *
+ * This file is part of Dicoogle/dicoogle-sdk.
+ *
+ * Dicoogle/dicoogle-sdk is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Dicoogle/dicoogle-sdk is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Dicoogle. If not, see .
+ */
+package pt.ua.dicoogle.sdk.mlprovider;
+
+import pt.ua.dicoogle.sdk.datastructs.dim.DimLevel;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * An ML dataset of DICOM objects.
+ */
+public class MLDicomDataset extends MLDataset {
+
+ private DimLevel level;
+ private List dimUIDs;
+
+ public MLDicomDataset(DimLevel level) {
+ super("", MLDataType.DICOM);
+ this.level = level;
+ dimUIDs = new ArrayList<>();
+ }
+
+ public MLDicomDataset(DimLevel level, List dimUIDs) {
+ super("", MLDataType.DICOM);
+ this.level = level;
+ this.dimUIDs = dimUIDs;
+ }
+
+ public DimLevel getLevel() {
+ return level;
+ }
+
+ public void setLevel(DimLevel level) {
+ this.level = level;
+ }
+
+ public List getDimUIDs() {
+ return dimUIDs;
+ }
+
+ public void setDimUIDs(List dimUIDs) {
+ this.dimUIDs = dimUIDs;
+ }
+}
diff --git a/sdk/src/main/java/pt/ua/dicoogle/sdk/mlprovider/MLException.java b/sdk/src/main/java/pt/ua/dicoogle/sdk/mlprovider/MLException.java
new file mode 100644
index 000000000..d74fa4c54
--- /dev/null
+++ b/sdk/src/main/java/pt/ua/dicoogle/sdk/mlprovider/MLException.java
@@ -0,0 +1,39 @@
+/**
+ * Copyright (C) 2014 Universidade de Aveiro, DETI/IEETA, Bioinformatics Group - http://bioinformatics.ua.pt/
+ *
+ * This file is part of Dicoogle/dicoogle-sdk.
+ *
+ * Dicoogle/dicoogle-sdk is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Dicoogle/dicoogle-sdk is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Dicoogle. If not, see .
+ */
+package pt.ua.dicoogle.sdk.mlprovider;
+
+public class MLException extends RuntimeException {
+
+ public MLException() {
+ super();
+ }
+
+ public MLException(String message) {
+ super(message);
+ }
+
+ public MLException(Exception cause) {
+ super(cause);
+ }
+
+ public MLException(String message, Exception cause) {
+ super(message, cause);
+ }
+
+}
diff --git a/sdk/src/main/java/pt/ua/dicoogle/sdk/mlprovider/MLImageDataset.java b/sdk/src/main/java/pt/ua/dicoogle/sdk/mlprovider/MLImageDataset.java
new file mode 100644
index 000000000..14ef9740e
--- /dev/null
+++ b/sdk/src/main/java/pt/ua/dicoogle/sdk/mlprovider/MLImageDataset.java
@@ -0,0 +1,57 @@
+/**
+ * Copyright (C) 2014 Universidade de Aveiro, DETI/IEETA, Bioinformatics Group - http://bioinformatics.ua.pt/
+ *
+ * This file is part of Dicoogle/dicoogle-sdk.
+ *
+ * Dicoogle/dicoogle-sdk is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Dicoogle/dicoogle-sdk is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Dicoogle. If not, see .
+ */
+package pt.ua.dicoogle.sdk.mlprovider;
+
+import java.util.HashMap;
+
+/**
+ * An ML dataset of image objects.
+ * Images are defined by {@see ImageEntry} objects and must have a label associated.
+ */
+public class MLImageDataset extends MLDataset {
+
+ private HashMap dataset;
+
+ private boolean multiClass;
+
+ public MLImageDataset() {
+ super("name", MLDataType.IMAGE);
+ }
+
+ public MLImageDataset(HashMap dataset) {
+ super("", MLDataType.IMAGE);
+ this.dataset = dataset;
+ }
+
+ public HashMap getDataset() {
+ return dataset;
+ }
+
+ public void setDataset(HashMap dataset) {
+ this.dataset = dataset;
+ }
+
+ public boolean isMultiClass() {
+ return multiClass;
+ }
+
+ public void setMultiClass(boolean multiClass) {
+ this.multiClass = multiClass;
+ }
+}
diff --git a/sdk/src/main/java/pt/ua/dicoogle/sdk/mlprovider/MLInference.java b/sdk/src/main/java/pt/ua/dicoogle/sdk/mlprovider/MLInference.java
new file mode 100644
index 000000000..dc0d7fa26
--- /dev/null
+++ b/sdk/src/main/java/pt/ua/dicoogle/sdk/mlprovider/MLInference.java
@@ -0,0 +1,96 @@
+/**
+ * Copyright (C) 2014 Universidade de Aveiro, DETI/IEETA, Bioinformatics Group - http://bioinformatics.ua.pt/
+ *
+ * This file is part of Dicoogle/dicoogle-sdk.
+ *
+ * Dicoogle/dicoogle-sdk is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Dicoogle/dicoogle-sdk is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Dicoogle. If not, see .
+ */
+package pt.ua.dicoogle.sdk.mlprovider;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import pt.ua.dicoogle.sdk.datastructs.dim.BulkAnnotation;
+
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * This object maps inferences done by the AI algorithms.
+ * It can contain a set of metrics, annotations and a DICOM SEG file.
+ */
+public class MLInference {
+
+ private Map metrics;
+
+ private String version;
+
+ private List annotations;
+
+ @JsonIgnore
+ private String resourcesFolder;
+
+ @JsonIgnore
+ private Path dicomSEG;
+
+ public MLInference() {
+ this.metrics = new HashMap<>();
+ this.annotations = new ArrayList<>();
+ }
+
+ public Map getMetrics() {
+ return metrics;
+ }
+
+ public void setMetrics(Map metrics) {
+ this.metrics = metrics;
+ }
+
+ public List getAnnotations() {
+ return annotations;
+ }
+
+ public void setAnnotations(List annotations) {
+ this.annotations = annotations;
+ }
+
+ public String getResourcesFolder() {
+ return resourcesFolder;
+ }
+
+ public void setResourcesFolder(String resourcesFolder) {
+ this.resourcesFolder = resourcesFolder;
+ }
+
+ public Path getDicomSEG() {
+ return dicomSEG;
+ }
+
+ public void setDicomSEG(Path dicomSEG) {
+ this.dicomSEG = dicomSEG;
+ }
+
+ public String getVersion() {
+ return version;
+ }
+
+ public void setVersion(String version) {
+ this.version = version;
+ }
+
+ public boolean hasResults() {
+ return metrics != null || annotations != null;
+ }
+}
diff --git a/sdk/src/main/java/pt/ua/dicoogle/sdk/mlprovider/MLInferenceRequest.java b/sdk/src/main/java/pt/ua/dicoogle/sdk/mlprovider/MLInferenceRequest.java
new file mode 100644
index 000000000..ac6e7b8cb
--- /dev/null
+++ b/sdk/src/main/java/pt/ua/dicoogle/sdk/mlprovider/MLInferenceRequest.java
@@ -0,0 +1,104 @@
+/**
+ * Copyright (C) 2014 Universidade de Aveiro, DETI/IEETA, Bioinformatics Group - http://bioinformatics.ua.pt/
+ *
+ * This file is part of Dicoogle/dicoogle-sdk.
+ *
+ * Dicoogle/dicoogle-sdk is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Dicoogle/dicoogle-sdk is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Dicoogle. If not, see .
+ */
+package pt.ua.dicoogle.sdk.mlprovider;
+
+import pt.ua.dicoogle.sdk.datastructs.dim.DimLevel;
+
+import java.awt.image.BufferedImage;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * This object is used in the infer servlet to serialize the incoming JSON objects.
+ */
+public class MLInferenceRequest {
+
+ private boolean isWsi;
+
+ private DimLevel level;
+
+ private String dimID;
+
+ private BufferedImage roi;
+
+ private String modelID;
+
+ private Map parameters;
+
+ public MLInferenceRequest(boolean isWsi, DimLevel level, String dimID, String modelID) {
+ this.isWsi = isWsi;
+ this.level = level;
+ this.dimID = dimID;
+ this.modelID = modelID;
+ parameters = new HashMap<>();
+ }
+
+ public boolean isWsi() {
+ return isWsi;
+ }
+
+ public void setWsi(boolean wsi) {
+ isWsi = wsi;
+ }
+
+ public DimLevel getLevel() {
+ return level;
+ }
+
+ public void setLevel(DimLevel level) {
+ this.level = level;
+ }
+
+ public String getDimID() {
+ return dimID;
+ }
+
+ public void setDimID(String dimID) {
+ this.dimID = dimID;
+ }
+
+ public BufferedImage getRoi() {
+ return roi;
+ }
+
+ public void setRoi(BufferedImage roi) {
+ this.roi = roi;
+ }
+
+ public boolean hasROI() {
+ return this.roi != null;
+ }
+
+ public String getModelID() {
+ return modelID;
+ }
+
+ public void setModelID(String modelID) {
+ this.modelID = modelID;
+ }
+
+ public Map getParameters() {
+ return parameters;
+ }
+
+ public void setParameters(Map parameters) {
+ this.parameters = parameters;
+ }
+
+}
diff --git a/sdk/src/main/java/pt/ua/dicoogle/sdk/mlprovider/MLMethod.java b/sdk/src/main/java/pt/ua/dicoogle/sdk/mlprovider/MLMethod.java
new file mode 100644
index 000000000..3d5bf36e6
--- /dev/null
+++ b/sdk/src/main/java/pt/ua/dicoogle/sdk/mlprovider/MLMethod.java
@@ -0,0 +1,28 @@
+/**
+ * Copyright (C) 2014 Universidade de Aveiro, DETI/IEETA, Bioinformatics Group - http://bioinformatics.ua.pt/
+ *
+ * This file is part of Dicoogle/dicoogle-sdk.
+ *
+ * Dicoogle/dicoogle-sdk is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Dicoogle/dicoogle-sdk is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Dicoogle. If not, see .
+ */
+package pt.ua.dicoogle.sdk.mlprovider;
+
+/**
+ * This enum lists the available methods of the MLProvider interface.
+ * This is used when requesting the available methods of a provider.
+ * It is a ENUM instead for example of a String to restrict the possible values.
+ */
+public enum MLMethod {
+ INFER, BULK_INFER, DATASTORE, CACHE, LIST_MODELS, CREATE_MODEL, MODEL_INFO, TRAIN_MODEL, STOP_TRAINING, DELETE_MODEL,
+}
diff --git a/sdk/src/main/java/pt/ua/dicoogle/sdk/mlprovider/MLModel.java b/sdk/src/main/java/pt/ua/dicoogle/sdk/mlprovider/MLModel.java
new file mode 100644
index 000000000..9d0fb4c14
--- /dev/null
+++ b/sdk/src/main/java/pt/ua/dicoogle/sdk/mlprovider/MLModel.java
@@ -0,0 +1,143 @@
+/**
+ * Copyright (C) 2014 Universidade de Aveiro, DETI/IEETA, Bioinformatics Group - http://bioinformatics.ua.pt/
+ *
+ * This file is part of Dicoogle/dicoogle-sdk.
+ *
+ * Dicoogle/dicoogle-sdk is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Dicoogle/dicoogle-sdk is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Dicoogle. If not, see .
+ */
+package pt.ua.dicoogle.sdk.mlprovider;
+
+import java.io.Serializable;
+import java.util.*;
+
+public class MLModel implements Serializable {
+
+ private String name;
+
+ private String id;
+
+ private String type;
+
+ private String description;
+
+ private Date creationDate;
+
+ private MLDataType dataType;
+
+ private Set labels;
+
+ private List parameters;
+
+ /**
+ * A number between 1 and n that specifies the magnification level of the images this model supports.
+ * It is only useful in pathology where algorithms might be trained on lower resolution levels of the pyramid.
+ */
+ private int processMagnification;
+
+ public MLModel(String name, String id) {
+ this.name = name;
+ this.id = id;
+ this.type = "";
+ labels = new TreeSet<>();
+ parameters = new ArrayList<>();
+ dataType = MLDataType.IMAGE;
+ creationDate = new Date();
+ processMagnification = 0;
+ }
+
+ public MLModel(String name, String id, List parameters) {
+ this(name, id);
+ this.parameters = parameters;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public Date getCreationDate() {
+ return creationDate;
+ }
+
+ public void setCreationDate(Date creationDate) {
+ this.creationDate = creationDate;
+ }
+
+ public MLDataType getDataType() {
+ return dataType;
+ }
+
+ public void setDataType(MLDataType dataType) {
+ this.dataType = dataType;
+ }
+
+ public Set getLabels() {
+ return labels;
+ }
+
+ public void setLabels(Set labels) {
+ this.labels = labels;
+ }
+
+ public List getParameters() {
+ return parameters;
+ }
+
+ public void setParameters(List parameters) {
+ this.parameters = parameters;
+ }
+
+ public void removeLabel(MLlabel label) {
+ this.labels.remove(label);
+ }
+
+ public void addLabel(MLlabel label) {
+ this.labels.add(label);
+ }
+
+ public int getProcessMagnification() {
+ return processMagnification;
+ }
+
+ public void setProcessMagnification(int processMagnification) {
+ this.processMagnification = processMagnification;
+ }
+}
diff --git a/sdk/src/main/java/pt/ua/dicoogle/sdk/mlprovider/MLModelParameter.java b/sdk/src/main/java/pt/ua/dicoogle/sdk/mlprovider/MLModelParameter.java
new file mode 100644
index 000000000..5a027809d
--- /dev/null
+++ b/sdk/src/main/java/pt/ua/dicoogle/sdk/mlprovider/MLModelParameter.java
@@ -0,0 +1,138 @@
+/**
+ * Copyright (C) 2014 Universidade de Aveiro, DETI/IEETA, Bioinformatics Group - http://bioinformatics.ua.pt/
+ *
+ * This file is part of Dicoogle/dicoogle-sdk.
+ *
+ * Dicoogle/dicoogle-sdk is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Dicoogle/dicoogle-sdk is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Dicoogle. If not, see .
+ */
+package pt.ua.dicoogle.sdk.mlprovider;
+
+import java.util.List;
+
+/**
+ * This object is used to map MLModel parameters.
+ * These parameters are used to fine tune a inference request to a model.
+ */
+public class MLModelParameter {
+
+ private MLModelParameterType type;
+ private String name;
+ private Object defaultValue;
+ private String description;
+ private List choices;
+
+ public enum MLModelParameterType {
+ TEXT, NUMBER, ENUM
+ }
+
+ public static class Choice {
+
+ private String name;
+ private Object value;
+
+ public Choice(String name, Object value) {
+ this.name = name;
+ this.value = value;
+ }
+
+ public Object getValue() {
+ return value;
+ }
+
+ public void setValue(Object value) {
+ this.value = value;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+ }
+
+ private MLModelParameter(MLModelParameterType type, String name, Object defaultValue, String description) {
+ this.type = type;
+ this.name = name;
+ this.defaultValue = defaultValue;
+ this.description = description;
+ }
+
+ private MLModelParameter(String name, List choices, Object defaultValue, String description) {
+ this(MLModelParameterType.ENUM, name, defaultValue, description);
+ this.choices = choices;
+ }
+
+ public static MLModelParameter buildNumberParam(String name, double defaultValue, String description) {
+ if (name == null || name.isEmpty())
+ throw new IllegalArgumentException();
+ return new MLModelParameter(MLModelParameterType.NUMBER, name, defaultValue, description);
+ }
+
+ public static MLModelParameter buildTextParam(String name, String defaultValue, String description) {
+ if (name == null || name.isEmpty())
+ throw new IllegalArgumentException();
+ return new MLModelParameter(MLModelParameterType.TEXT, name, defaultValue, description);
+ }
+
+ public static MLModelParameter buildEnumParam(String name, List choices, Object defaultValue,
+ String description) {
+ if (name == null || name.isEmpty())
+ throw new IllegalArgumentException();
+ if (choices == null || choices.isEmpty())
+ throw new IllegalArgumentException();
+ return new MLModelParameter(name, choices, defaultValue, description);
+ }
+
+ public MLModelParameterType getType() {
+ return type;
+ }
+
+ public void setType(MLModelParameterType type) {
+ this.type = type;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public Object getDefaultValue() {
+ return defaultValue;
+ }
+
+ public void setDefaultValue(Object defaultValue) {
+ this.defaultValue = defaultValue;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public List getChoices() {
+ return choices;
+ }
+
+ public void setChoices(List choices) {
+ this.choices = choices;
+ }
+}
diff --git a/sdk/src/main/java/pt/ua/dicoogle/sdk/mlprovider/MLModelTrainInfo.java b/sdk/src/main/java/pt/ua/dicoogle/sdk/mlprovider/MLModelTrainInfo.java
new file mode 100644
index 000000000..a2052c817
--- /dev/null
+++ b/sdk/src/main/java/pt/ua/dicoogle/sdk/mlprovider/MLModelTrainInfo.java
@@ -0,0 +1,103 @@
+/**
+ * Copyright (C) 2014 Universidade de Aveiro, DETI/IEETA, Bioinformatics Group - http://bioinformatics.ua.pt/
+ *
+ * This file is part of Dicoogle/dicoogle-sdk.
+ *
+ * Dicoogle/dicoogle-sdk is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Dicoogle/dicoogle-sdk is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Dicoogle. If not, see .
+ */
+package pt.ua.dicoogle.sdk.mlprovider;
+
+import java.util.Date;
+import java.util.Map;
+
+/**
+ * This object stores model information
+ */
+public class MLModelTrainInfo {
+
+ private Date modifiedTime;
+
+ private Date startTime;
+
+ private int currentEpoch;
+
+ private int totalEpochs;
+
+ private double bestMetric;
+
+ private String bestMetricKey;
+
+ private Map metrics;
+
+ public MLModelTrainInfo(Date modifiedTime, Date startTime) {
+ this.modifiedTime = modifiedTime;
+ this.startTime = startTime;
+ }
+
+ public Date getModifiedTime() {
+ return modifiedTime;
+ }
+
+ public void setModifiedTime(Date modifiedTime) {
+ this.modifiedTime = modifiedTime;
+ }
+
+ public Date getStartTime() {
+ return startTime;
+ }
+
+ public void setStartTime(Date startTime) {
+ this.startTime = startTime;
+ }
+
+ public int getCurrentEpoch() {
+ return currentEpoch;
+ }
+
+ public void setCurrentEpoch(int currentEpoch) {
+ this.currentEpoch = currentEpoch;
+ }
+
+ public int getTotalEpochs() {
+ return totalEpochs;
+ }
+
+ public void setTotalEpochs(int totalEpochs) {
+ this.totalEpochs = totalEpochs;
+ }
+
+ public double getBestMetric() {
+ return bestMetric;
+ }
+
+ public void setBestMetric(double bestMetric) {
+ this.bestMetric = bestMetric;
+ }
+
+ public String getBestMetricKey() {
+ return bestMetricKey;
+ }
+
+ public void setBestMetricKey(String bestMetricKey) {
+ this.bestMetricKey = bestMetricKey;
+ }
+
+ public Map getMetrics() {
+ return metrics;
+ }
+
+ public void setMetrics(Map metrics) {
+ this.metrics = metrics;
+ }
+}
diff --git a/sdk/src/main/java/pt/ua/dicoogle/sdk/mlprovider/MLProvider.java b/sdk/src/main/java/pt/ua/dicoogle/sdk/mlprovider/MLProvider.java
new file mode 100644
index 000000000..b415f5eb2
--- /dev/null
+++ b/sdk/src/main/java/pt/ua/dicoogle/sdk/mlprovider/MLProvider.java
@@ -0,0 +1,62 @@
+/**
+ * Copyright (C) 2014 Universidade de Aveiro, DETI/IEETA, Bioinformatics Group - http://bioinformatics.ua.pt/
+ *
+ * This file is part of Dicoogle/dicoogle-sdk.
+ *
+ * Dicoogle/dicoogle-sdk is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Dicoogle/dicoogle-sdk is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Dicoogle. If not, see .
+ */
+package pt.ua.dicoogle.sdk.mlprovider;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Data object to model MLPlugin instances.
+ */
+public class MLProvider {
+
+ public MLProvider(String name) {
+ this.name = name;
+ this.models = new ArrayList<>();
+ this.datasets = new ArrayList<>();
+ }
+
+ private List models;
+ private List datasets;
+ private String name;
+
+ public List getModels() {
+ return models;
+ }
+
+ public void setModels(List models) {
+ this.models = models;
+ }
+
+ public List getDatasets() {
+ return datasets;
+ }
+
+ public void setDatasets(List datasets) {
+ this.datasets = datasets;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+}
diff --git a/sdk/src/main/java/pt/ua/dicoogle/sdk/mlprovider/MLProviderInterface.java b/sdk/src/main/java/pt/ua/dicoogle/sdk/mlprovider/MLProviderInterface.java
new file mode 100644
index 000000000..88b96c1d2
--- /dev/null
+++ b/sdk/src/main/java/pt/ua/dicoogle/sdk/mlprovider/MLProviderInterface.java
@@ -0,0 +1,122 @@
+/**
+ * Copyright (C) 2014 Universidade de Aveiro, DETI/IEETA, Bioinformatics Group - http://bioinformatics.ua.pt/
+ *
+ * This file is part of Dicoogle/dicoogle-sdk.
+ *
+ * Dicoogle/dicoogle-sdk is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Dicoogle/dicoogle-sdk is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Dicoogle. If not, see .
+ */
+package pt.ua.dicoogle.sdk.mlprovider;
+
+import pt.ua.dicoogle.sdk.DicooglePlugin;
+import pt.ua.dicoogle.sdk.task.Task;
+
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Interface to define Machine Learning providers.
+ * A machine learning provider can be a remote service, hosted on the cloud, or a simple remote/local server
+ * that has machine learning algorithms installed for problem solving.
+ * Machine learning providers can work with either image or csv datasets.
+ * The purpose of this interface is to provide a way
+ * to integrate with services such as Google's Vertex API or Amazon's SageMaker API.
+ *
+ * @author Rui Jesus
+ */
+public abstract class MLProviderInterface implements DicooglePlugin {
+
+ protected Set acceptedDataTypes;
+
+ /**
+ * This method uploads data to the provider.
+ * The API assumes three kinds of data:
+ * - CSV files, identified by a URI
+ * - Image files, identified by a URI
+ * - DICOM files, identified by their respective UIDs.
+ * This method can be used to upload labelled or un-labelled datasets to the provider.
+ */
+ public abstract void dataStore(MLDataset dataset);
+
+ /**
+ * This method is similar to dataStore in that is also used to upload data to a provider.
+ * The main difference is that this method should be used to cache DICOM objects on the provider,
+ * so that the provider can for example run the inference tasks locally.
+ * Only DICOM objects can be cached.
+ * @param dataset a DICOM dataset to cache.
+ * @return a task to the cache operation. Returns true if the dataset was cached.
+ */
+ public abstract Task cache(MLDicomDataset dataset);
+
+ /**
+ * This method creates a model using a specific dataset
+ */
+ public abstract MLModel createModel();
+
+ /**
+ * This method lists the models created on this provider.
+ */
+ public abstract List listModels();
+
+ /**
+ * This method lists the models created on this provider.
+ * @param modelID model identifier
+ */
+ public abstract MLModelTrainInfo modelInfo(String modelID);
+
+ /**
+ * This method orders the training of a model.
+ * @param modelID the unique model identifier within the provider.
+ */
+ public abstract MLTrainTask trainModel(String modelID);
+
+ /**
+ * This method orders the training of a model.
+ * @param trainingTaskID the unique training task identifier.
+ */
+ public abstract boolean stopTraining(String trainingTaskID);
+
+ /**
+ * This method deletes a model
+ */
+ public abstract void deleteModel();
+
+ /**
+ * Order a prediction over a single object.
+ * The object can be a series instance, a sop instance or a 2D/3D ROI.
+ *
+ * @param inferRequest object that defines this inference request
+ */
+ public abstract Task infer(MLInferenceRequest inferRequest);
+
+ /**
+ * This method makes a bulk inference request using the selected model
+ */
+ public abstract void batchInfer();
+
+ /**
+ * This method indicates if the service is available.
+ * @return true if the provider is ready to be used, false otherwise.
+ */
+ public abstract boolean isAvailable();
+
+ /**
+ * This method can be used to determine which of the methods of this interface are implemented.
+ * @return a list of the methods implemented.
+ */
+ public abstract Set getImplementedMethods();
+
+ public Set getAcceptedDataTypes() {
+ return acceptedDataTypes;
+ }
+}
diff --git a/sdk/src/main/java/pt/ua/dicoogle/sdk/mlprovider/MLTrainTask.java b/sdk/src/main/java/pt/ua/dicoogle/sdk/mlprovider/MLTrainTask.java
new file mode 100644
index 000000000..3c51a372f
--- /dev/null
+++ b/sdk/src/main/java/pt/ua/dicoogle/sdk/mlprovider/MLTrainTask.java
@@ -0,0 +1,80 @@
+/**
+ * Copyright (C) 2014 Universidade de Aveiro, DETI/IEETA, Bioinformatics Group - http://bioinformatics.ua.pt/
+ *
+ * This file is part of Dicoogle/dicoogle-sdk.
+ *
+ * Dicoogle/dicoogle-sdk is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Dicoogle/dicoogle-sdk is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Dicoogle. If not, see .
+ */
+package pt.ua.dicoogle.sdk.mlprovider;
+
+/**
+ * Object to map training tasks.
+ * Training tasks have an associated life cycle and unique identifier.
+ * Additional information such as current epoch and iteration, as well as training details can be mapped in this object too.
+ */
+public class MLTrainTask {
+
+ /**
+ * Status of a training task request/job.
+ * It is used to identify the status of training tasks in execution but also training requests.
+ */
+ public enum TrainingStatus {
+ /**
+ * A training task was successfully submitted.
+ * A corresponding identifier should be generated to track the progress.
+ */
+ SUBMITTED,
+ /**
+ * A training job identified by a ID is currently running
+ */
+ RUNNING,
+ /**
+ * A training job identified by an ID was cancelled.
+ */
+ CANCELLED,
+ /**
+ * A training request was not processed because the service cannot process more training requests.
+ */
+ BUSY,
+ /**
+ * A training request was not processed because the request was malformed or some other error occured.
+ */
+ REJECTED
+ }
+
+ public MLTrainTask(String taskID, TrainingStatus status) {
+ this.taskID = taskID;
+ this.status = status;
+ }
+
+ private String taskID;
+
+ private TrainingStatus status;
+
+ public String getTaskID() {
+ return taskID;
+ }
+
+ public void setTaskID(String taskID) {
+ this.taskID = taskID;
+ }
+
+ public TrainingStatus getStatus() {
+ return status;
+ }
+
+ public void setStatus(TrainingStatus status) {
+ this.status = status;
+ }
+}
diff --git a/sdk/src/main/java/pt/ua/dicoogle/sdk/mlprovider/MLlabel.java b/sdk/src/main/java/pt/ua/dicoogle/sdk/mlprovider/MLlabel.java
new file mode 100644
index 000000000..64fb2efd4
--- /dev/null
+++ b/sdk/src/main/java/pt/ua/dicoogle/sdk/mlprovider/MLlabel.java
@@ -0,0 +1,150 @@
+/**
+ * Copyright (C) 2014 Universidade de Aveiro, DETI/IEETA, Bioinformatics Group - http://bioinformatics.ua.pt/
+ *
+ * This file is part of Dicoogle/dicoogle-sdk.
+ *
+ * Dicoogle/dicoogle-sdk is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Dicoogle/dicoogle-sdk is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Dicoogle. If not, see .
+ */
+package pt.ua.dicoogle.sdk.mlprovider;
+
+import java.io.Serializable;
+import java.util.Objects;
+
+/**
+ * A label object that belongs to a model.
+ * Labels must be unique within a model.
+ * The label definition proposed here follows the DICOM standard guidelines for segmentation objects.
+ * @see C.8.20.2 Segmentation Image Module for more information.
+ */
+public class MLlabel implements Comparable, Serializable {
+
+ public enum CodingSchemeDesignator {
+ DCM, // DICOM scheme code designator
+ SRT, // SNOMED scheme code designator
+ LN // LOINC scheme code designator
+ }
+
+ /**
+ * DICOM Segment Label (0062, 0005) is a user defined label.
+ */
+ private String name;
+
+ /**
+ * DICOM Segment Description (0062, 0007) is a user defined description.
+ */
+ private String description;
+
+ /**
+ * A hex color string that specifies the color this label should have.
+ */
+ private String color;
+
+ /**
+ * DICOM Code Value (0008,0100) is an identifier that is unambiguous within the Coding Scheme denoted by Coding Scheme Designator (0008,0102) and Coding Scheme Version (0008,0103).
+ */
+ private String codeValue;
+
+ /**
+ * DICOM Code Meaning (0008,0104), a human-readable description of the label,
+ * given by the combination of Code Value and Coding Scheme Designator.
+ */
+ private String codeMeaning;
+
+ /**
+ * DICOM attribute Coding Scheme Designator (0008,0102) defines the coding scheme in which the code for a term is defined.
+ * Typical values: "DCM" for DICOM defined codes, "SRT" for SNOMED and "LN" for LOINC
+ */
+ private CodingSchemeDesignator codingSchemeDesignator;
+
+ public MLlabel() {
+ this.description = "unknown";
+ this.codingSchemeDesignator = CodingSchemeDesignator.DCM;
+ this.codeValue = "333333";
+ this.codeMeaning = "unknown";
+ this.color = "#000000";
+ }
+
+ public MLlabel(String name) {
+ this();
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public String getColor() {
+ return color;
+ }
+
+ public void setColor(String color) {
+ this.color = color;
+ }
+
+ public String getCodeValue() {
+ return codeValue;
+ }
+
+ public void setCodeValue(String codeValue) {
+ this.codeValue = codeValue;
+ }
+
+ public String getCodeMeaning() {
+ return codeMeaning;
+ }
+
+ public void setCodeMeaning(String codeMeaning) {
+ this.codeMeaning = codeMeaning;
+ }
+
+ public CodingSchemeDesignator getCodingSchemeDesignator() {
+ return codingSchemeDesignator;
+ }
+
+ public void setCodingSchemeDesignator(CodingSchemeDesignator codingSchemeDesignator) {
+ this.codingSchemeDesignator = codingSchemeDesignator;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o)
+ return true;
+ if (o == null || getClass() != o.getClass())
+ return false;
+ MLlabel mLlabel = (MLlabel) o;
+ return name.equals(mLlabel.name);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(name);
+ }
+
+ @Override
+ public int compareTo(MLlabel o) {
+ return o.getName().compareTo(this.getName());
+ }
+}
diff --git a/sdk/src/main/java/pt/ua/dicoogle/sdk/settings/server/ServerSettings.java b/sdk/src/main/java/pt/ua/dicoogle/sdk/settings/server/ServerSettings.java
index b0c20d71a..6e7cbfbf7 100644
--- a/sdk/src/main/java/pt/ua/dicoogle/sdk/settings/server/ServerSettings.java
+++ b/sdk/src/main/java/pt/ua/dicoogle/sdk/settings/server/ServerSettings.java
@@ -65,6 +65,8 @@ interface Archive extends ServerSettingsReader.Archive {
void setDirectoryWatcherEnabled(boolean watch);
+ void setSupportWSI(boolean supportWSI);
+
void setEncryptUsersFile(boolean encrypt);
void setDIMProviders(List providers);
diff --git a/sdk/src/main/java/pt/ua/dicoogle/sdk/settings/server/ServerSettingsReader.java b/sdk/src/main/java/pt/ua/dicoogle/sdk/settings/server/ServerSettingsReader.java
index 02a44ed0b..f3c589be1 100644
--- a/sdk/src/main/java/pt/ua/dicoogle/sdk/settings/server/ServerSettingsReader.java
+++ b/sdk/src/main/java/pt/ua/dicoogle/sdk/settings/server/ServerSettingsReader.java
@@ -79,6 +79,9 @@ interface Archive {
@JsonGetter("watch-directory")
String getWatchDirectory();
+ @JsonGetter("support-wsi")
+ boolean isSupportWSI();
+
@JsonGetter("dim-provider")
@JacksonXmlElementWrapper(localName = "dim-providers")
List getDIMProviders();