Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
C
cfel_fmt
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
dataAnalysis
cfel_fmt
Commits
836abf74
Commit
836abf74
authored
7 years ago
by
Valerio Mariani
Browse files
Options
Downloads
Patches
Plain Diff
Fixed a few syntax problems and did some code cleanup
parent
8f35033b
No related branches found
No related tags found
No related merge requests found
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
crystfel_utils.py
+121
-171
121 additions, 171 deletions
crystfel_utils.py
geometry_utils.py
+109
-101
109 additions, 101 deletions
geometry_utils.py
parameter_utils.py
+25
-45
25 additions, 45 deletions
parameter_utils.py
with
255 additions
and
317 deletions
crystfel_utils.py
+
121
−
171
View file @
836abf74
...
...
@@ -32,42 +32,39 @@ import re
def
_assplode_algebraic
(
value
):
# Reimplementation of assplode_algegraic from
# libcrystfel/src/detector.c.
items
=
[
item
for
item
in
re
.
split
(
pattern
=
'
([+-])
'
,
string
=
value
.
strip
()
)
if
item
!=
''
item
for
item
in
re
.
split
(
pattern
=
'
([+-])
'
,
string
=
value
.
strip
()
)
if
item
!=
''
]
if
items
and
items
[
0
]
not
in
(
'
+
'
,
'
-
'
):
items
.
insert
(
index
=
0
,
object
=
'
+
'
)
return
[
''
.
join
(
iterable
=
(
items
[
x
],
items
[
x
+
1
])
)
for
x
in
range
(
start
=
0
,
stop
=
len
(
items
),
step
=
2
)
''
.
join
((
items
[
x
],
items
[
x
+
1
]))
for
x
in
range
(
0
,
len
(
items
),
2
)
]
def
_dir_conv
(
direction_x
,
direction_y
,
direction_z
,
value
):
# Reimplementation of dir_conv from
# libcrystfel/src/detector.c.
direction
=
[
direction_x
,
direction_y
,
direction_z
direction_x
,
direction_y
,
direction_z
]
items
=
_assplode_algebraic
(
value
)
if
items
:
raise
RuntimeError
(
'
Invalid direction: {}.
'
.
format
(
value
))
if
not
items
:
raise
RuntimeError
(
"
Invalid direction: {}.
"
.
format
(
value
))
for
item
in
items
:
axis
=
item
[
-
1
]
if
axis
!=
'
x
'
and
axis
!=
'
y
'
and
axis
!=
'
z
'
:
raise
RuntimeError
(
'
Invalid Symbol: {} (must be x, y or z).
'
.
format
(
axis
)
"
Invalid Symbol: {} (must be x, y or z).
"
.
format
(
axis
)
)
if
item
[:
-
1
]
==
'
+
'
:
...
...
@@ -90,16 +87,14 @@ def _dir_conv(direction_x, direction_y, direction_z, value):
def
_set_dim_structure_entry
(
key
,
value
,
panel
):
# Reimplementation of set_dim_structure_entry from
# libcrystfel/src/events.c.
if
panel
[
'
dim_structure
'
]
is
not
None
:
dim
=
panel
[
'
dim_structure
'
]
else
:
dim
=
[]
dim_index
=
int
(
key
[
3
])
if
dim_index
>
len
(
dim
)
-
1
:
for
_
in
range
(
start
=
len
(
dim
),
stop
=
dim_index
+
1
):
for
_
in
range
(
len
(
dim
),
dim_index
+
1
):
dim
.
append
(
None
)
if
value
==
'
ss
'
or
value
==
'
fs
'
or
value
==
'
%
'
:
...
...
@@ -107,35 +102,28 @@ def _set_dim_structure_entry(key, value, panel):
elif
value
.
isdigit
():
dim
[
dim_index
]
=
int
(
value
)
else
:
raise
RuntimeError
(
'
Invalid dim entry: {}.
'
.
format
(
value
))
raise
RuntimeError
(
"
Invalid dim entry: {}.
"
.
format
(
value
))
def
_parse_field_for_panel
(
key
,
value
,
panel
):
# Reimplementation of parse_field_for_panel from
# libcrystfel/src/detector.c.
if
key
==
'
min_fs
'
:
panel
[
'
origin_min_fs
'
]
=
int
(
value
)
panel
[
'
min_fs
'
]
=
int
(
value
)
elif
key
==
'
max_fs
'
:
panel
[
'
origin_max_fs
'
]
=
int
(
value
)
panel
[
'
max_fs
'
]
=
int
(
value
)
elif
key
==
'
min_ss
'
:
panel
[
'
origin_min_ss
'
]
=
int
(
value
)
panel
[
'
min_ss
'
]
=
int
(
value
)
elif
key
==
'
max_ss
'
:
panel
[
'
origin_max_ss
'
]
=
int
(
value
)
panel
[
'
max_ss
'
]
=
int
(
value
)
elif
key
==
'
corner_x
'
:
panel
[
'
cnx
'
]
=
float
(
value
)
elif
key
==
'
corner_y
'
:
panel
[
'
cny
'
]
=
float
(
value
)
elif
key
==
'
rail_direction
'
:
try
:
panel
[
'
rail_x
'
],
panel
[
'
rail_y
'
],
panel
[
'
rail_z
'
]
=
_dir_conv
(
...
...
@@ -145,20 +133,16 @@ def _parse_field_for_panel(key, value, panel):
value
=
value
)
except
RuntimeError
as
exc
:
raise
RuntimeError
(
'
Invalid rail direction.
'
,
exc
)
raise
RuntimeError
(
"
Invalid rail direction.
"
,
exc
)
elif
key
==
'
clen_for_centering
'
:
panel
[
'
clen_for_centering
'
]
=
float
(
value
)
elif
key
==
'
adu_per_eV
'
:
panel
[
'
adu_per_eV
'
]
=
float
(
value
)
elif
key
==
'
adu_per_photon
'
:
panel
[
'
adu_per_photon
'
]
=
float
(
value
)
elif
key
==
'
rigid_group
'
:
panel
[
'
rigid_group
'
]
=
value
elif
key
==
'
clen
'
:
try
:
panel
[
'
clen
'
]
=
float
(
value
)
...
...
@@ -168,33 +152,27 @@ def _parse_field_for_panel(key, value, panel):
panel
[
'
clen_from
'
]
=
value
elif
key
==
'
data
'
:
if
not
value
.
startswith
(
'
/
'
):
raise
RuntimeError
(
'
Invalid data location: {}
'
.
format
(
value
))
if
not
value
.
startswith
(
"
/
"
):
raise
RuntimeError
(
"
Invalid data location: {}
"
.
format
(
value
))
panel
[
'
data
'
]
=
value
elif
key
==
'
mask
'
:
if
not
value
.
startswith
(
'
/
'
):
raise
RuntimeError
(
'
Invalid data location: {}
'
.
format
(
value
))
if
not
value
.
startswith
(
"
/
"
):
raise
RuntimeError
(
"
Invalid data location: {}
"
.
format
(
value
))
panel
[
'
mask
'
]
=
value
elif
key
==
'
mask_file
'
:
panel
[
'
mask_file
'
]
=
value
elif
key
==
'
saturation_map
'
:
panel
[
'
saturation_map
'
]
=
value
elif
key
==
'
saturation_map_file
'
:
panel
[
'
saturation_map_file
'
]
=
value
elif
key
==
'
coffset
'
:
panel
[
'
coffset
'
]
=
float
(
value
)
elif
key
==
'
res
'
:
panel
[
'
res
'
]
=
float
(
value
)
elif
key
==
'
max_adu
'
:
panel
[
'
max_adu
'
]
=
value
elif
key
==
'
badrow_direction
'
:
if
value
==
'
x
'
:
panel
[
'
badrow
'
]
=
'
f
'
...
...
@@ -207,13 +185,12 @@ def _parse_field_for_panel(key, value, panel):
elif
value
==
'
-
'
:
panel
[
'
badrow
'
]
=
'
-
'
else
:
print
(
'
badrow_direction must be x, t, f, s, or
\'
-
\'
'
)
print
(
'
Assuming
\'
-
\'
.
'
)
print
(
"
badrow_direction must be x, t, f, s, or
\'
-
\'
"
)
print
(
"
Assuming
\'
-
\'
.
"
)
panel
[
'
badrow
'
]
=
'
-
'
elif
key
==
'
no_index
'
:
panel
[
'
no_index
'
]
=
bool
(
value
)
elif
key
==
'
fs
'
:
try
:
panel
[
'
fsx
'
],
panel
[
'
fsy
'
],
panel
[
'
fsz
'
]
=
_dir_conv
(
...
...
@@ -222,9 +199,8 @@ def _parse_field_for_panel(key, value, panel):
direction_z
=
panel
[
'
fsz
'
],
value
=
value
)
except
RuntimeError
as
exc
:
raise
RuntimeError
(
'
Invalid fast scan direction.
'
,
exc
)
raise
RuntimeError
(
"
Invalid fast scan direction.
"
,
exc
)
elif
key
==
'
ss
'
:
try
:
...
...
@@ -234,25 +210,22 @@ def _parse_field_for_panel(key, value, panel):
direction_z
=
panel
[
'
ssz
'
],
value
=
value
)
except
RuntimeError
as
exc
:
raise
RuntimeError
(
'
Invalid slow scan direction.
'
,
exc
)
raise
RuntimeError
(
"
Invalid slow scan direction.
"
,
exc
)
elif
key
.
startswith
(
'
dim
'
):
elif
key
.
startswith
(
"
dim
"
):
_set_dim_structure_entry
(
key
=
key
,
value
=
value
,
panel
=
panel
)
else
:
raise
RuntimeError
(
'
Unrecognised field: {}
'
.
format
(
key
))
raise
RuntimeError
(
"
Unrecognised field: {}
"
.
format
(
key
))
def
_parse_toplevel
(
key
,
value
,
detector
,
beam
,
panel
):
# Reimplementation of parse_toplevel from
# libcrystfel/src/detector.c.
if
key
==
'
mask_bad
'
:
try
:
detector
[
'
mask_bad
'
]
=
int
(
value
)
...
...
@@ -267,7 +240,6 @@ def _parse_toplevel(key, value, detector, beam, panel):
elif
key
==
'
coffset
'
:
panel
[
'
coffset
'
]
=
float
(
value
)
elif
key
==
'
photon_energy
'
:
if
value
.
startswith
(
'
/
'
):
beam
[
'
photon_energy
'
]
=
0.0
...
...
@@ -278,19 +250,15 @@ def _parse_toplevel(key, value, detector, beam, panel):
elif
key
==
'
photon_energy_scale
'
:
beam
[
'
photon_energy_scale
'
]
=
float
(
value
)
elif
key
==
'
peak_info_location
'
:
detector
[
'
peak_info_location
'
]
=
value
elif
(
key
.
startswith
(
'
rigid_group
'
)
and
not
key
.
startswith
(
'
rigid_group_collection
'
)
key
.
startswith
(
"
rigid_group
"
)
and
not
key
.
startswith
(
"
rigid_group_collection
"
)
):
detector
[
'
rigid_groups
'
][
key
[
12
:]]
=
value
.
split
(
'
,
'
)
elif
key
.
startswith
(
'
rigid_group_collection
'
):
elif
key
.
startswith
(
"
rigid_group_collection
"
):
detector
[
'
rigid_group_collections
'
][
key
[
23
:]]
=
value
.
split
(
'
,
'
)
else
:
_parse_field_for_panel
(
key
=
key
,
...
...
@@ -316,58 +284,54 @@ def _parse_field_bad(key, value, bad):
# Reimplementation of parse_field_bad from
# libcrystfel/src/detector.c.
if
key
==
'
min_x
'
:
bad
[
'
min_x
'
]
=
float
(
x
=
value
)
bad
[
'
min_x
'
]
=
float
(
value
)
_check_bad_fsss
(
bad_region
=
bad
,
is_fsss
=
False
)
elif
key
==
'
max_x
'
:
bad
[
'
max_x
'
]
=
float
(
x
=
value
)
bad
[
'
max_x
'
]
=
float
(
value
)
_check_bad_fsss
(
bad_region
=
bad
,
is_fsss
=
False
)
elif
key
==
'
min_y
'
:
bad
[
'
min_y
'
]
=
float
(
x
=
value
)
bad
[
'
min_y
'
]
=
float
(
value
)
_check_bad_fsss
(
bad_region
=
bad
,
is_fsss
=
False
)
elif
key
==
'
max_y
'
:
bad
[
'
max_y
'
]
=
float
(
x
=
value
)
bad
[
'
max_y
'
]
=
float
(
value
)
_check_bad_fsss
(
bad_region
=
bad
,
is_fsss
=
False
)
elif
key
==
'
min_fs
'
:
bad
[
'
min_fs
'
]
=
int
(
x
=
value
)
bad
[
'
min_fs
'
]
=
int
(
value
)
_check_bad_fsss
(
bad_region
=
bad
,
is_fsss
=
True
)
elif
key
==
'
max_fs
'
:
bad
[
'
max_fs
'
]
=
int
(
x
=
value
)
bad
[
'
max_fs
'
]
=
int
(
value
)
_check_bad_fsss
(
bad_region
=
bad
,
is_fsss
=
True
)
elif
key
==
'
min_ss
'
:
bad
[
'
min_ss
'
]
=
int
(
x
=
value
)
bad
[
'
min_ss
'
]
=
int
(
value
)
_check_bad_fsss
(
bad_region
=
bad
,
is_fsss
=
True
)
elif
key
==
'
max_ss
'
:
bad
[
'
max_ss
'
]
=
int
(
x
=
value
)
bad
[
'
max_ss
'
]
=
int
(
value
)
_check_bad_fsss
(
bad_region
=
bad
,
is_fsss
=
True
)
elif
key
==
'
panel
'
:
bad
[
'
panel
'
]
=
value
else
:
raise
RuntimeError
(
'
Unrecognised field: {}
'
.
format
(
key
))
raise
RuntimeError
(
"
Unrecognised field: {}
"
.
format
(
key
))
return
def
_check_point
(
name
,
panel
,
fs
_
,
ss
_
,
min_d
,
max_d
,
detector
):
def
_check_point
(
name
,
panel
,
fs
,
ss
,
min_d
,
max_d
,
detector
):
# Reimplementation of check_point from
# libcrystfel/src/detector.c.
xs_
=
fs_
*
panel
[
'
fsx
'
]
+
ss_
*
panel
[
'
ssx
'
]
ys_
=
fs_
*
panel
[
'
fsy
'
]
+
ss_
*
panel
[
'
ssy
'
]
rx_
=
(
xs_
+
panel
[
'
cnx
'
])
/
panel
[
'
res
'
]
ry_
=
(
ys_
+
panel
[
'
cny
'
])
/
panel
[
'
res
'
]
dist
=
math
.
sqrt
(
x
=
rx_
*
rx_
+
ry_
*
ry_
)
xs
=
fs
*
panel
[
'
fsx
'
]
+
ss
*
panel
[
'
ssx
'
]
ys
=
fs
*
panel
[
'
fsy
'
]
+
ss
*
panel
[
'
ssy
'
]
rx
=
(
xs
+
panel
[
'
cnx
'
])
/
panel
[
'
res
'
]
ry
=
(
ys
+
panel
[
'
cny
'
])
/
panel
[
'
res
'
]
dist
=
math
.
sqrt
(
rx
*
rx
+
ry
*
ry
)
if
dist
>
max_d
:
detector
[
'
furthest_out_panel
'
]
=
name
detector
[
'
furthest_out_fs
'
]
=
fs
_
detector
[
'
furthest_out_ss
'
]
=
ss
_
detector
[
'
furthest_out_fs
'
]
=
fs
detector
[
'
furthest_out_ss
'
]
=
ss
max_d
=
dist
elif
dist
<
min_d
:
detector
[
'
furthest_in_panel
'
]
=
name
detector
[
'
furthest_in_fs
'
]
=
fs
_
detector
[
'
furthest_in_ss
'
]
=
ss
_
detector
[
'
furthest_in_fs
'
]
=
fs
detector
[
'
furthest_in_ss
'
]
=
ss
min_d
=
dist
return
min_d
,
max_d
...
...
@@ -376,17 +340,14 @@ def _check_point(name, panel, fs_, ss_, min_d, max_d, detector):
def
_find_min_max_d
(
detector
):
# Reimplementation of find_min_max_d from
# libcrystfel/src/detector.c.
min_d
=
float
(
'
inf
'
)
max_d
=
0.0
for
name
,
panel
in
detector
[
'
panels
'
].
items
():
min_d
,
max_d
=
_check_point
(
name
=
name
,
panel
=
panel
,
fs
_
=
0
,
ss
_
=
0
,
fs
=
0
,
ss
=
0
,
min_d
=
min_d
,
max_d
=
max_d
,
detector
=
detector
...
...
@@ -395,18 +356,18 @@ def _find_min_max_d(detector):
min_d
,
max_d
=
_check_point
(
name
=
name
,
panel
=
panel
,
fs
_
=
panel
[
'
w
'
],
ss
_
=
0
,
fs
=
panel
[
'
w
'
],
ss
=
0
,
min_d
=
min_d
,
max_d
=
max_d
,
detector
=
detector
)
min_d
,
max_d
=
_check_point
(
name
=
name
,
panel
=
panel
,
fs
_
=
0
,
ss
_
=
panel
[
'
h
'
],
fs
=
0
,
ss
=
panel
[
'
h
'
],
min_d
=
min_d
,
max_d
=
max_d
,
detector
=
detector
...
...
@@ -415,8 +376,8 @@ def _find_min_max_d(detector):
min_d
,
max_d
=
_check_point
(
name
=
name
,
panel
=
panel
,
fs
_
=
panel
[
'
w
'
],
ss
_
=
panel
[
'
h
'
],
fs
=
panel
[
'
w
'
],
ss
=
panel
[
'
h
'
],
min_d
=
min_d
,
max_d
=
max_d
,
detector
=
detector
...
...
@@ -424,13 +385,14 @@ def _find_min_max_d(detector):
def
load_crystfel_geometry
(
filename
):
"""
Load a CrystFEL geometry file into a dictionary.
"""
Load a CrystFEL geometry file into a dictionary.
Reimplementation of the get_detector_geometry_2 function from
CrystFEL
in python. Return a dictionary with the geometry
information read from
the file. Convert entries in the geometry
file to keys in the
returned dictionary. For a full documentation
on the CrystFEL geometry
format, see:
Reimplementation of the get_detector_geometry_2 function from
CrystFEL
in python. Return a dictionary with the geometry
information read from
the file. Convert entries in the geometry
file to keys in the
returned dictionary. For a full documentation
on the CrystFEL geometry
format, see:
http://www.desy.de/~twhite/crystfel/manual-crystfel_geometry.html
...
...
@@ -444,11 +406,9 @@ def load_crystfel_geometry(filename):
Returns:
dict: dictionary with the geometry information loaded from the file.
dict: dictionary with the geometry information loaded from the
file.
"""
fhandle
=
open
(
file
=
filename
,
mode
=
'
r
'
)
beam
=
{
'
photon_energy
'
:
0.0
,
'
photon_energy_from
'
:
None
,
...
...
@@ -507,33 +467,34 @@ def load_crystfel_geometry(filename):
'
name
'
:
''
}
default_dim
=
[
'
ss
'
,
'
fs
'
]
default_dim
=
[
'
ss
'
,
'
fs
'
]
fhandle
=
open
(
file
=
filename
,
mode
=
'
r
'
)
fhlines
=
fhandle
.
readlines
()
for
line
in
fhlines
:
if
line
.
startswith
(
'
;
'
):
if
line
.
startswith
(
"
;
"
):
continue
line_without_comments
=
line
.
strip
().
split
(
sep
=
'
;
'
)[
0
]
line_items
=
re
.
split
(
pattern
=
'
([
\t
])
'
,
string
=
line_without_comments
)
line_items
=
[
item
for
item
in
line_items
if
item
not
in
(
''
,
'
'
,
'
\t
'
)
item
for
item
in
line_items
if
item
not
in
(
''
,
'
'
,
'
\t
'
)
]
if
len
(
s
=
line_items
)
<
3
:
if
len
(
line_items
)
<
3
:
continue
value
=
''
.
join
(
line_items
[
2
:])
if
line_items
[
1
]
!=
'
=
'
:
continue
path
=
re
.
split
(
'
(/)
'
,
line_items
[
0
])
path
=
[
item
for
item
in
path
if
item
not
in
'
/
'
]
if
len
(
s
=
path
)
<
2
:
if
len
(
path
)
<
2
:
_parse_toplevel
(
key
=
line_items
[
0
],
value
=
value
,
...
...
@@ -545,9 +506,7 @@ def load_crystfel_geometry(filename):
curr_bad
=
None
curr_panel
=
None
if
path
[
0
].
startswith
(
'
bad
'
):
if
path
[
0
].
startswith
(
"
bad
"
):
if
path
[
0
]
in
detector
[
'
bad
'
]:
curr_bad
=
detector
[
'
bad
'
][
path
[
0
]]
else
:
...
...
@@ -555,7 +514,6 @@ def load_crystfel_geometry(filename):
detector
[
'
bad
'
][
path
[
0
]]
=
curr_bad
else
:
if
path
[
0
]
in
detector
[
'
panels
'
]:
curr_panel
=
detector
[
'
panels
'
][
path
[
0
]]
else
:
...
...
@@ -579,9 +537,7 @@ def load_crystfel_geometry(filename):
raise
RuntimeError
(
"
No panel descriptions in geometry file.
"
)
num_placeholders_in_panels
=
None
for
panel
in
detector
[
'
panels
'
].
values
():
if
panel
[
'
dim_structure
'
]
is
not
None
:
curr_num_placeholders
=
panel
[
'
dim_structure
'
].
values
().
count
(
'
%
'
)
else
:
...
...
@@ -592,14 +548,12 @@ def load_crystfel_geometry(filename):
else
:
if
curr_num_placeholders
!=
num_placeholders_in_panels
:
raise
RuntimeError
(
'
All panels
\'
data and mask entries must have the same
'
'
number of placeholders.
'
"
All panels
\'
data and mask entries must have the same
"
"
number of placeholders.
"
)
num_placeholders_in_masks
=
None
for
panel
in
detector
[
'
panels
'
].
values
():
if
panel
[
'
mask
'
]
is
not
None
:
curr_num_placeholders
=
panel
[
'
mask
'
].
count
(
'
%
'
)
else
:
...
...
@@ -610,50 +564,50 @@ def load_crystfel_geometry(filename):
else
:
if
curr_num_placeholders
!=
num_placeholders_in_masks
:
raise
RuntimeError
(
'
All panels
\'
data and mask entries must have the same
'
'
number of placeholders.
'
"
All panels
\'
data and mask entries must have the same
"
"
number of placeholders.
"
)
if
num_placeholders_in_masks
>
num_placeholders_in_panels
:
raise
RuntimeError
(
'
Number of placeholders in mask cannot be larger the number
'
'
than for data.
'
"
Number of placeholders in mask cannot be larger the number
"
"
than for data.
"
)
dim_length
=
None
for
panel
in
detector
[
'
panels
'
].
values
():
if
panel
[
'
dim_structure
'
]
is
None
:
panel
[
'
dim_structure
'
]
=
copy
.
deepcopy
(
default_dim
)
found_ss
=
False
found_fs
=
False
found_placeholder
=
False
for
entry
in
panel
[
'
dim_structure
'
]:
if
entry
is
None
:
raise
RuntimeError
(
'
Not all dim entries are defined for all panels.
'
"
Not all dim entries are defined for all panels.
"
)
elif
entry
==
'
ss
'
:
if
found_ss
is
True
:
raise
RuntimeError
(
'
Only one slow scan dim coordinate is allowed.
'
"
Only one slow scan dim coordinate is allowed.
"
)
else
:
found_ss
=
True
elif
entry
==
'
fs
'
:
if
found_fs
is
True
:
raise
RuntimeError
(
'
Only one fast scan dim coordinate is allowed.
'
"
Only one fast scan dim coordinate is allowed.
"
)
else
:
found_fs
=
True
elif
entry
==
'
%
'
:
if
found_placeholder
is
True
:
raise
RuntimeError
(
'
Only one placeholder dim coordinate is allowed.
'
"
Only one placeholder dim coordinate is allowed.
"
)
else
:
found_placeholder
=
True
...
...
@@ -662,68 +616,67 @@ def load_crystfel_geometry(filename):
dim_length
=
len
(
panel
[
'
dim_structure
'
])
elif
dim_length
!=
len
(
panel
[
'
dim_structure
'
]):
raise
RuntimeError
(
'
Number of dim coordinates must be the same for all panels.
'
"
Number of dim coordinates must be the same for all panels.
"
)
if
dim_length
==
1
:
raise
RuntimeError
(
'
Number of dim coordinates must be at least two.
'
"
Number of dim coordinates must be at least two.
"
)
for
panel
in
detector
[
'
panels
'
].
values
():
if
panel
[
'
origin_min_fs
'
]
<
0
:
raise
RuntimeError
(
'
Please specify the minimum fs coordinate for
'
'
panel {}.
'
.
format
(
panel
[
'
name
'
])
"
Please specify the minimum fs coordinate for
"
"
panel {}.
"
.
format
(
panel
[
'
name
'
])
)
if
panel
[
'
origin_max_fs
'
]
<
0
:
raise
RuntimeError
(
'
Please specify the maximum fs coordinate for
'
'
panel {}.
'
.
format
(
panel
[
'
name
'
])
"
Please specify the maximum fs coordinate for
"
"
panel {}.
"
.
format
(
panel
[
'
name
'
])
)
if
panel
[
'
origin_min_ss
'
]
<
0
:
raise
RuntimeError
(
'
Please specify the minimum ss coordinate for
'
'
panel {}.
'
.
format
(
panel
[
'
name
'
])
"
Please specify the minimum ss coordinate for
"
"
panel {}.
"
.
format
(
panel
[
'
name
'
])
)
if
panel
[
'
origin_max_ss
'
]
<
0
:
raise
RuntimeError
(
'
Please specify the maximum ss coordinate for
'
'
panel {}.
'
.
format
(
panel
[
'
name
'
])
"
Please specify the maximum ss coordinate for
"
"
panel {}.
"
.
format
(
panel
[
'
name
'
])
)
if
panel
[
'
cnx
'
]
is
None
:
raise
RuntimeError
(
'
Please specify the corner X coordinate for
'
'
panel {}.
'
.
format
(
panel
[
'
name
'
])
"
Please specify the corner X coordinate for
"
"
panel {}.
"
.
format
(
panel
[
'
name
'
])
)
if
panel
[
'
clen
'
]
is
None
and
panel
[
'
clen_from
'
]
is
None
:
raise
RuntimeError
(
'
Please specify the camera length for
'
'
panel {}.
'
.
format
(
panel
[
'
name
'
])
"
Please specify the camera length for
"
"
panel {}.
"
.
format
(
panel
[
'
name
'
])
)
if
panel
[
'
res
'
]
<
0
:
raise
RuntimeError
(
'
Please specify the resolution or
'
'
panel {}.
'
.
format
(
panel
[
'
name
'
])
"
Please specify the resolution or
"
"
panel {}.
"
.
format
(
panel
[
'
name
'
])
)
if
panel
[
'
adu_per_eV
'
]
is
None
and
panel
[
'
adu_per_photon
'
]
is
None
:
raise
RuntimeError
(
'
Please specify either adu_per_eV or adu_per_photon
'
'
for panel {}.
'
.
format
(
panel
[
'
name
'
])
"
Please specify either adu_per_eV or adu_per_photon
"
"
for panel {}.
"
.
format
(
panel
[
'
name
'
])
)
if
panel
[
'
clen_for_centering
'
]
is
None
and
panel
[
'
rail_x
'
]
is
not
None
:
raise
RuntimeError
(
'
You must specify clen_for_centering if you specify the
'
'
rail direction (panel {})
'
.
format
(
panel
[
'
name
'
])
"
You must specify clen_for_centering if you specify the
"
"
rail direction (panel {})
"
.
format
(
panel
[
'
name
'
])
)
if
panel
[
'
rail_x
'
]
is
None
:
...
...
@@ -740,37 +693,34 @@ def load_crystfel_geometry(filename):
for
bad_region
in
detector
[
'
bad
'
].
values
():
if
bad_region
[
'
is_fsss
'
]
==
99
:
raise
RuntimeError
(
'
Please specify the coordinate ranges for bad
'
'
region {}.
'
.
format
(
bad_region
[
'
name
'
])
"
Please specify the coordinate ranges for bad
"
"
region {}.
"
.
format
(
bad_region
[
'
name
'
])
)
for
group
in
detector
[
'
rigid_groups
'
]:
for
name
in
detector
[
'
rigid_groups
'
][
group
]:
if
name
not
in
detector
[
'
panels
'
]:
raise
RuntimeError
(
'
Cannot add panel to rigid_group. Panel not
'
'
found: {}
'
.
format
(
name
)
"
Cannot add panel to rigid_group. Panel not
"
"
found: {}
"
.
format
(
name
)
)
for
group_collection
in
detector
[
'
rigid_group_collections
'
]:
for
name
in
detector
[
'
rigid_group_collections
'
][
group_collection
]:
if
name
not
in
detector
[
'
rigid_groups
'
]:
raise
RuntimeError
(
'
Cannot add rigid_group to collection. Rigid group
'
'
not found: {}
'
.
format
(
name
)
"
Cannot add rigid_group to collection. Rigid group
"
"
not found: {}
"
.
format
(
name
)
)
for
panel
in
detector
[
'
panels
'
].
values
():
d__
=
panel
[
'
fsx
'
]
*
panel
[
'
ssy
'
]
-
panel
[
'
ssx
'
]
*
panel
[
'
fsy
'
]
if
d__
==
0.0
:
raise
RuntimeError
(
'
Panel {} transformation is singluar.
'
)
panel
[
'
xfs
'
]
=
panel
[
'
ssy
'
]
/
d__
panel
[
'
yfs
'
]
=
panel
[
'
ssx
'
]
/
d__
panel
[
'
xss
'
]
=
panel
[
'
fsy
'
]
/
d__
panel
[
'
yss
'
]
=
panel
[
'
fsx
'
]
/
d__
d
=
panel
[
'
fsx
'
]
*
panel
[
'
ssy
'
]
-
panel
[
'
ssx
'
]
*
panel
[
'
fsy
'
]
if
d
==
0.0
:
raise
RuntimeError
(
"
Panel {} transformation is singluar.
"
)
panel
[
'
xfs
'
]
=
panel
[
'
ssy
'
]
/
d
panel
[
'
yfs
'
]
=
panel
[
'
ssx
'
]
/
d
panel
[
'
xss
'
]
=
panel
[
'
fsy
'
]
/
d
panel
[
'
yss
'
]
=
panel
[
'
fsx
'
]
/
d
_find_min_max_d
(
detector
)
fhandle
.
close
()
...
...
This diff is collapsed.
Click to expand it.
geometry_utils.py
+
109
−
101
View file @
836abf74
...
...
@@ -15,8 +15,8 @@
"""
Geometry utilities.
Functions that load, manipulate and apply geometry information to
detector
pixel data.
Functions that load, manipulate and apply geometry information to
detector
pixel data.
"""
from
__future__
import
(
absolute_import
,
division
,
print_function
,
...
...
@@ -27,63 +27,58 @@ import collections
import
numpy
PixelMaps
=
collections
.
namedtuple
(
'
PixelMaps
'
,
[
'
x
'
,
'
y
'
,
'
r
'
])
'''
A namedtuple used for pixel maps objects.
Pixel maps are arrays of the same shape of the data whose geometry they
describe. Each cell in the array holds the coordinate, in the reference system
of the physical detector, of the corresponding pixel in the data array.
The first two fields store the pixel maps for the x coordinate
and the y coordinate respectively. The third field is instead a pixel map
storing the distance of each pixel in the data array from the center of the
reference system.
'''
def
compute_pixel_maps
(
geometry
):
"""
Compute pixel maps from a CrystFEL geometry object.
"""
Compute pixel maps from a CrystFEL geometry object.
Take as input a CrystFEL-style geometry object (A dictionary
returned by the function load_crystfel_geometry function in the
crystfel_utils module) and return a PixelMap tuple . The origin
the
reference system used by the pixel maps is set at the beam
interaction
point.
crystfel_utils module) and return a PixelMap tuple . The origin
the
reference system used by the pixel maps is set at the beam
interaction
point.
Args:
geometry (dict): A CrystFEL geometry object (A dictionary returned by
the :obj:`cfelpyutils.crystfel_utils.load_crystfel_geometry`
geometry (dict): A CrystFEL geometry object (A dictionary
returned by the
:obj:`cfelpyutils.crystfel_utils.load_crystfel_geometry`
function).
Returns:
PixelMaps: a PixelMaps tuple.
Tuple[ndarray, ndarray, ndarray] A tuple containing the pixel
maps. The first two fields, named
"
x
"
and
"
y
"
respectively,
store the pixel maps for the x coordinate and the y coordinate.
The third field, named
"
r
"
, is instead a pixel map storing the
distance of each pixel in the data array from the center of the
reference system.
"""
# Determine the max fs and ss in the geometry object.
max_slab_fs
=
numpy
.
array
(
[
geometry
[
'
panels
'
][
k
][
'
max_fs
'
]
for
k
in
geometry
[
'
panels
'
]]
).
max
()
max_slab_ss
=
numpy
.
array
(
[
geometry
[
'
panels
'
][
k
][
'
max_ss
'
]
for
k
in
geometry
[
'
panels
'
]]
).
max
()
# Create the empty arrays that will store the pixel maps.
max_slab_fs
=
numpy
.
array
([
geometry
[
'
panels
'
][
k
][
'
max_fs
'
]
for
k
in
geometry
[
'
panels
'
]
]).
max
()
max_slab_ss
=
numpy
.
array
([
geometry
[
'
panels
'
][
k
][
'
max_ss
'
]
for
k
in
geometry
[
'
panels
'
]
]).
max
()
# Create empty arrays, of the same size of the input data, that
# will store the x and y pixel maps.
x_map
=
numpy
.
zeros
(
shape
=
(
max_slab_ss
+
1
,
max_slab_fs
+
1
),
dtype
=
numpy
.
float32
)
y_map
=
numpy
.
zeros
(
shape
=
(
max_slab_ss
+
1
,
max_slab_fs
+
1
),
dtype
=
numpy
.
float32
)
# Iterate over the panels.
# Iterate over the panels. For each panel, determine the pixel
# indeces, then compute the x,y vectors using a comples notation.
for
pan
in
geometry
[
'
panels
'
]:
# Determine the pixel indexes for the current panel.
i
,
j
=
numpy
.
meshgrid
(
numpy
.
arange
(
geometry
[
'
panels
'
][
pan
][
'
max_ss
'
]
-
...
...
@@ -98,46 +93,43 @@ def compute_pixel_maps(geometry):
indexing
=
'
ij
'
)
# Compute the x,y vectors, using the complex notation.
d_x
=
(
geometry
[
'
panels
'
][
pan
][
'
fsy
'
]
+
1J
*
geometry
[
'
panels
'
][
pan
][
'
fsx
'
]
)
d_y
=
(
geometry
[
'
panels
'
][
pan
][
'
ssy
'
]
+
1J
*
geometry
[
'
panels
'
][
pan
][
'
ssx
'
]
)
r_0
=
(
geometry
[
'
panels
'
][
pan
][
'
cny
'
]
+
1J
*
geometry
[
'
panels
'
][
pan
][
'
cnx
'
]
)
d_x
=
(
geometry
[
'
panels
'
][
pan
][
'
fsy
'
]
+
1J
*
geometry
[
'
panels
'
][
pan
][
'
fsx
'
])
d_y
=
(
geometry
[
'
panels
'
][
pan
][
'
ssy
'
]
+
1J
*
geometry
[
'
panels
'
][
pan
][
'
ssx
'
])
r_0
=
(
geometry
[
'
panels
'
][
pan
][
'
cny
'
]
+
1J
*
geometry
[
'
panels
'
][
pan
][
'
cnx
'
])
cmplx
=
i
*
d_y
+
j
*
d_x
+
r_0
# Compute values for the x and y maps.
y_map
[
x_map
[
geometry
[
'
panels
'
][
pan
][
'
min_ss
'
]:
geometry
[
'
panels
'
][
pan
][
'
max_ss
'
]
+
1
,
geometry
[
'
panels
'
][
pan
][
'
min_fs
'
]:
geometry
[
'
panels
'
][
pan
][
'
max_fs
'
]
+
1
]
=
cmplx
.
real
]
=
cmplx
.
imag
x
_map
[
y
_map
[
geometry
[
'
panels
'
][
pan
][
'
min_ss
'
]:
geometry
[
'
panels
'
][
pan
][
'
max_ss
'
]
+
1
,
geometry
[
'
panels
'
][
pan
][
'
min_fs
'
]:
geometry
[
'
panels
'
][
pan
][
'
max_fs
'
]
+
1
]
=
cmplx
.
imag
]
=
cmplx
.
real
#
C
ompute the values for the radius pixel map.
#
Finally, c
ompute the values for the radius pixel map.
r_map
=
numpy
.
sqrt
(
numpy
.
square
(
x_map
)
+
numpy
.
square
(
y_map
))
# Return the pixel maps as a tuple.
PixelMaps
=
collections
.
namedtuple
(
typename
=
'
PixelMaps
'
,
field_names
=
[
'
x
'
,
'
y
'
,
'
r
'
]
)
return
PixelMaps
(
x_map
,
y_map
,
r_map
)
def
apply_pixel_maps
(
data
,
pixel_maps
,
output_array
=
None
):
"""
Apply geometry in pixel map format to the input data.
"""
Apply geometry in pixel map format to the input data.
Turn an array of detector pixel values into an array
containing a representation of the physical layout of the detector.
...
...
@@ -150,20 +142,19 @@ def apply_pixel_maps(data, pixel_maps, output_array=None):
pixel_maps (PixelMaps): a pixelmap tuple, as returned by the
:obj:`compute_pixel_maps` function in this module.
output_array (Optional[ndarray]): a preallocated array (of
dtype
numpy.float32) to store the function output. If
provided, this
array will be filled by the function and
returned to the user.
If not provided, the function
will create a new array
automatically and return it to the
user. Defaults to None
(No array provided).
output_array (Optional[ndarray]): a preallocated array (of
dtype
numpy.float32) to store the function output. If
provided, this
array will be filled by the function and
and returned to the user.
If not provided, the function
will create a new array
automatically and return it to the
user. Defaults to None
(No array provided).
Returns:
ndarray: a numpy.float32 array containing the geometry
information
applied to the input data (i.e.: a
physical
representation
of the
layout of the detector).
ndarray: a numpy.float32 array containing the geometry
information
applied to the input data (i.e.: a representation
of the physical
layout of the detector).
"""
# If no output array was provided, create one.
if
output_array
is
None
:
output_array
=
numpy
.
zeros
(
...
...
@@ -171,70 +162,83 @@ def apply_pixel_maps(data, pixel_maps, output_array=None):
dtype
=
numpy
.
float32
)
# Apply the pixel map geometry information the data.
# Apply the pixel map geometry information the data, then return
# the resulting array.
output_array
[
pixel_maps
.
y
,
pixel_maps
.
x
]
=
data
.
ravel
()
# Return the output array.
return
output_array
def
compute_minimum_array_size
(
pixel_maps
):
"""
Compute the minimum size of an array that can store the applied geometry.
Compute the minimum size of an array that can store the applied
geometry.
Return the minimum size of an array that can store data on which the
geometry information described by the pixel maps has been applied.
Return the minimum size of an array that can store data on which
the geometry information described by the pixel maps has been
applied.
The returned array shape is big enough to display all the input
pixel
values in the reference system of the physical detector. The
array is
supposed to be centered at the center of the reference
system of the
detector (i.e: the beam interaction point).
The returned array shape is big enough to display all the input
pixel
values in the reference system of the physical detector. The
array is
supposed to be centered at the center of the reference
system of the
detector (i.e: the beam interaction point).
Args:
pixel_maps (PixelMaps): a PixelMaps tuple, as returned by the
:obj:`compute_pixel_maps` function in this module.
Tuple[ndarray, ndarray, ndarray]: a named tuple containing the
pixel maps. The first two fields,
"
x
"
and
"
y
"
, should store
the pixel maps for the x coordinateand the y coordinate.
The third,
"
r
"
, should instead store the distance of each
pixel in the data array from the center of the reference
system.
Returns:
tuple: numpy shape-like tuple storing the minimum array size.
Tuple[int, int]: a numpy-style shape tuple storing the minimum
array size.
"""
# Recover the x and y pixel maps.
# Find the largest absolute values of x and y in the maps. Since
# the returned array is centered on the origin, the minimum array
# size along a certain axis must be at least twice the maximum
# value for that axis. 2 pixels are added for good measure.
x_map
,
y_map
=
pixel_maps
.
x
,
pixel_maps
.
x
.
y
y_minimum
=
2
*
int
(
max
(
abs
(
y_map
.
max
()),
abs
(
y_map
.
min
())))
+
2
x_minimum
=
2
*
int
(
max
(
abs
(
x_map
.
max
()),
abs
(
x_map
.
min
())))
+
2
# Find the largest absolute values of x and y in the maps.
y_largest
=
2
*
int
(
max
(
abs
(
y_map
.
max
()),
abs
(
y_map
.
min
())))
+
2
x_largest
=
2
*
int
(
max
(
abs
(
x_map
.
max
()),
abs
(
x_map
.
min
())))
+
2
# Return a tuple with the computed shape.
return
(
y_largest
,
x_largest
)
# Return a numpy-style tuple with the computed shape.
return
(
y_minimum
,
x_minimum
)
def
adjust_pixel_maps_for_pyqtgraph
(
pixel_maps
):
"""
Adjust pixel maps for visualization of the data in a pyqtgraph widget.
Adjust pixel maps for visualization of the data in a pyqtgraph
widget.
The adjusted maps can be used for a Pyqtgraph ImageView widget.
Essentially, the origin of the reference system is moved to the
top-left of the image.
Args:
pixel_maps (PixelMaps): pixel maps, as returned by the
:obj:`compute_pixel_maps` function in this module.
Tuple[ndarray, ndarray, ndarray]: a named tuple containing the
pixel maps. The first two fields,
"
x
"
and
"
y
"
, should store the
pixel maps for the x coordinateand the y coordinate. The third,
"
r
"
, should instead store the distance of each pixel in the
data array from the center of the reference system.
Returns:
PixelMaps: a PixelMaps tuple containing the ajusted pixel maps for
the x and y coordinates in the first two fields, and the
value None in the third.
Tuple[ndarray, ndarray] A tuple containing the pixel
maps. The first two fields, named
"
x
"
and
"
y
"
respectively,
store the pixel maps for the x coordinate and the y
coordinate. The third field, named
"
r
"
, is instead a pixel
map storing the distance of each pixel in the data array
from the center of the reference system.
"""
# Compute the minimum image shape needed to represent the coordinates.
# Essentially, the origin of the reference system needs to be
# moved from the beam position to the top-left of the image that
# will be displayed. First, compute the size of the array used to
# display the data, then use this information to estimate the
# magnitude of the shift that needs to be applied to the origin of
# the system.
min_shape
=
compute_minimum_array_size
(
pixel_maps
)
# Convert the old pixemap values to the new pixelmap values.
new_x_map
=
numpy
.
array
(
object
=
pixel_maps
.
x
,
dtype
=
numpy
.
int
...
...
@@ -245,4 +249,8 @@ def adjust_pixel_maps_for_pyqtgraph(pixel_maps):
dtype
=
numpy
.
int
)
+
min_shape
[
0
]
//
2
-
1
return
PixelMaps
(
new_x_map
,
new_y_map
,
None
)
PixelMapsForIV
=
collections
.
namedtuple
(
typename
=
'
PixelMapsForIV
'
,
field_names
=
[
'
x
'
,
'
y
'
]
)
return
PixelMapsForIV
(
new_x_map
,
new_y_map
)
This diff is collapsed.
Click to expand it.
parameter_utils.py
+
25
−
45
View file @
836abf74
...
...
@@ -24,36 +24,35 @@ import ast
def
_parsing_error
(
section
,
option
):
# Raise an exception after a parsing error.
raise
RuntimeError
(
'
Error parsing parameter {0} in section [{1}]. Make sure that the
'
'
syntax is correct: list elements must be separated by commas and
'
'
dict entries must contain the colon symbol. Strings must be quoted,
'
'
even in lists and dicts.
'
.
format
(
option
,
section
)
"
Error parsing parameter {0} in section [{1}]. Make sure that the
"
"
syntax is correct: list elements must be separated by commas and
"
"
dict entries must contain the colon symbol. Strings must be quoted,
"
"
even in lists and dicts.
"
.
format
(
option
,
section
)
)
def
convert_parameters
(
config_dict
):
"""
Convert strings in parameter dictionaries to the corrent data type.
Read a parameter dictionary returned by the ConfigParser python
module,
and convert each entry in an object of the corresponding
type,
without changing the structure of the dictionary.
Read a parameter dictionary returned by the ConfigParser python
module,
and convert each entry in an object of the corresponding
type,
without changing the structure of the dictionary.
Try to convert each entry in the dictionary according to the following
rules. The first rule that applies to the entry determines the type.
Try to convert each entry in the dictionary according to the
following rules. The first rule that applies to the entry
determines the type.
- If the entry starts and ends with a single quote or double quote,
leave it as a string.
- If the entry starts and ends with a square bracket, convert it to a list.
- If the entry starts and ends with a square bracket, convert it to
a list.
- If the entry starts and ends with a curly braces, convert it to a
dictionary or a set.
- If the entry is the word None, without quotes, convert it to NoneType.
- If the entry is the word False, without quotes, convert it to a boolean
False.
- If the entry is the word None, without quotes, convert it to
NoneType.
- If the entry is the word False, without quotes, convert it to a
boolean False.
- If the entry is the word True, without quotes, convert it to a
boolean True.
- If none of the previous options match the content of the entry,
...
...
@@ -77,26 +76,24 @@ def convert_parameters(config_dict):
Raises:
RuntimeError: if an entry cannot be converted to any supported type.
RuntimeError: if an entry cannot be converted to any supported
type.
"""
# Create the dictionary that will be returned.
monitor_params
=
{}
# Iterate over the sections in the dictionary (first level).
# Iterate over the sections in the dictionary (first level in the
# configuration file). Add the section to the dictionary that will
# be returned.
for
section
in
config_dict
.
keys
():
# Add the section to the dictionary that will be returned.
monitor_params
[
section
]
=
{}
# Iterate over the content of the section (second level in the
# configuratio).
# Iterate then over the content of the section (second level in
# the configuration file). Get each option in turn and perform
# all the checks. If all checks fail, call the parsing_error
# function.
for
option
in
config_dict
[
'
section
'
].
keys
():
# Get the option from the dictionary.
recovered_option
=
config_dict
[
'
section
'
]
# Check if the option is a string delimited by single quotes.
if
(
recovered_option
.
startswith
(
"'"
)
and
recovered_option
.
endswith
(
"'"
)
...
...
@@ -104,7 +101,6 @@ def convert_parameters(config_dict):
monitor_params
[
section
][
option
]
=
recovered_option
[
1
:
-
1
]
continue
# Check if the option is a string delimited by double quotes.
if
(
recovered_option
.
startswith
(
'"'
)
and
recovered_option
.
endswith
(
'"'
)
...
...
@@ -112,8 +108,6 @@ def convert_parameters(config_dict):
monitor_params
[
section
][
option
]
=
recovered_option
[
1
:
-
1
]
continue
# Check if the option is a list. If it is, interpret it using the
# literal_eval function.
if
(
recovered_option
.
startswith
(
"
[
"
)
and
recovered_option
.
endswith
(
"
]
"
)
...
...
@@ -126,8 +120,6 @@ def convert_parameters(config_dict):
except
(
SyntaxError
,
ValueError
):
_parsing_error
(
section
,
option
)
# Check if the option is a dictionary or a set. If it is,
# interpret it using the literal_eval function.
if
(
recovered_option
.
startswith
(
"
{
"
)
and
recovered_option
.
endswith
(
"
}
"
)
...
...
@@ -140,40 +132,28 @@ def convert_parameters(config_dict):
except
(
SyntaxError
,
ValueError
):
_parsing_error
(
section
,
option
)
# Check if the option is the special string 'None' (without
# quotes).
if
recovered_option
==
'
None
'
:
monitor_params
[
section
][
option
]
=
None
continue
# Check if the option is the special string 'False' (without
# quotes).
if
recovered_option
==
'
False
'
:
monitor_params
[
section
][
option
]
=
False
continue
# Check if the option is the special string 'True' (without
# quotes).
if
recovered_option
==
'
True
'
:
monitor_params
[
section
][
option
]
=
True
continue
# Check if the option is an int by trying to convert it to an int.
try
:
monitor_params
[
section
][
option
]
=
int
(
recovered_option
)
continue
except
ValueError
:
# If the conversion to int failed, try to convert it to a
# float.
try
:
monitor_params
[
section
][
option
]
=
float
(
recovered_option
)
continue
except
ValueError
:
# If the conversion to float also failed, return a parsing
# error.
_parsing_error
(
section
,
option
)
# Returned the converted dictionary.
return
monitor_params
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
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!
Save comment
Cancel
Please
register
or
sign in
to comment