Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
Superflat_scripts
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Iterations
Wiki
Requirements
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Test cases
Artifacts
Deploy
Releases
Package registry
Container registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Issue analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
OPTIQUE
LEAPS
Superflat_scripts
Commits
de5e78db
Commit
de5e78db
authored
Sep 26, 2023
by
Francois POLACK
Browse files
Options
Downloads
Patches
Plain Diff
Feature: nexus_Save : save the height map under NeXus format
fix issues with scales
parent
773080b7
No related branches found
No related tags found
No related merge requests found
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
heightmap.py
+105
-13
105 additions, 13 deletions
heightmap.py
with
105 additions
and
13 deletions
heightmap.py
+
105
−
13
View file @
de5e78db
...
...
@@ -41,6 +41,8 @@ import ZygoDatx
from
processing
import
*
from
activefigure
import
*
import
pickle
from
pathlib
import
Path
from
nexusformat.nexus.tree
import
*
class
HeightMap
(
object
):
'''
! @brief The HeightMap object-
...
...
@@ -87,8 +89,8 @@ class HeightMap(object):
self
.
dzdx
=
None
## slope dze/dy
self
.
dzdy
=
None
## the fit parameter (rx, pitch, ry, roll,
z
0) [unused]
self
.
fitpars
=
None
## the fit parameter (
rot,
rx, pitch, ry, roll,
Z
0) [unused]
self
.
fitpar
am
s
=
None
## slope rms CPSD
self
.
srms
=
None
...
...
@@ -102,9 +104,10 @@ class HeightMap(object):
self
.
angle
=
None
self
.
Cx
=
None
self
.
Cy
=
None
## fiducial list and sample drawing defined 25/09/2023
self
.
fiducial_list
=
None
self
.
reference_point
=
None
self
.
sample_drawing
=
None
def
read_Zygofile
(
self
,
filename
=
''
,
origin
=
'
zero
'
):
"""
! Reads a Zygo datafile in .datx, .dat or xyz format, and loads it into the HeightMap object.
...
...
@@ -204,8 +207,8 @@ class HeightMap(object):
"""
size
=
(
self
.
pixel
[
0
]
*
self
.
z
.
shape
[
1
],
self
.
pixel
[
1
]
*
self
.
z
.
shape
[
0
])
org
=
(
(
self
.
pixel
[
0
]
+
offset
[
0
]
)
*
self
.
origin
[
0
],
(
self
.
pixel
[
1
]
+
offset
[
1
]
*
self
.
origin
[
1
]))
# org corrigé le 25/09/23 - FP
org
=
(
self
.
pixel
[
0
]
*
(
offset
[
0
]
+
self
.
origin
[
0
]
)
,
self
.
pixel
[
1
]
*
(
offset
[
1
]
+
self
.
origin
[
1
]))
self
.
x
=
np
.
linspace
(
org
[
0
],
org
[
0
]
+
size
[
0
],
num
=
self
.
z
.
shape
[
1
],
endpoint
=
False
)
self
.
y
=
np
.
linspace
(
org
[
1
],
org
[
1
]
+
size
[
1
],
num
=
self
.
z
.
shape
[
0
],
endpoint
=
False
)
...
...
@@ -274,8 +277,8 @@ class HeightMap(object):
and assign the residuals of the fit to the height error array (HeightMap.ze)
"""
print
(
"
\n
Remove best toroid with axis orientation {:.3f}mrad=
"
.
format
(
1e3
*
rot
))
(
fit
param
s
,
self
.
ze
)
=
fit_toroid
(
self
.
x
,
self
.
y
,
self
.
z
,
rot
)
(
Z0
,
pitch
,
roll
,
x2
,
y2
)
=
fit
param
s
(
fit
coeff
s
,
self
.
ze
)
=
fit_toroid
(
self
.
x
,
self
.
y
,
self
.
z
,
rot
)
(
Z0
,
pitch
,
roll
,
x2
,
y2
)
=
fit
coeff
s
self
.
angle
=
rot
# these are the removed curvatures = 1/R
self
.
Cx
=
2
*
x2
...
...
@@ -289,7 +292,8 @@ class HeightMap(object):
rx
=
0.5
/
x2
except
ZeroDivisionError
:
rx
=
math
.
inf
print
(
"
debug: fit params:
"
,
fitparams
)
self
.
fitparams
=
(
rot
,
rx
,
pitch
,
ry
,
roll
,
Z0
)
print
(
"
debug: fit params:
"
,
fitcoeffs
)
print
(
"
rx = {:.3e}m, pitch = {:.4e}rad, ry = {:.3e}m, roll = {:.4e}rad, Z0 = {:.3e}m
"
.
format
(
rx
,
pitch
,
ry
,
roll
,
Z0
))
self
.
detrend
=
'
tore
'
...
...
@@ -637,9 +641,97 @@ class HeightMap(object):
plt
.
ylabel
(
'
y (mm)
'
)
plt
.
title
(
"
testplot
"
)
def
nexus_save
(
self
,
filepath
):
fname
=
Path
(
filepath
).
with_name
(
Path
(
filepath
).
stem
+
'
.nxs
'
)
print
(
"
creating file
"
,
fname
)
# print("flipped axes", self.flipROI) WARNING if ROI is flipped the reference frame of rawZ and z are different
#define the absolute coordinates
xpix
=
self
.
pixel
[
0
]
ypix
=-
self
.
pixel
[
1
]
# set the coordinate origin in pixel units
if
self
.
fiducial_list
!=
None
and
self
.
reference_point
!=
None
:
refpoint
=
self
.
fiducial_list
[
self
.
reference_point
[
'
name
'
]]
# this is true if ref point is in meter and fiducials in pixels
origin_x
=
refpoint
[
'
coordinates
'
][
0
]
-
self
.
reference_point
[
'
coordinates
'
][
0
]
/
xpix
origin_y
=
refpoint
[
'
coordinates
'
][
1
]
-
self
.
reference_point
[
'
coordinates
'
][
1
]
/
ypix
print
(
'
origin =(
'
,
origin_x
,
'
,
'
,
origin_y
,
'
)
'
)
print
(
'
ROI origin =(
'
,
self
.
ROIorigin
[
0
],
'
,
'
,
self
.
ROIorigin
[
1
],
'
)
'
)
else
:
origin_x
=
0
origin_y
=
rawZ
.
shape
[
0
]
-
1
# Create raw_data
xraw
=
np
.
linspace
(
-
origin_x
*
xpix
,(
self
.
rawZ
.
shape
[
1
]
-
origin_x
)
*
xpix
,
num
=
self
.
rawZ
.
shape
[
1
],
endpoint
=
False
)
yraw
=
np
.
linspace
(
-
origin_y
*
ypix
,(
self
.
rawZ
.
shape
[
0
]
-
origin_y
)
*
ypix
,
num
=
self
.
rawZ
.
shape
[
0
],
endpoint
=
False
)
x
=
NXfield
(
xraw
,
name
=
'
x
'
,
unit
=
'
meter
'
)
y
=
NXfield
(
yraw
,
name
=
'
y
'
,
unit
=
'
meter
'
)
rawdata
=
NXdata
(
NXfield
(
self
.
z
,
name
=
'
height
'
,
unit
=
'
meter
'
),[
x
,
y
],
name
=
'
raw_data
'
)
#create detrended data group wit height and slope fields
height
=
NXfield
(
self
.
ze
,
name
=
'
height
'
,
unit
=
'
meter
'
)
xview
=
np
.
linspace
((
self
.
ROIorigin
[
0
]
-
origin_x
)
*
xpix
,(
self
.
ROIorigin
[
0
]
+
self
.
ROIsize
[
0
]
-
origin_x
)
*
xpix
,
num
=
self
.
z
.
shape
[
1
],
endpoint
=
False
)
yview
=
np
.
linspace
((
self
.
ROIorigin
[
1
]
-
origin_y
)
*
ypix
,(
self
.
ROIorigin
[
1
]
+
self
.
ROIsize
[
1
]
-
origin_y
)
*
ypix
,
num
=
self
.
z
.
shape
[
0
],
endpoint
=
False
)
x
=
NXfield
(
xview
,
name
=
'
x
'
,
unit
=
'
meter
'
)
y
=
NXfield
(
yview
,
name
=
'
y
'
,
unit
=
'
meter
'
)
slope_x
=
NXfield
(
self
.
dzdx
,
unit
=
'
radian
'
)
slope_y
=
NXfield
(
self
.
dzdy
,
unit
=
'
radian
'
)
detrended
=
NXdata
(
height
,[
x
,
y
],
slope_x
=
slope_x
,
slope_y
=
slope_y
,
name
=
'
detrended_data
'
)
#create the process group with detrending parameters and ROI definition
region
=
NXgroup
(
name
=
'
ROI
'
,
nxclass
=
'
NXregion
'
,
start
=
self
.
ROIorigin
,
count
=
self
.
ROIsize
)
region
.
region_type
=
NXattr
(
'
rectangular
'
)
process
=
NXprocess
(
region
)
process
.
program
=
NXattr
(
'
detrend
'
)
process
.
fit
=
NXattr
(
'
toroid
'
)
process
.
radius_x
=
NXfield
(
self
.
fitparams
[
1
],
unit
=
'
meter
'
)
process
.
radius_y
=
NXfield
(
self
.
fitparams
[
3
],
unit
=
'
meter
'
)
process
.
rotation
=
NXfield
(
self
.
fitparams
[
0
],
unit
=
'
meter
'
)
# the process.data group defining the process group will be a link. It cannot be set before the whole tree is created
#attach the process group to the detrended data group
detrended
.
process
=
process
#create the sample and instrument group
sample
=
NXsample
()
detector
=
NXdetector
(
pixel_size_x
=
NXfield
(
self
.
pixel
[
0
],
unit
=
'
meter
'
),
pixel_size_y
=
NXfield
(
self
.
pixel
[
1
],
unit
=
'
meter
'
))
instrument
=
NXinstrument
(
detector
)
#Create the measurement NXentry as complying to NXmetrology definition
entry
=
NXentry
(
detrended
,
rawdata
,
sample
,
instrument
,
name
=
'
measurement1
'
)
entry
.
definition
=
NXattr
(
'
NXmetrology
'
)
# add the data group as link to detrended group and set it as default
entry
.
data
=
NXlink
(
detrended
)
entry
.
data
.
set_default
()
# add a the source data to the process group as alink
process
.
data
=
NXlink
(
rawdata
)
#add a drawing in the sample group if defined
if
self
.
sample_drawing
!=
None
:
add_drawing
(
sample
,
self
.
sample_drawing
)
#add a fiducial group to the sample group
if
self
.
fiducial_list
!=
None
:
sample
.
fiducials
=
NXgroup
(
nxclass
=
'
NXfiducials
'
)
for
name
in
self
.
fiducial_list
:
fiducial
=
self
.
fiducial_list
[
name
]
coord
=
((
fiducial
[
'
coordinates
'
][
0
]
-
origin_x
)
*
xpix
,
(
fiducial
[
'
coordinates
'
][
1
]
-
origin_y
)
*
ypix
)
sample
.
fiducials
.
insert
(
NXfield
(
coord
,
name
=
name
))
#print(name, ': ', fiducial['mark'], fiducial['coordinates'][0]*self.pixel[0]*1.e3, fiducial['coordinates'][1]*self.pixel[1]*1.e3,'mm')
# erase the old file if any and write the NeXus tree to the file
if
Path
(
fname
).
exists
():
Path
(
fname
).
unlink
()
entry
.
save
(
fname
)
def
add_drawing
(
parent
,
filename
):
ext
=
Path
(
filename
).
suffix
if
ext
==
'
.svg
'
or
ext
==
'
.dxf
'
:
with
open
(
filename
,
'
r
'
)
as
file
:
text
=
file
.
read
()
parent
.
drawing
=
NXfield
(
text
)
elif
ext
==
'
.pdf
'
:
with
open
(
filename
,
'
rb
'
)
as
file
:
filedata
=
file
.
read
()
parent
.
drawing
=
NXfield
(
bytearray
(
filedata
),
dtype
=
'
uint8
'
)
else
:
print
(
"
Invalid drawing file extension:
"
,
ext
)
parent
.
drawing
.
format
=
NXattr
(
ext
)
# this function return a HeightMap object from a previously saved .hmap file
def
load
(
self
,
filepath
=
''
):
# this
module
function return
s
a HeightMap object from a previously saved .hmap file
def
load
(
filepath
=
''
):
if
not
Path
(
filepath
).
is_file
():
tkinter
.
Tk
().
withdraw
()
filepath
=
filedialog
.
askopenfilename
(
title
=
"
open a hmap file
"
,
filetypes
=
((
"
superflat hmap
"
,
"
*.hmap
"
),
(
"
all
"
,
"
*.*
"
)
)
)
...
...
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