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
e9da906f
Commit
e9da906f
authored
Feb 09, 2021
by
danyfel80
Browse files
merged well plate reader im
parent
347325b9
Changes
1
Hide whitespace changes
Inline
Side-by-side
WellPlateReader/src/main/java/plugins/adufour/hcs/io/WellPlateReader_Im.java
0 → 100644
View file @
e9da906f
package
plugins.adufour.hcs.io
;
import
java.awt.image.BufferedImage
;
import
java.io.File
;
import
java.io.FileInputStream
;
import
java.io.IOException
;
import
java.nio.file.Files
;
import
java.nio.file.Path
;
import
java.nio.file.Paths
;
import
java.util.ArrayList
;
import
java.util.Comparator
;
import
java.util.HashMap
;
import
java.util.Iterator
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Map.Entry
;
import
java.util.concurrent.CompletableFuture
;
import
java.util.concurrent.ExecutorService
;
import
java.util.concurrent.Executors
;
import
java.util.concurrent.Future
;
import
java.util.stream.Collectors
;
import
javax.imageio.ImageIO
;
import
javax.imageio.ImageReadParam
;
import
javax.imageio.ImageReader
;
import
danyfel80.wells.data.IField
;
import
danyfel80.wells.data.IPlate
;
import
danyfel80.wells.data.IWell
;
import
danyfel80.wells.data.columbus.ColumbusField
;
import
danyfel80.wells.data.im.ImChannel
;
import
danyfel80.wells.data.im.ImField
;
import
danyfel80.wells.data.im.ImPlane
;
import
danyfel80.wells.data.im.ImPlate
;
import
danyfel80.wells.data.im.ImTimepoint
;
import
danyfel80.wells.util.MessageProgressListener
;
import
danyfel80.wells.util.stream.StreamUtils
;
import
icy.image.IcyBufferedImage
;
import
icy.image.colormap.IcyColorMap
;
import
icy.image.colormap.LinearColorMap
;
import
icy.sequence.Sequence
;
import
icy.type.dimension.Dimension2D
;
import
icy.type.dimension.Dimension2D.Double
;
import
ome.xml.meta.OMEXMLMetadata
;
import
ome.xml.model.primitives.PositiveInteger
;
/**
* Well plate reader for plates exported by the Image Mining software.
*
* @author Daniel Felipe Gonzalez Obando
*/
public
class
WellPlateReader_Im
extends
AbstractWellPlateReader
{
@Override
public
String
getSystemName
()
{
return
"IM"
;
}
@Override
public
boolean
isValidPlate
(
File
file
)
{
if
(!
file
.
exists
()
||
!
file
.
isDirectory
())
return
false
;
Path
folderPath
=
file
.
toPath
();
Path
xmlFile
=
Paths
.
get
(
""
+
folderPath
.
getParent
(),
folderPath
.
getFileName
()
+
".xml"
);
// Check if an XML descriptor exists next to this directory
return
Files
.
exists
(
xmlFile
);
}
@Override
public
Future
<
ImPlate
>
loadPlateFromFolder
(
File
folder
,
MessageProgressListener
progressListener
)
{
ExecutorService
executor
=
Executors
.
newSingleThreadExecutor
((
Runnable
r
)
->
{
return
new
Thread
(
r
,
"ImWellPlateReader"
);
});
Future
<
ImPlate
>
future
=
executor
.
submit
(()
->
{
return
loadPlateFromFolder_internal
(
folder
,
progressListener
);
});
executor
.
shutdown
();
return
future
;
}
private
ImPlate
loadPlateFromFolder_internal
(
File
folder
,
MessageProgressListener
progressListener
)
throws
IOException
{
Path
xmlFilePath
;
{
Path
folderPath
=
folder
.
toPath
();
xmlFilePath
=
Paths
.
get
(
""
+
folderPath
.
getParent
(),
folderPath
.
getFileName
()
+
".xml"
);
}
if
(
progressListener
!=
null
)
{
progressListener
.
notifyProgress
(-
1
,
"Loading well plate: "
+
xmlFilePath
);
}
ImPlate
plate
=
new
ImPlate
.
Builder
(
xmlFilePath
.
toString
(),
folder
.
toString
())
.
progressListener
(
progressListener
).
build
();
if
(
progressListener
!=
null
)
{
progressListener
.
notifyProgress
(
1
,
"Well plate loaded: "
+
xmlFilePath
);
}
return
plate
;
}
@Override
public
Future
<?
extends
Sequence
>
loadField
(
IPlate
plate
,
IWell
well
,
IField
field
,
Sequence
sequence
,
MessageProgressListener
progressListener
)
{
CompletableFuture
<
Sequence
>
future
=
new
CompletableFuture
<
Sequence
>();
if
(!(
field
instanceof
ImField
))
{
future
.
completeExceptionally
(
new
ClassCastException
(
"Provided field is not of type "
+
ColumbusField
.
class
.
getName
()));
return
future
;
}
if
(!(
plate
instanceof
ImPlate
))
{
future
.
completeExceptionally
(
new
ClassCastException
(
"Provided field is not of type "
+
ColumbusField
.
class
.
getName
()));
return
future
;
}
if
(
sequence
==
null
)
{
sequence
=
new
Sequence
();
}
sequence
.
beginUpdate
();
ImPlate
imPlate
=
(
ImPlate
)
plate
;
OMEXMLMetadata
metadata
=
sequence
.
getOMEXMLMetadata
();
metadata
.
setPlateName
(
imPlate
.
getName
(),
0
);
metadata
.
setPlateID
(
imPlate
.
getId
(),
0
);
metadata
.
setPlateRows
(
new
PositiveInteger
(
imPlate
.
getDimension
().
height
),
0
);
metadata
.
setPlateColumns
(
new
PositiveInteger
(
imPlate
.
getDimension
().
width
),
0
);
sequence
.
setPositionX
(
field
.
getPosition
().
getX
());
sequence
.
setPositionY
(
field
.
getPosition
().
getY
());
Dimension2D
.
Double
pixelSize
=
new
Dimension2D
.
Double
();
Map
<
Integer
,
String
>
channelNames
=
new
HashMap
<>();
Map
<
Integer
,
IcyColorMap
>
channelColors
=
new
HashMap
<>();
try
{
loadPlanes
(
imPlate
,
(
ImField
)
field
,
sequence
,
pixelSize
,
channelNames
,
channelColors
);
sequence
.
setPixelSizeX
(
pixelSize
.
getSizeX
());
sequence
.
setPixelSizeY
(
pixelSize
.
getSizeY
());
for
(
Entry
<
Integer
,
String
>
entry
:
channelNames
.
entrySet
())
{
sequence
.
setChannelName
(
entry
.
getKey
(),
entry
.
getValue
());
}
for
(
Entry
<
Integer
,
IcyColorMap
>
entry
:
channelColors
.
entrySet
())
{
sequence
.
setColormap
(
entry
.
getKey
(),
entry
.
getValue
(),
true
);
}
}
finally
{
sequence
.
endUpdate
();
}
future
.
complete
(
sequence
);
return
future
;
}
private
void
loadPlanes
(
ImPlate
plate
,
ImField
field
,
Sequence
sequence
,
Double
pixelSize
,
Map
<
Integer
,
String
>
channelNames
,
Map
<
Integer
,
IcyColorMap
>
channelColors
)
{
List
<
List
<
IcyBufferedImage
>>
planes
=
field
.
getPlanes
().
values
().
stream
()
.
sorted
(
Comparator
.
comparingDouble
(
ImPlane:
:
getPositionZ
))
.
map
(
StreamUtils
.
wrapFunction
(
plane
->
loadPlane
(
sequence
,
pixelSize
,
channelNames
,
channelColors
,
plate
,
field
,
plane
)))
.
collect
(
Collectors
.
toList
());
int
z
=
0
,
t
;
for
(
Iterator
<
List
<
IcyBufferedImage
>>
itZ
=
planes
.
iterator
();
itZ
.
hasNext
();)
{
List
<
IcyBufferedImage
>
planeImages
=
(
List
<
IcyBufferedImage
>)
itZ
.
next
();
t
=
0
;
for
(
Iterator
<
IcyBufferedImage
>
itT
=
planeImages
.
iterator
();
itT
.
hasNext
();)
{
IcyBufferedImage
image
=
(
IcyBufferedImage
)
itT
.
next
();
sequence
.
setImage
(
t
,
z
,
image
);
t
++;
}
z
++;
}
}
private
List
<
IcyBufferedImage
>
loadPlane
(
Sequence
sequence
,
Dimension2D
.
Double
pixelSize
,
Map
<
Integer
,
String
>
channelNames
,
Map
<
Integer
,
IcyColorMap
>
channelColors
,
ImPlate
plate
,
ImField
field
,
ImPlane
plane
)
{
List
<
IcyBufferedImage
>
timeImages
=
plane
.
getTimepoints
().
values
().
stream
()
.
sorted
(
Comparator
.
comparingLong
(
ImTimepoint:
:
getId
))
.
map
(
StreamUtils
.
wrapFunction
(
t
->
loadTimePoint
(
sequence
,
pixelSize
,
channelNames
,
channelColors
,
plate
,
field
,
plane
,
t
)))
.
collect
(
Collectors
.
toList
());
return
timeImages
;
}
private
IcyBufferedImage
loadTimePoint
(
Sequence
sequence
,
Dimension2D
.
Double
pixelSize
,
Map
<
Integer
,
String
>
channelNames
,
Map
<
Integer
,
IcyColorMap
>
channelColors
,
ImPlate
plate
,
ImField
field
,
ImPlane
plane
,
ImTimepoint
t
)
throws
IOException
{
ImChannel
firstChannel
=
t
.
getChannels
().
values
().
stream
().
findFirst
().
get
();
pixelSize
.
setSize
(
firstChannel
.
getImage
().
getResolution
());
String
imageFile
=
firstChannel
.
getImage
().
getUrl
();
ImageReader
reader
=
ImageIO
.
getImageReadersByFormatName
(
"tiff"
).
next
();
try
{
reader
.
setInput
(
new
FileInputStream
(
imageFile
));
int
nChannels
=
t
.
getChannels
().
size
();
List
<
BufferedImage
>
channels
=
new
ArrayList
<>(
nChannels
);
List
<
IcyColorMap
>
colorMaps
=
LinearColorMap
.
getLinearColorMaps
(
false
,
false
);
for
(
int
ch
=
0
;
ch
<
nChannels
;
ch
++)
{
ImageReadParam
p
=
new
ImageReadParam
();
p
.
setDestination
(
new
BufferedImage
(
reader
.
getWidth
(
ch
),
reader
.
getHeight
(
ch
),
BufferedImage
.
TYPE_USHORT_GRAY
));
channels
.
add
(
reader
.
read
(
ch
,
p
));
channelNames
.
put
(
ch
,
"ch"
+
ch
);
channelColors
.
put
(
ch
,
colorMaps
.
get
((
1
+
ch
)
%
colorMaps
.
size
()));
}
return
IcyBufferedImage
.
createFrom
(
channels
);
}
finally
{
reader
.
dispose
();
}
}
}
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment