Skip to content
GitLab
Menu
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
1611bbe0
Commit
1611bbe0
authored
Jan 25, 2021
by
danyfel80
Browse files
Old opera format importer Working ok
parent
ab714727
Changes
31
Hide whitespace changes
Inline
Side-by-side
WellPlateReader/src/main/java/plugins/adufour/hcs/NewWellPlateImporter.java
0 → 100644
View file @
1611bbe0
/**
*
*/
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
()
{
}
}
WellPlateReader/src/main/java/plugins/adufour/hcs/WellPlateImporter.java
View file @
1611bbe0
...
...
@@ -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_
Opera
Columbus
New
;
import
plugins.adufour.hcs.io.WellPlateReader_Columbus
OperaFlex
;
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_
Opera
Columbus
New
.
class
.
asSubclass
(
WellPlateReader
.
class
));
importers
.
add
((
Class
<
WellPlateReader
>)
WellPlateReader_Columbus
OperaFlex
.
class
.
asSubclass
(
WellPlateReader
.
class
));
}
// Add available file filters
...
...
WellPlateReader/src/main/java/plugins/adufour/hcs/data/IField.java
View file @
1611bbe0
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
();
}
WellPlateReader/src/main/java/plugins/adufour/hcs/data/IPlate.java
View file @
1611bbe0
...
...
@@ -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
();
}
WellPlateReader/src/main/java/plugins/adufour/hcs/data/IWell.java
View file @
1611bbe0
...
...
@@ -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
();
}
WellPlateReader/src/main/java/plugins/adufour/hcs/data/IWellShape.java
0 → 100644
View file @
1611bbe0
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
();
}
WellPlateReader/src/main/java/plugins/adufour/hcs/data/columbus/ColumbusField.java
View file @
1611bbe0
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
;
}
}
WellPlateReader/src/main/java/plugins/adufour/hcs/data/columbus/ColumbusImage.java
View file @
1611bbe0
...
...
@@ -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
;