From 2520718f2cd9e289267ffa7cb439151a70e52d8e Mon Sep 17 00:00:00 2001 From: root Date: Tue, 12 Aug 2025 11:36:07 +0200 Subject: [PATCH] 08 2025 --- .../camera_config/S10BC02-DSRM310.json | 12 +- .../camera_config/SARES20-CAMS142-M1.json | 8 +- .../camera_config/SARES20-CAMS142-M2.json | 14 +- .../camera_config/SARES20-CAMS142-M3.json | 8 +- .../camera_config/SARES20-PROF141-M1.json | 1 + .../camera_config/SARES20-PROF146-M1.json | 1 + .../camera_config/SATBD01-DSCR210.json | 4 +- .../camera_config/SATES30-CAMS182-GIGE1.json | 12 +- .../camera_config/SATES30-CAMS182-GIGE2.json | 12 +- .../camera_config/SATES30-CAMS182-GIGE6.json | 1 + .../camera_config/SATES31-CAMS187-PCO2.json | 13 + .../camera_config/SATOP11-PSAS079.json | 8 +- .../camera_config/SATOP31-PSCA176.json | 2 +- .../camera_config/SATUN04-DSCR050.json | 3 +- .../camera_config/SLAAR02-LPMO05-C301.json | 27 ++ .../camera_config/SLAAR02-LPMO06-C302.json | 27 ++ .../camera_config/SLAAR21-LCAM-C561.json | 10 +- .../camera_config/permanent_instances.json | 5 +- configuration/camera_config/servers.json | 7 + .../camera_config/test_bschannel.json | 10 + configuration/camera_config/test_stddaq.json | 10 + .../pipeline_config/AGalvotest1.json | 20 ++ .../pipeline_config/AGalvotest2.json | 20 ++ .../pipeline_config/SARBD02-DSCR050_sp.json | 10 +- .../SARES11-SPEC125-M1_psen_db.json | 2 +- .../SARES11-SPEC125-M2_db.json | 6 +- .../pipeline_config/SARES21-PBPS141_proc.json | 10 +- .../pipeline_config/SARFE10-PBPS053_proc.json | 38 +-- .../SARFE10-PSSS059-LB_psss.json | 2 +- .../pipeline_config/SARFE10-PSSS059_psss.json | 2 +- .../pipeline_config/SAROP11-PBPS110_proc.json | 38 +-- .../pipeline_config/SAROP11-PBPS122_proc.json | 38 +-- .../pipeline_config/SAROP21-ATT01_proc.json | 10 +- .../pipeline_config/SAROP21-PBPS103_proc.json | 38 +-- .../pipeline_config/SAROP21-PBPS133_proc.json | 38 +-- .../pipeline_config/SAROP31-PBPS113_proc.json | 38 +-- .../pipeline_config/SAROP31-PBPS149_proc.json | 38 +-- .../pipeline_config/SATBD02-DSCR050_sp.json | 7 +- .../SATES21-CAMS-PATT1_spec_db.json | 16 +- .../SATES21-CAMS154-M1_spec_db.json | 18 +- .../SATES22-ADTEST1-CAM4_sp.json | 11 + .../SATES22-ADTEST1-CAM7_sp.json | 11 + .../SATES24-CAMS161-M1_spec_db.json | 25 +- .../SATES30-RIXS-CAM01_proc.json | 2 +- .../SATES31-CAMS187-PCO2_proc.json | 16 + .../SATES31-CAMS187-PCO2_sp.json | 12 + .../SATES31-CAMS187-RIXS1_sp.json | 4 +- .../pipeline_config/SATOP31-ATT01_proc.json | 6 +- .../SATOP31-PMOS132-2D_pmos.json | 2 +- .../pipeline_config/SATOP31-PSRD132_pmos.json | 4 +- .../pipeline_config/SATUN04-DSCR05_sp.json | 11 + .../SLAAR02-LPMO05-C301_sp.json | 11 + .../SLAAR02-LPMO06-C302_sp.json | 11 + .../pipeline_config/permanent_instances.json | 4 + configuration/pipeline_config/servers.json | 13 +- .../pipeline_config/simulation_sp.json | 12 +- .../pipeline_config/test_bschannel_sp.json | 12 + .../pipeline_config/test_stddaq_sp.json | 12 + .../swissfel_spectral_processing.py | 65 +++- .../swissfel_spectral_processing_bkg2.py | 310 ++++++++++++++++++ .../swissfel_spectral_processing_fast.py | 58 +++- 61 files changed, 926 insertions(+), 270 deletions(-) create mode 100644 configuration/camera_config/SATES31-CAMS187-PCO2.json create mode 100644 configuration/camera_config/SLAAR02-LPMO05-C301.json create mode 100644 configuration/camera_config/SLAAR02-LPMO06-C302.json create mode 100644 configuration/camera_config/test_bschannel.json create mode 100644 configuration/camera_config/test_stddaq.json create mode 100644 configuration/pipeline_config/AGalvotest1.json create mode 100644 configuration/pipeline_config/AGalvotest2.json create mode 100644 configuration/pipeline_config/SATES22-ADTEST1-CAM4_sp.json create mode 100644 configuration/pipeline_config/SATES22-ADTEST1-CAM7_sp.json create mode 100644 configuration/pipeline_config/SATES31-CAMS187-PCO2_proc.json create mode 100644 configuration/pipeline_config/SATES31-CAMS187-PCO2_sp.json create mode 100644 configuration/pipeline_config/SATUN04-DSCR05_sp.json create mode 100644 configuration/pipeline_config/SLAAR02-LPMO05-C301_sp.json create mode 100644 configuration/pipeline_config/SLAAR02-LPMO06-C302_sp.json create mode 100644 configuration/pipeline_config/test_bschannel_sp.json create mode 100644 configuration/pipeline_config/test_stddaq_sp.json create mode 100644 configuration/user_scripts/swissfel_spectral_processing_bkg2.py diff --git a/configuration/camera_config/S10BC02-DSRM310.json b/configuration/camera_config/S10BC02-DSRM310.json index ac81bf5..a30052d 100644 --- a/configuration/camera_config/S10BC02-DSRM310.json +++ b/configuration/camera_config/S10BC02-DSRM310.json @@ -16,9 +16,14 @@ "rotate": 0, "roi": null, "image_background": null, - "source_type": "bsread", + "source_type": "stddaq", "name": "S10BC02-DSRM310", + "__source_type": "bsread", "source": "S10BC02-DSRM310", + "url": "sf-daq-6.psi.ch:6379", + "_source": "tcp://sf-daq-6.psi.ch:30032", + "_source_type": "array10", + "mode": "SUB", "group": [ "Electrons" ], @@ -26,6 +31,7 @@ "connections": 2, "_buffer_size": 40, "threaded": true, - "debug": true, - "_forwarder_port": 9015 + "debug": false, + "_forwarder_port": 9015, + "no_client_timeout": 0 } \ No newline at end of file diff --git a/configuration/camera_config/SARES20-CAMS142-M1.json b/configuration/camera_config/SARES20-CAMS142-M1.json index eb589f3..072fa2f 100644 --- a/configuration/camera_config/SARES20-CAMS142-M1.json +++ b/configuration/camera_config/SARES20-CAMS142-M1.json @@ -1,10 +1,10 @@ { "camera_calibration": { "reference_marker": [ - 642, - 497, - 644, - 499 + 788, + 450, + 795, + 459 ], "reference_marker_width": 16.256, "reference_marker_height": 16.256, diff --git a/configuration/camera_config/SARES20-CAMS142-M2.json b/configuration/camera_config/SARES20-CAMS142-M2.json index e7fae46..ab43027 100644 --- a/configuration/camera_config/SARES20-CAMS142-M2.json +++ b/configuration/camera_config/SARES20-CAMS142-M2.json @@ -1,13 +1,13 @@ { "camera_calibration": { "reference_marker": [ - 1100, - 1230, - 1102, - 1232 + 1207, + 1207, + 1209, + 1209 ], "reference_marker_width": 20.0, - "reference_marker_height": 12.356435643564357, + "reference_marker_height": 20.0, "angle_horizontal": 0.0, "angle_vertical": 0.0 }, @@ -24,5 +24,7 @@ "Photonics", "Bernina" ], - "alias": [] + "alias": [ + "THC_INLINE (SARES20-CAMS142-M2)" + ] } \ No newline at end of file diff --git a/configuration/camera_config/SARES20-CAMS142-M3.json b/configuration/camera_config/SARES20-CAMS142-M3.json index e859bca..cc4decb 100644 --- a/configuration/camera_config/SARES20-CAMS142-M3.json +++ b/configuration/camera_config/SARES20-CAMS142-M3.json @@ -1,10 +1,10 @@ { "camera_calibration": { "reference_marker": [ - 1492, - 705, - 1494, - 707 + 1496, + 704, + 1498, + 706 ], "reference_marker_width": 19.333333333333332, "reference_marker_height": 22.4, diff --git a/configuration/camera_config/SARES20-PROF141-M1.json b/configuration/camera_config/SARES20-PROF141-M1.json index 26b0f2b..f6acab5 100644 --- a/configuration/camera_config/SARES20-PROF141-M1.json +++ b/configuration/camera_config/SARES20-PROF141-M1.json @@ -20,6 +20,7 @@ "name": "SARES20-PROF141-M1", "protocol": "tcp", "source": "SARES20-PROF141-M1", + "forwarder_port": 9013, "_debug": true, "alias": [ "PROF_KB (SARES20-PROF141-M1) (SARES20-PROF141-M1)" diff --git a/configuration/camera_config/SARES20-PROF146-M1.json b/configuration/camera_config/SARES20-PROF146-M1.json index 6647aa8..c66b520 100644 --- a/configuration/camera_config/SARES20-PROF146-M1.json +++ b/configuration/camera_config/SARES20-PROF146-M1.json @@ -24,6 +24,7 @@ "Photonics", "Bernina" ], + "forwarder_port": 9044, "alias": [ "PROF_DSD (SARES20-PROF146-M1)(SARES20-PROF146-M1)" ] diff --git a/configuration/camera_config/SATBD01-DSCR210.json b/configuration/camera_config/SATBD01-DSCR210.json index 88e601d..eb400b9 100644 --- a/configuration/camera_config/SATBD01-DSCR210.json +++ b/configuration/camera_config/SATBD01-DSCR210.json @@ -1,9 +1,9 @@ { "camera_calibration": { "reference_marker": [ - 955, + 1195, 585, - 1291, + 1531, 1476 ], "reference_marker_width": 6000.0, diff --git a/configuration/camera_config/SATES30-CAMS182-GIGE1.json b/configuration/camera_config/SATES30-CAMS182-GIGE1.json index 7b6cef6..e31dba3 100644 --- a/configuration/camera_config/SATES30-CAMS182-GIGE1.json +++ b/configuration/camera_config/SATES30-CAMS182-GIGE1.json @@ -1,13 +1,13 @@ { "camera_calibration": { "reference_marker": [ - 219, - 281, - 316, - 382 + 177, + 95, + 419, + 337 ], - "reference_marker_width": 5000.0, - "reference_marker_height": 5000.0, + "reference_marker_width": 10000.0, + "reference_marker_height": 10000.0, "angle_horizontal": 0.0, "angle_vertical": 0.0 }, diff --git a/configuration/camera_config/SATES30-CAMS182-GIGE2.json b/configuration/camera_config/SATES30-CAMS182-GIGE2.json index 0055bb2..986cb45 100644 --- a/configuration/camera_config/SATES30-CAMS182-GIGE2.json +++ b/configuration/camera_config/SATES30-CAMS182-GIGE2.json @@ -1,13 +1,13 @@ { "camera_calibration": { "reference_marker": [ - 736, - 100, - 1828, - 1175 + 904, + 147, + 1155, + 411 ], - "reference_marker_width": 5000.0, - "reference_marker_height": 5000.0, + "reference_marker_width": 1000.0, + "reference_marker_height": 1000.0, "angle_horizontal": 0.0, "angle_vertical": 0.0 }, diff --git a/configuration/camera_config/SATES30-CAMS182-GIGE6.json b/configuration/camera_config/SATES30-CAMS182-GIGE6.json index d8d90f8..a7b7cd5 100644 --- a/configuration/camera_config/SATES30-CAMS182-GIGE6.json +++ b/configuration/camera_config/SATES30-CAMS182-GIGE6.json @@ -18,6 +18,7 @@ "image_background": null, "source_type": "bsread", "protocol": "tcp", + "forwarder_port": 9009, "source": "SATES30-CAMS182-GIGE6", "name": "SATES30-CAMS182-GIGE6", "prefix": "SATES30-CAMS182-GIGE6", diff --git a/configuration/camera_config/SATES31-CAMS187-PCO2.json b/configuration/camera_config/SATES31-CAMS187-PCO2.json new file mode 100644 index 0000000..a4c579a --- /dev/null +++ b/configuration/camera_config/SATES31-CAMS187-PCO2.json @@ -0,0 +1,13 @@ +{ + "camera_calibration": null, + "mirror_x": false, + "mirror_y": false, + "rotate": 0, + "roi": null, + "image_background": null, + "source_type": "bsread", + "name": "SATES31-CAMS187-PCO2", + "source": "SATES31-CAMS187-PCO2", + "prefix": "SATES31-CAMS187-PCO2", + "forwarder_port": 9013 +} \ No newline at end of file diff --git a/configuration/camera_config/SATOP11-PSAS079.json b/configuration/camera_config/SATOP11-PSAS079.json index 130ad0e..5f81b98 100644 --- a/configuration/camera_config/SATOP11-PSAS079.json +++ b/configuration/camera_config/SATOP11-PSAS079.json @@ -27,10 +27,10 @@ "hardware_configuration": { "EXPOSURE": 1.0, "HSSPEED": 0.0, - "REGIONX_START": 8.0, - "REGIONY_START": 810.0, - "REGIONX_END": 4104.0, - "REGIONY_END": 1200.0, + "REGIONX_START": 1420, + "REGIONY_START": 790.0, + "REGIONX_END": 3210, + "REGIONY_END": 1130, "TRIGGER": 1, "TRIGGERSOURCE": 0, "DELAY": 0.0, diff --git a/configuration/camera_config/SATOP31-PSCA176.json b/configuration/camera_config/SATOP31-PSCA176.json index b396c72..48ecb84 100644 --- a/configuration/camera_config/SATOP31-PSCA176.json +++ b/configuration/camera_config/SATOP31-PSCA176.json @@ -12,7 +12,7 @@ "angle_vertical": 0.0 }, "mirror_x": false, - "mirror_y": false, + "mirror_y": true, "rotate": 0, "roi": null, "image_background": null, diff --git a/configuration/camera_config/SATUN04-DSCR050.json b/configuration/camera_config/SATUN04-DSCR050.json index a291430..ac87e82 100644 --- a/configuration/camera_config/SATUN04-DSCR050.json +++ b/configuration/camera_config/SATUN04-DSCR050.json @@ -17,7 +17,8 @@ "roi": null, "image_background": null, "source_type": "epics", - "source": "SATUN04-DSCR050:RF", + "_source": "SATUN04-DSCR050:RF", + "source": "SATUN04-DSCR050", "name": "SATUN04-DSCR050", "group": [ "Electrons" diff --git a/configuration/camera_config/SLAAR02-LPMO05-C301.json b/configuration/camera_config/SLAAR02-LPMO05-C301.json new file mode 100644 index 0000000..c5ed868 --- /dev/null +++ b/configuration/camera_config/SLAAR02-LPMO05-C301.json @@ -0,0 +1,27 @@ +{ + "camera_calibration": { + "reference_marker": [ + 1, + 1, + 2, + 2 + ], + "reference_marker_width": 5.3, + "reference_marker_height": 5.3, + "angle_horizontal": 0.0, + "angle_vertical": 0.0 + }, + "mirror_x": false, + "mirror_y": false, + "rotate": 0, + "roi": null, + "image_background": null, + "source_type": "bsread", + "name": "SLAAR02-LPMO05-C301", + "source": "SLAAR02-LPMO05-C301", + "group": [ + "Laser", + "Bernina" + ], + "alias": [] +} \ No newline at end of file diff --git a/configuration/camera_config/SLAAR02-LPMO06-C302.json b/configuration/camera_config/SLAAR02-LPMO06-C302.json new file mode 100644 index 0000000..a34fe5e --- /dev/null +++ b/configuration/camera_config/SLAAR02-LPMO06-C302.json @@ -0,0 +1,27 @@ +{ + "camera_calibration": { + "reference_marker": [ + 122, + 130, + 133, + 139 + ], + "reference_marker_width": 58.0, + "reference_marker_height": 48.4, + "angle_horizontal": 0.0, + "angle_vertical": 0.0 + }, + "mirror_x": false, + "mirror_y": false, + "rotate": 0, + "roi": null, + "image_background": null, + "source_type": "bsread", + "name": "SLAAR02-LPMO06-C302", + "source": "SLAAR02-LPMO06-C302", + "group": [ + "Laser", + "Bernina" + ], + "alias": [] +} \ No newline at end of file diff --git a/configuration/camera_config/SLAAR21-LCAM-C561.json b/configuration/camera_config/SLAAR21-LCAM-C561.json index e20b600..410ac45 100644 --- a/configuration/camera_config/SLAAR21-LCAM-C561.json +++ b/configuration/camera_config/SLAAR21-LCAM-C561.json @@ -1,13 +1,13 @@ { "camera_calibration": { "reference_marker": [ - 98, - 85, - 109, - 96 + 122, + 130, + 133, + 139 ], "reference_marker_width": 58.0, - "reference_marker_height": 58.4, + "reference_marker_height": 48.4, "angle_horizontal": 0.0, "angle_vertical": 0.0 }, diff --git a/configuration/camera_config/permanent_instances.json b/configuration/camera_config/permanent_instances.json index 780d3d8..37ddaca 100644 --- a/configuration/camera_config/permanent_instances.json +++ b/configuration/camera_config/permanent_instances.json @@ -1,5 +1,4 @@ { - "#S10BC02-DSRM310": "S10BC02-DSRM310", "#SAROP21-PPRM133": "SAROP21-PPRM133", "#SATES21-ADTEST1-CAM1": "SATES21-ADTEST1-CAM1", "#SATES21-ADTEST1-CAM2": "SATES21-ADTEST1-CAM2", @@ -7,6 +6,7 @@ "#SATES21-ADTEST1-CAM4": "SATES21-ADTEST1-CAM4", "#SATES21-ADTEST1-CAM5": "SATES21-ADTEST1-CAM5", "#SINBC02-DSRM310": "SINBC02-DSRM310", + "S10BC02-DSRM310": "S10BC02-DSRM310", "S10BD01-DSCR030": "S10BD01-DSCR030", "S10DI01-DSCR020": "S10DI01-DSCR020", "SARCL01-DSCR170": "SARCL01-DSCR170", @@ -43,6 +43,7 @@ "SATES24-CAMS161-M1": "SATES24-CAMS161-M1", "SATES30-CAMS182-GIGE1": "SATES30-CAMS182-GIGE1", "SATES30-CAMS182-GIGE2": "SATES30-CAMS182-GIGE2", + "SATES30-CAMS182-GIGE6": "SATES30-CAMS182-GIGE6", "SATES30-RIXS-CAM01": "SATES30-RIXS-CAM01", "SATES31-CAMS187-RIXS1": "SATES31-CAMS187-RIXS1", "SATFE10-PSRD066": "SATFE10-PSRD066", @@ -55,5 +56,7 @@ "SINDI02-DSCR075": "SINDI02-DSCR075", "SLAAR02-LPMO01-C321": "SLAAR02-LPMO01-C321", "SLAAR02-LPMO02-C322": "SLAAR02-LPMO02-C322", + "SLAAR02-LPMO05-C301": "SLAAR02-LPMO05-C301", + "SLAAR02-LPMO06-C302": "SLAAR02-LPMO06-C302", "SLAAR12-LSPC-SPEC1": "SLAAR12-LSPC-SPEC1" } \ No newline at end of file diff --git a/configuration/camera_config/servers.json b/configuration/camera_config/servers.json index ddf4ed3..efa1c42 100644 --- a/configuration/camera_config/servers.json +++ b/configuration/camera_config/servers.json @@ -44,6 +44,9 @@ "S10DI01-DSCR020", "SATBD02-DSCR050", "SARCL01-DSCR170", + "SARBD02-DSCR051", + "test_bschannel", + "test_stddaq", "SARCL02-DSCR280" ] }, @@ -104,6 +107,8 @@ "enabled": true, "expanding": false, "instances": [ + "SLAAR02-LPMO05-C301", + "SLAAR02-LPMO06-C302", "SARES20-CAMS142-M1", "SARES20-CAMS142-M2", "SARES20-CAMS142-M3", @@ -135,7 +140,9 @@ "SATES30-CAMS182-GIGE3", "SATES30-CAMS182-GIGE4", "SATES30-CAMS182-GIGE5", + "SATES30-CAMS182-GIGE6", "SATES30-RIXS-CAM01", + "SATES31-CAMS187-PCO2", "furka_jungfrau" ] }, diff --git a/configuration/camera_config/test_bschannel.json b/configuration/camera_config/test_bschannel.json new file mode 100644 index 0000000..ab415b6 --- /dev/null +++ b/configuration/camera_config/test_bschannel.json @@ -0,0 +1,10 @@ +{ + "name": "test_bschannel", + "mirror_x": false, + "mirror_y": false, + "rotate": 0, + "source_type": "bschannel", + "source": "tcp://sf-daq-6.psi.ch:30031", + "channel": "S10BC02-DSRM310:FPICTURE", + "mode": "SUB" +} \ No newline at end of file diff --git a/configuration/camera_config/test_stddaq.json b/configuration/camera_config/test_stddaq.json new file mode 100644 index 0000000..4ef7453 --- /dev/null +++ b/configuration/camera_config/test_stddaq.json @@ -0,0 +1,10 @@ +{ + "name": "test_stddaq", + "mirror_x": false, + "mirror_y": false, + "rotate": 0, + "source_type": "stddaq", + "source": "S10BC02-DSRM310", + "url": "sf-daq-6.psi.ch:6379", + "mode": "SUB" +} \ No newline at end of file diff --git a/configuration/pipeline_config/AGalvotest1.json b/configuration/pipeline_config/AGalvotest1.json new file mode 100644 index 0000000..7269c5c --- /dev/null +++ b/configuration/pipeline_config/AGalvotest1.json @@ -0,0 +1,20 @@ +{ + "image_background_enable": false, + "image_background": null, + "image_threshold": null, + "image_region_of_interest": null, + "image_good_region": { + "threshold": 0.5, + "gfscale": 3.0 + }, + "image_slices": null, + "pipeline_type": "processing", + "camera_name": "SLAAR02-LPMO05-C301", + "name": "AGalvotest1", + "function": "pprm_simple.py", + "mode": "PUSH", + "allow_type_changes": false, + "no_client_timeout": 0, + "port": "9015", + "reload": true +} \ No newline at end of file diff --git a/configuration/pipeline_config/AGalvotest2.json b/configuration/pipeline_config/AGalvotest2.json new file mode 100644 index 0000000..bd6a907 --- /dev/null +++ b/configuration/pipeline_config/AGalvotest2.json @@ -0,0 +1,20 @@ +{ + "image_background_enable": false, + "image_background": null, + "image_threshold": null, + "image_region_of_interest": null, + "image_good_region": { + "threshold": 0.5, + "gfscale": 3.0 + }, + "image_slices": null, + "pipeline_type": "processing", + "camera_name": "SLAAR02-LPMO06-C302", + "name": "AGalvotest2", + "function": "pprm_simple.py", + "mode": "PUSH", + "allow_type_changes": false, + "no_client_timeout": 0, + "port": "9015", + "reload": true +} \ No newline at end of file diff --git a/configuration/pipeline_config/SARBD02-DSCR050_sp.json b/configuration/pipeline_config/SARBD02-DSCR050_sp.json index 9d78fcb..30a70fd 100644 --- a/configuration/pipeline_config/SARBD02-DSCR050_sp.json +++ b/configuration/pipeline_config/SARBD02-DSCR050_sp.json @@ -1,12 +1,12 @@ { - "image_background_enable": true, + "image_background_enable": false, "image_background": "SARBD02-DSCR050_20250305_182528_541069", "image_threshold": null, "image_region_of_interest": [ - 1171, - 448, - 461, - 1364 + 1012, + 519, + 446, + 1492 ], "image_good_region": null, "image_slices": null, diff --git a/configuration/pipeline_config/SARES11-SPEC125-M1_psen_db.json b/configuration/pipeline_config/SARES11-SPEC125-M1_psen_db.json index 612cd3f..a751cc0 100644 --- a/configuration/pipeline_config/SARES11-SPEC125-M1_psen_db.json +++ b/configuration/pipeline_config/SARES11-SPEC125-M1_psen_db.json @@ -1,6 +1,6 @@ { "image_background_enable": "passive", - "image_background": "SARES11-SPEC125-M1_20250501_183259_735224", + "image_background": "SARES11-SPEC125-M1_20250619_162742_527140", "image_threshold": null, "image_region_of_interest": null, "image_good_region": null, diff --git a/configuration/pipeline_config/SARES11-SPEC125-M2_db.json b/configuration/pipeline_config/SARES11-SPEC125-M2_db.json index bd1793d..f991302 100644 --- a/configuration/pipeline_config/SARES11-SPEC125-M2_db.json +++ b/configuration/pipeline_config/SARES11-SPEC125-M2_db.json @@ -12,10 +12,10 @@ "mode": "PUSH", "allow_type_changes": false, "roi_signal": [ - 1000, - 1200, + 700, 1100, - 1700 + 0, + 2000 ], "roi_background": [ 0, diff --git a/configuration/pipeline_config/SARES21-PBPS141_proc.json b/configuration/pipeline_config/SARES21-PBPS141_proc.json index 846db95..84bbb4e 100644 --- a/configuration/pipeline_config/SARES21-PBPS141_proc.json +++ b/configuration/pipeline_config/SARES21-PBPS141_proc.json @@ -26,10 +26,10 @@ "down": "SARES21-PBPS141:Lnk9Ch0-PP_VAL_PD2", "right": "SARES21-PBPS141:Lnk9Ch0-PP_VAL_PD3", "left": "SARES21-PBPS141:Lnk9Ch0-PP_VAL_PD0", - "up_calib": 9.086696828684651e-06, - "down_calib": 8.479198152755808e-06, - "left_calib": 2.402225113860666e-05, - "right_calib": 1.253692752001019e-05, + "up_calib": 0.0034218450588557347, + "down_calib": 0.0032857555923560184, + "left_calib": 0.008527766407422569, + "right_calib": 0.005182206376186726, "horiz_calib": -5.93887, "vert_calib": -9.0057, "uJ_calib": 941.943984588351, @@ -94,5 +94,5 @@ 0.11052246554408188, 0.11072063526778356 ], - "calib_datetime": "2025-05-06 11:19:16" + "calib_datetime": "2025-07-18 08:38:03" } \ No newline at end of file diff --git a/configuration/pipeline_config/SARFE10-PBPS053_proc.json b/configuration/pipeline_config/SARFE10-PBPS053_proc.json index 7b99638..85b47e8 100644 --- a/configuration/pipeline_config/SARFE10-PBPS053_proc.json +++ b/configuration/pipeline_config/SARFE10-PBPS053_proc.json @@ -26,12 +26,12 @@ "down": "SARFE10-PBPS053:Lnk9Ch0-PP_VAL_PD2", "right": "SARFE10-PBPS053:Lnk9Ch0-PP_VAL_PD3", "left": "SARFE10-PBPS053:Lnk9Ch0-PP_VAL_PD0", - "up_calib": 5.3603874230730805e-05, - "down_calib": 6.429273872665403e-05, - "left_calib": 0.0001873753953620842, - "right_calib": 0.00011135083709105292, - "horiz_calib": -3.5966302878741434, - "vert_calib": -5.704870102644, + "up_calib": 8.633479112505974e-05, + "down_calib": 0.0001042203401418397, + "left_calib": 0.0003061204498256338, + "right_calib": 0.00017606576126609594, + "horiz_calib": -3.393096838515036, + "vert_calib": -5.192750296774873, "uJ_calib": 834.5191797495979, "threshold": 0, "queue_length": 5000, @@ -69,9 +69,9 @@ 0.3 ], "calib_x_norm": [ - 0.08373324791431114, - 0.0002666207178174507, - -0.08308957010589782 + 0.08811721513032335, + -4.067443571301668e-05, + -0.08871239762620074 ], "calib_y_range": [ -0.3, @@ -79,20 +79,20 @@ 0.3 ], "calib_y_norm": [ - 0.05334340044159048, - 6.423190047678002e-05, - -0.051829896970023125 + 0.05874380605733328, + 2.452356570837876e-05, + -0.056801900111640324 ], "calib_time": "2022-11-28 16:19:37", - "calib_datetime": "2025-05-12 19:38:08", + "calib_datetime": "2025-06-30 21:22:50", "calib_x_norm_std": [ - 0.03694393985351428, - 0.036381119656154114, - 0.037504981101666966 + 0.061973364995272784, + 0.05926920770976579, + 0.06478227269887708 ], "calib_y_norm_std": [ - 0.032515850998287014, - 0.031406268858134787, - 0.03357316145483791 + 0.06312747470291118, + 0.058446505041557885, + 0.061107151961064754 ] } \ No newline at end of file diff --git a/configuration/pipeline_config/SARFE10-PSSS059-LB_psss.json b/configuration/pipeline_config/SARFE10-PSSS059-LB_psss.json index 310639a..c5a585a 100644 --- a/configuration/pipeline_config/SARFE10-PSSS059-LB_psss.json +++ b/configuration/pipeline_config/SARFE10-PSSS059-LB_psss.json @@ -8,7 +8,7 @@ "pipeline_type": "processing", "camera_name": "SARFE10-PSSS059-LB", "name": "SARFE10-PSSS059-LB_psss", - "function": "psss_2.py", + "function": "swissfel_spectral_processing.py", "mode": "PUSH", "allow_type_changes": false, "no_client_timeout": 0, diff --git a/configuration/pipeline_config/SARFE10-PSSS059_psss.json b/configuration/pipeline_config/SARFE10-PSSS059_psss.json index 6786b89..07a0732 100644 --- a/configuration/pipeline_config/SARFE10-PSSS059_psss.json +++ b/configuration/pipeline_config/SARFE10-PSSS059_psss.json @@ -8,7 +8,7 @@ "pipeline_type": "processing", "camera_name": "SARFE10-PSSS059", "name": "SARFE10-PSSS059_psss", - "function": "swissfel_spectral_processing_fast.py", + "function": "swissfel_spectral_processing.py", "mode": "PUSH", "allow_type_changes": false, "no_client_timeout": 0, diff --git a/configuration/pipeline_config/SAROP11-PBPS110_proc.json b/configuration/pipeline_config/SAROP11-PBPS110_proc.json index 05e3c06..055d1e0 100644 --- a/configuration/pipeline_config/SAROP11-PBPS110_proc.json +++ b/configuration/pipeline_config/SAROP11-PBPS110_proc.json @@ -26,12 +26,12 @@ "down": "SAROP11-PBPS110:Lnk9Ch0-PP_VAL_PD2", "right": "SAROP11-PBPS110:Lnk9Ch0-PP_VAL_PD3", "left": "SAROP11-PBPS110:Lnk9Ch0-PP_VAL_PD0", - "up_calib": 1.778951980962652e-05, - "down_calib": 1.647636031137421e-05, - "left_calib": 1.343967521143297e-05, - "right_calib": 1.4712267477026206e-05, - "horiz_calib": -4.084489404678124, - "vert_calib": -4.152037498266164, + "up_calib": 0.0001022569332245865, + "down_calib": 9.511294471959562e-05, + "left_calib": 8.063480882131907e-05, + "right_calib": 8.028682306967998e-05, + "horiz_calib": -4.224711312085033, + "vert_calib": -4.13819794609348, "uJ_calib": 605.4608924473305, "threshold": 0, "queue_length": 1000, @@ -69,9 +69,9 @@ 0.3 ], "calib_x_norm": [ - 0.07355089424549768, - 0.0005918260320667978, - -0.07334629180492924 + 0.07025056065580759, + 5.415676993147808e-05, + -0.07177097778249114 ], "calib_y_range": [ -0.3, @@ -79,19 +79,19 @@ 0.3 ], "calib_y_norm": [ - 0.07059159363843578, - -0.0010492828771324209, - -0.07391577178168675 + 0.07125245801920767, + -7.646332998672576e-05, + -0.07373818955636538 ], - "calib_datetime": "2025-05-08 19:40:32", + "calib_datetime": "2025-07-17 21:44:14", "calib_x_norm_std": [ - 0.03951572779577543, - 0.036895048152752644, - 0.04082834764914548 + 0.04567411017192871, + 0.04489322077121599, + 0.045452729857613255 ], "calib_y_norm_std": [ - 0.042522854070151855, - 0.04157478982211735, - 0.03874863852211236 + 0.045872146420338974, + 0.04796098280035745, + 0.044361688908978424 ] } \ No newline at end of file diff --git a/configuration/pipeline_config/SAROP11-PBPS122_proc.json b/configuration/pipeline_config/SAROP11-PBPS122_proc.json index 0ad9774..31e798b 100644 --- a/configuration/pipeline_config/SAROP11-PBPS122_proc.json +++ b/configuration/pipeline_config/SAROP11-PBPS122_proc.json @@ -27,12 +27,12 @@ "down": "SAROP11-PBPS122:Lnk9Ch0-PP_VAL_PD2", "right": "SAROP11-PBPS122:Lnk9Ch0-PP_VAL_PD3", "left": "SAROP11-PBPS122:Lnk9Ch0-PP_VAL_PD0", - "up_calib": 3.136666045188568e-05, - "down_calib": 4.287710153537755e-05, - "left_calib": 1.9240676699217273e-05, - "right_calib": 1.9033978392323185e-05, - "horiz_calib": -4.800851116441316, - "vert_calib": -4.325389727023896, + "up_calib": 7.351388736143368e-05, + "down_calib": 0.00010575994016525625, + "left_calib": 6.948416622613705e-05, + "right_calib": 6.608864655210245e-05, + "horiz_calib": -4.356338212003961, + "vert_calib": -4.095658834474431, "uJ_calib": 605.9512700123181, "threshold": 0, "queue_length": 1000, @@ -70,14 +70,14 @@ 0.3 ], "calib_x_norm": [ - 0.06260165947402832, - 0.0005469889807531498, - -0.06237617996473284 + 0.06890356395488378, + -0.0004675885333441556, + -0.06882678910785368 ], "calib_x_norm_std": [ - 0.037489193261730905, - 0.04049565430616364, - 0.036369883937793064 + 0.0464095778335109, + 0.04783392945726656, + 0.044714614533193406 ], "calib_y_range": [ -0.3, @@ -85,14 +85,14 @@ 0.3 ], "calib_y_norm": [ - 0.0680948696951371, - -0.001074835754827735, - -0.07062095428052871 + 0.07370253499550317, + 0.00026569111039769416, + -0.07279404205081079 ], "calib_y_norm_std": [ - 0.036781724002055614, - 0.03612254480714764, - 0.039495450086968996 + 0.042861938803805864, + 0.046628964274299044, + 0.044222723318716746 ], - "calib_datetime": "2025-05-08 19:20:54" + "calib_datetime": "2025-07-17 21:43:10" } \ No newline at end of file diff --git a/configuration/pipeline_config/SAROP21-ATT01_proc.json b/configuration/pipeline_config/SAROP21-ATT01_proc.json index e05bef1..d06c320 100644 --- a/configuration/pipeline_config/SAROP21-ATT01_proc.json +++ b/configuration/pipeline_config/SAROP21-ATT01_proc.json @@ -29,12 +29,12 @@ "reload": true, "dark_buffer_length": 3, "calibration": [ - -9.73024084e-19, - 3.28988958e-16, - 1.0206364e-12 + -7.63784366e-19, + -2.36924701e-16, + 1.4943272e-12 ], "roi": [ - 600, + 800, 1600 ], "dpx_poly": 50, @@ -46,6 +46,6 @@ "is_fel_dark": 0, "event_code_laser_delayed": 25, "event_code_laser_dark": 25, - "event_code_fel_dark": 201, + "event_code_fel_dark": 64, "port": "9003" } \ No newline at end of file diff --git a/configuration/pipeline_config/SAROP21-PBPS103_proc.json b/configuration/pipeline_config/SAROP21-PBPS103_proc.json index 6fc3298..d1b0471 100644 --- a/configuration/pipeline_config/SAROP21-PBPS103_proc.json +++ b/configuration/pipeline_config/SAROP21-PBPS103_proc.json @@ -10,19 +10,19 @@ "check_timestamp": true, "stream_timeout": 20, "queue_length": 5000, - "down_calib": 1.3438944081736304e-05, + "down_calib": 1.5289933529766168e-06, "xpos_odd_w_pvname": "SAROP21-PBPS103:XPOS-ODD-HIST-W", "ypos_all_y_pvname": "SAROP21-PBPS103:YPOS-ALL-HIST-Y", "ypos_all_w_pvname": "SAROP21-PBPS103:YPOS-ALL-HIST-W", "name": "SAROP21-PBPS103_proc", - "vert_calib": -3.9358348895956135, + "vert_calib": -3.933091298181025, "bsread_address": "", "right": "SAROP21-PBPS103:Lnk9Ch0-PP_VAL_PD3", "ypos_dif_w_pvname": "SAROP21-PBPS103:YPOS-DIF-HIST-W", "ypos_odd_x_pvname": "SAROP21-PBPS103:YPOS-ODD-HIST-X", "function": "pbps_full", "port": "9009", - "left_calib": 8.747777364727171e-06, + "left_calib": 8.51985418426329e-07, "down": "SAROP21-PBPS103:Lnk9Ch0-PP_VAL_PD2", "ypos_odd_w_pvname": "SAROP21-PBPS103:YPOS-ODD-HIST-W", "xpos_odd_y_pvname": "SAROP21-PBPS103:XPOS-ODD-HIST-Y", @@ -32,7 +32,7 @@ "ypos_evn_x_pvname": "SAROP21-PBPS103:YPOS-EVN-HIST-X", "uJ_calib": 605.9512700123181, "xpos_evn_m_pvname": "SAROP21-PBPS103:XPOS-EVN-HIST-M", - "horiz_calib": -4.106805000082229, + "horiz_calib": -4.3381383543483505, "ypos_all_m_pvname": "SAROP21-PBPS103:YPOS-ALL-HIST-M", "ypos_dif_m_pvname": "SAROP21-PBPS103:YPOS-DIF-HIST-M", "bsread_channels": [ @@ -45,7 +45,7 @@ "ypos_evn_w_pvname": "SAROP21-PBPS103:YPOS-EVN-HIST-W", "pipeline_type": "stream", "ypos_all_x_pvname": "SAROP21-PBPS103:YPOS-ALL-HIST-X", - "right_calib": 9.684568190671639e-06, + "right_calib": 9.523986071299896e-07, "xpos_all_m_pvname": "SAROP21-PBPS103:XPOS-ALL-HIST-M", "xpos_odd_m_pvname": "SAROP21-PBPS103:XPOS-ODD-HIST-M", "left": "SAROP21-PBPS103:Lnk9Ch0-PP_VAL_PD0", @@ -58,7 +58,7 @@ "ypos_evn_y_pvname": "SAROP21-PBPS103:YPOS-EVN-HIST-Y", "xpos_odd_x_pvname": "SAROP21-PBPS103:XPOS-ODD-HIST-X", "threshold": 0, - "up_calib": 1.2578887233395516e-05, + "up_calib": 1.4557228389427614e-06, "ypos_odd_m_pvname": "SAROP21-PBPS103:YPOS-ODD-HIST-M", "xpos_all_x_pvname": "SAROP21-PBPS103:XPOS-ALL-HIST-X", "up": "SAROP21-PBPS103:Lnk9Ch0-PP_VAL_PD1", @@ -69,9 +69,9 @@ 0.3 ], "calib_x_norm": [ - 0.07264113800909158, - -0.00027682928694833323, - -0.07345783673842782 + 0.0688426139078096, + -0.00017495557137281405, + -0.06946556139475711 ], "calib_y_range": [ -0.3, @@ -79,19 +79,19 @@ 0.3 ], "calib_y_norm": [ - 0.07681455660145628, - -0.0005021565266583652, - -0.07563086268838766 + 0.08127191573286321, + 0.000395220890146269, + -0.07127984432353003 ], "calib_x_norm_std": [ - 0.3239146627568919, - 0.3360879764341496, - 0.31769366304131247 + 0.05618368921948914, + 0.031260276512354725, + 0.03343277006478486 ], "calib_y_norm_std": [ - 0.3375259185485036, - 0.3494180218450826, - 0.34646009364333663 + 0.03983144338005543, + 0.04203066731355165, + 0.03945612564739388 ], - "calib_datetime": "2025-05-12 18:46:13" + "calib_datetime": "2025-07-18 08:12:36" } \ No newline at end of file diff --git a/configuration/pipeline_config/SAROP21-PBPS133_proc.json b/configuration/pipeline_config/SAROP21-PBPS133_proc.json index b6ad412..3d3887d 100644 --- a/configuration/pipeline_config/SAROP21-PBPS133_proc.json +++ b/configuration/pipeline_config/SAROP21-PBPS133_proc.json @@ -27,12 +27,12 @@ "down": "SAROP21-PBPS133:Lnk9Ch0-PP_VAL_PD2", "right": "SAROP21-PBPS133:Lnk9Ch0-PP_VAL_PD3", "left": "SAROP21-PBPS133:Lnk9Ch0-PP_VAL_PD0", - "up_calib": 1.1994417318403323e-05, - "down_calib": 1.1777156969811e-05, - "left_calib": 8.546152470880694e-06, - "right_calib": 8.292371780859814e-06, - "horiz_calib": -4.030808070907288, - "vert_calib": -3.9995027435812665, + "up_calib": 1.4747247514734858e-06, + "down_calib": 1.42535974283956e-06, + "left_calib": 9.034139608852398e-07, + "right_calib": 8.990738532348965e-07, + "horiz_calib": -4.318186025090137, + "vert_calib": -4.353176127757587, "uJ_calib": 605.4608924473305, "threshold": 0, "queue_length": 3000, @@ -70,14 +70,14 @@ 0.3 ], "calib_x_norm": [ - 0.07558987766893042, - 0.00010780904235330975, - -0.07326364982362192 + 0.07026520386341667, + -0.0001555796103222294, + -0.06868202919087854 ], "calib_x_norm_std": [ - 0.37640119241355796, - 0.3766165188476263, - 0.38834395117940335 + 0.03593882830801818, + 0.031721088035632165, + 0.03381114098823549 ], "calib_y_range": [ -0.3, @@ -85,14 +85,14 @@ 0.3 ], "calib_y_norm": [ - 0.07489741542673554, - 0.0007133487847056664, - -0.07512123400735467 + 0.06929021697237708, + 0.0005273168268902044, + -0.06854018142895585 ], "calib_y_norm_std": [ - 0.4039920352608262, - 0.4026890943163395, - 0.3902031448932646 + 0.04223293863234544, + 0.04921758401755543, + 0.04487262986719493 ], - "calib_datetime": "2025-05-10 10:06:36" + "calib_datetime": "2025-07-18 08:13:56" } \ No newline at end of file diff --git a/configuration/pipeline_config/SAROP31-PBPS113_proc.json b/configuration/pipeline_config/SAROP31-PBPS113_proc.json index 3cd7ffe..1872d69 100644 --- a/configuration/pipeline_config/SAROP31-PBPS113_proc.json +++ b/configuration/pipeline_config/SAROP31-PBPS113_proc.json @@ -26,12 +26,12 @@ "down": "SAROP31-PBPS113:Lnk9Ch0-PP_VAL_PD2", "right": "SAROP31-PBPS113:Lnk9Ch0-PP_VAL_PD3", "left": "SAROP31-PBPS113:Lnk9Ch0-PP_VAL_PD0", - "up_calib": 3.861793515770638e-05, - "down_calib": 4.4900118787754264e-05, - "left_calib": 9.126519109105711e-05, - "right_calib": 0.00011276977914264295, - "horiz_calib": -3.8084771908604007, - "vert_calib": -6.247648389472207, + "up_calib": 1.5555950635219156e-06, + "down_calib": 1.5863259817149662e-06, + "left_calib": 4.522479527187428e-06, + "right_calib": 5.042093412646135e-06, + "horiz_calib": -10.217744421858216, + "vert_calib": 64.64999936036992, "uJ_calib": 941.943984588351, "threshold": 0, "queue_length": 300, @@ -70,14 +70,14 @@ 0.3 ], "calib_x_norm": [ - 0.0786096188018742, - 0.00035821990918893194, - -0.0789336642299587 + 0.027476180760177122, + 0.0007477943868970838, + -0.031245194058756053 ], "calib_x_norm_std": [ - 0.040490407392167534, - 0.04028139405139821, - 0.03862030068928889 + 0.548319590284712, + 0.5516448585709409, + 0.5458879023627853 ], "calib_y_range": [ -0.3, @@ -85,14 +85,14 @@ 0.3 ], "calib_y_norm": [ - 0.04775193765978428, - -0.00032249451531026196, - -0.04828419667374328 + -0.012427589505407299, + -7.386532969491803e-05, + -0.0031468469541893235 ], "calib_y_norm_std": [ - 0.0376808182312105, - 0.0399368891843527, - 0.037962528852795725 + 0.5359666485603565, + 0.5471586459810386, + 0.5649269726881252 ], - "calib_datetime": "2025-05-12 19:40:38" + "calib_datetime": "2025-07-11 13:29:23" } \ No newline at end of file diff --git a/configuration/pipeline_config/SAROP31-PBPS149_proc.json b/configuration/pipeline_config/SAROP31-PBPS149_proc.json index 4088534..b97a101 100644 --- a/configuration/pipeline_config/SAROP31-PBPS149_proc.json +++ b/configuration/pipeline_config/SAROP31-PBPS149_proc.json @@ -27,12 +27,12 @@ "down": "SAROP31-PBPS149:Lnk9Ch0-PP_VAL_PD2", "right": "SAROP31-PBPS149:Lnk9Ch0-PP_VAL_PD3", "left": "SAROP31-PBPS149:Lnk9Ch0-PP_VAL_PD0", - "up_calib": 8.923922065175471e-06, - "down_calib": 9.805425067137745e-06, - "left_calib": 5.870948933687726e-06, - "right_calib": 8.378280574406873e-06, - "horiz_calib": -3.775717899566187, - "vert_calib": -3.8593992845314324, + "up_calib": 1.7257138767496805e-06, + "down_calib": 1.6633104167303162e-06, + "left_calib": 4.841112180846291e-06, + "right_calib": 5.88459407152098e-06, + "horiz_calib": -8.521995715357336, + "vert_calib": -19.803743284465746, "uJ_calib": 605.9512700123181, "threshold": 0.0, "queue_length": 300, @@ -71,14 +71,14 @@ 0.3 ], "calib_x_norm": [ - 0.08010117214752004, - 0.00011095255532506727, - -0.07880900492607362 + 0.034869462299519136, + 5.445654136857332e-05, + -0.03553658107817827 ], "calib_x_norm_std": [ - 0.03546822052236209, - 0.03566075428198375, - 0.038689695811515164 + 0.5521538969221853, + 0.5807997036780183, + 0.560907907220158 ], "calib_y_range": [ -0.3, @@ -86,14 +86,14 @@ 0.3 ], "calib_y_norm": [ - 0.07814310330557633, - -0.0003988992296753892, - -0.07732150550150274 + 0.01521561218564969, + -5.73608923202534e-05, + -0.015081690267803441 ], "calib_y_norm_std": [ - 0.07331681331314215, - 0.03660437215717908, - 0.036695466427208896 + 0.5696086871998763, + 0.5656565843542883, + 0.5606055691837639 ], - "calib_datetime": "2025-05-12 19:42:03" + "calib_datetime": "2025-07-11 13:30:43" } \ No newline at end of file diff --git a/configuration/pipeline_config/SATBD02-DSCR050_sp.json b/configuration/pipeline_config/SATBD02-DSCR050_sp.json index 36a7047..e223389 100644 --- a/configuration/pipeline_config/SATBD02-DSCR050_sp.json +++ b/configuration/pipeline_config/SATBD02-DSCR050_sp.json @@ -2,7 +2,12 @@ "image_background_enable": false, "image_background": "SATBD02-DSCR050_20250217_170917_808358", "image_threshold": null, - "image_region_of_interest": null, + "image_region_of_interest": [ + 180, + 2342, + 81, + 1919 + ], "image_good_region": null, "image_slices": null, "pipeline_type": "processing", diff --git a/configuration/pipeline_config/SATES21-CAMS-PATT1_spec_db.json b/configuration/pipeline_config/SATES21-CAMS-PATT1_spec_db.json index 2762450..ee8cc36 100644 --- a/configuration/pipeline_config/SATES21-CAMS-PATT1_spec_db.json +++ b/configuration/pipeline_config/SATES21-CAMS-PATT1_spec_db.json @@ -1,6 +1,6 @@ { "image_background_enable": "passive", - "image_background": "SATES21-CAMS-PATT1_20250511_094953_959660", + "image_background": "SATES21-CAMS-PATT1_20250624_174643_619689", "image_threshold": null, "image_region_of_interest": null, "image_good_region": null, @@ -19,17 +19,11 @@ "port": "9003", "project_axis": 0, "reload": true, - "roi_background": [ - 9, - 444, - 10, - 2501 - ], "roi_signal": [ - 9, - 444, - 10, - 2501 + 82, + 414, + 375, + 2505 ], "enforce_pid": true, "enforce_timestamp": true, diff --git a/configuration/pipeline_config/SATES21-CAMS154-M1_spec_db.json b/configuration/pipeline_config/SATES21-CAMS154-M1_spec_db.json index 95b12dd..e548210 100644 --- a/configuration/pipeline_config/SATES21-CAMS154-M1_spec_db.json +++ b/configuration/pipeline_config/SATES21-CAMS154-M1_spec_db.json @@ -1,12 +1,12 @@ { "image_background_enable": "passive", - "image_background": "SATES21-CAMS154-M1_20250430_112650_821925", + "image_background": "SATES21-CAMS154-M1_20250708_105621_406300", "image_threshold": null, "image_region_of_interest": null, "image_good_region": null, "image_slices": null, "pipeline_type": "processing", - "function": "maloja_spectrometer.py", + "function": "spectrometer.py", "camera_name": "SATES21-CAMS154-M1", "name": "SATES21-CAMS154-M1_spec_db", "mode": "PUSH", @@ -20,15 +20,9 @@ "threshold": 10, "project_axis": 0, "roi_signal": [ - 1, - 847, - 1, - 1635 - ], - "roi_background": [ - 1, - 847, - 1, - 1635 + 190, + 761, + 405, + 1322 ] } \ No newline at end of file diff --git a/configuration/pipeline_config/SATES22-ADTEST1-CAM4_sp.json b/configuration/pipeline_config/SATES22-ADTEST1-CAM4_sp.json new file mode 100644 index 0000000..ce860d6 --- /dev/null +++ b/configuration/pipeline_config/SATES22-ADTEST1-CAM4_sp.json @@ -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": "SATES22-ADTEST1-CAM4", + "name": "SATES22-ADTEST1-CAM4_sp" +} \ No newline at end of file diff --git a/configuration/pipeline_config/SATES22-ADTEST1-CAM7_sp.json b/configuration/pipeline_config/SATES22-ADTEST1-CAM7_sp.json new file mode 100644 index 0000000..484afc6 --- /dev/null +++ b/configuration/pipeline_config/SATES22-ADTEST1-CAM7_sp.json @@ -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": "SATES22-ADTEST1-CAM7", + "name": "SATES22-ADTEST1-CAM7_sp" +} \ No newline at end of file diff --git a/configuration/pipeline_config/SATES24-CAMS161-M1_spec_db.json b/configuration/pipeline_config/SATES24-CAMS161-M1_spec_db.json index 6e1a32d..b2370e3 100644 --- a/configuration/pipeline_config/SATES24-CAMS161-M1_spec_db.json +++ b/configuration/pipeline_config/SATES24-CAMS161-M1_spec_db.json @@ -1,17 +1,34 @@ { - "image_background_enable": false, - "image_background": null, + "image_background_enable": "passive", + "image_background": "SATES24-CAMS161-M1_20250712_122200_955534", "image_threshold": null, "image_region_of_interest": null, "image_good_region": null, "image_slices": null, "pipeline_type": "processing", - "function": "Laser_Quick_Int.py", + "function": "spectrometer.py", "camera_name": "SATES24-CAMS161-M1", "name": "SATES24-CAMS161-M1_spec_db", "mode": "PUSH", "allow_type_changes": false, "processing_threads": 4, "thread_buffer_size": 30, - "reload": true + "reload": true, + "threshold": 10, + "enforce_pid": true, + "enforce_timestamp": true, + "check_timestamp": true, + "roi_background": [ + 40, + 110, + 5, + 1648 + ], + "roi_signal": [ + 110, + 180, + 5, + 1648 + ], + "project_axis": 0 } \ No newline at end of file diff --git a/configuration/pipeline_config/SATES30-RIXS-CAM01_proc.json b/configuration/pipeline_config/SATES30-RIXS-CAM01_proc.json index 2dccf15..ae77c86 100644 --- a/configuration/pipeline_config/SATES30-RIXS-CAM01_proc.json +++ b/configuration/pipeline_config/SATES30-RIXS-CAM01_proc.json @@ -1,6 +1,6 @@ { "image_background_enable": true, - "image_background": "SATES30-RIXS-CAM01_20250325_105110_535588", + "image_background": "SATES30-RIXS-CAM01_20250716_200949_694408", "image_threshold": null, "image_region_of_interest": null, "image_good_region": null, diff --git a/configuration/pipeline_config/SATES31-CAMS187-PCO2_proc.json b/configuration/pipeline_config/SATES31-CAMS187-PCO2_proc.json new file mode 100644 index 0000000..4c04695 --- /dev/null +++ b/configuration/pipeline_config/SATES31-CAMS187-PCO2_proc.json @@ -0,0 +1,16 @@ +{ + "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": "SATES31-CAMS187-PCO2", + "name": "SATES31-CAMS187-PCO2_proc", + "function": "profiles.py", + "mode": "PUSH", + "allow_type_changes": false, + "block": false, + "no_client_timeout": 0 +} \ No newline at end of file diff --git a/configuration/pipeline_config/SATES31-CAMS187-PCO2_sp.json b/configuration/pipeline_config/SATES31-CAMS187-PCO2_sp.json new file mode 100644 index 0000000..67b453a --- /dev/null +++ b/configuration/pipeline_config/SATES31-CAMS187-PCO2_sp.json @@ -0,0 +1,12 @@ +{ + "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": "SATES31-CAMS187-PCO2", + "name": "SATES31-CAMS187-PCO2_sp", + "max_frame_rate": 5.1 +} \ No newline at end of file diff --git a/configuration/pipeline_config/SATES31-CAMS187-RIXS1_sp.json b/configuration/pipeline_config/SATES31-CAMS187-RIXS1_sp.json index 4602dfd..586b8ef 100644 --- a/configuration/pipeline_config/SATES31-CAMS187-RIXS1_sp.json +++ b/configuration/pipeline_config/SATES31-CAMS187-RIXS1_sp.json @@ -1,6 +1,6 @@ { - "image_background_enable": true, - "image_background": "SATES31-CAMS187-RIXS1_20250513_091423_890325", + "image_background_enable": false, + "image_background": "SATES31-CAMS187-RIXS1_20250515_224135_992441", "image_threshold": null, "image_region_of_interest": null, "image_good_region": null, diff --git a/configuration/pipeline_config/SATOP31-ATT01_proc.json b/configuration/pipeline_config/SATOP31-ATT01_proc.json index 1bc37eb..c1a96dd 100644 --- a/configuration/pipeline_config/SATOP31-ATT01_proc.json +++ b/configuration/pipeline_config/SATOP31-ATT01_proc.json @@ -46,9 +46,9 @@ "global_stage": "SLAAT31-LMOT-M816:MOT", "feedback_output": "SLAAT01-LSCP-DRS1FNS:CH2:BSTART", "feedback_buffer": 200, - "feedback_deadband": 50, - "feedback_target": 1450, - "feedback_step": 0.01 + "feedback_deadband": 100, + "feedback_target": 1420, + "feedback_step": 0.02 }, "filter_window": 101, "filter": true diff --git a/configuration/pipeline_config/SATOP31-PMOS132-2D_pmos.json b/configuration/pipeline_config/SATOP31-PMOS132-2D_pmos.json index 8da19e3..caf52c7 100644 --- a/configuration/pipeline_config/SATOP31-PMOS132-2D_pmos.json +++ b/configuration/pipeline_config/SATOP31-PMOS132-2D_pmos.json @@ -1,6 +1,6 @@ { "image_background_enable": true, - "image_background": "SATOP31-PMOS132-2D_20250311_183617_282213", + "image_background": "SATOP31-PMOS132-2D_20250707_152837_645169", "image_threshold": null, "image_region_of_interest": null, "image_good_region": null, diff --git a/configuration/pipeline_config/SATOP31-PSRD132_pmos.json b/configuration/pipeline_config/SATOP31-PSRD132_pmos.json index dbcab27..2bbb03d 100644 --- a/configuration/pipeline_config/SATOP31-PSRD132_pmos.json +++ b/configuration/pipeline_config/SATOP31-PSRD132_pmos.json @@ -1,6 +1,6 @@ { - "image_background_enable": false, - "image_background": "SATOP31-PSRD132_20250216_120304_546817", + "image_background_enable": true, + "image_background": "SATOP31-PSRD132_20250705_102222_768278", "image_threshold": null, "image_region_of_interest": null, "image_good_region": null, diff --git a/configuration/pipeline_config/SATUN04-DSCR05_sp.json b/configuration/pipeline_config/SATUN04-DSCR05_sp.json new file mode 100644 index 0000000..12657aa --- /dev/null +++ b/configuration/pipeline_config/SATUN04-DSCR05_sp.json @@ -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": "SATUN04-DSCR05", + "name": "SATUN04-DSCR05_sp" +} \ No newline at end of file diff --git a/configuration/pipeline_config/SLAAR02-LPMO05-C301_sp.json b/configuration/pipeline_config/SLAAR02-LPMO05-C301_sp.json new file mode 100644 index 0000000..37d6fd8 --- /dev/null +++ b/configuration/pipeline_config/SLAAR02-LPMO05-C301_sp.json @@ -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": "SLAAR02-LPMO05-C301", + "name": "SLAAR02-LPMO05-C301_sp" +} \ No newline at end of file diff --git a/configuration/pipeline_config/SLAAR02-LPMO06-C302_sp.json b/configuration/pipeline_config/SLAAR02-LPMO06-C302_sp.json new file mode 100644 index 0000000..52e7aea --- /dev/null +++ b/configuration/pipeline_config/SLAAR02-LPMO06-C302_sp.json @@ -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": "SLAAR02-LPMO06-C302", + "name": "SLAAR02-LPMO06-C302_sp" +} \ No newline at end of file diff --git a/configuration/pipeline_config/permanent_instances.json b/configuration/pipeline_config/permanent_instances.json index 306a2fe..f4e7d92 100644 --- a/configuration/pipeline_config/permanent_instances.json +++ b/configuration/pipeline_config/permanent_instances.json @@ -53,10 +53,13 @@ "#test_stream": "test_stream", "#test_tadej": "test_tadej", "#testdb_ib": "testdb_ib", + "AGalvotest1": "AGalvotest1", + "AGalvotest2": "AGalvotest2", "Bernina_mid_IR_CEP_analysis": "Bernina_mid_IR_CEP_analysis", "Bernina_mid_IR_CEP_populate_pvs": "Bernina_mid_IR_CEP_populate_pvs", "Bernina_mid_IR_CEP_projection": "Bernina_mid_IR_CEP_projection", "Bernina_tt_kb_populate_pvs": "Bernina_tt_kb_populate_pvs", + "S10BC02-DSRM310_sp": "S10BC02-DSRM310_sp", "S10BD01-DSCR030_profiles": "S10BD01-DSCR030_profiles", "SARBD01-DSCR110_sp1": "SARBD01-DSCR110_sp_rep", "SARBD02-DSCR050_pref": "SARBD02-DSCR050_pref", @@ -120,6 +123,7 @@ "SATES30-RIXS-CAM01_fit": "SATES30-RIXS-CAM01_fit", "SATES30-RIXS-CAM01_proc": "SATES30-RIXS-CAM01_proc", "SATES30-RIXS-CAM01_repeater": "SATES30-RIXS-CAM01_repeater", + "SATES31-CAMS187-PCO2_proc": "SATES31-CAMS187-PCO2_proc", "SATES31-CAMS187-RIXS1_proc": "SATES31-CAMS187-RIXS1_proc", "SATES31-CAMS187-RIXS1_proc_db_proxy": "SATES31-CAMS187-RIXS1_proc_db_proxy", "SATES31-CAMS187-RIXS1_sp": "SATES31-CAMS187-RIXS1_sp", diff --git a/configuration/pipeline_config/servers.json b/configuration/pipeline_config/servers.json index 48574d0..fc9807f 100644 --- a/configuration/pipeline_config/servers.json +++ b/configuration/pipeline_config/servers.json @@ -27,6 +27,8 @@ "enabled": true, "expanding": false, "instances": [ + "AGalvotest1:9040", + "AGalvotest2:9041", "SARFE10-PBPS053_proc:9004", "SAROP21-ATT01_proc:9003", "Bernina_tt_kb_populate_pvs:9030", @@ -97,7 +99,10 @@ "SARBD01-DSCR050", "SARBD02-DSCR050", "SARBD02-DSCR051", - "S10DI01-DSCR020" + "S10DI01-DSCR020", + "S10BC02-DSRM310", + "test_bschannel", + "test_stddaq" ], "enabled": true, "expanding": false, @@ -156,7 +161,8 @@ "SATES21-CAMS154-GIGE6", "SATES21-CAMS154-GIGE7", "SATES21-CAMS154-GIGE7b", - "SATES21-CAMS154-GIGE8" + "SATES21-CAMS154-GIGE8", + "SATOP21-PMOS127-1D" ], "enabled": true, "expanding": false, @@ -281,6 +287,8 @@ "SATES30-CAMS182-GIGE5", "SATES30-CAMS182-GIGE6", "SATES30-RIXS-CAM01", + "SATOP31-PMOS132-1D", + "SATES31-CAMS187-PCO2", "furka_jungfrau" ], "enabled": true, @@ -292,6 +300,7 @@ "SATES30-RIXS-CAM01_proc:9100", "SATES30-RIXS-CAM01_repeater:9006", "SATES30-RIXS-CAM01_fit:9010", + "SATES31-CAMS187-PCO2_proc:9012", "test_load_file", "SATES30-CAMS182-GIGE1_sp", "SATES31-CAMS187-RIXS1_proc_db_proxy:9011", diff --git a/configuration/pipeline_config/simulation_sp.json b/configuration/pipeline_config/simulation_sp.json index 727fa22..7a0b728 100644 --- a/configuration/pipeline_config/simulation_sp.json +++ b/configuration/pipeline_config/simulation_sp.json @@ -1,7 +1,7 @@ { "image_background_enable": false, "image_background": "simulation_20241114_103340_976351", - "image_threshold": 0.0, + "image_threshold": 20.0, "image_region_of_interest": [ 463, 342, @@ -9,8 +9,8 @@ 168 ], "image_good_region": { - "threshold": 0.5, - "gfscale": 6.0 + "threshold": 0.05, + "gfscale": 2.0 }, "image_slices": null, "pipeline_type": "processing", @@ -18,7 +18,7 @@ "name": "simulation_sp", "reload": true, "_function": "bunch_length_op", - "fw_threshold": 0.1, + "fw_threshold": 0.2, "no_client_timeout": 0, "image_background_subtraction": true, "slice_orientation": "horizontal", @@ -28,5 +28,7 @@ "mode": "0.0", "angle": 0.0, "order": 1 - } + }, + "function": "bunch_length_op", + "averaging": 4 } \ No newline at end of file diff --git a/configuration/pipeline_config/test_bschannel_sp.json b/configuration/pipeline_config/test_bschannel_sp.json new file mode 100644 index 0000000..5f27ed2 --- /dev/null +++ b/configuration/pipeline_config/test_bschannel_sp.json @@ -0,0 +1,12 @@ +{ + "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": "test_bschannel", + "name": "test_bschannel_sp", + "max_frame_rate": 5.1 +} \ No newline at end of file diff --git a/configuration/pipeline_config/test_stddaq_sp.json b/configuration/pipeline_config/test_stddaq_sp.json new file mode 100644 index 0000000..8660f40 --- /dev/null +++ b/configuration/pipeline_config/test_stddaq_sp.json @@ -0,0 +1,12 @@ +{ + "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": "test_stddaq", + "name": "test_stddaq_sp", + "max_frame_rate": 5.1 +} \ No newline at end of file diff --git a/configuration/user_scripts/swissfel_spectral_processing.py b/configuration/user_scripts/swissfel_spectral_processing.py index 8eb4e27..a74c809 100644 --- a/configuration/user_scripts/swissfel_spectral_processing.py +++ b/configuration/user_scripts/swissfel_spectral_processing.py @@ -42,9 +42,7 @@ def get_spectrum(image, background): profile[j] += image[i, j] - background[i, j] return profile - def update_PVs(buffer, *pv_names): - """Continuously read from buffer and write to EPICS PVs.""" pvs = create_thread_pvs(list(pv_names)) while True: time.sleep(0.1) @@ -52,12 +50,13 @@ def update_PVs(buffer, *pv_names): rec = buffer.popleft() except IndexError: continue - try: - for pv, val in zip(pvs, rec): - if pv and pv.connected and (val is not None): + for pv, val in zip(pvs, rec): + if pv and pv.connected and (val is not None): + try: pv.put(val) - except Exception: - _logger.exception("Error updating channels") + except Exception as e: + _logger.error(f"Error writing to {pv.pvname}: {e}") + def initialize(params): @@ -118,6 +117,16 @@ def initialize(params): f"{camera}:AVG-SPECTRUM_Y", f"{camera}:AVG-FIT-SPECTRUM_Y" ] + global ARRAY_PVS + ARRAY_PVS = set([ + f"{camera}:SPECTRUM_Y", + f"{camera}:FIT-SPECTRUM_Y", + f"{camera}:AVG-SPECTRUM_Y", + f"{camera}:AVG-FIT-SPECTRUM_Y", + f"{camera}:FIT-SPECTRUM_Y-RAVG" + # add any others here + ]) + # All PVs (original + running average + N-shot average) all_pv_names = base_pv_names + ravg_pv_names + avg_pv_names @@ -126,6 +135,35 @@ def initialize(params): thread = Thread(target=update_PVs, args=(buffer, *all_pv_names), daemon=True) thread.start() +def _pv_safe(val, pvname): + if pvname in ARRAY_PVS: + # array PV: must always send a 1D numpy array + if isinstance(val, np.ndarray): + if val.ndim == 1: + return val.astype(np.float64) + elif val.ndim == 0: + # Scalar array, wrap as 1-element + return np.array([val.item()], dtype=np.float64) + else: + raise ValueError(f"{pvname}: expected 1D array, got shape {val.shape}") + elif isinstance(val, (list, tuple)): + return np.array(val, dtype=np.float64) + elif isinstance(val, (float, int, np.generic)): + return np.array([val], dtype=np.float64) + else: + raise TypeError(f"{pvname}: expected array, got {type(val)}") + else: + # scalar PV: must always send float + if isinstance(val, np.ndarray): + if val.size == 1: + return float(val.item()) + else: + raise ValueError(f"{pvname}: expected scalar, got array of size {val.size}") + elif isinstance(val, (np.generic, float, int)): + return float(val) + else: + raise TypeError(f"{pvname}: expected scalar, got {type(val)}") + def process_image(image, pulse_id, timestamp, x_axis, y_axis, parameters, bsdata=None, background=None): """ @@ -180,6 +218,7 @@ def process_image(image, pulse_id, timestamp, x_axis, y_axis, parameters, bsdata ) # Reconstruct fitted curve fit_spectrum = offset + amp_fit * np.exp(-((axis - center)**2) / (2 * sigma**2)) + #fit_spectrum = np.abs(fit_spectrum) # Moments sm_norm = smoothed / np.sum(smoothed) @@ -198,7 +237,7 @@ def process_image(image, pulse_id, timestamp, x_axis, y_axis, parameters, bsdata f"{camera}:FIT-FWHM": np.float64(2.355 * sigma), f"{camera}:FIT-RMS": np.float64(sigma), f"{camera}:FIT-RES": np.float64(2.355 * sigma / center * 1000), - f"{camera}:FIT-SPECTRUM_Y": fit_spectrum, + f"{camera}:FIT-SPECTRUM_Y": np.float64(fit_spectrum), f"{camera}:SPECT-COM": spect_com, f"{camera}:SPECT-RMS": spect_std, f"{camera}:SPECT-SKEW": spect_skew, @@ -218,6 +257,7 @@ def process_image(image, pulse_id, timestamp, x_axis, y_axis, parameters, bsdata # N-shot average and average fitted spectrum avg_buffer.append(spectrum) avg_spectrum = np.mean(np.stack(avg_buffer), axis=0) + avg_spectrum = np.abs(avg_spectrum) fit_avg = offset + amp_fit * np.exp(-((axis - center)**2) / (2 * sigma**2)) # using avg fit params below sm_avg = scipy.signal.savgol_filter(avg_spectrum, 51, 3) min_a, max_a = sm_avg.min(), sm_avg.max() @@ -226,6 +266,8 @@ def process_image(image, pulse_id, timestamp, x_axis, y_axis, parameters, bsdata sm_avg[::2], axis[::2], offset=min_a, amplitude=amp_a, skip=skip_a, maxfev=10 ) fit_avg_spectrum = offs_a + amp_fit_a * np.exp(-((axis - center_a)**2) / (2 * sigma_a**2)) + fit_avg_spectrum = np.abs(fit_avg_spectrum) + # Average moments sm_norm_a = sm_avg / np.sum(sm_avg) spect_com_a = np.sum(axis * sm_norm_a) @@ -236,11 +278,11 @@ def process_image(image, pulse_id, timestamp, x_axis, y_axis, parameters, bsdata spect_res_a = spect_iqr_a / spect_com_a * 1000 avg_results = { - f"{camera}:AVG-FIT-COM": np.float64(center_a), + f"{camera}:AVG-FIT-COM": np.float64(center), f"{camera}:AVG-FIT-FWHM": np.float64(2.355 * sigma_a), f"{camera}:AVG-FIT-RMS": np.float64(sigma_a), f"{camera}:AVG-FIT-RES": np.float64(2.355 * sigma_a / center_a * 1000), - f"{camera}:AVG-SPECT-COM": spect_com_a, + f"{camera}:AVG-SPECT-COM": spect_com, f"{camera}:AVG-SPECT-RMS": spect_std_a, f"{camera}:AVG-SPECT-SKEW": spect_skew_a, f"{camera}:AVG-SPECT-IQR": spect_iqr_a, @@ -255,7 +297,8 @@ def process_image(image, pulse_id, timestamp, x_axis, y_axis, parameters, bsdata try: if pulse_id > sent_pid: sent_pid = pulse_id - entry = tuple(full_results.get(pv) for pv in all_pv_names) + #entry = tuple(full_results.get(pv) for pv in all_pv_names) + entry = tuple(_pv_safe(full_results.get(pv), pv) for pv in all_pv_names) buffer.append(entry) finally: epics_lock.release() diff --git a/configuration/user_scripts/swissfel_spectral_processing_bkg2.py b/configuration/user_scripts/swissfel_spectral_processing_bkg2.py new file mode 100644 index 0000000..5649b8c --- /dev/null +++ b/configuration/user_scripts/swissfel_spectral_processing_bkg2.py @@ -0,0 +1,310 @@ +from logging import getLogger +from cam_server.pipeline.data_processing import functions +from cam_server.utils import create_thread_pvs, epics_lock +from collections import deque +import json +import numpy as np +import scipy.signal +import numba +import time +import sys +from threading import Thread + +# Configure Numba to use multiple threads +numba.set_num_threads(4) + +_logger = getLogger(__name__) + +# Shared state globals +global_roi = [0, 0] +initialized = False +sent_pid = -1 +buffer = deque(maxlen=5) +channel_pv_names = None +base_pv_names = [] +all_pv_names = [] +global_ravg_length = 100 +ravg_buffers = {} +# Configuration for rolling-average of statistics + +# Configuration for N-shot average spectrum +global_avg_length = 100 +avg_buffer = None +avg_pv_names = [] + +@numba.njit(parallel=False) +def get_spectrum(image, background): + """Compute background-subtracted spectrum via row-wise summation.""" + y, x = image.shape + profile = np.zeros(x, dtype=np.float64) + for i in numba.prange(y): + for j in range(x): + profile[j] += image[i, j] - background[i, j] + return profile + + +def update_PVs(buffer, *pv_names): + """Continuously read from buffer and write to EPICS PVs.""" + pvs = create_thread_pvs(list(pv_names)) + while True: + time.sleep(0.1) + try: + rec = buffer.popleft() + except IndexError: + continue + try: + for pv, val in zip(pvs, rec): + if pv and pv.connected and (val is not None): + pv.put(val) + except Exception: + _logger.exception("Error updating channels") + + +def initialize(params): + """Initialize PV names, running-average settings, N-shot average, and launch update thread.""" + global channel_pv_names, base_pv_names, all_pv_names, global_ravg_length + global global_avg_length, avg_buffer, avg_pv_names + + camera = params["camera_name"] + e_int = params["e_int_name"] + e_axis = params["e_axis_name"] + + # Fit/result PV names + center_pv = f"{camera}:FIT-COM" + fwhm_pv = f"{camera}:FIT-FWHM" + fit_rms_pv = f"{camera}:FIT-RMS" + fit_res_pv = f"{camera}:FIT-RES" + fit_spec_pv = f"{camera}:FIT-SPECTRUM_Y" + + # ROI PVs for dynamic read + ymin_pv = f"{camera}:SPC_ROI_YMIN" + ymax_pv = f"{camera}:SPC_ROI_YMAX" + axis_pv = e_axis + channel_pv_names = [ymin_pv, ymax_pv, axis_pv] + + # Spectrum statistical PV names + com_pv = f"{camera}:SPECT-COM" + std_pv = f"{camera}:SPECT-RMS" + skew_pv = f"{camera}:SPECT-SKEW" + iqr_pv = f"{camera}:SPECT-IQR" + res_pv = f"{camera}:SPECT-RES" + + # Base PVs for update thread (order matters) + base_pv_names = [ + e_int, center_pv, fwhm_pv, fit_rms_pv, + fit_res_pv, fit_spec_pv, com_pv, std_pv, skew_pv, iqr_pv, res_pv + ] + + # Running-average configuration + global_ravg_length = params.get('RAVG_length', global_ravg_length) + exclude = {e_int, e_axis, f"{camera}:processing_parameters"} + ravg_base = [pv for pv in base_pv_names if pv not in exclude] + ravg_pv_names = [pv + '-RAVG' for pv in ravg_base] + + # N-shot average configuration + global_avg_length = params.get('avg_nshots', global_avg_length) + avg_buffer = deque(maxlen=global_avg_length) + # Define PVs for N-shot average statistics and spectra + avg_pv_names = [ + f"{camera}:AVG-FIT-COM", + f"{camera}:AVG-FIT-FWHM", + f"{camera}:AVG-FIT-RMS", + f"{camera}:AVG-FIT-RES", + f"{camera}:AVG-SPECT-COM", + f"{camera}:AVG-SPECT-RMS", + f"{camera}:AVG-SPECT-SKEW", + f"{camera}:AVG-SPECT-IQR", + f"{camera}:AVG-SPECT-RES", + f"{camera}:AVG-SPECTRUM_Y", + f"{camera}:AVG-FIT-SPECTRUM_Y" + ] + global ARRAY_PVS + ARRAY_PVS = set([ + f"{camera}:SPECTRUM_Y", + f"{camera}:FIT-SPECTRUM_Y", + f"{camera}:AVG-SPECTRUM_Y", + f"{camera}:AVG-FIT-SPECTRUM_Y" + # add any others here + ]) + + + # All PVs (original + running average + N-shot average) + all_pv_names = base_pv_names + ravg_pv_names + avg_pv_names + + # Start background thread for PV updates + thread = Thread(target=update_PVs, args=(buffer, *all_pv_names), daemon=True) + thread.start() + +def _pv_safe(val, pvname): + if pvname in ARRAY_PVS: + # array PV: must always send a 1D numpy array + if isinstance(val, np.ndarray): + if val.ndim == 1: + return val.astype(np.float64) + elif val.ndim == 0: + # Scalar array, wrap as 1-element + return np.array([val.item()], dtype=np.float64) + else: + raise ValueError(f"{pvname}: expected 1D array, got shape {val.shape}") + elif isinstance(val, (list, tuple)): + return np.array(val, dtype=np.float64) + elif isinstance(val, (float, int, np.generic)): + return np.array([val], dtype=np.float64) + else: + raise TypeError(f"{pvname}: expected array, got {type(val)}") + else: + # scalar PV: must always send float + if isinstance(val, np.ndarray): + if val.size == 1: + return float(val.item()) + else: + raise ValueError(f"{pvname}: expected scalar, got array of size {val.size}") + elif isinstance(val, (np.generic, float, int)): + return float(val) + else: + raise TypeError(f"{pvname}: expected scalar, got {type(val)}") + + +def process_image(image, pulse_id, timestamp, x_axis, y_axis, parameters, bsdata=None, background=None): + """ + Main entrypoint: subtract background, crop ROI, smooth, fit Gaussian, + compute metrics, N-shot average, queue PV updates (with running averages). + Returns a dict of processed PV values (original and average channels). + """ + global initialized, sent_pid, channel_pv_names + global global_ravg_length, ravg_buffers, avg_buffer + try: + if not initialized: + initialize(parameters) + initialized = True + + camera = parameters["camera_name"] + + # Dynamic ROI and axis PV read + ymin_pv, ymax_pv, axis_pv = create_thread_pvs(channel_pv_names) + if ymin_pv and ymin_pv.connected: + global_roi[0] = ymin_pv.value + if ymax_pv and ymax_pv.connected: + global_roi[1] = ymax_pv.value + + if not (axis_pv and axis_pv.connected): + _logger.warning("Energy axis not connected") + return None + axis = axis_pv.value[:image.shape[1]] + + # Preprocess image + proc_img = image.astype(np.float32) - np.float32(parameters.get("pixel_bkg", 0)) + nrows, _ = proc_img.shape + + # Background image + bg_img = parameters.pop('background_data', None) + bg_img = bg_img.astype(np.float32) if isinstance(bg_img, np.ndarray) and bg_img.shape == proc_img.shape else None + + # Crop ROI + ymin, ymax = map(int, global_roi) + if 0 <= ymin < ymax <= nrows: + proc_img = proc_img[ymin:ymax, :] + if bg_img is not None: + bg_img = bg_img[ymin:ymax, :] + + # Extract spectrum and fitted spectrum + spectrum = get_spectrum(proc_img, bg_img) if bg_img is not None else np.sum(proc_img, axis=0) + smoothed = scipy.signal.savgol_filter(spectrum, 51, 3) + minimum, maximum = smoothed.min(), smoothed.max() + amplitude = maximum - minimum + skip = amplitude <= nrows * 1.5 + offset, amp_fit, center, sigma = functions.gauss_fit_psss( + smoothed[::2], axis[::2], offset=minimum, amplitude=amplitude, skip=skip, maxfev=10 + ) + # Reconstruct fitted curve + fit_spectrum = offset + amp_fit * np.exp(-((axis - center)**2) / (2 * sigma**2)) + #fit_spectrum = np.abs(fit_spectrum) + + # Moments + sm_norm = smoothed / np.sum(smoothed) + spect_com = np.sum(axis * sm_norm) + spect_std = np.sqrt(np.sum((axis - spect_com)**2 * sm_norm)) + spect_skew = np.sum((axis - spect_com)**3 * sm_norm) / (spect_std**3) + cum = np.cumsum(sm_norm); e25 = np.interp(0.25, cum, axis); e75 = np.interp(0.75, cum, axis) + spect_iqr = e75 - e25; spect_sum = np.sum(spectrum) + + # Original result + result = { + parameters["e_int_name"]: spectrum, + parameters["e_axis_name"]: axis, + f"{camera}:SPECTRUM_Y_SUM": spect_sum, + f"{camera}:FIT-COM": np.float64(center), + f"{camera}:FIT-FWHM": np.float64(2.355 * sigma), + f"{camera}:FIT-RMS": np.float64(sigma), + f"{camera}:FIT-RES": np.float64(2.355 * sigma / center * 1000), + f"{camera}:FIT-SPECTRUM_Y": np.float64(fit_spectrum), + f"{camera}:SPECT-COM": spect_com, + f"{camera}:SPECT-RMS": spect_std, + f"{camera}:SPECT-SKEW": spect_skew, + f"{camera}:SPECT-IQR": spect_iqr, + f"{camera}:SPECT-RES": np.float64(spect_iqr / spect_com * 1000), + f"{camera}:processing_parameters": json.dumps({"roi": global_roi}) + } + + # Rolling averages + exclude = {parameters["e_int_name"], parameters["e_axis_name"], f"{camera}:processing_parameters"} + ravg_results = {} + for base_pv in (pv for pv in base_pv_names if pv not in exclude): + buf = ravg_buffers.setdefault(base_pv, deque(maxlen=global_ravg_length)) + buf.append(result[base_pv]) + ravg_results[f"{base_pv}-RAVG"] = np.mean(buf) + + # N-shot average and average fitted spectrum + avg_buffer.append(spectrum) + avg_spectrum = np.mean(np.stack(avg_buffer), axis=0) + avg_spectrum = np.abs(avg_spectrum) + fit_avg = offset + amp_fit * np.exp(-((axis - center)**2) / (2 * sigma**2)) # using avg fit params below + sm_avg = scipy.signal.savgol_filter(avg_spectrum, 51, 3) + min_a, max_a = sm_avg.min(), sm_avg.max() + amp_a = max_a - min_a; skip_a = amp_a <= nrows * 1.5 + offs_a, amp_fit_a, center_a, sigma_a = functions.gauss_fit_psss( + sm_avg[::2], axis[::2], offset=min_a, amplitude=amp_a, skip=skip_a, maxfev=10 + ) + fit_avg_spectrum = offs_a + amp_fit_a * np.exp(-((axis - center_a)**2) / (2 * sigma_a**2)) + fit_avg_spectrum = np.abs(fit_avg_spectrum) + + # Average moments + sm_norm_a = sm_avg / np.sum(sm_avg) + spect_com_a = np.sum(axis * sm_norm_a) + spect_std_a = np.sqrt(np.sum((axis - spect_com_a)**2 * sm_norm_a)) + spect_skew_a = np.sum((axis - spect_com_a)**3 * sm_norm_a) / (spect_std_a**3) + cum_a = np.cumsum(sm_norm_a); e25_a = np.interp(0.25, cum_a, axis); e75_a = np.interp(0.75, cum_a, axis) + spect_iqr_a = e75_a - e25_a + spect_res_a = spect_iqr_a / spect_com_a * 1000 + + avg_results = { + f"{camera}:AVG-FIT-COM": np.float64(center), + f"{camera}:AVG-FIT-FWHM": np.float64(2.355 * sigma_a), + f"{camera}:AVG-FIT-RMS": np.float64(sigma_a), + f"{camera}:AVG-FIT-RES": np.float64(2.355 * sigma_a / center_a * 1000), + f"{camera}:AVG-SPECT-COM": spect_com, + f"{camera}:AVG-SPECT-RMS": spect_std_a, + f"{camera}:AVG-SPECT-SKEW": spect_skew_a, + f"{camera}:AVG-SPECT-IQR": spect_iqr_a, + f"{camera}:AVG-SPECT-RES": np.float64(spect_res_a), + f"{camera}:AVG-SPECTRUM_Y": avg_spectrum, + f"{camera}:AVG-FIT-SPECTRUM_Y": fit_avg_spectrum + } + + # Merge and queue + full_results = {**result, **ravg_results, **avg_results} + if epics_lock.acquire(False): + try: + if pulse_id > sent_pid: + sent_pid = pulse_id + #entry = tuple(full_results.get(pv) for pv in all_pv_names) + entry = tuple(_pv_safe(full_results.get(pv), pv) for pv in all_pv_names) + buffer.append(entry) + finally: + epics_lock.release() + + return full_results + + except Exception as ex: + _logger.warning("Processing error: %s", ex) + return {} diff --git a/configuration/user_scripts/swissfel_spectral_processing_fast.py b/configuration/user_scripts/swissfel_spectral_processing_fast.py index 34c3a3d..91bff61 100644 --- a/configuration/user_scripts/swissfel_spectral_processing_fast.py +++ b/configuration/user_scripts/swissfel_spectral_processing_fast.py @@ -164,35 +164,45 @@ def process_image(image, pulse_id, timestamp, x_axis, y_axis, parameters, bsdata if 0 <= ymin_i < ymax_i <= nrows: proc_img = proc_img[ymin_i:ymax_i, :] + # Trim x_axis to match the cropped image width + axis = x_axis[:proc_img.shape[1]] + # Spectrum via vector sum spectrum = np.sum(proc_img, axis=0) # Smooth smoothed = scipy.signal.savgol_filter(spectrum, 51, 3) + # Fit Gaussian minimum, maximum = smoothed.min(), smoothed.max() amplitude = maximum - minimum skip = amplitude <= nrows * 1.5 offset, amp_fit, center, sigma = functions.gauss_fit_psss( - smoothed[::2], x_axis[:len(smoothed)][::2], offset=minimum, - amplitude=amplitude, skip=skip, maxfev=10 + smoothed[::2], + axis[:len(smoothed)][::2], + offset=minimum, + amplitude=amplitude, + skip=skip, + maxfev=10 + ) + fit_spectrum = offset + amp_fit * np.exp( + -((axis[:len(smoothed)] - center)**2) / (2 * sigma**2) ) - fit_spectrum = offset + amp_fit * np.exp(-((x_axis[:len(smoothed)] - center)**2) / (2 * sigma**2)) # Compute stats sm_norm = smoothed / np.sum(smoothed) - spect_com = np.dot(x_axis[:len(sm_norm)], sm_norm) - spect_std = np.sqrt(np.dot((x_axis[:len(sm_norm)] - spect_com)**2, sm_norm)) - spect_skew = np.dot((x_axis[:len(sm_norm)] - spect_com)**3, sm_norm) / (spect_std**3) + spect_com = np.dot(axis[:len(sm_norm)], sm_norm) + spect_std = np.sqrt(np.dot((axis[:len(sm_norm)] - spect_com)**2, sm_norm)) + spect_skew = np.dot((axis[:len(sm_norm)] - spect_com)**3, sm_norm) / (spect_std**3) cum = np.cumsum(sm_norm) - e25 = np.interp(0.25, cum, x_axis[:len(cum)]) - e75 = np.interp(0.75, cum, x_axis[:len(cum)]) + e25 = np.interp(0.25, cum, axis[:len(cum)]) + e75 = np.interp(0.75, cum, axis[:len(cum)]) spect_iqr = e75 - e25 spect_sum = spectrum.sum() # Original result result = { parameters["e_int_name"]: spectrum, - parameters["e_axis_name"]: x_axis[:len(spectrum)], + parameters["e_axis_name"]: axis, f"{camera}:SPECTRUM_Y_SUM": spect_sum, f"{camera}:FIT-COM": np.float64(center), f"{camera}:FIT-FWHM": np.float64(2.355 * sigma), @@ -212,7 +222,11 @@ def process_image(image, pulse_id, timestamp, x_axis, y_axis, parameters, bsdata # Running averages (thread-safe, incremental sum) ravg_results = {} - exclude = {parameters["e_int_name"], parameters["e_axis_name"], f"{camera}:processing_parameters"} + exclude = { + parameters["e_int_name"], + parameters["e_axis_name"], + f"{camera}:processing_parameters" + } with ravg_lock: for pv in base_pv_names: if pv not in exclude: @@ -236,23 +250,30 @@ def process_image(image, pulse_id, timestamp, x_axis, y_axis, parameters, bsdata avg_buffer.append(spectrum) avg_sum += spectrum avg_spectrum = avg_sum / len(avg_buffer) + # Fit and stats on avg_spectrum sm_avg = scipy.signal.savgol_filter(avg_spectrum, 51, 3) min_a, max_a = sm_avg.min(), sm_avg.max() amp_a = max_a - min_a skip_a = amp_a <= nrows * 1.5 offs_a, amp_fit_a, center_a, sigma_a = functions.gauss_fit_psss( - sm_avg[::2], x_axis[:len(sm_avg)][::2], offset=min_a, - amplitude=amp_a, skip=skip_a, maxfev=10 + sm_avg[::2], + axis[:len(sm_avg)][::2], + offset=min_a, + amplitude=amp_a, + skip=skip_a, + maxfev=10 + ) + fit_avg_spectrum = offs_a + amp_fit_a * np.exp( + -((axis[:len(sm_avg)] - center_a)**2) / (2 * sigma_a**2) ) - fit_avg_spectrum = offs_a + amp_fit_a * np.exp(-((x_axis[:len(sm_avg)] - center_a)**2) / (2 * sigma_a**2)) sm_norm_a = sm_avg / np.sum(sm_avg) - spect_com_a = np.dot(x_axis[:len(sm_norm_a)], sm_norm_a) - spect_std_a = np.sqrt(np.dot((x_axis[:len(sm_norm_a)] - spect_com_a)**2, sm_norm_a)) - spect_skew_a = np.dot((x_axis[:len(sm_norm_a)] - spect_com_a)**3, sm_norm_a) / (spect_std_a**3) + spect_com_a = np.dot(axis[:len(sm_norm_a)], sm_norm_a) + spect_std_a = np.sqrt(np.dot((axis[:len(sm_norm_a)] - spect_com_a)**2, sm_norm_a)) + spect_skew_a = np.dot((axis[:len(sm_norm_a)] - spect_com_a)**3, sm_norm_a) / (spect_std_a**3) cum_a = np.cumsum(sm_norm_a) - e25_a = np.interp(0.25, cum_a, x_axis[:len(cum_a)]) - e75_a = np.interp(0.75, cum_a, x_axis[:len(cum_a)]) + e25_a = np.interp(0.25, cum_a, axis[:len(cum_a)]) + e75_a = np.interp(0.75, cum_a, axis[:len(cum_a)]) spect_iqr_a = e75_a - e25_a spect_res_a = spect_iqr_a / spect_com_a * 1000 @@ -281,3 +302,4 @@ def process_image(image, pulse_id, timestamp, x_axis, y_axis, parameters, bsdata epics_lock.release() return full +