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 @@ ...@@ -12,7 +12,7 @@
<description/> <description/>
<build> <build>
<plugins> <plugins>
<!--<plugin> <plugin>
<groupId>org.codehaus.mojo</groupId> <groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId> <artifactId>exec-maven-plugin</artifactId>
<version>1.3.2</version> <version>1.3.2</version>
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
<configuration> <configuration>
<mainClass>icy.main.Icy</mainClass> <mainClass>icy.main.Icy</mainClass>
</configuration> </configuration>
</plugin>--> </plugin>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId> <artifactId>maven-javadoc-plugin</artifactId>
......
package plugins.adufour.hcs.data; package plugins.adufour.hcs.data;
import java.awt.Point; import java.awt.Point;
import java.awt.geom.Rectangle2D;
import java.util.Map; import java.util.Map;
public interface IWell public interface IWell
...@@ -12,4 +13,11 @@ public interface IWell ...@@ -12,4 +13,11 @@ public interface IWell
Map<Long, ? extends IField> getFields(); Map<Long, ? extends IField> getFields();
IWellShape getShape(); 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; ...@@ -4,46 +4,61 @@ import java.awt.Color;
import plugins.adufour.hcs.data.IChannel; import plugins.adufour.hcs.data.IChannel;
public class ColumbusChannel implements IChannel { public class ColumbusChannel implements IChannel
{
public static class Builder {
public static ColumbusChannel fromImage(ColumbusImage image) { public static class Builder
ColumbusChannel ch = new ColumbusChannel(); {
ch.image = image; public static ColumbusChannel fromImage(ColumbusImage image)
return ch; {
} ColumbusChannel ch = new ColumbusChannel();
} ch.image = image;
return ch;
private ColumbusImage image; }
}
@Override
public long getId() { private ColumbusImage image;
return image.getChannelId();
} @Override
public long getId()
@Override {
public String getName() { return image.getChannelId();
return image.getChannelName(); }
}
@Override
@Override public String getName()
public Color getColor() { {
return image.getChannelColor(); return image.getChannelName();
} }
@Override @Override
public double getExcitationWavelength() { public Color getColor()
return image.getExcitationWavelength(); {
} return image.getChannelColor();
}
@Override
public double getEmissionWavelength() { @Override
return image.getEmissionWavelength(); public double getExcitationWavelength()
} {
return image.getExcitationWavelength();
@Override }
public ColumbusImage getImage() {
return image; @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; ...@@ -9,7 +9,6 @@ import java.util.Map.Entry;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import plugins.adufour.hcs.data.IField; import plugins.adufour.hcs.data.IField;
import plugins.adufour.hcs.data.IPlane;
import plugins.adufour.hcs.util.CollectionUtils; import plugins.adufour.hcs.util.CollectionUtils;
public class ColumbusField implements IField public class ColumbusField implements IField
...@@ -34,6 +33,10 @@ public class ColumbusField implements IField ...@@ -34,6 +33,10 @@ public class ColumbusField implements IField
.map(im -> new Rectangle2D.Double(im.getPositionX(), im.getPositionY(), .map(im -> new Rectangle2D.Double(im.getPositionX(), im.getPositionY(),
im.getSizeX() * im.getResolutionX(), im.getSizeY() * im.getResolutionY())) im.getSizeX() * im.getResolutionX(), im.getSizeY() * im.getResolutionY()))
.orElse(new Rectangle2D.Double()); .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; return field;
} }
...@@ -43,6 +46,7 @@ public class ColumbusField implements IField ...@@ -43,6 +46,7 @@ public class ColumbusField implements IField
public Point2D.Double position; public Point2D.Double position;
private Map<Long, ColumbusPlane> planes; private Map<Long, ColumbusPlane> planes;
public Rectangle2D bounds; public Rectangle2D bounds;
public Rectangle2D pixelBounds;
@Override @Override
public long getId() public long getId()
...@@ -57,7 +61,7 @@ public class ColumbusField implements IField ...@@ -57,7 +61,7 @@ public class ColumbusField implements IField
} }
@Override @Override
public Map<Long, ? extends IPlane> getPlanes() public Map<Long, ColumbusPlane> getPlanes()
{ {
return Collections.unmodifiableMap(planes); return Collections.unmodifiableMap(planes);
} }
...@@ -71,8 +75,25 @@ public class ColumbusField implements IField ...@@ -71,8 +75,25 @@ public class ColumbusField implements IField
@Override @Override
public Rectangle2D getPixelBounds() public Rectangle2D getPixelBounds()
{ {
// TODO Auto-generated method stub return pixelBounds;
return null; }
@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; package plugins.adufour.hcs.data.columbus;
import java.awt.Color; import java.awt.Color;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
import java.util.Optional; import java.util.Optional;
...@@ -21,7 +18,6 @@ public class ColumbusImage implements IImage ...@@ -21,7 +18,6 @@ public class ColumbusImage implements IImage
public static class Builder 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 final static Date DEFAULT_DATE = new Date();
public static ColumbusImage fromXMLElement(Element imageElement) public static ColumbusImage fromXMLElement(Element imageElement)
...@@ -31,7 +27,7 @@ public class ColumbusImage implements IImage ...@@ -31,7 +27,7 @@ public class ColumbusImage implements IImage
String imageState = XMLUtil.getElementValue(imageElement, "State", "Ok"); String imageState = XMLUtil.getElementValue(imageElement, "State", "Ok");
Element urlElement = XMLUtil.getElement(imageElement, "URL"); Element urlElement = XMLUtil.getElement(imageElement, "URL");
long imageBufferNumber = XMLUtil.getAttributeLongValue(urlElement, "BufferNo", 0); long imageBufferNumber = XMLUtil.getAttributeLongValue(urlElement, "BufferNo", 0);
String imageURL = urlElement.getNodeValue(); String imageURL = urlElement.getTextContent();
long imageRow = XMLUtil.getElementLongValue(imageElement, "Row", 0); long imageRow = XMLUtil.getElementLongValue(imageElement, "Row", 0);
long imageColumn = XMLUtil.getElementLongValue(imageElement, "Col", 0); long imageColumn = XMLUtil.getElementLongValue(imageElement, "Col", 0);
long imageFieldId = XMLUtil.getElementLongValue(imageElement, "FieldID", 0); long imageFieldId = XMLUtil.getElementLongValue(imageElement, "FieldID", 0);
...@@ -39,7 +35,7 @@ public class ColumbusImage implements IImage ...@@ -39,7 +35,7 @@ public class ColumbusImage implements IImage
long imageTimepointId = XMLUtil.getElementLongValue(imageElement, "TimepointID", 0); long imageTimepointId = XMLUtil.getElementLongValue(imageElement, "TimepointID", 0);
long imageChannelId = XMLUtil.getElementLongValue(imageElement, "ChannelID", 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)); // Long imageColorValue = new Long(XMLUtil.getElementLongValue(imageElement, "ChannelColor", 0));
// int blue = (int) ((imageColorValue >> 24) & 0xff); // int blue = (int) ((imageColorValue >> 24) & 0xff);
// int green = (int) ((imageColorValue >> 16) & 0xff); // int green = (int) ((imageColorValue >> 16) & 0xff);
...@@ -51,30 +47,30 @@ public class ColumbusImage implements IImage ...@@ -51,30 +47,30 @@ public class ColumbusImage implements IImage
"SpinningDiskConfocal"); "SpinningDiskConfocal");
Element resolutionXElement = XMLUtil.getElement(imageElement, "ImageResolutionX"); Element resolutionXElement = XMLUtil.getElement(imageElement, "ImageResolutionX");
double imageResolutionX = Double.parseDouble(resolutionXElement.getNodeValue()) double imageResolutionX = Double.parseDouble(resolutionXElement.getTextContent())
* (XMLUtil.getAttributeValue(resolutionXElement, "Unit", "m") == "m" ? 1000000 : 1); * (XMLUtil.getAttributeValue(resolutionXElement, "Unit", "m").equals("m") ? 1000000 : 1);
Element resolutionYElement = XMLUtil.getElement(imageElement, "ImageResolutionY"); Element resolutionYElement = XMLUtil.getElement(imageElement, "ImageResolutionY");
double imageResolutionY = Double.parseDouble(resolutionYElement.getNodeValue()) double imageResolutionY = Double.parseDouble(resolutionYElement.getTextContent())
* (XMLUtil.getAttributeValue(resolutionYElement, "Unit", "m") == "m" ? 1000000 : 1); * (XMLUtil.getAttributeValue(resolutionYElement, "Unit", "m").equals("m") ? 1000000 : 1);
long imageSizeX = XMLUtil.getElementLongValue(imageElement, "ImageSizeX", 0); long imageSizeX = XMLUtil.getElementLongValue(imageElement, "ImageSizeX", 0);
long imageSizeY = XMLUtil.getElementLongValue(imageElement, "ImageSizeY", 0); long imageSizeY = XMLUtil.getElementLongValue(imageElement, "ImageSizeY", 0);
Element positionXElement = XMLUtil.getElement(imageElement, "PositionX"); Element positionXElement = XMLUtil.getElement(imageElement, "PositionX");
double imagePositionX = Double.parseDouble(positionXElement.getNodeValue()) double imagePositionX = Double.parseDouble(positionXElement.getTextContent())
* (XMLUtil.getAttributeValue(positionXElement, "Unit", "m") == "m" ? 1000000 : 1); * (XMLUtil.getAttributeValue(positionXElement, "Unit", "m").equals("m") ? 1000000 : 1);
Element positionYElement = XMLUtil.getElement(imageElement, "PositionY"); Element positionYElement = XMLUtil.getElement(imageElement, "PositionY");
double imagePositionY = Double.parseDouble(positionYElement.getNodeValue()) double imagePositionY = Double.parseDouble(positionYElement.getTextContent())
* (XMLUtil.getAttributeValue(positionYElement, "Unit", "m") == "m" ? 1000000 : 1); * (XMLUtil.getAttributeValue(positionYElement, "Unit", "m").equals("m") ? 1000000 : 1);
Element positionZElement = XMLUtil.getElement(imageElement, "PositionZ"); Element positionZElement = XMLUtil.getElement(imageElement, "PositionZ");
double imagePositionZ = Double.parseDouble(positionZElement.getNodeValue()) double imagePositionZ = Double.parseDouble(positionZElement.getTextContent())
* (XMLUtil.getAttributeValue(positionZElement, "Unit", "m") == "m" ? 1000000 : 1); * (XMLUtil.getAttributeValue(positionZElement, "Unit", "m").equals("m") ? 1000000 : 1);
Element absPositionZElement = XMLUtil.getElement(imageElement, "AbsPositionZ"); Element absPositionZElement = XMLUtil.getElement(imageElement, "AbsPositionZ");
double imageAbsPositionZ = Double.parseDouble(absPositionZElement.getNodeValue()) double imageAbsPositionZ = Double.parseDouble(absPositionZElement.getTextContent())
* (XMLUtil.getAttributeValue(absPositionZElement, "Unit", "m") == "m" ? 1000000 : 1); * (XMLUtil.getAttributeValue(absPositionZElement, "Unit", "m").equals("m") ? 1000000 : 1);
Element timeElement = XMLUtil.getElement(imageElement, "MeasurementTimeOffset"); 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)) Date imageDate = Optional.ofNullable(XMLUtil.getElementValue(imageElement, "AbsTime", null))
.flatMap(timeStr -> { .flatMap(timeStr -> {
...@@ -89,10 +85,10 @@ public class ColumbusImage implements IImage ...@@ -89,10 +85,10 @@ public class ColumbusImage implements IImage
}).orElse(DEFAULT_DATE); }).orElse(DEFAULT_DATE);
Element excitationElement = XMLUtil.getElement(imageElement, "MainExcitationWavelength"); Element excitationElement = XMLUtil.getElement(imageElement, "MainExcitationWavelength");
double imageExcitationWavelength = Double.parseDouble(excitationElement.getNodeValue()); double imageExcitationWavelength = Double.parseDouble(excitationElement.getTextContent());
Element emissionElement = XMLUtil.getElement(imageElement, "MainEmissionWavelength"); Element emissionElement = XMLUtil.getElement(imageElement, "MainEmissionWavelength");
double imageEmissionWavelength = Double.parseDouble(emissionElement.getNodeValue()); double imageEmissionWavelength = Double.parseDouble(emissionElement.getTextContent());
ColumbusImage image = new ColumbusImage(); ColumbusImage image = new ColumbusImage();
...@@ -296,4 +292,12 @@ public class ColumbusImage implements IImage ...@@ -296,4 +292,12 @@ public class ColumbusImage implements IImage
return emissionWavelength; 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; ...@@ -9,42 +9,54 @@ import java.util.stream.Collectors;
import plugins.adufour.hcs.data.IPlane; import plugins.adufour.hcs.data.IPlane;
import plugins.adufour.hcs.util.CollectionUtils; import plugins.adufour.hcs.util.CollectionUtils;
public class ColumbusPlane implements IPlane { public class ColumbusPlane implements IPlane
{
public static final class Builder {
public static final class Builder
public static ColumbusPlane fromImages(List<ColumbusImage> planeImages) { {
Map<Long, List<ColumbusImage>> timepointImages = planeImages.stream()
.collect(Collectors.groupingBy(ColumbusImage::getTimepointId)); public static ColumbusPlane fromImages(List<ColumbusImage> planeImages)
ColumbusPlane plane = new ColumbusPlane(); {
plane.id = planeImages.stream().findAny().map(im -> im.getPlaneId()).orElse(-1L); Map<Long, List<ColumbusImage>> timepointImages = planeImages.stream()
plane.positionZ = planeImages.stream().findAny().map(im -> im.getPositionZ()).orElse(0d); .collect(Collectors.groupingBy(ColumbusImage::getTimepointId));
plane.timepoints = timepointImages.entrySet().stream() ColumbusPlane plane = new ColumbusPlane();
.map(timepointEntry -> CollectionUtils.newEntry(timepointEntry.getKey(), plane.id = planeImages.stream().findAny().map(im -> im.getPlaneId()).orElse(-1L);
ColumbusTimepoint.Builder.fromImages(timepointEntry.getValue()))) plane.positionZ = planeImages.stream().findAny().map(im -> im.getPositionZ()).orElse(0d);
.collect(Collectors.toMap(Entry::getKey, Entry::getValue)); plane.timepoints = timepointImages.entrySet().stream()
return plane; .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;
private long id;
@Override private double positionZ;
public long getId() { private Map<Long, ColumbusTimepoint> timepoints;
return id;
} @Override
public long getId()
@Override {
public double getPositionZ() { return id;
return positionZ; }
}
@Override
@Override public double getPositionZ()
public Map<Long, ColumbusTimepoint> getTimepoints() { {
return Collections.unmodifiableMap(timepoints); 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; ...@@ -2,8 +2,7 @@ package plugins.adufour.hcs.data.columbus;
import java.awt.Dimension; import java.awt.Dimension;
import java.io.IOException; import java.io.IOException;
import java.text.DateFormat; import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.Collections; import java.util.Collections;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
...@@ -31,7 +30,6 @@ public class ColumbusPlate implements IPlate ...@@ -31,7 +30,6 @@ public class ColumbusPlate implements IPlate
public static class Builder 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 final static Date DEFAULT_DATE = new Date();
private String xmlDescriptorFile; private String xmlDescriptorFile;
...@@ -60,7 +58,8 @@ public class ColumbusPlate implements IPlate ...@@ -60,7 +58,8 @@ public class ColumbusPlate implements IPlate
Element platesElement = XMLUtil.getElement(rootElement, "Plates"); Element platesElement = XMLUtil.getElement(rootElement, "Plates");
List<Element> plateElements = XMLUtil.getElements(platesElement, "Plate"); List<Element> plateElements = XMLUtil.getElements(platesElement, "Plate");
ColumbusPlate plate = getPlatefromElement(plateElements.get(0)); ColumbusPlate plate = getPlatefromElement(plateElements.get(0));
plate.folder = Paths.get(xmlDescriptorFile).getParent().toString();
notifyProgress(() -> 0.2, () -> "Reading plate images"); notifyProgress(() -> 0.2, () -> "Reading plate images");
Element imagesElement = XMLUtil.getElement(rootElement, "Images"); Element imagesElement = XMLUtil.getElement(rootElement, "Images");
Map<String, ColumbusImage> images = getImagesFromElement(imagesElement); Map<String, ColumbusImage> images = getImagesFromElement(imagesElement);
...@@ -148,6 +147,7 @@ public class ColumbusPlate implements IPlate ...@@ -148,6 +147,7 @@ public class ColumbusPlate implements IPlate
} }
} }
private String folder;
private String id; private String id;
private String measurementId; private String measurementId;
private Date measurementDate; private Date measurementDate;
...@@ -160,6 +160,10 @@ public class ColumbusPlate implements IPlate ...@@ -160,6 +160,10 @@ public class ColumbusPlate implements IPlate
private ColumbusPlate() private ColumbusPlate()
{ {
} }
public String getFolder() {
return folder;
}
public String getId() public String getId()
{ {
......
...@@ -42,4 +42,10 @@ public class ColumbusTimepoint implements ITimepoint ...@@ -42,4 +42,10 @@ public class ColumbusTimepoint implements ITimepoint
{ {
return Collections.unmodifiableMap(channels); return Collections.unmodifiableMap(channels);
} }
@Override
public String toString()
{
return "Timepoint " + getId();
}
} }
...@@ -6,12 +6,14 @@ import java.util.Collections; ...@@ -6,12 +6,14 @@ import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry;