Files
sf-op/script/Tools/CameraCorrelation.py
gobbo_a 8beeb7dbc7
2023-08-17 15:16:51 +02:00

119 lines
4.3 KiB
Python

import math
import sys, traceback
from mathutils import fit_polynomial, PolynomialFunction
from plotutils import plot_line, plot_function
from ch.psi.pshell.swing.Shell import getColorStdout
import org.apache.commons.math3.stat.correlation.PearsonsCorrelation as PearsonsCorrelation
import ch.psi.pshell.bs.StreamMerger as StreamMerger
_stop_exec = False
_task = None
_dispatcher_stream = None
def start_camera_correlation(dispatcer_channel, camera_channel, samples=50, modulo=1, offset=0, plt=None):
global _stop_exec, _task, _dispatcher_stream
stop_camera_correlation()
if plt:
for s in plt.getAllSeries():
plt.removeSeries(s)
class LinearFit(ReadonlyAsyncRegisterBase, ReadonlyRegisterArray):
def getSize(self):
return 2
def set(self, pars):
self.onReadout(to_array(pars, 'd'))
class Correlation(ReadonlyAsyncRegisterBase):
def set(self, val):
self.onReadout(val)
add_device(LinearFit("linear_fit"), True)
add_device(Correlation("correlation"), True)
try:
_dispatcher_stream = Stream("corr_stream", dispatcher)
_dispatcher_stream.addScalar(dispatcer_channel, dispatcer_channel, modulo, offset)
_dispatcher_stream.initialize()
_dispatcher_stream.start(True)
_dispatcher_stream.setBufferCapacity(500)
camera_name, camera_channel = camera_channel.split(" ")
shared = camera_name.endswith("_sp1")
cam_server.start(camera_name, shared )
camera_stream = cam_server.stream
camera_stream.setBufferCapacity(500)
camera_stream.waitCacheChange(10000);
def merger_task():
merger = StreamMerger("stream", _dispatcher_stream, camera_stream)
try:
if plt:
sd = LinePlotSeries("Data")
plt.addSeries(sd)
sd.setLinesVisible(False)
sd.setPointSize(4)
else:
ax,ay = [],[]
merger.monitored=True
merger.start()
merger.waitCacheChange(5000)
dx=merger.getChild(dispatcer_channel)
dy=merger.getChild(camera_channel)
while(not _stop_exec):
merger.waitCacheChange(10000)
x=dx.read()
y=dy.read()
if plt:
sd.appendData(x, y)
while len(sd.x) > samples:
sd.token.remove(0) #Remove First Element
ax,ay = sd.x,sd.y
else:
ax.append(x); ay.append(y)
while len(ax) > samples:
ax.pop(0); ay.pop(0)
if len(ax)>2:
x1, x2 = min(ax), max(ax)
if x1!=x2:
#Display correlation
corr= PearsonsCorrelation().correlation(to_array(ax,'d'), to_array(ay,'d'))
correlation.set(corr)
pars_lin = (a0,a1) = fit_polynomial(ay, ax, 1)
linear_fit.set(pars_lin)
y1,y2 = poly(x1, pars_lin), poly(x2, pars_lin)
if plt:
invoke((plot_line,(plt, x1, y1, x2, y2, 2, Color.BLUE, "Fit Linear")), False)
finally:
merger.close()
_task = fork(merger_task)
except:
stop_camera_correlation()
raise
def stop_camera_correlation():
global _stop_exec, _task, _dispatcher_stream
_stop_exec = True
if _task:
join(_task)
cam_server.stop()
if _dispatcher_stream:
_dispatcher_stream.close()
_stop_exec = False
_task = None
_dispatcher_stream = None
#Testing
start_camera_correlation("SINEG01-DICT215:B1_CHARGE", "SATES31-CAMS187-RIXS1_sp1 intensity", samples = 40, plt=plot(None)[0])
try:
time.sleep(10.0)
finally:
stop_camera_correlation()