Commit 2689e592 authored by danyfel80's avatar danyfel80
Browse files

Columbus supported first commit

Todo
- Support ScanR and IM formats: adapt old method
- Test on multiple Columbus images
parent 8ba0fc0e
......@@ -12,7 +12,7 @@
<description/>
<build>
<plugins>
<!--<plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.3.2</version>
......@@ -27,7 +27,7 @@
<configuration>
<mainClass>icy.main.Icy</mainClass>
</configuration>
</plugin>-->
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
......
package plugins.adufour.hcs.data;
import java.awt.Point;
import java.awt.geom.Rectangle2D;
import java.util.Map;
public interface IWell
......@@ -12,4 +13,11 @@ public interface IWell
Map<Long, ? extends IField> getFields();
IWellShape getShape();
/**
* @param field
* The target field;
* @return The bounds of the field relative to well bounds.
*/
Rectangle2D getFieldBoundsOnWell(IField field);
}
......@@ -4,46 +4,61 @@ import java.awt.Color;
import plugins.adufour.hcs.data.IChannel;
public class ColumbusChannel implements IChannel {
public static class Builder {
public static ColumbusChannel fromImage(ColumbusImage image) {
ColumbusChannel ch = new ColumbusChannel();
ch.image = image;
return ch;
}
}
private ColumbusImage image;
@Override
public long getId() {
return image.getChannelId();
}
@Override
public String getName() {
return image.getChannelName();
}
@Override
public Color getColor() {
return image.getChannelColor();
}
@Override
public double getExcitationWavelength() {
return image.getExcitationWavelength();
}
@Override
public double getEmissionWavelength() {
return image.getEmissionWavelength();
}
@Override
public ColumbusImage getImage() {
return image;
}
public class ColumbusChannel implements IChannel
{
public static class Builder
{
public static ColumbusChannel fromImage(ColumbusImage image)
{
ColumbusChannel ch = new ColumbusChannel();
ch.image = image;
return ch;
}
}
private ColumbusImage image;
@Override
public long getId()
{
return image.getChannelId();
}
@Override
public String getName()
{
return image.getChannelName();
}
@Override
public Color getColor()
{
return image.getChannelColor();
}
@Override
public double getExcitationWavelength()
{
return image.getExcitationWavelength();
}
@Override
public double getEmissionWavelength()
{
return image.getEmissionWavelength();
}
@Override
public ColumbusImage getImage()
{
return image;
}
@Override
public String toString()
{
return "Channel " + getId() + ": " + getColor().toString();
}
}
......@@ -9,7 +9,6 @@ import java.util.Map.Entry;
import java.util.stream.Collectors;
import plugins.adufour.hcs.data.IField;
import plugins.adufour.hcs.data.IPlane;
import plugins.adufour.hcs.util.CollectionUtils;
public class ColumbusField implements IField
......@@ -34,6 +33,10 @@ public class ColumbusField implements IField
.map(im -> new Rectangle2D.Double(im.getPositionX(), im.getPositionY(),
im.getSizeX() * im.getResolutionX(), im.getSizeY() * im.getResolutionY()))
.orElse(new Rectangle2D.Double());
field.pixelBounds = fieldImages.stream().findAny()
.map(im -> new Rectangle2D.Double(im.getPositionX() / im.getResolutionX(),
im.getPositionY() / im.getResolutionY(), im.getSizeX(), im.getSizeY()))
.orElse(new Rectangle2D.Double());
return field;
}
......@@ -43,6 +46,7 @@ public class ColumbusField implements IField
public Point2D.Double position;
private Map<Long, ColumbusPlane> planes;
public Rectangle2D bounds;
public Rectangle2D pixelBounds;
@Override
public long getId()
......@@ -57,7 +61,7 @@ public class ColumbusField implements IField
}
@Override
public Map<Long, ? extends IPlane> getPlanes()
public Map<Long, ColumbusPlane> getPlanes()
{
return Collections.unmodifiableMap(planes);
}
......@@ -71,8 +75,25 @@ public class ColumbusField implements IField
@Override
public Rectangle2D getPixelBounds()
{
// TODO Auto-generated method stub
return null;
return pixelBounds;
}
@Override
public String toString()
{
String fieldString = "Field " + getId() + "[";
if (getBounds() != null)
{
Rectangle2D bnds = getBounds();
fieldString += bnds.getX() + ", " + bnds.getY() + ", " + bnds.getWidth() + ", " + bnds.getHeight();
}
else
{
fieldString += "null";
}
fieldString += "]";
return fieldString;
}
}
package plugins.adufour.hcs.data.columbus;
import java.awt.Color;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Optional;
......@@ -21,7 +18,6 @@ public class ColumbusImage implements IImage
public static class Builder
{
private final static DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
private final static Date DEFAULT_DATE = new Date();
public static ColumbusImage fromXMLElement(Element imageElement)
......@@ -31,7 +27,7 @@ public class ColumbusImage implements IImage
String imageState = XMLUtil.getElementValue(imageElement, "State", "Ok");
Element urlElement = XMLUtil.getElement(imageElement, "URL");
long imageBufferNumber = XMLUtil.getAttributeLongValue(urlElement, "BufferNo", 0);
String imageURL = urlElement.getNodeValue();
String imageURL = urlElement.getTextContent();
long imageRow = XMLUtil.getElementLongValue(imageElement, "Row", 0);
long imageColumn = XMLUtil.getElementLongValue(imageElement, "Col", 0);
long imageFieldId = XMLUtil.getElementLongValue(imageElement, "FieldID", 0);
......@@ -39,7 +35,7 @@ public class ColumbusImage implements IImage
long imageTimepointId = XMLUtil.getElementLongValue(imageElement, "TimepointID", 0);
long imageChannelId = XMLUtil.getElementLongValue(imageElement, "ChannelID", 0);
String imageChannelName = XMLUtil.getElementValue(imageElement, "FieldID", "Channel " + imageChannelId);
String imageChannelName = XMLUtil.getElementValue(imageElement, "ChannelName", "Channel " + imageChannelId);
// Long imageColorValue = new Long(XMLUtil.getElementLongValue(imageElement, "ChannelColor", 0));
// int blue = (int) ((imageColorValue >> 24) & 0xff);
// int green = (int) ((imageColorValue >> 16) & 0xff);
......@@ -51,30 +47,30 @@ public class ColumbusImage implements IImage
"SpinningDiskConfocal");
Element resolutionXElement = XMLUtil.getElement(imageElement, "ImageResolutionX");
double imageResolutionX = Double.parseDouble(resolutionXElement.getNodeValue())
* (XMLUtil.getAttributeValue(resolutionXElement, "Unit", "m") == "m" ? 1000000 : 1);
double imageResolutionX = Double.parseDouble(resolutionXElement.getTextContent())
* (XMLUtil.getAttributeValue(resolutionXElement, "Unit", "m").equals("m") ? 1000000 : 1);
Element resolutionYElement = XMLUtil.getElement(imageElement, "ImageResolutionY");
double imageResolutionY = Double.parseDouble(resolutionYElement.getNodeValue())
* (XMLUtil.getAttributeValue(resolutionYElement, "Unit", "m") == "m" ? 1000000 : 1);
double imageResolutionY = Double.parseDouble(resolutionYElement.getTextContent())
* (XMLUtil.getAttributeValue(resolutionYElement, "Unit", "m").equals("m") ? 1000000 : 1);
long imageSizeX = XMLUtil.getElementLongValue(imageElement, "ImageSizeX", 0);
long imageSizeY = XMLUtil.getElementLongValue(imageElement, "ImageSizeY", 0);
Element positionXElement = XMLUtil.getElement(imageElement, "PositionX");
double imagePositionX = Double.parseDouble(positionXElement.getNodeValue())
* (XMLUtil.getAttributeValue(positionXElement, "Unit", "m") == "m" ? 1000000 : 1);
double imagePositionX = Double.parseDouble(positionXElement.getTextContent())
* (XMLUtil.getAttributeValue(positionXElement, "Unit", "m").equals("m") ? 1000000 : 1);
Element positionYElement = XMLUtil.getElement(imageElement, "PositionY");
double imagePositionY = Double.parseDouble(positionYElement.getNodeValue())
* (XMLUtil.getAttributeValue(positionYElement, "Unit", "m") == "m" ? 1000000 : 1);
double imagePositionY = Double.parseDouble(positionYElement.getTextContent())
* (XMLUtil.getAttributeValue(positionYElement, "Unit", "m").equals("m") ? 1000000 : 1);
Element positionZElement = XMLUtil.getElement(imageElement, "PositionZ");
double imagePositionZ = Double.parseDouble(positionZElement.getNodeValue())
* (XMLUtil.getAttributeValue(positionZElement, "Unit", "m") == "m" ? 1000000 : 1);
double imagePositionZ = Double.parseDouble(positionZElement.getTextContent())
* (XMLUtil.getAttributeValue(positionZElement, "Unit", "m").equals("m") ? 1000000 : 1);
Element absPositionZElement = XMLUtil.getElement(imageElement, "AbsPositionZ");
double imageAbsPositionZ = Double.parseDouble(absPositionZElement.getNodeValue())
* (XMLUtil.getAttributeValue(absPositionZElement, "Unit", "m") == "m" ? 1000000 : 1);
double imageAbsPositionZ = Double.parseDouble(absPositionZElement.getTextContent())
* (XMLUtil.getAttributeValue(absPositionZElement, "Unit", "m").equals("m") ? 1000000 : 1);
Element timeElement = XMLUtil.getElement(imageElement, "MeasurementTimeOffset");
double imageTime = Double.parseDouble(timeElement.getNodeValue());
double imageTime = Double.parseDouble(timeElement.getTextContent());
Date imageDate = Optional.ofNullable(XMLUtil.getElementValue(imageElement, "AbsTime", null))
.flatMap(timeStr -> {
......@@ -89,10 +85,10 @@ public class ColumbusImage implements IImage
}).orElse(DEFAULT_DATE);
Element excitationElement = XMLUtil.getElement(imageElement, "MainExcitationWavelength");
double imageExcitationWavelength = Double.parseDouble(excitationElement.getNodeValue());
double imageExcitationWavelength = Double.parseDouble(excitationElement.getTextContent());
Element emissionElement = XMLUtil.getElement(imageElement, "MainEmissionWavelength");
double imageEmissionWavelength = Double.parseDouble(emissionElement.getNodeValue());
double imageEmissionWavelength = Double.parseDouble(emissionElement.getTextContent());
ColumbusImage image = new ColumbusImage();
......@@ -296,4 +292,12 @@ public class ColumbusImage implements IImage
return emissionWavelength;
}
@Override
public String toString()
{
return "Image [url=" + url + ", bufferNumber=" + bufferNumber + ", row=" + row + ", column=" + column
+ ", resolutionX=" + resolutionX + ", resolutionY=" + resolutionY + ", sizeX=" + sizeX + ", sizeY="
+ sizeY + ", positionX=" + positionX + ", positionY=" + positionY + ", positionZ=" + positionZ + "]";
}
}
......@@ -9,42 +9,54 @@ import java.util.stream.Collectors;
import plugins.adufour.hcs.data.IPlane;
import plugins.adufour.hcs.util.CollectionUtils;
public class ColumbusPlane implements IPlane {
public static final class Builder {
public static ColumbusPlane fromImages(List<ColumbusImage> planeImages) {
Map<Long, List<ColumbusImage>> timepointImages = planeImages.stream()
.collect(Collectors.groupingBy(ColumbusImage::getTimepointId));
ColumbusPlane plane = new ColumbusPlane();
plane.id = planeImages.stream().findAny().map(im -> im.getPlaneId()).orElse(-1L);
plane.positionZ = planeImages.stream().findAny().map(im -> im.getPositionZ()).orElse(0d);
plane.timepoints = timepointImages.entrySet().stream()
.map(timepointEntry -> CollectionUtils.newEntry(timepointEntry.getKey(),
ColumbusTimepoint.Builder.fromImages(timepointEntry.getValue())))
.collect(Collectors.toMap(Entry::getKey, Entry::getValue));
return plane;
}
}
private long id;
private double positionZ;
private Map<Long, ColumbusTimepoint> timepoints;
@Override
public long getId() {
return id;
}
@Override
public double getPositionZ() {
return positionZ;
}
@Override
public Map<Long, ColumbusTimepoint> getTimepoints() {
return Collections.unmodifiableMap(timepoints);
}
public class ColumbusPlane implements IPlane
{
public static final class Builder
{
public static ColumbusPlane fromImages(List<ColumbusImage> planeImages)
{
Map<Long, List<ColumbusImage>> timepointImages = planeImages.stream()
.collect(Collectors.groupingBy(ColumbusImage::getTimepointId));
ColumbusPlane plane = new ColumbusPlane();
plane.id = planeImages.stream().findAny().map(im -> im.getPlaneId()).orElse(-1L);
plane.positionZ = planeImages.stream().findAny().map(im -> im.getPositionZ()).orElse(0d);
plane.timepoints = timepointImages.entrySet().stream()
.map(timepointEntry -> CollectionUtils.newEntry(timepointEntry.getKey(),
ColumbusTimepoint.Builder.fromImages(timepointEntry.getValue())))
.collect(Collectors.toMap(Entry::getKey, Entry::getValue));
return plane;
}
}
private long id;
private double positionZ;
private Map<Long, ColumbusTimepoint> timepoints;
@Override
public long getId()
{
return id;
}
@Override
public double getPositionZ()
{
return positionZ;
}
@Override
public Map<Long, ColumbusTimepoint> getTimepoints()
{
return Collections.unmodifiableMap(timepoints);
}
@Override
public String toString()
{
return "Plane " + getId() + ": posZ=" + getPositionZ();
}
}
......@@ -2,8 +2,7 @@ package plugins.adufour.hcs.data.columbus;
import java.awt.Dimension;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.nio.file.Paths;
import java.util.Collections;
import java.util.Date;
import java.util.List;
......@@ -31,7 +30,6 @@ public class ColumbusPlate implements IPlate
public static class Builder
{
private final static DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
private final static Date DEFAULT_DATE = new Date();
private String xmlDescriptorFile;
......@@ -60,7 +58,8 @@ public class ColumbusPlate implements IPlate
Element platesElement = XMLUtil.getElement(rootElement, "Plates");
List<Element> plateElements = XMLUtil.getElements(platesElement, "Plate");
ColumbusPlate plate = getPlatefromElement(plateElements.get(0));
plate.folder = Paths.get(xmlDescriptorFile).getParent().toString();
notifyProgress(() -> 0.2, () -> "Reading plate images");
Element imagesElement = XMLUtil.getElement(rootElement, "Images");
Map<String, ColumbusImage> images = getImagesFromElement(imagesElement);
......@@ -148,6 +147,7 @@ public class ColumbusPlate implements IPlate
}
}
private String folder;
private String id;
private String measurementId;
private Date measurementDate;
......@@ -160,6 +160,10 @@ public class ColumbusPlate implements IPlate
private ColumbusPlate()
{
}
public String getFolder() {
return folder;
}
public String getId()
{
......
......@@ -42,4 +42,10 @@ public class ColumbusTimepoint implements ITimepoint
{
return Collections.unmodifiableMap(channels);
}
@Override
public String toString()
{
return "Timepoint " + getId();
}
}
......@@ -6,12 +6,14 @@ import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import org.w3c.dom.Element;
import icy.util.XMLUtil;
import plugins.adufour.hcs.data.IField;
import plugins.adufour.hcs.data.IWell;
import plugins.adufour.hcs.util.CollectionUtils;
......@@ -93,4 +95,19 @@ public class ColumbusWell implements IWell
return shape;
}
@Override
public Rectangle2D getFieldBoundsOnWell(IField field)
{
// creating a copy of the already field on well bounds.
return field.getBounds().getBounds2D();
}
@Override
public String toString()
{
String wellString = "Well " + Objects.toString(id) + " at (";
wellString += (positionInPlate != null) ? (positionInPlate.x + ", " + positionInPlate.y) : "null";
wellString += ")";
return wellString;
}
}
package plugins.adufour.hcs.data.im;
import java.awt.Color;
import plugins.adufour.hcs.data.IChannel;
/**
* @author Daniel Felipe Gonzalez Obando
*/
public class ImChannel implements IChannel
{
@Override
public long getId()
{
// TODO Auto-generated method stub
return 0;
}
@Override
public String getName()
{
// TODO Auto-generated method stub
return null;
}
@Override
public Color getColor()
{
// TODO Auto-generated method stub
return null;
}
@Override
public double getExcitationWavelength()
{
// TODO Auto-generated method stub
return 0;
}
@Override
public double getEmissionWavelength()
{
// TODO Auto-generated method stub
return 0;
}
@Override
public ImImage getImage()
{
// TODO Auto-generated method stub
return null;
}
}
......@@ -5,8 +5,11 @@ import java.awt.geom.Rectangle2D;
import java.util.Map;
import plugins.adufour.hcs.data.IField;
import plugins.adufour.hcs.data.IPlane;
/**
* @author Daniel Felipe Gonzalez Obando
*
*/
public class ImField implements IField
{
......@@ -25,7 +28,7 @@ public class ImField implements IField
}
@Override
public Map<Long, ? extends IPlane> getPlanes()
public Map<Long, ImPlane> getPlanes()
{
// TODO Auto-generated method stub
return null;
......
package plugins.adufour.hcs.data.im;
import java.awt.Color;