08 2025
This commit is contained in:
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"image_background_enable": false,
|
||||
"image_background": null,
|
||||
"image_threshold": null,
|
||||
"image_region_of_interest": null,
|
||||
"image_good_region": null,
|
||||
"image_slices": null,
|
||||
"pipeline_type": "processing",
|
||||
"camera_name": "SARBD02-DSCR051",
|
||||
"name": "SARBD02-DSCR051_sp"
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"name": "X01DD-SC-CAM1_proc",
|
||||
"pipeline_type": "stream",
|
||||
"input_pipeline": "X01DD-SC-CAM1_sp",
|
||||
"mode": "PUB",
|
||||
"block": false,
|
||||
"function": "temp_epics_forwarder_sp.py",
|
||||
"_max_frame_rate": 10.1,
|
||||
"throw_epics_errors": true,
|
||||
"abort_on_timeout": true,
|
||||
"stream_timeout": 60,
|
||||
"reload": true
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
import sys
|
||||
import os
|
||||
from cam_server.pipeline.data_processing import functions, processor
|
||||
from collections import OrderedDict
|
||||
from cam_server.pipeline.data_processing import functions
|
||||
from cam_server.utils import create_thread_pvs, epics_lock
|
||||
from logging import getLogger
|
||||
import math
|
||||
|
||||
_logger = getLogger(__name__)
|
||||
|
||||
throw_epics_errors = True
|
||||
|
||||
mean_x_pv, mean_y_pv, sig_x_pv, sig_y_pv = None, None, None, None
|
||||
mean_x_name, mean_y_name, sig_x_name, sig_y_name = None, None, None, None
|
||||
ampl_x_pv, ampl_y_pv, integ_x_pv, integ_y_pv = None, None, None, None
|
||||
ampl_x_name, ampl_y_name, integ_x_name, integ_y_name = None, None, None, None
|
||||
sent_pid = -1
|
||||
|
||||
initialized = False
|
||||
def initialize(parameters):
|
||||
global initialized
|
||||
global mean_x_name, mean_y_name, sig_x_name, sig_y_name, ampl_x_name, ampl_y_name, integ_x_name, integ_y_name
|
||||
prefix = parameters["camera_name"]
|
||||
mean_x_name = prefix + ":POS-X"
|
||||
mean_y_name = prefix + ":POS-Y"
|
||||
sig_x_name = prefix + ":SIG-X"
|
||||
sig_y_name = prefix + ":SIG-Y"
|
||||
ampl_x_name = prefix + ":AMPL-X"
|
||||
ampl_y_name = prefix + ":AMPL-Y"
|
||||
integ_x_name = prefix + ":INTEG-X"
|
||||
integ_y_name = prefix + ":INTEG-Y"
|
||||
initialized = True
|
||||
|
||||
|
||||
def process_image(image, pulse_id, timestamp, x_axis, y_axis, parameters, bsdata):
|
||||
global initialized, sent_pid
|
||||
global mean_x_pv, mean_y_pv, sig_x_pv, sig_y_pv, ampl_x_pv, ampl_y_pv, integ_x_pv, integ_y_pv
|
||||
global mean_x_name, mean_y_name, sig_x_name, sig_y_name, ampl_x_name, ampl_y_name, integ_x_name, integ_y_name
|
||||
prefix = parameters["camera_name"]
|
||||
if not initialized:
|
||||
initialize(parameters)
|
||||
initialized = True
|
||||
r = processor.process_image(image, pulse_id, timestamp, x_axis, y_axis, parameters, bsdata)
|
||||
ret = OrderedDict()
|
||||
|
||||
x_fit_integ = r["gr_x_fit_amplitude"] * r["gr_x_fit_standard_deviation"] * math.sqrt(2*math.pi)
|
||||
y_fit_integ = r["gr_y_fit_amplitude"] * r["gr_y_fit_standard_deviation"] * math.sqrt(2*math.pi)
|
||||
|
||||
|
||||
ret[prefix+":intensity"] = r["intensity"]
|
||||
ret[prefix+":x_fit_mean"] = r["x_fit_mean"]
|
||||
ret[prefix+":y_fit_mean"] = r["y_fit_mean"]
|
||||
ret[prefix+":x_fit_standard_deviation"] = r["x_fit_standard_deviation"]
|
||||
ret[prefix+":y_fit_standard_deviation"] = r["y_fit_standard_deviation"]
|
||||
ret[prefix+":x_center_of_mass"] = r["x_center_of_mass"]
|
||||
ret[prefix+":y_center_of_mass"] = r["y_center_of_mass"]
|
||||
ret[prefix+":x_rms"] = r["x_rms"]
|
||||
ret[prefix+":y_rms"] = r["y_rms"]
|
||||
ret[prefix+":x_fwhm"] = r["x_fwhm"]
|
||||
ret[prefix+":y_fwhm"] = r["y_fwhm"]
|
||||
ret[prefix+":x_fit_amplitude"] = r["x_fit_amplitude"]
|
||||
ret[prefix+":y_fit_amplitude"] = r["y_fit_amplitude"]
|
||||
ret[prefix+":x_fit_integ"] = x_fit_integ
|
||||
ret[prefix+":y_fit_integ"] = y_fit_integ
|
||||
ret[prefix+":gr_x_fit_mean"] = r["gr_x_fit_mean"]
|
||||
ret[prefix+":gr_y_fit_mean"] = r["gr_y_fit_mean"]
|
||||
ret[prefix+":gr_x_fit_standard_deviation"] = r["gr_x_fit_standard_deviation"]
|
||||
ret[prefix+":gr_y_fit_standard_deviation"] = r["gr_y_fit_standard_deviation"]
|
||||
|
||||
mean_x_pv, mean_y_pv, sig_x_pv, sig_y_pv, ampl_x_pv, ampl_y_pv, integ_x_pv, integ_y_pv = create_thread_pvs([mean_x_name, mean_y_name, sig_x_name, sig_y_name, ampl_x_name, ampl_y_name, integ_x_name, integ_y_name])
|
||||
epics_error = None
|
||||
|
||||
if pulse_id > sent_pid:
|
||||
sent_pid = pulse_id
|
||||
if epics_lock.acquire(False):
|
||||
try:
|
||||
for (pv, value) in [ (mean_x_pv, r["gr_x_fit_mean"]), \
|
||||
(mean_y_pv, r["gr_y_fit_mean"]), \
|
||||
(sig_x_pv, r["gr_x_fit_standard_deviation"]), \
|
||||
(sig_y_pv, r["gr_y_fit_standard_deviation"]), \
|
||||
(ampl_x_pv, r["gr_x_fit_amplitude"]), \
|
||||
(ampl_y_pv, r["gr_y_fit_amplitude"]), \
|
||||
(integ_x_pv, x_fit_integ), \
|
||||
(integ_y_pv, y_fit_integ) \
|
||||
]:
|
||||
if pv and pv.connected:
|
||||
pv.put(value)
|
||||
else:
|
||||
_logger.warning("PV not connected: %s" % (str(pv),))
|
||||
#epics_error = "PV not connected: %s" % (str(pv),)
|
||||
except Exception as e:
|
||||
epics_error = "Error writing PVs: %s" % (str(e),)
|
||||
finally:
|
||||
epics_lock.release()
|
||||
else:
|
||||
_logger.warning("Cannot aquire EPICS lock")
|
||||
|
||||
if epics_error:
|
||||
_logger.warning(epics_error)
|
||||
if throw_epics_errors:
|
||||
raise Exception(epics_error)
|
||||
|
||||
return ret
|
||||
else:
|
||||
_logger.warning("Invalid PID: %s last:%s"% (str(pulse_id), str(sent_pid),))
|
||||
sent_pid = 0 # It should be single threaded, assumes the camera instance restarted
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
import sys
|
||||
import os
|
||||
|
||||
from cam_server.pipeline.data_processing import functions
|
||||
|
||||
# Bunch length measurement using the streak camera
|
||||
|
||||
import numpy as np
|
||||
from scipy import interpolate
|
||||
from scipy.signal import find_peaks
|
||||
import math
|
||||
from logging import getLogger
|
||||
|
||||
_logger = getLogger(__name__)
|
||||
|
||||
class PpolPeakValley():
|
||||
def __init__(self):
|
||||
self.x, self.y = self.lensrms()
|
||||
|
||||
def lenrms(image, x_axis=None, row_range=(60, 80), offset=2100, plot=False):
|
||||
row_start, row_end = row_range
|
||||
if row_end >= image.shape[0]:
|
||||
raise ValueError("Row range exceeds image height")
|
||||
|
||||
# Sum over selected rows to get horizontal profile
|
||||
averaged_row = np.sum(image[row_start:row_end + 1, :], axis=0)
|
||||
|
||||
# Subtract offset and clip to zero
|
||||
data = np.maximum(averaged_row - offset, 0)
|
||||
|
||||
# Use pixel index as x_axis if not provided
|
||||
if x_axis is None:
|
||||
x_axis = np.arange(data.shape[0])
|
||||
|
||||
# Compute moments
|
||||
mx1 = np.sum(x_axis * data) / np.sum(data)
|
||||
mx2 = np.sum((x_axis ** 2) * data) / np.sum(data)
|
||||
lenrms = np.sqrt(mx2 - mx1 ** 2)
|
||||
|
||||
return ret
|
||||
@@ -0,0 +1,92 @@
|
||||
from collections import OrderedDict
|
||||
from cam_server.utils import create_thread_pvs, epics_lock
|
||||
from logging import getLogger
|
||||
import json
|
||||
import math
|
||||
|
||||
_logger = getLogger(__name__)
|
||||
|
||||
mean_x_name, mean_y_name, sig_x_name, sig_y_name = None, None, None, None
|
||||
ampl_x_name, ampl_y_name, integ_x_name, integ_y_name = None, None, None, None
|
||||
camera_name = None
|
||||
sent_pid = -1
|
||||
|
||||
initialized = False
|
||||
throw_epics_errors = False
|
||||
|
||||
|
||||
def initialize(parameters, data):
|
||||
global initialized, camera_name
|
||||
global mean_x_name, mean_y_name, sig_x_name, sig_y_name, ampl_x_name, ampl_y_name, integ_x_name, integ_y_name
|
||||
processing_parameters = json.loads(data["processing_parameters"])
|
||||
camera_name = processing_parameters["camera_name"]
|
||||
mean_x_name = camera_name + ":POS-X"
|
||||
mean_y_name = camera_name + ":POS-Y"
|
||||
sig_x_name = camera_name + ":SIG-X"
|
||||
sig_y_name = camera_name + ":SIG-Y"
|
||||
ampl_x_name = camera_name + ":AMPL-X"
|
||||
ampl_y_name = camera_name + ":AMPL-Y"
|
||||
integ_x_name = camera_name + ":INTEG-X"
|
||||
integ_y_name = camera_name + ":INTEG-Y"
|
||||
initialized = True
|
||||
|
||||
|
||||
def process(data, pulse_id, timestamp, parameters):
|
||||
global initialized, sent_pid, camera_name
|
||||
global mean_x_name, mean_y_name, sig_x_name, sig_y_name
|
||||
|
||||
if not initialized:
|
||||
initialize(parameters, data)
|
||||
initialized = True
|
||||
|
||||
mean_x_pv, mean_y_pv, sig_x_pv, sig_y_pv, ampl_x_pv, ampl_y_pv, integ_x_pv, integ_y_pv = create_thread_pvs([mean_x_name, mean_y_name, sig_x_name, sig_y_name, ampl_x_name, ampl_y_name, integ_x_name, integ_y_name])
|
||||
|
||||
ret = OrderedDict()
|
||||
throw_epics_errors = parameters.get("throw_epics_errors", True)
|
||||
|
||||
x_fit_integ = data["x_fit_amplitude"] * data["x_fit_standard_deviation"] * math.sqrt(2*math.pi)
|
||||
y_fit_integ = data["y_fit_amplitude"] * data["y_fit_standard_deviation"] * math.sqrt(2*math.pi)
|
||||
|
||||
channels = ["intensity", "x_fit_mean", "y_fit_mean", "x_fit_standard_deviation", "y_fit_standard_deviation",
|
||||
"x_center_of_mass", "y_center_of_mass", "x_rms", "y_rms", "x_fwhm", "y_fwhm","x_fit_amplitude", "y_fit_amplitude"]
|
||||
|
||||
for c in channels:
|
||||
ret[camera_name + ":" + c] = data[c]
|
||||
ret[camera_name + ":x_fit_integ"] = x_fit_integ
|
||||
ret[camera_name + ":y_fit_integ"] = y_fit_integ
|
||||
|
||||
epics_error = None
|
||||
|
||||
if pulse_id > sent_pid:
|
||||
sent_pid = pulse_id
|
||||
if epics_lock.acquire(False):
|
||||
try:
|
||||
for (pv, value) in [(mean_x_pv, data["x_center_of_mass"]), \
|
||||
(mean_y_pv, data["y_center_of_mass"]), \
|
||||
(sig_x_pv, data["x_rms"]), \
|
||||
(sig_y_pv, data["y_rms"]), \
|
||||
(ampl_x_pv, data["x_fit_amplitude"]), \
|
||||
(ampl_y_pv, data["y_fit_amplitude"]), \
|
||||
(integ_x_pv, x_fit_integ), \
|
||||
(integ_y_pv, y_fit_integ) \
|
||||
]:
|
||||
if pv and pv.connected:
|
||||
pv.put(value)
|
||||
else:
|
||||
_logger.warning("PV not connected: %s" % (str(pv),))
|
||||
# epics_error = "PV not connected: %s" % (str(pv),)
|
||||
except Exception as e:
|
||||
epics_error = "Error writing PVs: %s" % (str(e),)
|
||||
finally:
|
||||
epics_lock.release()
|
||||
else:
|
||||
_logger.warning("Cannot aquire EPICS lock")
|
||||
|
||||
if epics_error:
|
||||
_logger.warning(epics_error)
|
||||
if throw_epics_errors:
|
||||
raise Exception(epics_error)
|
||||
return ret
|
||||
else:
|
||||
_logger.warning("Invalid PID: %s last:%s" % (str(pulse_id), str(sent_pid),))
|
||||
sent_pid = 0 # It should be single threaded, assumes the camera instance restarted
|
||||
Reference in New Issue
Block a user