Commit 1611bbe0 authored by danyfel80's avatar danyfel80
Browse files

Old opera format importer Working ok

parent ab714727
/**
*
*/
package plugins.adufour.hcs;
import java.io.File;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.Future;
import icy.plugin.PluginDescriptor;
import icy.plugin.PluginLoader;
import icy.system.IcyHandledException;
import icy.system.thread.ThreadUtil;
import plugins.adufour.ezplug.EzPlug;
import plugins.adufour.ezplug.EzStoppable;
import plugins.adufour.ezplug.EzVarFolder;
import plugins.adufour.hcs.data.IPlate;
import plugins.adufour.hcs.gui.NewWellPlateViewer;
import plugins.adufour.hcs.io.AbstractWellPlateReader;
import plugins.adufour.hcs.io.WellPlateReader_EvotecPerkinElmerOperaFlex;
/**
* @author Daniel Felipe Gonzalez Obando
*/
public class NewWellPlateImporter extends EzPlug implements EzStoppable
{
private static final Set<AbstractWellPlateReader> availableReaders = new HashSet<>();
public static AbstractWellPlateReader getReaderFor(File file)
{
loadAvailableReaders();
for (AbstractWellPlateReader reader : availableReaders)
if (reader.isValidPlate(file))
return reader;
return null;
}
private static void loadAvailableReaders()
{
if (availableReaders.isEmpty())
reloadAvailableReaders();
}
@SuppressWarnings("unchecked")
public static void reloadAvailableReaders()
{
availableReaders.clear();
ArrayList<Class<? extends AbstractWellPlateReader>> importers = new ArrayList<>();
for (PluginDescriptor pd : PluginLoader.getPlugins(AbstractWellPlateReader.class))
{
importers.add((Class<? extends AbstractWellPlateReader>) pd.getPluginClass());
}
if (importers.isEmpty())
{
// Probably debugging within Eclipse => add ONE (known) entry manually
importers.add(WellPlateReader_EvotecPerkinElmerOperaFlex.class.asSubclass(AbstractWellPlateReader.class));
}
// Add available file filters
for (Class<? extends AbstractWellPlateReader> importerClass : importers)
try
{
availableReaders.add(importerClass.newInstance());
}
catch (Exception e)
{
throw new RuntimeException(e);
}
}
private EzVarFolder varInDirectory;
@Override
protected void initialize()
{
varInDirectory = new EzVarFolder("Well plate folder", null);
addEzComponent(varInDirectory);
}
@Override
protected void execute()
{
File targetDirectory = varInDirectory.getValue(true);
if (!isHeadLess())
{
this.getUI().setProgressBarVisible(true);
}
notifyProgressUI(0.001, "Loading plate " + targetDirectory.getName());
getPreferencesRoot().put("lastUsedDirectory", targetDirectory.getPath());
try
{
AbstractWellPlateReader reader = getReaderFor(targetDirectory);
Future<? extends IPlate> plateFuture = reader.loadPlateFromFolder(targetDirectory, this::notifyProgressUI);
IPlate plate = plateFuture.get();
ThreadUtil.invokeLater(() -> {
NewWellPlateViewer wellPlateViewer = new NewWellPlateViewer(plate, reader);
wellPlateViewer.pack();
wellPlateViewer.addToDesktopPane();
wellPlateViewer.setVisible(true);
});
}
catch (Exception e)
{
e.printStackTrace();
throw new IcyHandledException(e);
}
finally
{
if (!isHeadLess())
{
this.getUI().setProgressBarVisible(false);
}
}
}
private void notifyProgressUI(double progress, String message)
{
if (isHeadLess())
{
System.out.println(
"Loading well plate " + ((int) Math.round(progress * 100)) + "%: " + Objects.toString(message));
}
else
{
if (!Double.isNaN(progress))
{
getUI().setProgressBarValue(progress);
}
if (message != null)
{
getUI().setProgressBarMessage(message);
}
}
}
@Override
public void clean()
{
}
}
......@@ -21,7 +21,7 @@ import plugins.adufour.hcs.data.WellPlate;
import plugins.adufour.hcs.gui.WellPlateViewer;
import plugins.adufour.hcs.io.WellPlateReader;
import plugins.adufour.hcs.io.WellPlateReader_Opera;
import plugins.adufour.hcs.io.WellPlateReader_OperaColumbusNew;
import plugins.adufour.hcs.io.WellPlateReader_ColumbusOperaFlex;
public class WellPlateImporter extends PluginActionable {
private static final Set<WellPlateReader> availableReaders = new HashSet<WellPlateReader>();
......@@ -37,7 +37,7 @@ public class WellPlateImporter extends PluginActionable {
if (importers.isEmpty()) {
// Probably debugging within Eclipse => add one (known) entry manually
importers.add((Class<WellPlateReader>) WellPlateReader_Opera.class.asSubclass(WellPlateReader.class));
importers.add((Class<WellPlateReader>) WellPlateReader_OperaColumbusNew.class.asSubclass(WellPlateReader.class));
importers.add((Class<WellPlateReader>) WellPlateReader_ColumbusOperaFlex.class.asSubclass(WellPlateReader.class));
}
// Add available file filters
......
package plugins.adufour.hcs.data;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.Map;
public interface IField {
long getId();
public interface IField
{
long getId();
Point2D getPosition();
Point2D getPosition();
Map<Long, ? extends IPlane> getPlanes();
Map<Long, ? extends IPlane> getPlanes();
Rectangle2D getBounds();
Rectangle2D getPixelBounds();
}
......@@ -3,14 +3,35 @@ package plugins.adufour.hcs.data;
import java.awt.Dimension;
import java.util.Map;
public interface IPlate {
String getId();
/**
* A well plate.
*
* @author Daniel Felipe Gonzalez Obando
*/
public interface IPlate
{
/**
* @return The identifier of this plate.
*/
String getId();
String getName();
/**
* @return The name of this plate.
*/
String getName();
String getType();
/**
* @return The type of this plate.
*/
String getType();
Dimension getDimension();
/**
* @return The dimension of this plate (number of rows and columns).
*/
Dimension getDimension();
Map<Long, ? extends IWell> getWells();
/**
* @return The wells contained in this plate, indexed by well id.
*/
Map<Long, ? extends IWell> getWells();
}
......@@ -3,10 +3,13 @@ package plugins.adufour.hcs.data;
import java.awt.Point;
import java.util.Map;
public interface IWell {
long getId();
public interface IWell
{
long getId();
Point getPositionInPlate();
Point getPositionInPlate();
Map<Long, ? extends IField> getFields();
Map<Long, ? extends IField> getFields();
IWellShape getShape();
}
package plugins.adufour.hcs.data;
import java.awt.Shape;
/**
* Represents the shape a well has when laid over the GUI.
*
* @author Daniel Felipe Gonzalez Obando
*/
public interface IWellShape
{
Shape getShape();
}
package plugins.adufour.hcs.data.columbus;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.Collections;
import java.util.List;
import java.util.Map;
......@@ -11,43 +12,67 @@ import plugins.adufour.hcs.data.IField;
import plugins.adufour.hcs.data.IPlane;
import plugins.adufour.hcs.util.CollectionUtils;
public class ColumbusField implements IField {
public static class Builder {
public static ColumbusField fromImages(List<ColumbusImage> fieldImages) {
Map<Long, List<ColumbusImage>> planeImages = fieldImages.stream()
.collect(Collectors.groupingBy(ColumbusImage::getPlaneId));
ColumbusField field = new ColumbusField();
field.id = fieldImages.stream().findAny().map(im -> im.getFieldId()).orElse(-1L);
field.position = fieldImages.stream().findAny()
.map(im -> new Point2D.Double(im.getPositionX(), im.getPositionY())).orElse(new Point2D.Double());
field.planes = planeImages.entrySet().stream()
.map(planeEntry -> CollectionUtils.newEntry(planeEntry.getKey(),
ColumbusPlane.Builder.fromImages(planeEntry.getValue())))
.collect(Collectors.toMap(Entry::getKey, Entry::getValue));
return field;
}
}
private long id;
public Point2D.Double position;
private Map<Long, ColumbusPlane> planes;
@Override
public long getId() {
return id;
}
@Override
public Point2D getPosition() {
return position;
}
@Override
public Map<Long, ? extends IPlane> getPlanes() {
return Collections.unmodifiableMap(planes);
}
public class ColumbusField implements IField
{
public static class Builder
{
public static ColumbusField fromImages(List<ColumbusImage> fieldImages)
{
Map<Long, List<ColumbusImage>> planeImages = fieldImages.stream()
.collect(Collectors.groupingBy(ColumbusImage::getPlaneId));
ColumbusField field = new ColumbusField();
field.id = fieldImages.stream().findAny().map(im -> im.getFieldId()).orElse(-1L);
field.position = fieldImages.stream().findAny()
.map(im -> new Point2D.Double(im.getPositionX(), im.getPositionY())).orElse(new Point2D.Double());
field.planes = planeImages.entrySet().stream()
.map(planeEntry -> CollectionUtils.newEntry(planeEntry.getKey(),
ColumbusPlane.Builder.fromImages(planeEntry.getValue())))
.collect(Collectors.toMap(Entry::getKey, Entry::getValue));
field.bounds = fieldImages.stream().findAny()
.map(im -> new Rectangle2D.Double(im.getPositionX(), im.getPositionY(),
im.getSizeX() * im.getResolutionX(), im.getSizeY() * im.getResolutionY()))
.orElse(new Rectangle2D.Double());
return field;
}
}
private long id;
public Point2D.Double position;
private Map<Long, ColumbusPlane> planes;
public Rectangle2D bounds;
@Override
public long getId()
{
return id;
}
@Override
public Point2D getPosition()
{
return position;
}
@Override
public Map<Long, ? extends IPlane> getPlanes()
{
return Collections.unmodifiableMap(planes);
}
@Override
public Rectangle2D getBounds()
{
return bounds;
}
@Override
public Rectangle2D getPixelBounds()
{
// TODO Auto-generated method stub
return null;
}
}
......@@ -7,257 +7,293 @@ import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Optional;
import javax.xml.bind.DatatypeConverter;
import org.w3c.dom.Element;
import icy.util.ColorUtil;
import icy.util.XMLUtil;
import plugins.adufour.hcs.data.IImage;
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) {
String imageVersion = XMLUtil.getAttributeValue(imageElement, "Version", "1");
String imageId = XMLUtil.getElementValue(imageElement, "id", null);
String imageState = XMLUtil.getElementValue(imageElement, "State", "Ok");
Element urlElement = XMLUtil.getElement(imageElement, "URL");
long imageBufferNumber = XMLUtil.getAttributeLongValue(urlElement, "BufferNo", 0);
String imageURL = urlElement.getNodeValue();
long imageRow = XMLUtil.getElementLongValue(imageElement, "Row", 0);
long imageColumn = XMLUtil.getElementLongValue(imageElement, "Col", 0);
long imageFieldId = XMLUtil.getElementLongValue(imageElement, "FieldID", 0);
long imagePlaneId = XMLUtil.getElementLongValue(imageElement, "PlaneID", 0);
long imageTimepointId = XMLUtil.getElementLongValue(imageElement, "TimepointID", 0);
long imageChannelId = XMLUtil.getElementLongValue(imageElement, "ChannelID", 0);
String imageChannelName = XMLUtil.getElementValue(imageElement, "FieldID", "Channel " + imageChannelId);
// Long imageColorValue = new Long(XMLUtil.getElementLongValue(imageElement, "ChannelColor", 0));
// int blue = (int) ((imageColorValue >> 24) & 0xff);
// int green = (int) ((imageColorValue >> 16) & 0xff);
// int red = (int) ((imageColorValue >> 8) & 0xff);
// int alpha = (int) (imageColorValue & 0xff);
String imageChannelType = XMLUtil.getElementValue(imageElement, "ChannelType", "Fluorescence");
String imageAcquisitionType = XMLUtil.getElementValue(imageElement, "AcquisitionType",
"SpinningDiskConfocal");
Element resolutionXElement = XMLUtil.getElement(imageElement, "ImageResolutionX");
double imageResolutionX = Double.parseDouble(resolutionXElement.getNodeValue())
* (XMLUtil.getAttributeValue(resolutionXElement, "Unit", "m") == "m" ? 1000000 : 1);
Element resolutionYElement = XMLUtil.getElement(imageElement, "ImageResolutionY");
double imageResolutionY = Double.parseDouble(resolutionYElement.getNodeValue())
* (XMLUtil.getAttributeValue(resolutionYElement, "Unit", "m") == "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);
Element positionYElement = XMLUtil.getElement(imageElement, "PositionY");
double imagePositionY = Double.parseDouble(positionYElement.getNodeValue())
* (XMLUtil.getAttributeValue(positionYElement, "Unit", "m") == "m" ? 1000000 : 1);
Element positionZElement = XMLUtil.getElement(imageElement, "PositionZ");
double imagePositionZ = Double.parseDouble(positionZElement.getNodeValue())
* (XMLUtil.getAttributeValue(positionZElement, "Unit", "m") == "m" ? 1000000 : 1);
Element absPositionZElement = XMLUtil.getElement(imageElement, "AbsPositionZ");
double imageAbsPositionZ = Double.parseDouble(absPositionZElement.getNodeValue())
* (XMLUtil.getAttributeValue(absPositionZElement, "Unit", "m") == "m" ? 1000000 : 1);
Element timeElement = XMLUtil.getElement(imageElement, "MeasurementTimeOffset");
double imageTime = Double.parseDouble(timeElement.getNodeValue());
Date imageDate = Optional.ofNullable(XMLUtil.getElementValue(imageElement, "AbsTime", null))
.flatMap(timeStr -> {
try {
return Optional.of(DATE_FORMAT.parse(timeStr));
} catch (ParseException e) {
throw new RuntimeException("Cannot format acquisition date", e);
}
}).orElse(DEFAULT_DATE);
Element excitationElement = XMLUtil.getElement(imageElement, "MainExcitationWavelength");
double imageExcitationWavelength = Double.parseDouble(excitationElement.getNodeValue());
Element emissionElement = XMLUtil.getElement(imageElement, "MainEmissionWavelength");
double imageEmissionWavelength = Double.parseDouble(emissionElement.getNodeValue());
ColumbusImage image = new ColumbusImage();
image.version = imageVersion;
image.id = imageId;
image.state = imageState;
image.bufferNumber = imageBufferNumber;
image.url = imageURL;
image.row = imageRow;
image.column = imageColumn;
image.fieldId = imageFieldId;
image.planeId = imagePlaneId;
image.timepointId = imageTimepointId;
image.channelId = imageChannelId;
image.channelName = imageChannelName;
image.channelColor = ColorUtil.getColorFromWavelength(imageEmissionWavelength);
image.channelType = imageChannelType;
image.acquisitionType = imageAcquisitionType;
image.resolutionX = imageResolutionX;
image.resolutionY = imageResolutionY;
image.sizeX = imageSizeX;
image.sizeY = imageSizeY;
image.positionX = imagePositionX;
image.positionY = imagePositionY;
image.positionZ = imagePositionZ;
image.absPositionZ = imageAbsPositionZ;
image.time = imageTime;
image.date = imageDate;
image.excitationWavelength = imageExcitationWavelength;
image.emissionWavelength = imageEmissionWavelength;
return image;
}
}
private String version;
private String id;
private String state;
private long bufferNumber;
private String url;
private long row;
private long column;
private long fieldId;
private long planeId;
private long timepointId;
private long channelId;
private String channelName;
private Color channelColor;
private String channelType;
private String acquisitionType;
private double resolutionX;
private double resolutionY;
private long sizeX;
private long sizeY;
private double positionX;
private double positionY;
private double absPositionZ;
private double positionZ;
private double time;
private Date date;
private double excitationWavelength;
private double emissionWavelength;
private ColumbusImage() {
}
public String getVersion() {
return version;
}
public String getId() {
return id;
}
public String getState() {
return state;
}
public long getBufferNumber() {
return bufferNumber;
}
public String getUrl() {
return url;
}
public long getRow() {
return row;
}
public long getColumn() {
return column;
}
public long getFieldId() {
return fieldId;
}
public long getPlaneId() {
return planeId;
}
public long getTimepointId() {
return timepointId;