Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
7
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Open sidebar
GEPARD
GEPARD
Commits
fa8cd07f
Commit
fa8cd07f
authored
Dec 16, 2019
by
Josef Brandt
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
AdvancedLogging, RepeatCom-Decorator in WITec-Com
parent
40f9393a
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
369 additions
and
165 deletions
+369
-165
__main__.py
__main__.py
+37
-11
detectionview.py
detectionview.py
+37
-9
errors.py
errors.py
+6
-0
gepardlogging.py
gepardlogging.py
+44
-0
opticalscan.py
opticalscan.py
+56
-54
ramancom/WITecCOM.py
ramancom/WITecCOM.py
+79
-18
ramancom/ramanbase.py
ramancom/ramanbase.py
+2
-1
ramancom/simulatedraman.py
ramancom/simulatedraman.py
+11
-7
ramanscanui.py
ramanscanui.py
+58
-38
sampleview.py
sampleview.py
+20
-9
segmentation.py
segmentation.py
+19
-18
No files found.
__main__.py
View file @
fa8cd07f
...
...
@@ -18,22 +18,26 @@ You should have received a copy of the GNU General Public License
along with this program, see COPYING.
If not, see <https://www.gnu.org/licenses/>.
"""
import
logging
import
traceback
import
os
from
io
import
StringIO
from
PyQt5
import
QtCore
,
QtWidgets
,
QtGui
from
.sampleview
import
SampleView
from
.scalebar
import
ScaleBar
from
.ramancom.ramancontrol
import
defaultPath
from
.ramancom.ramanSwitch
import
RamanSwitch
from
.analysis.colorlegend
import
ColorLegend
from
.gepardlogging
import
setDefaultLoggingConfig
class
GEPARDMainWindow
(
QtWidgets
.
QMainWindow
):
def
__init__
(
self
,
log
path
):
def
__init__
(
self
,
log
ger
):
super
(
GEPARDMainWindow
,
self
).
__init__
()
self
.
setWindowTitle
(
"GEPARD"
)
self
.
resize
(
900
,
700
)
self
.
view
=
SampleView
(
log
path
)
self
.
view
=
SampleView
(
log
ger
)
self
.
view
.
imparent
=
self
self
.
view
.
ScalingChanged
.
connect
(
self
.
scalingChanged
)
self
.
scalebar
=
ScaleBar
(
self
)
...
...
@@ -332,6 +336,31 @@ if __name__ == '__main__':
import
sys
from
time
import
localtime
,
strftime
def
excepthook
(
excType
,
excValue
,
tracebackobj
):
"""
Global function to catch unhandled exceptions.
@param excType exception type
@param excValue exception value
@param tracebackobj traceback object
:return:
"""
tbinfofile
=
StringIO
()
traceback
.
print_tb
(
tracebackobj
,
None
,
tbinfofile
)
tbinfofile
.
seek
(
0
)
tbinfo
=
tbinfofile
.
read
()
logging
.
critical
(
"Fatal error in program excecution!"
)
logging
.
critical
(
tbinfo
)
from
.errors
import
showErrorMessageAsWidget
showErrorMessageAsWidget
(
tbinfo
)
sys
.
exit
(
1
)
sys
.
excepthook
=
excepthook
logger
=
logging
.
getLogger
(
__name__
)
setDefaultLoggingConfig
(
logger
)
app
=
QtWidgets
.
QApplication
(
sys
.
argv
)
app
.
setApplicationName
(
"GEPARD"
)
# appname needed for logpath
...
...
@@ -342,14 +371,11 @@ if __name__ == '__main__':
if
not
os
.
path
.
exists
(
logpath
):
os
.
mkdir
(
logpath
)
logname
=
os
.
path
.
join
(
logpath
,
'logfile.txt'
)
fp
=
open
(
logname
,
"a"
)
sys
.
stderr
=
fp
sys
.
stdout
=
fp
print
(
"starting GEPARD at: "
+
strftime
(
"%d %b %Y %H:%M:%S"
,
localtime
()),
flush
=
True
)
logger
.
addHandler
(
logging
.
FileHandler
(
logname
))
gepard
=
GEPARDMainWindow
(
logpath
)
logger
.
info
(
"starting GEPARD at: "
+
strftime
(
"%d %b %Y %H:%M:%S"
,
localtime
()))
gepard
=
GEPARDMainWindow
(
logger
)
gepard
.
showMaximized
()
ret
=
app
.
exec_
()
if
fp
is
not
None
:
fp
.
close
()
detectionview.py
View file @
fa8cd07f
...
...
@@ -19,6 +19,8 @@ along with this program, see COPYING.
If not, see <https://www.gnu.org/licenses/>.
"""
import
numpy
as
np
import
os
import
logging
from
PyQt5
import
QtCore
,
QtWidgets
,
QtGui
from
matplotlib.backends.backend_qt5agg
import
FigureCanvasQTAgg
import
matplotlib.pyplot
as
plt
...
...
@@ -26,9 +28,10 @@ from threading import Thread
from
.segmentation
import
Segmentation
from
.analysis.particleCharacterization
import
getParticleStatsWithPixelScale
,
loadZValImageFromDataset
from
.errors
import
InvalidParticleError
from
.errors
import
InvalidParticleError
,
showErrorMessageAsWidget
from
.uielements
import
TimeEstimateProgressbar
from
.scenePyramid
import
ScenePyramid
from
.gepardlogging
import
setDefaultLoggingConfig
Nscreen
=
1000
...
...
@@ -283,6 +286,11 @@ class ParticleDetectionView(QtWidgets.QWidget):
self
.
threadrunning
=
False
self
.
view
=
parent
logPath
=
os
.
path
.
join
(
self
.
dataset
.
path
,
'detectionlog.txt'
)
self
.
logger
=
logging
.
getLogger
(
'detection'
)
self
.
logger
.
addHandler
(
logging
.
FileHandler
(
logPath
))
setDefaultLoggingConfig
(
self
.
logger
)
vbox
=
QtWidgets
.
QVBoxLayout
()
hbox
=
QtWidgets
.
QHBoxLayout
()
...
...
@@ -657,13 +665,24 @@ class ParticleDetectionView(QtWidgets.QWidget):
self
.
seg
.
setParameters
(
**
kwargs
)
seedradius
=
self
.
seedradiusedit
.
value
()
if
showname
is
not
None
:
stepImg
,
imgtype
=
self
.
seg
.
apply2Image
(
img
,
self
.
imglabel
.
seedpoints
,
self
.
imglabel
.
seeddeletepoints
,
seedradius
,
self
.
dataset
,
return_step
=
showname
)
self
.
imglabel
.
showStep
(
stepImg
,
imgtype
)
try
:
stepImg
,
imgtype
=
self
.
seg
.
apply2Image
(
img
,
self
.
imglabel
.
seedpoints
,
self
.
imglabel
.
seeddeletepoints
,
seedradius
,
self
.
dataset
,
self
.
logger
,
return_step
=
showname
)
self
.
imglabel
.
showStep
(
stepImg
,
imgtype
)
except
:
showErrorMessageAsWidget
(
'Fatal error in particle detection, see detectionlog for info'
)
self
.
logger
.
exception
(
'Fatal error in particle detection'
)
else
:
measurementpoints
,
contours
=
self
.
seg
.
apply2Image
(
img
,
self
.
imglabel
.
seedpoints
,
self
.
imglabel
.
seeddeletepoints
,
seedradius
,
self
.
dataset
)
self
.
imglabel
.
updateDetectionResults
(
contours
,
measurementpoints
)
try
:
measurementpoints
,
contours
=
self
.
seg
.
apply2Image
(
img
,
self
.
imglabel
.
seedpoints
,
self
.
imglabel
.
seeddeletepoints
,
seedradius
,
self
.
dataset
,
self
.
logger
)
self
.
imglabel
.
updateDetectionResults
(
contours
,
measurementpoints
)
except
:
showErrorMessageAsWidget
(
'Fatal error in particle detection, see detectionlog for info'
)
self
.
logger
.
exception
(
'Fatal error in particle detection'
)
@
QtCore
.
pyqtSlot
()
def
clearDetection
(
self
):
...
...
@@ -707,6 +726,7 @@ class ParticleDetectionView(QtWidgets.QWidget):
Detect all particles
:return:
"""
self
.
logger
.
info
(
'Starting particle detection'
)
self
.
saveDetectParams
(
self
.
dataset
)
if
self
.
thread
is
not
None
and
self
.
thread
.
is_alive
():
self
.
cancelThread
()
...
...
@@ -757,6 +777,11 @@ class ParticleDetectionView(QtWidgets.QWidget):
self
.
progressbar
.
setValue
(
newVal
)
def
_worker
(
self
):
logPath
=
os
.
path
.
join
(
self
.
dataset
.
path
,
'detectionlog.txt'
)
detectLogger
=
logging
.
getLogger
(
'detection_worker'
)
detectLogger
.
addHandler
(
logging
.
FileHandler
(
logPath
))
setDefaultLoggingConfig
(
detectLogger
)
kwargs
=
{}
seedpoints
,
deletepoints
=
[],
[]
if
self
.
dataset
is
not
None
:
...
...
@@ -766,8 +791,11 @@ class ParticleDetectionView(QtWidgets.QWidget):
kwargs
[
name
]
=
valuefunc
()
seedradius
=
self
.
seedradiusedit
.
value
()
self
.
seg
.
setParameters
(
**
kwargs
)
measurementPoints
,
contours
=
self
.
seg
.
apply2Image
(
self
.
img
,
seedpoints
,
deletepoints
,
seedradius
,
self
.
dataset
)
try
:
measurementPoints
,
contours
=
self
.
seg
.
apply2Image
(
self
.
img
,
seedpoints
,
deletepoints
,
seedradius
,
self
.
dataset
,
detectLogger
)
except
:
showErrorMessageAsWidget
(
'Fatal error in particle detection, see detectionlog for info'
)
detectLogger
.
exception
(
'Fatal error in particle detection'
)
if
measurementPoints
is
None
:
# computation was canceled
return
...
...
errors.py
View file @
fa8cd07f
...
...
@@ -31,3 +31,9 @@ class NotConnectedContoursError(Exception):
class
TileSizeError
(
Exception
):
pass
def
showErrorMessageAsWidget
(
errorMessage
):
from
PyQt5
import
QtWidgets
app
=
QtWidgets
.
QApplication
(
sys
.
argv
)
#an app is needed to create and show QWidgets..
QtWidgets
.
QMessageBox
.
critical
(
QtWidgets
.
QWidget
(),
'Fatal Error'
,
errorMessage
)
gepardlogging.py
0 → 100644
View file @
fa8cd07f
# -*- coding: utf-8 -*-
"""
GEPARD - Gepard-Enabled PARticle Detection
Copyright (C) 2018 Lars Bittrich and Josef Brandt, Leibniz-Institut für
Polymerforschung Dresden e. V. <bittrich-lars@ipfdd.de>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program, see COPYING.
If not, see <https://www.gnu.org/licenses/>.
"""
import
logging
def
setDefaultLoggingConfig
(
logger
:
logging
.
Logger
):
"""
Applies a default configuration to the specified logger
Parameters
----------
logger : logging.Logger
DESCRIPTION.
Returns
-------
None.
"""
logger
.
addHandler
(
logging
.
StreamHandler
())
logger
.
setLevel
(
logging
.
WARNING
)
formatter
=
logging
.
Formatter
(
'%(asctime)s - %(levelname)s - %(message)s'
)
for
handler
in
logger
.
handlers
:
handler
.
setFormatter
(
formatter
)
\ No newline at end of file
opticalscan.py
View file @
fa8cd07f
...
...
@@ -24,64 +24,65 @@ import numpy as np
from
multiprocessing
import
Process
,
Queue
,
Event
import
queue
from
.imagestitch
import
imageStacking
import
sys
,
os
import
os
,
sys
import
logging
import
cv2
from
.helperfunctions
import
cv2imread_fix
,
cv2imwrite_fix
from
time
import
time
from
time
import
time
,
localtime
,
strftime
from
.opticalbackground
import
BackGroundManager
from
.uielements
import
TimeEstimateProgressbar
from
.zlevelsetter
import
ZLevelSetter
from
.scenePyramid
import
ScenePyramid
from
.gepardlogging
import
setDefaultLoggingConfig
def
scan
(
path
,
sol
,
zpositions
,
grid
,
controlclass
,
dataqueue
,
stopevent
,
logpath
=
''
,
ishdr
=
False
):
stopevent
,
logpath
,
ishdr
=
False
):
if
ishdr
:
merge_mertens
=
cv2
.
createMergeMertens
()
fp
=
None
if
logpath
!=
''
:
try
:
fp
=
open
(
os
.
path
.
join
(
logpath
,
'scanlog.txt'
),
'a'
)
sys
.
stderr
=
fp
sys
.
stdout
=
fp
except
IOError
:
print
(
'separate logging failed'
,
flush
=
True
)
pass
print
(
'starting new optical scan'
,
flush
=
True
)
logger
=
logging
.
getLogger
()
logger
.
setLevel
(
logging
.
INFO
)
logger
.
addHandler
(
logging
.
FileHandler
(
logpath
))
logger
.
info
(
'starting new optical scan'
)
setDefaultLoggingConfig
(
logger
)
try
:
ramanctrl
=
controlclass
(
logger
)
ramanctrl
.
connect
()
zlist
=
list
(
enumerate
(
zpositions
))
for
i
,
p
in
enumerate
(
grid
):
x
,
y
=
p
z
=
sol
[
0
]
*
x
+
sol
[
1
]
*
y
+
sol
[
2
]
for
k
,
zk
in
(
zlist
if
i
%
2
==
0
else
zlist
[::
-
1
]):
name
=
f
"image_
{
i
}
_
{
k
}
.bmp"
logger
.
info
(
f
'taking image
{
name
}
, time: '
+
strftime
(
"%d %b %Y %H:%M:%S"
,
localtime
()))
zik
=
z
+
zk
assert
not
np
.
isnan
(
zik
)
logger
.
info
(
f
"moving to:
{
x
}
,
{
y
}
,
{
zik
}
, time: "
+
strftime
(
"%d %b %Y %H:%M:%S"
,
localtime
()))
ramanctrl
.
moveToAbsolutePosition
(
x
,
y
,
zik
)
if
ishdr
:
img_list
=
[]
fname
=
os
.
path
.
join
(
path
,
f
"tmp.bmp"
)
values
=
[
5.
,
25.
,
100.
]
for
j
,
val
in
enumerate
(
values
if
(
i
%
2
+
k
%
2
)
%
2
==
0
else
reversed
(
values
)):
ramanctrl
.
setBrightness
(
val
)
ramanctrl
.
saveImage
(
fname
)
img_list
.
append
(
cv2imread_fix
(
fname
))
res_mertens
=
merge_mertens
.
process
(
img_list
)
res_mertens_8bit
=
np
.
clip
(
res_mertens
*
255
,
0
,
255
).
astype
(
'uint8'
)
cv2imwrite_fix
(
os
.
path
.
join
(
path
,
name
),
res_mertens_8bit
)
else
:
ramanctrl
.
saveImage
(
os
.
path
.
join
(
path
,
name
))
if
stopevent
.
is_set
():
ramanctrl
.
disconnect
()
return
dataqueue
.
put
(
i
)
ramanctrl
.
disconnect
()
except
:
logger
.
exception
(
'Fatal error in optical scan'
)
from
.errors
import
showErrorMessageAsWidget
showErrorMessageAsWidget
(
'See opticalScanLog in project directory for information'
)
ramanctrl
=
controlclass
()
ramanctrl
.
connect
()
zlist
=
list
(
enumerate
(
zpositions
))
for
i
,
p
in
enumerate
(
grid
):
x
,
y
=
p
z
=
sol
[
0
]
*
x
+
sol
[
1
]
*
y
+
sol
[
2
]
for
k
,
zk
in
(
zlist
if
i
%
2
==
0
else
zlist
[::
-
1
]):
name
=
f
"image_
{
i
}
_
{
k
}
.bmp"
print
(
"time:"
,
time
(),
flush
=
True
)
zik
=
z
+
zk
assert
not
np
.
isnan
(
zik
)
print
(
"moving to:"
,
x
,
y
,
zik
,
flush
=
True
)
ramanctrl
.
moveToAbsolutePosition
(
x
,
y
,
zik
)
if
ishdr
:
img_list
=
[]
fname
=
os
.
path
.
join
(
path
,
f
"tmp.bmp"
)
values
=
[
5.
,
25.
,
100.
]
for
j
,
val
in
enumerate
(
values
if
(
i
%
2
+
k
%
2
)
%
2
==
0
else
reversed
(
values
)):
ramanctrl
.
setBrightness
(
val
)
ramanctrl
.
saveImage
(
fname
)
img_list
.
append
(
cv2imread_fix
(
fname
))
res_mertens
=
merge_mertens
.
process
(
img_list
)
res_mertens_8bit
=
np
.
clip
(
res_mertens
*
255
,
0
,
255
).
astype
(
'uint8'
)
cv2imwrite_fix
(
os
.
path
.
join
(
path
,
name
),
res_mertens_8bit
)
else
:
ramanctrl
.
saveImage
(
os
.
path
.
join
(
path
,
name
))
if
stopevent
.
is_set
():
ramanctrl
.
disconnect
()
return
dataqueue
.
put
(
i
)
ramanctrl
.
disconnect
()
if
fp
is
not
None
:
fp
.
close
()
def
subtractBackground
(
image
,
background
):
avg
=
np
.
mean
(
background
)
...
...
@@ -284,9 +285,9 @@ class OpticalScan(QtWidgets.QWidget):
boundaryUpdate
=
QtCore
.
pyqtSignal
()
backGroundSavedToPath
=
QtCore
.
pyqtSignal
(
int
,
str
)
def
__init__
(
self
,
ramanctrl
,
dataset
,
log
path
=
''
,
parent
=
None
):
def
__init__
(
self
,
ramanctrl
,
dataset
,
log
ger
,
parent
=
None
):
super
().
__init__
(
parent
,
QtCore
.
Qt
.
Window
)
self
.
log
path
=
log
path
self
.
log
ger
=
log
ger
self
.
view
:
QtWidgets
.
QGraphicsView
=
parent
mainLayout
=
QtWidgets
.
QVBoxLayout
()
...
...
@@ -638,17 +639,17 @@ class OpticalScan(QtWidgets.QWidget):
self
.
dataset
.
zpositions
=
zrange
width
,
height
,
rotationvalue
=
self
.
dataset
.
imagedim_df
print
(
"Width, height, rotation:"
,
width
,
height
,
rotationvalue
)
print
(
"Points x:
"
,
points
[:,
0
].
min
(),
points
[:,
0
].
max
())
print
(
"Points y:
"
,
points
[:,
1
].
min
(),
points
[:,
1
].
max
())
print
(
"Points z:
"
,
points
[:,
2
].
min
(),
points
[:,
2
].
max
())
self
.
logger
.
debug
(
f
"Width:
{
width
}
, height:
{
height
}
, rotation:
{
rotationvalue
}
"
)
self
.
logger
.
debug
(
f
"Points x:
{
points
[:,
0
].
min
(),
points
[:,
0
].
max
()
}
"
)
self
.
logger
.
debug
(
f
"Points y:
{
points
[:,
1
].
min
(),
points
[:,
1
].
max
()
}
"
)
self
.
logger
.
debug
(
f
"Points z:
{
points
[:,
2
].
min
(),
points
[:,
2
].
max
()
}
"
)
A
=
np
.
ones
((
points
.
shape
[
0
],
3
))
A
[:,:
2
]
=
points
[:,:
2
]
b
=
points
[:,
2
]
sol
=
np
.
linalg
.
lstsq
(
A
,
b
,
rcond
=
None
)[
0
]
self
.
dataset
.
heightmap
=
sol
print
(
"Fit deviation:
"
,
sol
[
0
]
*
points
[:,
0
]
+
sol
[
1
]
*
points
[:,
1
]
+
sol
[
2
]
-
points
[:,
2
]
)
self
.
logger
.
info
(
f
"Fit deviation:
{
sol
[
0
]
*
points
[:,
0
]
+
sol
[
1
]
*
points
[:,
1
]
+
sol
[
2
]
-
points
[:,
2
]
}
"
)
path
=
self
.
dataset
.
getScanPath
()
# get zmin and zmax in absolut software z coordinates
...
...
@@ -676,10 +677,11 @@ class OpticalScan(QtWidgets.QWidget):
self
.
ramanctrl
.
disconnect
()
self
.
processstopevent
=
Event
()
self
.
dataqueue
=
Queue
()
logpath
=
os
.
path
.
join
(
self
.
dataset
.
path
,
'opticalScanLog.txt'
)
self
.
process
=
Process
(
target
=
scan
,
args
=
(
path
,
sol
,
self
.
dataset
.
zpositions
,
self
.
dataset
.
grid
,
self
.
ramanctrl
.
__class__
,
self
.
dataqueue
,
self
.
processstopevent
,
self
.
logpath
,
self
.
hdrcheck
.
isChecked
()))
logpath
,
self
.
hdrcheck
.
isChecked
()))
self
.
process
.
start
()
self
.
progressbar
.
enable
()
self
.
progressbar
.
resetTimerAndCounter
()
...
...
ramancom/WITecCOM.py
View file @
fa8cd07f
...
...
@@ -36,9 +36,54 @@ except ModuleNotFoundError:
from
ramanbase
import
RamanBase
from
configRaman
import
RamanSettingParam
from
socket
import
gethostname
from
..errors
import
showErrorMessageAsWidget
class
WITecCOM
(
RamanBase
):
def
comErrorRepeater
(
comCallFunction
):
"""
A wrapper function for handling rarely occuring com errors.
If a com error occurs, a sleep time of one second is done, than the function is repeated.
This is done three times. If still no success was achieved, the com interface is reconnected
and, again, the function is started three times at maximum.
If none of this worked, an error message is shown and an exception is raised.
Parameters
----------
comCallFunction : function object
The function to apply the wrapper to.
Returns
-------
wrapper : function object
The wrapped function
"""
def
wrapper
(
*
args
,
**
kwargs
):
def
tryFunctionThreeTimes
():
success
=
False
for
_
in
range
(
3
):
try
:
comCallFunction
(
*
args
,
**
kwargs
)
success
=
True
break
except
pythoncom
.
com_error
:
sleep
(
1.
)
return
success
comObj
=
args
[
0
]
#self is always passed as first argument
functionSucceeded
=
tryFunctionThreeTimes
()
if
not
functionSucceeded
:
comObj
.
disconnect
()
sleep
(
1.
)
comObj
.
connect
()
functionSucceeded
=
tryFunctionThreeTimes
()
if
not
functionSucceeded
:
showErrorMessageAsWidget
(
f
'Com error on function
{
comCallFunction
.
__name__
}
'
)
raise
pythoncom
.
com_error
return
wrapper
CLSID
=
"{C45E77CE-3D66-489A-B5E2-159F443BD1AA}"
magn
=
20
...
...
@@ -46,7 +91,7 @@ class WITecCOM(RamanBase):
ramanParameters
=
[
RamanSettingParam
(
'IntegrationTime (s)'
,
'double'
,
default
=
0.5
,
minVal
=
0.01
,
maxVal
=
100
),
RamanSettingParam
(
'Accumulations'
,
'int'
,
default
=
5
,
minVal
=
1
,
maxVal
=
100
)]
def
__init__
(
self
,
hostname
=
None
):
def
__init__
(
self
,
logger
,
hostname
=
None
):
super
().
__init__
()
self
.
name
=
'WITecCOM'
if
hostname
is
None
:
...
...
@@ -55,6 +100,7 @@ class WITecCOM(RamanBase):
clsctx
=
pythoncom
.
CLSCTX_REMOTE_SERVER
)
self
.
advancedInterface
=
False
self
.
doAutoFocus
=
False
self
.
logger
=
logger
def
connect
(
self
):
if
not
self
.
IBUCSAccess
.
RequestWriteAccess
(
True
):
...
...
@@ -73,7 +119,7 @@ class WITecCOM(RamanBase):
try
:
vnr
=
float
(
vnr
)
except
ValueError
:
print
(
"WITec: unknown version format:
"
,
version
)
self
.
logger
.
critical
(
f
"WITec: unknown version format:
{
version
}
"
)
vnr
=
0.0
# version format unknown
self
.
version
=
vnr
...
...
@@ -208,10 +254,12 @@ class WITecCOM(RamanBase):
self
.
ramanParameters
.
append
(
RamanSettingParam
(
'Autofocus'
,
'checkBox'
,
default
=
False
))
self
.
ramanParameters
.
append
(
RamanSettingParam
(
'Spectra Batch Size'
,
'int'
,
default
=
1000
,
minVal
=
1
,
maxVal
=
1e6
))
@
comErrorRepeater
def
getBrightness
(
self
):
assert
self
.
connected
return
self
.
BrightnessMan
.
GetValue
()
@
comErrorRepeater
def
setBrightness
(
self
,
newval
):
if
newval
<
0
:
newval
=
0.0
...
...
@@ -220,6 +268,7 @@ class WITecCOM(RamanBase):
self
.
BrightnessMan
.
SetValue
(
newval
)
sleep
(.
1
)
@
comErrorRepeater
def
getRamanPositionShift
(
self
):
rx
=
.
5
-
self
.
RamanRelativeXMan
.
GetValue
()
# current assumption is, that image center is current position
ry
=
self
.
RamanRelativeYMan
.
GetValue
()
-
.
5
...
...
@@ -231,6 +280,7 @@ class WITecCOM(RamanBase):
self
.
IBUCSAccess
.
RequestWriteAccess
(
False
)
self
.
connected
=
False
@
comErrorRepeater
def
getPosition
(
self
):
assert
self
.
connected
self
.
PosXCurFloatMan
.
Update
()
...
...
@@ -241,17 +291,20 @@ class WITecCOM(RamanBase):
z
=
self
.
PosZCurFloatMan
.
GetSingleValueAsDouble
()[
1
]
return
x
,
y
,
z
@
comErrorRepeater
def
getSoftwareZ
(
self
):
self
.
PosZCurFloatMan
.
Update
()
z
=
self
.
PosZCurFloatMan
.
GetSingleValueAsDouble
()[
1
]
return
z
@
comErrorRepeater
def
getUserZ
(
self
):
assert
self
.
connected
self
.
PosZCurUserFloatMan
.
Update
()
z
=
self
.
PosZCurUserFloatMan
.
GetSingleValueAsDouble
()[
1
]
return
z
@
comErrorRepeater
def
moveToAbsolutePosition
(
self
,
x
,
y
,
z
=
None
,
epsxy
=
0.11
,
epsz
=
0.011
):
assert
self
.
connected
initpos
=
self
.
getPosition
()
...
...
@@ -271,9 +324,9 @@ class WITecCOM(RamanBase):
numFails
+=
1
sleep
(.
1
)
if
numFails
>
0
:
print
(
f
'
{
numFails
}
of max.
{
maxFails
}
unsuccessfull position submits to Position:
{
x
}
,
{
y
}
'
,
flush
=
True
)
self
.
logger
.
info
(
f
'
{
numFails
}
of max.
{
maxFails
}
unsuccessfull position submits to Position:
{
x
}
,
{
y
}
'
)
if
not
positionSubmitted
:
pr
in
t
(
f
'Error setting Position:
{
x
}
,
{
y
}
\n
Expecting
\"
signal ignored
\"
warning'
,
flush
=
True
)
self
.
logger
.
warn
in
g
(
f
'Error setting Position:
{
x
}
,
{
y
}
\n
Expecting
\"
signal ignored
\"
warning'
)
# wait till position is found within accuracy of epsxy; check if position changes at all
distance
=
2
*
epsxy
...
...
@@ -281,15 +334,15 @@ class WITecCOM(RamanBase):
curpos
=
self
.
getPosition
()
distance
=
max
(
abs
(
curpos
[
0
]
-
x
),
abs
(
curpos
[
1
]
-
y
))
if
((
time
()
-
t0
>
0.5
)
and
max
(
abs
(
curpos
[
0
]
-
initpos
[
0
]),
abs
(
curpos
[
1
]
-
initpos
[
1
]))
<
epsxy
)
or
(
time
()
-
t0
>
10.
):
print
(
"WARNING: signal ignored:"
,
time
()
-
t0
,
x
,
y
,
curpos
,
initpos
)
sys
.
stdout
.
flush
()
self
.
logger
.
warning
(
f
"WARNING: signal ignored:, time:
{
time
()
-
t0
}
, x:
{
x
}
, y:
{
y
}
, curPos:
{
curpos
}
, initpos:
{
initpos
}
"
)
break
sleep
(.
01
)
sleep
(.
1
)
initpos
=
self
.
getPosition
()
if
z
is
not
None
:
self
.
moveZto
(
z
,
epsz
)
@
comErrorRepeater
def
moveZto
(
self
,
z
,
epsz
=
0.011
):
assert
self
.
connected
#z = round(z,2)
...
...
@@ -303,21 +356,26 @@ class WITecCOM(RamanBase):
curpos
=
self
.
PosZCurFloatMan
.
GetSingleValueAsDouble
()[
1
]
distance
=
abs
(
curpos
-
z
)
if
((
time
()
-
t0
>
0.5
)
and
abs
(
curpos
-
initpos
)
<
epsz
)
or
(
time
()
-
t0
>
10.
):
print
(
"WARNING: signal z ignored:"
,
time
()
-
t0
)
sys
.
stdout
.
flush
()
self
.
logger
.
warning
(
f
"WARNING: signal z ignored after
{
time
()
-
t0
}
seconds"
)
break
sleep
(.
01
)
sleep
(.
1
)
@
comErrorRepeater
def
saveImage
(
self
,
fname
):
"""
Save current camera image to file name
:return:
"""
assert
self
.
connected
self
.
ImageNameMan
.
SetValue
(
fname
)
self
.
ImageSaveMan
.
OperateTrigger
()
sleep
(.
1
)
@
comErrorRepeater
def
getImageDimensions
(
self
,
mode
=
'df'
):
""" Get the image width and height in um and the orientation angle in degrees.
"""
Get the image width and height in um and the orientation angle in degrees.
"""
assert
self
.
connected
width
,
height
=
self
.
ImageWidthMan
.
GetValue
(),
self
.
ImageHeightMan
.
GetValue
()
...
...
@@ -333,7 +391,9 @@ class WITecCOM(RamanBase):
Busy
=
self
.
SequencerBusyStatus
.
GetSingleValueAsInt
()[
1
]
if
not
Busy
:
break
####TODO: should the below methods also get the comErrorRepeater?? Repeating these commands could mess up something...
def
initiateMeasurement
(
self
,
ramanSettings
):
assert
self
.
connected
if
self
.
advancedInterface
:
...
...
@@ -343,14 +403,14 @@ class WITecCOM(RamanBase):
self
.
initateSilentSpectrumAcquisition
(
ramanSettings
)
else
:
self
.
initiateTimeSeriesMeasurement
(
ramanSettings
)
def
triggerMeasurement
(
self
,
num
):
if
self
.
advancedInterface
and
self
.
doAutoFocus
:
self
.
doSpectralAutoFocus
()
self
.
acquireSilentSpectrum
(
num
)
else
:
self
.
triggerTimeSeriesMeasurement
(
num
)
def
finishMeasurement
(
self
,
aborted
=
False
):
if
self
.
advancedInterface
and
self
.
doAutoFocus
:
state
=
self
.
BeamPathState
.
GetValue
()
...
...
@@ -410,7 +470,7 @@ class WITecCOM(RamanBase):
else
:
sleep
(
0.02
)
if
time
()
-
t1
>
3.
: