Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
XRD
darfix
Commits
c6aa6fbc
Commit
c6aa6fbc
authored
Aug 10, 2021
by
Julia Garriga Ferrer
Browse files
Merge branch 'export_grainplot_data' into 'master'
Export grainplot data See merge request
!132
parents
5075e98e
d0625ddc
Pipeline
#52378
failed with stage
in 2 minutes and 14 seconds
Changes
4
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
darfix/app/ows_to_script.py
View file @
c6aa6fbc
...
...
@@ -84,7 +84,7 @@ if __name__ == '__main__':
type=str,
default=None)
parser.add_argument(
'-t
r
',
'-t
d
',
'--treated_data',
help='Directory to save treated data',
type=str,
...
...
darfix/gui/grainPlotWidget.py
View file @
c6aa6fbc
...
...
@@ -26,7 +26,7 @@
__authors__
=
[
"J. Garriga"
]
__license__
=
"MIT"
__date__
=
"0
7
/0
6
/2021"
__date__
=
"
1
0/0
8
/2021"
from
matplotlib.colors
import
hsv_to_rgb
import
numpy
...
...
@@ -37,6 +37,7 @@ from silx.gui.plot import Plot2D
from
silx.image.marchingsquares
import
find_contours
from
silx.math.medianfilter
import
medfilt2d
from
silx.utils.enum
import
Enum
as
_Enum
from
silx.io.dictdump
import
dicttonx
import
darfix
from
.operationThread
import
OperationThread
...
...
@@ -61,7 +62,7 @@ class GrainPlotWidget(qt.QMainWindow):
sigComputed
=
qt
.
Signal
()
def
__init__
(
self
,
parent
=
None
):
qt
.
Q
Widget
.
__init__
(
self
,
parent
)
qt
.
Q
MainWindow
.
__init__
(
self
,
parent
)
self
.
_methodCB
=
qt
.
QComboBox
()
self
.
_methodCB
.
addItems
(
Method
.
values
())
...
...
@@ -90,10 +91,14 @@ class GrainPlotWidget(qt.QMainWindow):
levelsLayout
.
addWidget
(
self
.
_contoursPlot
,
2
,
0
,
1
,
3
)
self
.
_levelsWidget
.
setLayout
(
levelsLayout
)
self
.
_mosaicityPlot
=
Plot2D
(
parent
=
self
)
self
.
_exportButton
=
qt
.
QPushButton
(
"Export maps"
)
self
.
_exportButton
.
setEnabled
(
False
)
self
.
_exportButton
.
clicked
.
connect
(
self
.
exportMaps
)
layout
.
addWidget
(
self
.
_methodCB
)
layout
.
addWidget
(
self
.
_levelsWidget
)
layout
.
addWidget
(
self
.
_plotWidget
)
layout
.
addWidget
(
self
.
_mosaicityPlot
)
layout
.
addWidget
(
self
.
_exportButton
)
self
.
_plotWidget
.
hide
()
self
.
_mosaicityPlot
.
hide
()
self
.
_mosaicityPlot
.
getColorBarWidget
().
hide
()
...
...
@@ -122,6 +127,7 @@ class GrainPlotWidget(qt.QMainWindow):
self
.
origin
=
(
px
,
py
)
self
.
scale
=
(
xscale
,
yscale
)
if
self
.
dataset
.
dims
.
ndim
>
1
:
self
.
_curves
=
{}
self
.
ori_dist
,
self
.
hsv_key
=
self
.
dataset
.
compute_mosaicity_colorkey
()
xdim
=
self
.
dataset
.
dims
.
get
(
1
)
ydim
=
self
.
dataset
.
dims
.
get
(
0
)
...
...
@@ -163,6 +169,7 @@ class GrainPlotWidget(qt.QMainWindow):
for
i
in
range
(
rg
):
self
.
_methodCB
.
model
().
item
(
i
).
setEnabled
(
True
)
self
.
_methodCB
.
setCurrentIndex
(
0
)
self
.
_exportButton
.
setEnabled
(
True
)
else
:
print
(
"
\n
Computation aborted"
)
...
...
@@ -196,6 +203,7 @@ class GrainPlotWidget(qt.QMainWindow):
colors
=
self
.
_curvesColormap
.
applyToData
(
levels
)
xdim
=
self
.
dataset
.
dims
.
get
(
1
)
ydim
=
self
.
dataset
.
dims
.
get
(
0
)
self
.
_curves
=
{}
for
ipolygon
,
polygon
in
enumerate
(
polygons
):
# iso contours
for
icontour
,
contour
in
enumerate
(
polygon
):
...
...
@@ -204,15 +212,20 @@ class GrainPlotWidget(qt.QMainWindow):
# isClosed = numpy.allclose(contour[0], contour[-1])
x
=
contour
[:,
1
]
y
=
contour
[:,
0
]
x
*=
(
xdim
.
unique_values
[
-
1
]
-
xdim
.
unique_values
[
0
])
/
(
xdim
.
size
-
1
)
y
*=
(
ydim
.
unique_values
[
-
1
]
-
ydim
.
unique_values
[
0
])
/
(
ydim
.
size
-
1
)
rescale_x
=
(
xdim
.
unique_values
[
-
1
]
-
xdim
.
unique_values
[
0
])
/
(
xdim
.
size
-
1
)
rescale_y
=
(
ydim
.
unique_values
[
-
1
]
-
ydim
.
unique_values
[
0
])
/
(
ydim
.
size
-
1
)
x
*=
rescale_x
y
*=
rescale_y
if
self
.
_centerDataCheckbox
.
isChecked
():
xcenter
=
(
xdim
.
unique_values
[
-
1
]
-
xdim
.
unique_values
[
0
])
/
2
x
-=
xcenter
ycenter
=
(
ydim
.
unique_values
[
-
1
]
-
ydim
.
unique_values
[
0
])
/
2
y
-=
ycenter
legend
=
"custom-polygon-%d"
%
icontour
*
(
ipolygon
+
1
)
legend
=
"poly{}.{}"
.
format
(
icontour
,
ipolygon
)
self
.
_curves
[
legend
]
=
{
"points"
:
(
x
.
copy
(),
y
.
copy
()),
"color"
:
colors
[
ipolygon
]
}
self
.
_contoursPlot
.
addCurve
(
x
=
x
,
y
=
y
,
linestyle
=
"-"
,
linewidth
=
2.0
,
legend
=
legend
,
resetzoom
=
False
,
color
=
colors
[
ipolygon
])
...
...
@@ -273,3 +286,77 @@ class GrainPlotWidget(qt.QMainWindow):
img
[
img
<
Imin
]
=
Imin
return
medfilt2d
(
img
)
def
exportMaps
(
self
):
"""
Creates dictionay with maps information and exports it to a nexus file
"""
if
self
.
dataset
and
self
.
dataset
.
dims
.
ndim
>
1
:
nx
=
{
"entry"
:
{
"MOSAICITY"
:
{
">"
+
Method
.
MOSAICITY
.
name
:
"../maps/"
+
Method
.
MOSAICITY
.
name
,
"@signal"
:
Method
.
MOSAICITY
.
name
,
"@NX_class"
:
"NXdata"
},
"maps"
:
{
Method
.
MOSAICITY
.
name
:
hsv_to_rgb
(
self
.
_computeMosaicity
()),
Method
.
MOSAICITY
.
name
+
"@interpretation"
:
"rgba-image"
,
"@NX_class"
:
"NXcollection"
},
Method
.
ORI_DIST
.
name
:
{
"key"
:
{
"image"
:
hsv_to_rgb
(
self
.
hsv_key
),
"scale"
:
self
.
_contoursPlot
.
getImage
().
getScale
(),
"xlabel"
:
self
.
_contoursPlot
.
getImage
().
getXLabel
(),
"ylabel"
:
self
.
_contoursPlot
.
getImage
().
getYLabel
(),
"image@interpretation"
:
"rgba-image"
,
},
"curves"
:
self
.
_curves
},
"@NX_class"
:
"NXentry"
,
"@default"
:
"data"
,
},
"@NX_class"
:
"NXroot"
,
"@default"
:
"entry"
}
for
axis
,
dim
in
self
.
dataset
.
dims
:
nx
[
"entry"
][
"maps"
].
update
(
{
Method
.
COM
.
name
:
self
.
_moments
[
axis
][
0
],
Method
.
FWHM
.
name
:
self
.
_moments
[
axis
][
1
],
Method
.
SKEWNESS
.
name
:
self
.
_moments
[
axis
][
2
],
Method
.
KURTOSIS
.
name
:
self
.
_moments
[
axis
][
3
]
}
)
else
:
nx
=
{
"entry"
:
{
"data"
:
{
">"
+
Method
.
COM
.
name
:
"../maps/"
+
Method
.
COM
.
name
,
"@signal"
:
Method
.
COM
.
name
,
"@NX_class"
:
"NXdata"
},
"maps"
:
{
Method
.
COM
.
name
:
self
.
_moments
[
0
][
0
],
Method
.
FWHM
.
name
:
self
.
_moments
[
0
][
1
],
Method
.
SKEWNESS
.
name
:
self
.
_moments
[
0
][
2
],
Method
.
KURTOSIS
.
name
:
self
.
_moments
[
0
][
3
],
"@NX_class"
:
"NXcollection"
},
"@NX_class"
:
"NXentry"
,
"@default"
:
"data"
,
},
"@NX_class"
:
"NXroot"
,
"@default"
:
"entry"
}
fileDialog
=
qt
.
QFileDialog
()
fileDialog
.
setFileMode
(
fileDialog
.
AnyFile
)
fileDialog
.
setAcceptMode
(
fileDialog
.
AcceptSave
)
fileDialog
.
setOption
(
fileDialog
.
DontUseNativeDialog
)
fileDialog
.
setDefaultSuffix
(
".h5"
)
if
fileDialog
.
exec_
():
dicttonx
(
nx
,
fileDialog
.
selectedFiles
()[
0
])
darfix/io/utils.py
View file @
c6aa6fbc
...
...
@@ -26,7 +26,7 @@
__authors__
=
[
"J. Garriga"
]
__license__
=
"MIT"
__date__
=
"0
6
/0
2
/202
0
"
__date__
=
"0
3
/0
7
/202
1
"
import
logging
import
h5py
...
...
@@ -72,6 +72,92 @@ def advancement_display(iteration, total, prefix='', suffix='', decimals=1, leng
print
()
def
write_maps
(
h5_file
,
list_of_maps
,
default_map
,
entry
,
processing_order
,
data_path
=
'/'
,
overwrite
=
True
):
"""
Write a stack of components and its parameters into .h5
:param str h5_file: path to the hdf5 file
:param str entry: entry name
:param dict dimensions: Dictionary with the dimensions names and values
:param numpy.ndarray W: Matrix with the rocking curves values
:param numpy.ndarray data: Stack with the components
:param int processing_order: processing order of treatment
:param str data_path: path to store the data
"""
process_name
=
'process_'
+
str
(
processing_order
)
def
get_interpretation
(
my_data
):
"""Return hdf5 attribute for this type of data"""
if
isinstance
(
my_data
,
numpy
.
ndarray
):
if
my_data
.
ndim
==
1
:
return
'spectrum'
elif
my_data
.
ndim
in
(
2
,
3
):
return
'image'
return
None
def
save_key
(
path_name
,
key_path
,
value
,
overwrite
=
True
):
"""Save the given value to the associated path. Manage numpy arrays
and dictionaries"""
key_path
=
key_path
.
replace
(
'.'
,
'/'
)
# save if is dict
if
isinstance
(
value
,
dict
):
h5_path
=
'/'
.
join
((
path_name
,
key_path
))
dicttoh5
(
value
,
h5file
=
h5_file
,
h5path
=
h5_path
,
overwrite_data
=
True
,
mode
=
'a'
)
else
:
with
h5py
.
File
(
h5_file
,
'a'
)
as
h5f
:
nx
=
h5f
.
require_group
(
path_name
)
if
overwrite
and
key_path
in
nx
:
del
nx
[
key_path
]
try
:
nx
[
key_path
]
=
value
except
TypeError
as
e
:
_logger
.
error
(
'Unable to write'
,
str
(
key_path
),
'reason is'
,
str
(
e
))
else
:
interpretation
=
get_interpretation
(
value
)
if
interpretation
:
nx
[
key_path
].
attrs
[
'interpretation'
]
=
interpretation
with
h5py
.
File
(
h5_file
,
'a'
)
as
h5f
:
h5f
.
attrs
[
"default"
]
=
entry
nx_entry
=
h5f
.
require_group
(
'/'
.
join
((
data_path
,
entry
)))
nx_entry
.
attrs
[
"NX_class"
]
=
"NXentry"
nx_entry
.
attrs
[
"default"
]
=
"data"
nx_process
=
nx_entry
.
require_group
(
process_name
)
nx_process
.
attrs
[
'NX_class'
]
=
"NXprocess"
if
overwrite
:
for
key
in
(
'program'
,
'version'
,
'date'
,
'processing_order'
):
if
key
in
nx_process
:
del
nx_process
[
key
]
nx_process
[
'program'
]
=
'darfix'
nx_process
[
'version'
]
=
'0.2'
nx_process
[
'date'
]
=
datetime
.
now
().
replace
(
microsecond
=
0
).
isoformat
()
nx_process
[
'processing_order'
]
=
numpy
.
int32
(
processing_order
)
results
=
nx_process
.
require_group
(
"results"
)
results
.
attrs
[
"NX_class"
]
=
"NXcollection"
nx_data
=
nx_entry
.
require_group
(
"data"
)
nx_data
.
attrs
[
"NX_class"
]
=
"NXdata"
default
=
list_of_maps
[
default_map
]
source_addr
=
entry
+
"/"
+
process_name
+
"/results/"
+
default_map
results
.
attrs
[
"target"
]
=
default_map
save_key
(
results
.
name
,
default_map
,
default
)
save_key
(
nx_data
.
name
,
default_map
,
h5f
[
source_addr
])
for
_map
in
list_of_maps
:
if
_map
==
default_map
:
continue
if
isinstance
(
list_of_maps
[
_map
],
dict
):
maps
=
results
.
require_group
(
_map
)
maps
.
attrs
[
"NX_class"
]
=
"NXcollection"
for
method
in
list_of_maps
[
_map
]:
save_key
(
maps
.
name
,
method
,
list_of_maps
[
_map
][
method
])
else
:
save_key
(
results
.
name
,
_map
,
list_of_maps
[
_map
])
def
read_components
(
h5_file
):
"""
Read a stack of components and its parameters from a Nexus file.
...
...
@@ -142,7 +228,7 @@ def write_components(h5_file, entry, dimensions, W, data, processing_order,
nx
[
key_path
].
attrs
[
'interpretation'
]
=
interpretation
with
h5py
.
File
(
h5_file
,
'a'
)
as
h5f
:
h5f
.
attrs
[
"default"
]
=
"
entry
"
h5f
.
attrs
[
"default"
]
=
entry
nx_entry
=
h5f
.
require_group
(
'/'
.
join
((
data_path
,
entry
)))
nx_entry
.
attrs
[
"NX_class"
]
=
"NXentry"
nx_entry
.
attrs
[
"default"
]
=
"data"
...
...
@@ -169,7 +255,7 @@ def write_components(h5_file, entry, dimensions, W, data, processing_order,
nx_data
=
nx_entry
.
require_group
(
"data"
)
nx_data
.
attrs
[
"NX_class"
]
=
"NXdata"
nx_data
.
attrs
[
"signal"
]
=
"components"
source_addr
=
"
entry/"
+
process_name
+
"/results/components"
source_addr
=
entry
+
"
/"
+
process_name
+
"/results/components"
results
.
attrs
[
"target"
]
=
"components"
save_key
(
results
.
name
,
"W"
,
W
)
...
...
examples/plot_oridist_contours.py
0 → 100644
View file @
c6aa6fbc
#!/usr/bin/env python
# coding: utf-8
# /*##########################################################################
#
# Copyright (c) 2020 European Synchrotron Radiation Facility
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
# ###########################################################################*/
"""Sample code illustrating how to custom silx view into another application.
"""
__authors__
=
[
"J. Garriga"
]
__license__
=
"MIT"
__date__
=
"10/08/2021"
import
argparse
import
signal
import
sys
from
silx.gui
import
qt
from
silx.gui.plot
import
Plot2D
from
silx.io.dictdump
import
nxtodict
from
darfix.gui.grainPlotWidget
import
Method
class
PlotOriDistContours
(
qt
.
QMainWindow
):
def
__init__
(
self
,
filename
,
parent
=
None
):
qt
.
QMainWindow
.
__init__
(
self
,
parent
)
plot
=
Plot2D
(
parent
=
self
)
try
:
h5file
=
nxtodict
(
filename
)
key
=
h5file
[
"entry"
][
Method
.
ORI_DIST
.
name
][
"key"
]
curves
=
h5file
[
"entry"
][
Method
.
ORI_DIST
.
name
][
"curves"
]
plot
.
addImage
(
key
[
"image"
],
xlabel
=
key
[
"xlabel"
],
ylabel
=
key
[
"ylabel"
],
scale
=
tuple
(
key
[
"scale"
]))
for
legend
in
curves
:
if
legend
!=
"@NX_class"
:
curve
=
curves
[
legend
]
plot
.
addCurve
(
x
=
curve
[
"points"
][
0
],
y
=
curve
[
"points"
][
1
],
linestyle
=
"-"
,
linewidth
=
2.0
,
legend
=
legend
,
resetzoom
=
False
,
color
=
curve
[
"color"
])
except
KeyError
:
raise
KeyError
(
"Make sure orientation distribution key has been saved"
)
self
.
setCentralWidget
(
plot
)
def
createParser
():
parser
=
argparse
.
ArgumentParser
(
description
=
__doc__
)
parser
.
add_argument
(
'file'
,
type
=
str
,
nargs
=
argparse
.
ZERO_OR_MORE
,
help
=
'Data file to show (h5 file)'
)
return
parser
def
exec_
(
argv
):
qapp
=
qt
.
QApplication
([])
# add connection with ctrl + c signal
qt
.
QLocale
.
setDefault
(
qt
.
QLocale
.
c
())
signal
.
signal
(
signal
.
SIGINT
,
sigintHandler
)
sys
.
excepthook
=
qt
.
exceptionHandler
timer
=
qt
.
QTimer
()
timer
.
start
(
500
)
# Application have to wake up Python interpreter, else SIGINT is not
# catch
timer
.
timeout
.
connect
(
lambda
:
None
)
parser
=
createParser
()
options
=
parser
.
parse_args
(
argv
[
1
:])
w
=
PlotOriDistContours
(
options
.
file
[
0
])
w
.
show
()
qapp
.
exec_
()
def
sigintHandler
(
*
args
):
"""Handler for the SIGINT signal."""
qt
.
QApplication
.
quit
()
if
__name__
==
"__main__"
:
exec_
(
sys
.
argv
)
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a 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