Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Bioimage Analysis
wellPlateReader
Commits
2689e592
Commit
2689e592
authored
Feb 01, 2021
by
danyfel80
Browse files
Columbus supported first commit
Todo - Support ScanR and IM formats: adapt old method - Test on multiple Columbus images
parent
8ba0fc0e
Changes
31
Hide whitespace changes
Inline
Side-by-side
WellPlateReader/pom.xml
View file @
2689e592
...
...
@@ -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>
...
...
WellPlateReader/src/main/java/plugins/adufour/hcs/data/IWell.java
View file @
2689e592
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
);
}
WellPlateReader/src/main/java/plugins/adufour/hcs/data/columbus/ColumbusChannel.java
View file @
2689e592
...
...
@@ -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
();
}
}
WellPlateReader/src/main/java/plugins/adufour/hcs/data/columbus/ColumbusField.java
View file @
2689e592
...
...
@@ -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
I
Plane
>
getPlanes
()
public
Map
<
Long
,
Columbus
Plane
>
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
;
}
}
WellPlateReader/src/main/java/plugins/adufour/hcs/data/columbus/ColumbusImage.java
View file @
2689e592
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
.
get
NodeValue
();
String
imageURL
=
urlElement
.
get
TextContent
();
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
.
get
NodeValue
())
*
(
XMLUtil
.
getAttributeValue
(
resolutionXElement
,
"Unit"
,
"m"
)
==
"m"
?
1000000
:
1
);
double
imageResolutionX
=
Double
.
parseDouble
(
resolutionXElement
.
get
TextContent
())
*
(
XMLUtil
.
getAttributeValue
(
resolutionXElement
,
"Unit"
,
"m"
)
.
equals
(
"m"
)
?
1000000
:
1
);
Element
resolutionYElement
=
XMLUtil
.
getElement
(
imageElement
,
"ImageResolutionY"
);
double
imageResolutionY
=
Double
.
parseDouble
(
resolutionYElement
.
get
NodeValue
())
*
(
XMLUtil
.
getAttributeValue
(
resolutionYElement
,
"Unit"
,
"m"
)
==
"m"
?
1000000
:
1
);
double
imageResolutionY
=
Double
.
parseDouble
(
resolutionYElement
.
get
TextContent
())
*
(
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
.
get
NodeValue
())
*
(
XMLUtil
.
getAttributeValue
(
positionXElement
,
"Unit"
,
"m"
)
==
"m"
?
1000000
:
1
);
double
imagePositionX
=
Double
.
parseDouble
(
positionXElement
.
get
TextContent
())
*
(
XMLUtil
.
getAttributeValue
(
positionXElement
,
"Unit"
,
"m"
)
.
equals
(
"m"
)
?
1000000
:
1
);
Element
positionYElement
=
XMLUtil
.
getElement
(
imageElement
,
"PositionY"
);
double
imagePositionY
=
Double
.
parseDouble
(
positionYElement
.
get
NodeValue
())
*
(
XMLUtil
.
getAttributeValue
(
positionYElement
,
"Unit"
,
"m"
)
==
"m"
?
1000000
:
1
);
double
imagePositionY
=
Double
.
parseDouble
(
positionYElement
.
get
TextContent
())
*
(
XMLUtil
.
getAttributeValue
(
positionYElement
,
"Unit"
,
"m"
)
.
equals
(
"m"
)
?
1000000
:
1
);
Element
positionZElement
=
XMLUtil
.
getElement
(
imageElement
,
"PositionZ"
);
double
imagePositionZ
=
Double
.
parseDouble
(
positionZElement
.
get
NodeValue
())
*
(
XMLUtil
.
getAttributeValue
(
positionZElement
,
"Unit"
,
"m"
)
==
"m"
?
1000000
:
1
);
double
imagePositionZ
=
Double
.
parseDouble
(
positionZElement
.
get
TextContent
())
*
(
XMLUtil
.
getAttributeValue
(
positionZElement
,
"Unit"
,
"m"
)
.
equals
(
"m"
)
?
1000000
:
1
);
Element
absPositionZElement
=
XMLUtil
.
getElement
(
imageElement
,
"AbsPositionZ"
);
double
imageAbsPositionZ
=
Double
.
parseDouble
(
absPositionZElement
.
get
NodeValue
())
*
(
XMLUtil
.
getAttributeValue
(
absPositionZElement
,
"Unit"
,
"m"
)
==
"m"
?
1000000
:
1
);
double
imageAbsPositionZ
=
Double
.
parseDouble
(
absPositionZElement
.
get
TextContent
())
*
(
XMLUtil
.
getAttributeValue
(
absPositionZElement
,
"Unit"
,
"m"
)
.
equals
(
"m"
)
?
1000000
:
1
);
Element
timeElement
=
XMLUtil
.
getElement
(
imageElement
,
"MeasurementTimeOffset"
);
double
imageTime
=
Double
.
parseDouble
(
timeElement
.
get
NodeValue
());
double
imageTime
=
Double
.
parseDouble
(
timeElement
.
get
TextContent
());
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
.
get
NodeValue
());
double
imageExcitationWavelength
=
Double
.
parseDouble
(
excitationElement
.
get
TextContent
());
Element
emissionElement
=
XMLUtil
.
getElement
(
imageElement
,
"MainEmissionWavelength"
);
double
imageEmissionWavelength
=
Double
.
parseDouble
(
emissionElement
.
get
NodeValue
());
double
imageEmissionWavelength
=
Double
.
parseDouble
(
emissionElement
.
get
TextContent
());
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
+
"]"
;
}
}
WellPlateReader/src/main/java/plugins/adufour/hcs/data/columbus/ColumbusPlane.java
View file @
2689e592
...
...
@@ -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
(
0
d
);
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
(
0
d
);
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
();
}
}
WellPlateReader/src/main/java/plugins/adufour/hcs/data/columbus/ColumbusPlate.java
View file @
2689e592
...
...
@@ -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
()
{
...
...
WellPlateReader/src/main/java/plugins/adufour/hcs/data/columbus/ColumbusTimepoint.java
View file @
2689e592
...
...
@@ -42,4 +42,10 @@ public class ColumbusTimepoint implements ITimepoint
{
return
Collections
.
unmodifiableMap
(
channels
);
}
@Override
public
String
toString
()
{
return
"Timepoint "
+
getId
();
}
}
WellPlateReader/src/main/java/plugins/adufour/hcs/data/columbus/ColumbusWell.java
View file @
2689e592
...
...
@@ -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
;
}
}
WellPlateReader/src/main/java/plugins/adufour/hcs/data/im/ImChannel.java
0 → 100644
View file @
2689e592
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
;
}
}
WellPlateReader/src/main/java/plugins/adufour/hcs/data/im/ImField.java
View file @
2689e592
...
...
@@ -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
,
I
m
Plane
>
getPlanes
()
{
// TODO Auto-generated method stub
return
null
;
...
...
WellPlateReader/src/main/java/plugins/adufour/hcs/data/im/ImImage.java
0 → 100644
View file @
2689e592
package
plugins.adufour.hcs.data.im
;
import
java.awt.Color
;