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
56680e49
Commit
56680e49
authored
Nov 9, 2023
by
Francois POLACK
Browse files
Options
Downloads
Patches
Plain Diff
Feat: Graphic line interpolation of the curve added to the RMS slope graphs
parent
c84081ee
No related branches found
No related tags found
No related merge requests found
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
crmsfig.py
+215
-0
215 additions, 0 deletions
crmsfig.py
heightmap.py
+3
-1
3 additions, 1 deletion
heightmap.py
line-48.png
+0
-0
0 additions, 0 deletions
line-48.png
with
218 additions
and
1 deletion
crmsfig.py
0 → 100644
+
215
−
0
View file @
56680e49
# -*- coding: utf-8 -*-
'''
This file is part of the Superflat Evaluation Toolkit
Evaluation of surface height data based on PSD tools
This file defines the ActiveFigure class, which is the main storage element of surface height measurements
'''
__author__
=
"
François Polack
"
__copyright__
=
"
2022, Superflat-PCP project
"
__email__
=
"
superflat-pcp@synchrotron-soleil.fr
"
__version__
=
"
0.1.0
"
import
numpy
as
np
import
warnings
import
matplotlib.pyplot
as
plt
import
matplotlib.figure
as
fig
# from matplotlib.patches import PathPatch
# from matplotlib.path import Path
from
matplotlib.backend_tools
import
ToolBase
,
RubberbandBase
,
ToolToggleBase
#, ToolCursorPosition #
class
LineMode
(
ToolToggleBase
):
from
pathlib
import
Path
default_keymap
=
(
'
ctrl+L
'
,
'
ctrl+l
'
)
description
=
"
line drawing mode
"
image
=
str
(
Path
(
__file__
).
parent
)
+
"
/line-48.png
"
def
__init__
(
self
,
*
args
,
**
kwargs
):
self
.
figure
=
kwargs
[
'
figure
'
]
kwargs
=
{}
super
().
__init__
(
*
args
,
**
kwargs
)
def
trigger
(
self
,
sender
,
event
,
data
=
None
):
#on trigger update tool button state and call set_linemode on figure
super
().
trigger
(
sender
,
event
,
data
=
data
)
# print('figure is', self.figure, 'state=', self.toggled)
# if self.toggled:
# sender.toolmanager.trigger_tool('Line_tool', sender=self, data=('init',()))
# else:
# sender.toolmanager.trigger_tool('Line_tool', sender=self, data=('quit',()))
self
.
figure
.
set_linemode
(
self
.
toggled
)
class
LineTool
(
RubberbandBase
):
"""
Tool button switch to line drawing mode
The trigger associated functions change the cursor to indicate activity
"""
# keyboard shortcut
description
=
'
Line drawing tool
'
def
__init__
(
self
,
*
args
,
**
kwargs
):
self
.
figure
=
kwargs
[
'
figure
'
]
kwargs
=
{}
super
().
__init__
(
*
args
,
**
kwargs
)
def
draw_rubberband
(
self
,
*
data
):
x
=
[
self
.
figure
.
node_x
[
-
1
],
data
[
0
]]
y
=
[
self
.
figure
.
node_y
[
-
1
],
data
[
1
]]
# print("RB tool", cmd ,':', pos)
# if cmd=='init':
# print('activate line tool', self.figure)
# elif cmd == 'quit':
# print('quit line tool', self.figure)
def
remove_rubberband
(
self
):
print
(
'
quit RB tool
'
)
class
Crms_fig
(
fig
.
Figure
):
def
__init__
(
self
,
*
args
,
**
kwargs
):
super
().
__init__
(
*
args
,
**
kwargs
)
self
.
cid
=
self
.
canvas
.
mpl_connect
(
'
button_press_event
'
,
self
.
button_press
)
self
.
canvas
.
mpl_connect
(
'
draw_event
'
,
self
.
on_draw
)
self
.
linemode
=
False
self
.
lineedit
=
False
self
.
vertices
=
[]
self
.
index
=-
1
#active vertex last one is default for line construction
self
.
mvcid
=
0
#mouse move connection
self
.
brcid
=
0
# button release connection
self
.
epsilon
=
5
def
set_linemode
(
self
,
state
)
:
self
.
linemode
=
state
if
state
:
print
(
'
linemode on
'
)
if
len
(
self
.
vertices
)
>
0
:
self
.
lineedit
=
True
self
.
canvas
.
set_cursor
(
3
)
else
:
print
(
'
linemode off
'
)
self
.
lineedit
=
False
self
.
canvas
.
set_cursor
(
1
)
def
on_draw
(
self
,
event
):
"""
Callback for draws.
"""
self
.
background
=
self
.
canvas
.
copy_from_bbox
(
self
.
gca
().
bbox
)
# self.ax.draw_artist(self.pathpatch)
# self.ax.draw_artist(self.line)
# self.canvas.blit(self.ax.bbox)
def
get_vertex_index
(
self
,
event
):
#xy=self.line.get_data()
xyt
=
self
.
line
.
get_transform
().
transform
(
self
.
vertices
)
# converts point coordinates into pixel units
xt
,
yt
=
xyt
[:,
0
],
xyt
[:,
1
]
d
=
np
.
sqrt
((
xt
-
event
.
x
)
**
2
+
(
yt
-
event
.
y
)
**
2
)
ind
=
d
.
argmin
()
return
ind
if
d
[
ind
]
<
self
.
epsilon
else
None
def
get_insert_index
(
self
,
event
):
#xy=self.line.get_data()
xyt
=
self
.
line
.
get_transform
().
transform
(
self
.
vertices
)
# converts point coordinates into pixel units
point
=
[
event
.
x
,
event
.
y
]
segments
=
np
.
diff
(
xyt
,
1
,
0
)
# 1st order finite difference with respect to axis 0
unitvects
=
(
segments
.
transpose
()
/
np
.
linalg
.
norm
(
segments
,
axis
=
1
))
# beware shape is (2,N)
distances
=
(
np
.
array
(
point
)
-
np
.
array
(
xyt
))[:
-
1
,:]
t
=
np
.
dot
(
distances
,
unitvects
).
diagonal
()
d2
=
distances
-
(
unitvects
*
t
).
transpose
()
tnorm
=
t
/
np
.
linalg
.
norm
(
segments
,
axis
=
1
)
d
=
np
.
linalg
.
norm
(
d2
,
axis
=
1
)
# print(unitvects)
print
(
tnorm
)
# print(d2)
print
(
d
)
# U2=np.square(np.linalg.norm(segments, axis=1))
# d=np.sqrt((np.square(U2)-np.square(UV))/U2)
# xt, yt = xyt[:, 0], xyt[:, 1]
# d = np.sqrt((xt - event.x)**2 + (yt - event.y)**2)
ind
=
d
.
argmin
()
return
ind
if
d
[
ind
]
<
self
.
epsilon
and
tnorm
[
ind
]
>
0
and
tnorm
[
ind
]
<
1.
else
None
def
button_press
(
self
,
event
):
if
event
.
inaxes
is
self
.
gca
().
axes
and
self
.
linemode
:
if
self
.
lineedit
:
index
=
self
.
get_vertex_index
(
event
)
if
index
!=
None
:
print
(
'
>>
'
,
index
,
self
.
vertices
[
index
])
self
.
index
=
index
self
.
mvcid
=
self
.
canvas
.
mpl_connect
(
'
motion_notify_event
'
,
self
.
on_mouse_move
)
self
.
brcid
=
self
.
canvas
.
mpl_connect
(
'
button_release_event
'
,
self
.
on_button_release
)
else
:
# print('>>', event.modifiers)
if
'
ctrl
'
in
event
.
modifiers
:
index
=
self
.
get_insert_index
(
event
)
print
(
"
add point
"
,
index
)
return
if
event
.
dblclick
:
#self.canvas.manager.toolmanager.trigger_tool('Line_tool', sender=self)
event
.
canvas
.
mpl_disconnect
(
self
.
mvcid
)
self
.
mvcid
=
0
print
(
"
vertices
"
,
self
.
vertices
)
self
.
lineedit
=
True
else
:
self
.
vertices
.
append
((
event
.
xdata
,
event
.
ydata
))
vertex
=
self
.
vertices
.
copy
()
vertex
.
append
((
event
.
xdata
,
event
.
ydata
))
x
,
y
=
zip
(
*
vertex
)
# print(x, y)
# print('vertices', self.vertices)
if
len
(
self
.
vertices
)
==
1
:
self
.
line
,
=
self
.
gca
().
plot
(
x
,
y
,
'
g
'
,
marker
=
'
s
'
,
markerfacecolor
=
'
r
'
,
animated
=
True
)
self
.
mvcid
=
self
.
canvas
.
mpl_connect
(
'
motion_notify_event
'
,
self
.
on_mouse_move
)
else
:
self
.
line
.
set_data
(
list
(
x
),
list
(
y
))
def
on_mouse_move
(
self
,
event
):
# print('on move')
if
event
.
inaxes
is
self
.
gca
().
axes
and
self
.
linemode
:
x
,
y
=
self
.
line
.
get_data
()
x
[
self
.
index
]
=
event
.
xdata
y
[
self
.
index
]
=
event
.
ydata
self
.
line
.
set_data
(
x
,
y
)
# print(self.line.get_data())
self
.
canvas
.
restore_region
(
self
.
background
)
self
.
gca
().
draw_artist
(
self
.
line
)
self
.
canvas
.
blit
(
self
.
gca
().
bbox
)
def
on_button_release
(
self
,
event
):
if
event
.
inaxes
is
self
.
gca
().
axes
and
self
.
lineedit
:
self
.
vertices
[
self
.
index
]
=
(
event
.
xdata
,
event
.
ydata
)
x
,
y
=
zip
(
*
self
.
vertices
)
self
.
line
.
set_data
(
list
(
x
),
list
(
y
))
event
.
canvas
.
mpl_disconnect
(
self
.
mvcid
)
event
.
canvas
.
mpl_disconnect
(
self
.
brcid
)
self
.
brcid
=
self
.
mvcid
=
0
def
create_crms_figure
(
**
kwargs
):
import
warnings
#activating special toolbar
stdmgr
=
plt
.
rcParams
[
'
toolbar
'
]
warnings
.
simplefilter
(
'
ignore
'
,
category
=
UserWarning
)
plt
.
rcParams
[
'
toolbar
'
]
=
'
toolmanager
'
warnings
.
resetwarnings
()
csfig
=
plt
.
figure
(
FigureClass
=
Crms_fig
,
**
kwargs
)
# new plot window
# csfig.canvas.manager.toolmanager.add_tool('Line_tool', LineTool, figure=csfig) # manager.add_tool
csfig
.
canvas
.
manager
.
toolmanager
.
add_tool
(
'
Line_mode
'
,
LineMode
,
figure
=
csfig
)
#now unused
# csfig.canvas.manager.toolbar.add_tool('Line_mode', 'Special', -1) #container.add_tool
csfig
.
canvas
.
manager
.
toolbar
.
add_toolitem
(
'
Line_mode
'
,
'
Special
'
,
-
1
,
LineMode
.
image
,
LineMode
.
description
,
True
)
#container.add_tool
#switching back to standard pyplot toolbar
plt
.
rcParams
[
'
toolbar
'
]
=
stdmgr
return
csfig
\ No newline at end of file
This diff is collapsed.
Click to expand it.
heightmap.py
+
3
−
1
View file @
56680e49
...
@@ -759,7 +759,9 @@ class HeightMap(object):
...
@@ -759,7 +759,9 @@ class HeightMap(object):
The cumulative rms slope error is the square root of the slope CPSD
The cumulative rms slope error is the square root of the slope CPSD
"""
"""
plt
.
figure
(
figsize
=
fig
.
figaspect
(
0.5
))
# new plot window
from
crmsfig
import
create_crms_figure
csfig
=
create_crms_figure
(
figsize
=
fig
.
figaspect
(
0.5
))
# new plot window
if
tangential
:
if
tangential
:
plt
.
plot
(
self
.
sf
*
1e-3
,
self
.
srms
*
1e6
)
plt
.
plot
(
self
.
sf
*
1e-3
,
self
.
srms
*
1e6
)
plt
.
title
(
'
Cumulated RMS tangential slopes {}
'
.
format
(
comment
))
plt
.
title
(
'
Cumulated RMS tangential slopes {}
'
.
format
(
comment
))
...
...
This diff is collapsed.
Click to expand it.
line-48.png
0 → 100644
+
0
−
0
View file @
56680e49
459 B
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