From b41f3193abd716457d42cdd2aa843090588be00f Mon Sep 17 00:00:00 2001 From: root Date: Thu, 6 Apr 2023 10:41:04 +0200 Subject: [PATCH] Add example pipeline in C --- .../camera_config/SARES20-CAMS142-M3.json | 6 +- .../camera_config/SATOP21-PMOS127-2D.json | 31 +++ .../camera_config/permanent_instances.json | 1 + configuration/camera_config/servers.json | 3 +- .../SARES11-XMI125-C4P1_db.json | 6 +- .../SARES20-PROF141-M1_proc.json | 10 +- .../pipeline_config/SARFE10-PBPS053_proc.json | 38 ++-- .../pipeline_config/SAROP11-PBPS110_proc.json | 38 ++-- .../pipeline_config/SAROP11-PBPS122_proc.json | 38 ++-- .../pipeline_config/SATBD02-DSCR050_sp.json | 17 +- .../SATOP21-PMOS127-2D_pmos.json | 20 ++ .../SATOP21-PMOS127-2D_sp.json | 11 + .../SLAAR02-LPMO02-C322_proc.json | 3 +- .../pipeline_config/permanent_instances.json | 38 +--- configuration/pipeline_config/servers.json | 7 +- configuration/pipeline_config/test_furka.json | 3 +- configuration/user_scripts/bernina.py | 11 +- configuration/user_scripts/pmos127-2D.py | 157 +++++++++++++ configuration/user_scripts/pprm_simple.py | 19 +- configuration/user_scripts/single_photon.c | 214 ++++++++++++++++++ configuration/user_scripts/test_pprm.py | 18 ++ 21 files changed, 571 insertions(+), 118 deletions(-) create mode 100644 configuration/camera_config/SATOP21-PMOS127-2D.json create mode 100644 configuration/pipeline_config/SATOP21-PMOS127-2D_pmos.json create mode 100644 configuration/pipeline_config/SATOP21-PMOS127-2D_sp.json create mode 100644 configuration/user_scripts/pmos127-2D.py create mode 100644 configuration/user_scripts/single_photon.c create mode 100644 configuration/user_scripts/test_pprm.py diff --git a/configuration/camera_config/SARES20-CAMS142-M3.json b/configuration/camera_config/SARES20-CAMS142-M3.json index 66372e2..cbaf700 100644 --- a/configuration/camera_config/SARES20-CAMS142-M3.json +++ b/configuration/camera_config/SARES20-CAMS142-M3.json @@ -1,9 +1,9 @@ { "camera_calibration": { "reference_marker": [ - 352, + 338, 502, - 453, + 441, 606 ], "reference_marker_width": 413.0, @@ -25,6 +25,6 @@ "Bernina" ], "alias": [ - "CAMERA_BSSS (SARES20-CAMS142-M3)" + "SAMPLECAM_INLINE (SARES20-CAMS142-M3)" ] } \ No newline at end of file diff --git a/configuration/camera_config/SATOP21-PMOS127-2D.json b/configuration/camera_config/SATOP21-PMOS127-2D.json new file mode 100644 index 0000000..a996270 --- /dev/null +++ b/configuration/camera_config/SATOP21-PMOS127-2D.json @@ -0,0 +1,31 @@ +{ + "camera_calibration": { + "reference_marker": [ + 0, + 0, + 100, + 100 + ], + "reference_marker_width": 100.0, + "reference_marker_height": 100.0, + "angle_horizontal": 0.0, + "angle_vertical": 0.0 + }, + "mirror_x": false, + "mirror_y": false, + "rotate": 0, + "roi": null, + "image_background": null, + "source_type": "bsread", + "prefix": "SATOP21-PMOS127-2D", + "source": "SATOP21-PMOS127-2D", + "name": "SATOP21-PMOS127-2D", + "connections": 2, + "buffer_size": 0, + "forwarder_port": [], + "group": [ + "Photonics" + ], + "alias": [], + "protocol": "tcp" +} \ No newline at end of file diff --git a/configuration/camera_config/permanent_instances.json b/configuration/camera_config/permanent_instances.json index 7060264..471bf91 100644 --- a/configuration/camera_config/permanent_instances.json +++ b/configuration/camera_config/permanent_instances.json @@ -19,6 +19,7 @@ "SATES30-CAMS182-GIGE1": "SATES30-CAMS182-GIGE1", "SATES30-CAMS182-GIGE2": "SATES30-CAMS182-GIGE2", "SATES31-CAMS187-RIXS1": "SATES31-CAMS187-RIXS1", + "SATOP21-PMOS127-2D": "SATOP21-PMOS127-2D", "SATOP31-PMOS132-2D": "SATOP31-PMOS132-2D", "SINDI02-DSCR075": "SINDI02-DSCR075", "SLAAR02-LPMO01-C321": "SLAAR02-LPMO01-C321", diff --git a/configuration/camera_config/servers.json b/configuration/camera_config/servers.json index 5b1a970..0d80379 100644 --- a/configuration/camera_config/servers.json +++ b/configuration/camera_config/servers.json @@ -17,7 +17,8 @@ "expanding": false, "instances": [ "SARFE10-PPRM064", - "SATOP31-PMOS132-2D" + "SATOP31-PMOS132-2D", + "SATOP21-PMOS127-2D" ] }, "http://sf-daqsync-08.psi.ch:8880": { diff --git a/configuration/pipeline_config/SARES11-XMI125-C4P1_db.json b/configuration/pipeline_config/SARES11-XMI125-C4P1_db.json index 2b0aa44..4862c67 100644 --- a/configuration/pipeline_config/SARES11-XMI125-C4P1_db.json +++ b/configuration/pipeline_config/SARES11-XMI125-C4P1_db.json @@ -11,10 +11,10 @@ "name": "SARES11-XMI125-C4P1_db", "mode": "PUSH", "roi_signal": [ - 100, - 700, 550, - 750 + 900, + 500, + 700 ], "no_client_timeout": 0, "pixel_bkg": 0, diff --git a/configuration/pipeline_config/SARES20-PROF141-M1_proc.json b/configuration/pipeline_config/SARES20-PROF141-M1_proc.json index 596c0ef..71e534e 100644 --- a/configuration/pipeline_config/SARES20-PROF141-M1_proc.json +++ b/configuration/pipeline_config/SARES20-PROF141-M1_proc.json @@ -8,6 +8,10 @@ "pipeline_type": "processing", "camera_name": "SARES20-PROF141-M1", "name": "SARES20-PROF141-M1_proc", - "function": "bernina", - "mode": "PUSH" -} + "_function": "bernina", + "function": "test_pprm.py", + "create_header": "once", + "block": false, + "mode": "PUSH", + "reload": true +} \ 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 9b74ffc..a4fcac8 100644 --- a/configuration/pipeline_config/SARFE10-PBPS053_proc.json +++ b/configuration/pipeline_config/SARFE10-PBPS053_proc.json @@ -17,12 +17,12 @@ "down": "SARFE10-CVME-PHO6212:Lnk9Ch13-DATA-SUM", "right": "SARFE10-CVME-PHO6212:Lnk9Ch14-DATA-SUM", "left": "SARFE10-CVME-PHO6212:Lnk9Ch15-DATA-SUM", - "up_calib": 0.15959758776955815, - "down_calib": 0.17081416074661804, - "left_calib": 0.44737311355742443, - "right_calib": 0.2736612788911648, - "horiz_calib": -3.928214392529789, - "vert_calib": -7.346281801499673, + "up_calib": 0.29332902630344176, + "down_calib": 0.30758809127657744, + "left_calib": 0.8548507102577435, + "right_calib": 0.5254048353918549, + "horiz_calib": -3.9686377191422566, + "vert_calib": -6.757177531835748, "uJ_calib": 834.5191797495979, "threshold": 0, "queue_length": 5000, @@ -60,9 +60,9 @@ 0.3 ], "calib_x_norm": [ - 0.07705425324290305, - 0.000292090419390871, - -0.0756869008908959 + 0.07725444027758947, + -0.0008820870911578288, + -0.0739309393064352 ], "calib_y_range": [ -0.3, @@ -70,20 +70,20 @@ 0.3 ], "calib_y_norm": [ - 0.0405085485929619, - 0.00025258183377802507, - -0.04116542147956046 + 0.044622126986971204, + -0.0008061137879948807, + -0.04417234336298802 ], "calib_time": "2022-11-28 16:19:37", - "calib_datetime": "2023-03-13 17:13:41", + "calib_datetime": "2023-03-20 14:25:54", "calib_x_norm_std": [ - 0.06063214980948818, - 0.06221414202235211, - 0.06667909972355505 + 0.09961747340145947, + 0.10733784051069324, + 0.0929030520787079 ], "calib_y_norm_std": [ - 0.06069608759370142, - 0.05655588611057008, - 0.06231444141801817 + 0.09287619707647062, + 0.092107183273319, + 0.09302589672639311 ] } \ No newline at end of file diff --git a/configuration/pipeline_config/SAROP11-PBPS110_proc.json b/configuration/pipeline_config/SAROP11-PBPS110_proc.json index 71e7fef..6e75235 100644 --- a/configuration/pipeline_config/SAROP11-PBPS110_proc.json +++ b/configuration/pipeline_config/SAROP11-PBPS110_proc.json @@ -19,12 +19,12 @@ "down": "SAROP11-CVME-PBPS2:Lnk9Ch11-DATA-SUM", "right": "SAROP11-CVME-PBPS2:Lnk9Ch14-DATA-SUM", "left": "SAROP11-CVME-PBPS2:Lnk9Ch15-DATA-SUM", - "up_calib": 4.176246646802521, - "down_calib": 5.0147722517321744, - "left_calib": 4.226868737030241, - "right_calib": 4.595144040785396, - "horiz_calib": -5.938292083354949, - "vert_calib": 5.750883131195752, + "up_calib": 0.6296855239312056, + "down_calib": 0.6822391000717031, + "left_calib": 0.4013112158986877, + "right_calib": 0.43663511455622184, + "horiz_calib": -4.489940533745727, + "vert_calib": 4.432874535470348, "uJ_calib": 605.4608924473305, "threshold": 0, "queue_length": 5000, @@ -62,9 +62,9 @@ 0.3 ], "calib_x_norm": [ - 0.05144210467883525, - 0.0006052215239522377, - -0.04959704792226395 + 0.06455376367074324, + -0.004423482191118885, + -0.06907829570520817 ], "calib_y_range": [ -0.3, @@ -72,19 +72,19 @@ 0.3 ], "calib_y_norm": [ - -0.05168657093812036, - 0.0007021663413024587, - 0.05264523103248323 + -0.06564181411065985, + -0.0008317809501211942, + 0.06971053913078763 ], - "calib_datetime": "2023-03-02 10:00:35", + "calib_datetime": "2023-03-20 14:28:15", "calib_x_norm_std": [ - 0.594488273756939, - 0.6069233875455338, - 0.63112542665871 + 0.05738778249204604, + 0.06125085163512557, + 0.06392592319735892 ], "calib_y_norm_std": [ - 0.5810483125243515, - 0.6050056030333926, - 0.6023487356109991 + 0.07023632581683162, + 0.07117317113274499, + 0.08021938968881043 ] } \ 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 fee2075..e1f877c 100644 --- a/configuration/pipeline_config/SAROP11-PBPS122_proc.json +++ b/configuration/pipeline_config/SAROP11-PBPS122_proc.json @@ -18,12 +18,12 @@ "down": "SAROP11-CVME-PBPS1:Lnk9Ch5-DATA-SUM", "right": "SAROP11-CVME-PBPS1:Lnk9Ch3-DATA-SUM", "left": "SAROP11-CVME-PBPS1:Lnk9Ch7-DATA-SUM", - "up_calib": 3.112906892007253, - "down_calib": 2.42031522941779, - "left_calib": 3.0712034522489846, - "right_calib": 2.6667721760426386, - "horiz_calib": -5.887206380557174, - "vert_calib": 5.859029430684977, + "up_calib": 4.856902438997528, + "down_calib": 3.6407001867683255, + "left_calib": 2.5431847379184935, + "right_calib": 2.258752231178428, + "horiz_calib": -4.923045366857815, + "vert_calib": 5.191012812577014, "uJ_calib": 605.9512700123181, "threshold": 0, "queue_length": 1000, @@ -66,14 +66,14 @@ 0.3 ], "calib_x_norm": [ - 0.052679439786701664, - 0.001497643249781178, - -0.04923647095519678 + 0.06097587138301983, + -0.0005498292535706359, + -0.06089990982331022 ], "calib_x_norm_std": [ - 0.6146987957054612, - 0.6088117395208462, - 0.5948902988515276 + 0.12938263783219212, + 0.13160024776911167, + 0.1278339097734837 ], "calib_y_range": [ -0.3, @@ -81,15 +81,15 @@ 0.3 ], "calib_y_norm": [ - -0.050746643828704, - 0.000785186946847148, - 0.05165939578899666 + -0.054567022258138184, + 0.003407500099057587, + 0.061017358220810655 ], "calib_y_norm_std": [ - 0.6016897603750389, - 0.5789543559357142, - 0.593537052066037 + 0.14051543884010068, + 0.14684107677948718, + 0.1415533936562058 ], - "calib_datetime": "2023-03-02 10:03:18", + "calib_datetime": "2023-03-20 14:30:57", "reload": true } \ 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 f8152bb..683482e 100644 --- a/configuration/pipeline_config/SATBD02-DSCR050_sp.json +++ b/configuration/pipeline_config/SATBD02-DSCR050_sp.json @@ -3,16 +3,17 @@ "image_background": "SATBD02-DSCR050_20221013_123827_350915", "image_threshold": null, "image_region_of_interest": [ - 232, - 1625, - 534, - 861 + 94, + 1700, + 521, + 1145 ], - "image_good_region": { - "threshold": 0.10000000000000003, - "gfscale": 10.0 + "image_good_region": null, + "image_slices": { + "number_of_slices": 10, + "scale": 1.8, + "orientation": "horizontal" }, - "image_slices": null, "pipeline_type": "processing", "camera_name": "SATBD02-DSCR050", "name": "SATBD02-DSCR050_sp", diff --git a/configuration/pipeline_config/SATOP21-PMOS127-2D_pmos.json b/configuration/pipeline_config/SATOP21-PMOS127-2D_pmos.json new file mode 100644 index 0000000..a34cbcf --- /dev/null +++ b/configuration/pipeline_config/SATOP21-PMOS127-2D_pmos.json @@ -0,0 +1,20 @@ +{ + "image_background_enable": false, + "image_background": "SATOP31-PMOS132-2D_20220607_121502_104208", + "image_threshold": null, + "image_region_of_interest": null, + "image_good_region": null, + "image_slices": null, + "pipeline_type": "processing", + "camera_name": "SATOP21-PMOS127-2D", + "name": "SATOP21-PMOS127-2D_pmos", + "function": "pmos132-2D.py", + "mode": "PUB", + "no_client_timeout": 0, + "reload": true, + "processing_threads": 6, + "thread_buffer_size": 30, + "abort_on_error": false, + "pixel_bkg": 1, + "port": "9001" +} \ No newline at end of file diff --git a/configuration/pipeline_config/SATOP21-PMOS127-2D_sp.json b/configuration/pipeline_config/SATOP21-PMOS127-2D_sp.json new file mode 100644 index 0000000..40c6ff4 --- /dev/null +++ b/configuration/pipeline_config/SATOP21-PMOS127-2D_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": "SATOP21-PMOS127-2D", + "name": "SATOP21-PMOS127-2D_sp" +} \ No newline at end of file diff --git a/configuration/pipeline_config/SLAAR02-LPMO02-C322_proc.json b/configuration/pipeline_config/SLAAR02-LPMO02-C322_proc.json index bcf9492..4a7cc5b 100644 --- a/configuration/pipeline_config/SLAAR02-LPMO02-C322_proc.json +++ b/configuration/pipeline_config/SLAAR02-LPMO02-C322_proc.json @@ -10,5 +10,6 @@ "name": "SLAAR02-LPMO02-C322_proc", "function": "pprm_simple.py", "mode": "PUSH", - "no_client_timeout": 0 + "no_client_timeout": 0, + "reload": true } \ No newline at end of file diff --git a/configuration/pipeline_config/permanent_instances.json b/configuration/pipeline_config/permanent_instances.json index 803b90e..d05f13d 100644 --- a/configuration/pipeline_config/permanent_instances.json +++ b/configuration/pipeline_config/permanent_instances.json @@ -1,51 +1,19 @@ { - "#S10BC02-DSRM310_ib": "S10BC02-DSRM310_ib", "#S10BC02-DSRM310_profiles": "S10BC02-DSRM310_profiles", - "#S10BD01-DSCR030_ib": "S10BD01-DSCR030_ib", - "#SARCL01-DSCR170_ib": "SARCL01-DSCR170_ib", "#SARES11-SPEC125-M1_psen_db": "SARES11-SPEC125-M1_psen_db", - "#SARES11-SPEC125-M1_psen_ib": "SARES11-SPEC125-M1_psen_ib", "#SARES11-SPEC125-M1_test": "SARES11-SPEC125-M1_test", "#SARES11-SPEC125-M2_psen_db1": "SARES11-SPEC125-M2_psen_db", - "#SARES11-SPEC125-M2_psen_ib": "SARES11-SPEC125-M2_psen_ib", - "#SARES11-XMI125-C4P1_ib": "SARES11-XMI125-C4P1_ib", - "#SARES11-XPR125-C4P2_sp": "SARES11-XPR125-C4P2_sp", "#SARES12-CAMS128-M1_psen_db": "SARES12-CAMS128-M1_psen_db", - "#SARES12-CAMS128-M1_psen_ib": "SARES12-CAMS128-M1_psen_ib", "#SARES20-CAMS142-M1_psen_db": "SARES20-CAMS142-M1_psen_db", - "#SARES20-CAMS142-M1_psen_ib": "SARES20-CAMS142-M1_psen_ib", - "#SARES20-CAMS142-M3_ib": "SARES20-CAMS142-M3_ib", - "#SARES20-CAMS142-M5_psen_ib": "SARES20-CAMS142-M5_psen_ib", - "#SARES20-DSDPPRM_ib": "SARES20-DSDPPRM_ib", "#SARES20-DSDPPRM_proc": "SARES20-DSDPPRM_proc", - "#SARES20-PROF141-M1_ib": "SARES20-PROF141-M1_ib", - "#SARES20-PROF141-M1_proc": "SARES20-PROF141-M1_proc", - "#SARES30-CAMS156-PCO1_ib": "SARES30-CAMS156-PCO1_ib", - "#SARES30-CAMS156-XE_ib": "SARES30-CAMS156-XE_ib", - "#SARFE10-PPRM064_ib": "SARFE10-PPRM064_ib", - "#SARFE10-PSSS059_store": "SARFE10-PSSS059_store", "#SAROP11-ATT01_proc": "SAROP11-ATT01_proc", - "#SAROP21-PPRM102_ib": "SAROP21-PPRM102_ib", "#SAROP21-PPRM102_proc": "SAROP21-PPRM102_proc", "#SAROP21-PPRM113_proc": "SAROP21-PPRM113_proc", - "#SAROP21-PPRM138_ib": "SAROP21-PPRM138_ib", - "#SAROP31-PPRM113_ib": "SAROP31-PPRM113_ib", - "#SAROP31-PPRM150_ib": "SAROP31-PPRM150_ib", - "#SATBD02-DSCR050_ib": "SATBD02-DSCR050_ib", - "#SATES21-CAMS-PATT1_spec_ib": "SATES21-CAMS-PATT1_spec_ib", - "#SATES21-CAMS154-M1_spec_ib": "SATES21-CAMS154-M1_spec_ib", - "#SATES24-CAMS161-M1_spec_ib": "SATES24-CAMS161-M1_spec_ib", - "#SATES30-CAMS182-GIGE1_ib": "SATES30-CAMS182-GIGE1_ib", - "#SATES30-CAMS182-GIGE2_ib": "SATES30-CAMS182-GIGE2_ib", - "#SATES31-CAMS187-RIXS1_ib": "SATES31-CAMS187-RIXS1_ib", - "#SATOP31-PMOS132-2D_store": "SATOP31-PMOS132-2D_store", - "#SINBC02-DSRM310_ib": "SINBC02-DSRM310_ib", "#SINBC02-DSRM310_profiles": "SINBC02-DSRM310_profiles", - "#SINDI02-DSCR075_ib": "SINDI02-DSCR075_ib", "#jungfrau_proc": "jungfrau_proc", - "#test_furka": "test_furka", "#test_merge": "test_merge", "#test_proc_with_bs": "test_proc_with_bs", + "#test_str": "test_str", "#test_stream": "test_stream", "#test_tadej": "test_tadej", "#testdb_ib": "testdb_ib", @@ -55,6 +23,7 @@ "SARES20-CAMS142-M3_proc": "SARES20-CAMS142-M3_proc", "SARES20-CAMS142-M5_psen_db": "SARES20-CAMS142-M5_psen_db", "SARES20-CAMS142-M5_psen_db_proxy": "SARES20-CAMS142-M5_psen_db_proxy", + "SARES20-PROF141-M1_proc": "SARES20-PROF141-M1_proc", "SARES30-CAMS156-XE_proc": "SARES30-CAMS156-XE_proc", "SARFE10-PBPS053_proc": "SARFE10-PBPS053_proc", "SARFE10-PPRM064_proc": "SARFE10-PPRM064_proc", @@ -79,6 +48,7 @@ "SATES30-CAMS182-GIGE1_profiles": "SATES30-CAMS182-GIGE1_profiles", "SATES30-CAMS182-GIGE2_profiles": "SATES30-CAMS182-GIGE2_profiles", "SATES31-CAMS187-RIXS1_proc": "SATES31-CAMS187-RIXS1_proc", + "SATOP21-PMOS127-2D_pmos": "SATOP21-PMOS127-2D_pmos", "SATOP31-PMOS132-2D_pmos": "SATOP31-PMOS132-2D_pmos", "SINDI02-DSCR075_profiles": "SINDI02-DSCR075_profiles", "SLAAR02-LPMO01-C321_proc": "SLAAR02-LPMO01-C321_proc", @@ -87,5 +57,5 @@ "SLAAR21-LCAM-CS842_proc": "SLAAR21-LCAM-CS842_proc", "SLAAR21-LCAM-CS843_proc": "SLAAR21-LCAM-CS843_proc", "SLAAR21-LCAM-CS844_proc": "SLAAR21-LCAM-CS844_proc", - "test_str": "test_str" + "test_furka": "test_furka" } \ No newline at end of file diff --git a/configuration/pipeline_config/servers.json b/configuration/pipeline_config/servers.json index 8817684..9d031f2 100644 --- a/configuration/pipeline_config/servers.json +++ b/configuration/pipeline_config/servers.json @@ -44,6 +44,7 @@ "SAROP21-PBPS133_proc:9008", "SARFE10-PPRM064_ib:9015", "SATOP31-PMOS132-2D_sp", + "SATOP21-PMOS127-2D_pmos", "SARFE10-PPRM064_sp", "SARFE10-PPRM064_proc:9014", "SATOP31-PMOS132-2D_pmos:9001", @@ -217,7 +218,7 @@ "SARES20-PROF141-M1_proc:9016", "SARES20-PROF141-M1_ib:9013", "SARES20-PROF146-M1_sp", - "#SARES20-PROF146-M1_proc:9018", + "SARES20-PROF146-M1_proc:9018", "SARES20-DSDPPRM_proc:9014", "SARES20-DSDPPRM_ib:9020", "SLAAR21-LCAM-CS841_proc:9021", @@ -233,9 +234,9 @@ "http://sf-daqsync-15.psi.ch:8881": { "cameras": [ "SATES31-CAMS187-RIXS1", - "SATES30-RIXS-CAM01", "SATES30-CAMS182-GIGE1", - "SATES30-CAMS182-GIGE2" + "SATES30-CAMS182-GIGE2", + "SATES30-RIXS-CAM01" ], "enabled": true, "expanding": false, diff --git a/configuration/pipeline_config/test_furka.json b/configuration/pipeline_config/test_furka.json index 55e2766..6540d82 100644 --- a/configuration/pipeline_config/test_furka.json +++ b/configuration/pipeline_config/test_furka.json @@ -8,7 +8,8 @@ "pipeline_type": "processing", "camera_name": "simulation", "name": "test_furka", - "function": "furka.py", + "_function": "furka.py", + "function": "single_photon.c", "mode": "PUB", "reload": true } \ No newline at end of file diff --git a/configuration/user_scripts/bernina.py b/configuration/user_scripts/bernina.py index c73223f..26e7211 100644 --- a/configuration/user_scripts/bernina.py +++ b/configuration/user_scripts/bernina.py @@ -1,6 +1,6 @@ from collections import OrderedDict from cam_server.pipeline.data_processing import functions, processor - +import numpy as np def process_image(image, pulse_id, timestamp, x_axis, y_axis, parameters, bsdata): r = processor.process_image(image, pulse_id, timestamp, x_axis, y_axis, parameters, bsdata) @@ -8,5 +8,12 @@ def process_image(image, pulse_id, timestamp, x_axis, y_axis, parameters, bsdata channels = ["intensity","x_center_of_mass","x_fwhm","x_rms","x_fit_amplitude", "x_fit_mean","x_fit_offset","x_fit_standard_deviation","x_profile","y_center_of_mass","y_fwhm","y_rms","y_fit_amplitude", "y_fit_mean","y_fit_offset","y_fit_standard_deviation","y_profile"] prefix = parameters["camera_name"] for c in channels: - ret[prefix+":"+c] = r[c] + value = r[c] + if isinstance(value,np.floating): + value=float(value) + if isinstance(value,np.integer): + value=int(value) + if type(value) == list: + value = np.array(value) + ret[prefix+":"+c] = value return ret diff --git a/configuration/user_scripts/pmos127-2D.py b/configuration/user_scripts/pmos127-2D.py new file mode 100644 index 0000000..6dd002f --- /dev/null +++ b/configuration/user_scripts/pmos127-2D.py @@ -0,0 +1,157 @@ +from logging import getLogger + +from cam_server.pipeline.data_processing import functions +from cam_server.utils import create_thread_pvs, epics_lock + + +import json + +import numpy +import scipy.signal +import scipy.optimize +import numba + +numba.set_num_threads(4) + +_logger = getLogger(__name__) + +channel_names = None +output_pv, center_pv, fwhm_pv, ymin_pv, ymax_pv, axis_pv = None, None, None, None, None, None +roi = [0, 0] +initialized = False +sent_pid = -1 + + +@numba.njit(parallel=True) +def get_spectrum(image, background): + y = image.shape[0] + x = image.shape[1] + + profile = numpy.zeros(x, dtype=numpy.uint32) + + for i in numba.prange(y): + for j in range(x): + v = image[i, j] + b = background[i, j] + if v > b: + v -= b + else: + v = 0 + profile[j] += v + return profile + + +def initialize(parameters): + global ymin_pv, ymax_pv, axis_pv, output_pv, center_pv, fwhm_pv + global channel_names + epics_pv_name_prefix = parameters["camera_name"] + output_pv_name = epics_pv_name_prefix + ":SPECTRUM_Y" + center_pv_name = epics_pv_name_prefix + ":SPECTRUM_CENTER" + fwhm_pv_name = epics_pv_name_prefix + ":SPECTRUM_FWHM" + ymin_pv_name = epics_pv_name_prefix + ":SPC_ROI_YMIN" + ymax_pv_name = epics_pv_name_prefix + ":SPC_ROI_YMAX" + axis_pv_name = epics_pv_name_prefix + ":SPECTRUM_X" + channel_names = [output_pv_name, center_pv_name, fwhm_pv_name, ymin_pv_name, ymax_pv_name, axis_pv_name] + + +def process_image(image, pulse_id, timestamp, x_axis, y_axis, parameters, bsdata=None, background=None): + global roi, initialized, sent_pid + global channel_names + + if not initialized: + initialize(parameters) + initialized = True + [output_pv, center_pv, fwhm_pv, ymin_pv, ymax_pv, axis_pv] = create_thread_pvs(channel_names) + processed_data = dict() + epics_pv_name_prefix = parameters["camera_name"] + + if ymin_pv and ymin_pv.connected: + roi[0] = ymin_pv.value + if ymax_pv and ymax_pv.connected: + roi[1] = ymax_pv.value + if axis_pv and axis_pv.connected: + axis = axis_pv.value + else: + axis = None + + if axis is None: + _logger.warning("Energy axis not connected"); + return None + + if len(axis) < image.shape[1]: + _logger.warning("Energy axis length %d < image width %d", len(axis), image.shape[1]) + return None + + # match the energy axis to image width + axis = axis[:image.shape[1]] + + processing_image = image + processing_image = image.astype(np.float32) - np.float32(parameters["pixel_bkg"]) + + nrows, ncols = processing_image.shape + + # validate background data if passive mode (background subtraction handled here) + background_image = parameters.pop('background_data', None) + if isinstance(background_image, numpy.ndarray): + if background_image.shape != processing_image.shape: + _logger.info("Invalid background shape: %s instead of %s" % ( + str(background_image.shape), str(processing_image.shape))) + background_image = None + else: + background_image = None + + processed_data[epics_pv_name_prefix + ":processing_parameters"] = json.dumps( + {"roi": roi, "background": None if (background_image is None) else parameters.get('image_background')}) + + # crop the image in y direction + ymin, ymax = int(roi[0]), int(roi[1]) + if nrows >= ymax > ymin >= 0: + if (nrows != ymax) or (ymin != 0): + processing_image = processing_image[ymin: ymax, :] + if background_image is not None: + background_image = background_image[ymin:ymax, :] + + # remove the background and collapse in y direction to get the spectrum + if background_image is not None: + spectrum = get_spectrum(processing_image, background_image) + else: + spectrum = processing_image.sum(0, 'uint32') + + # smooth the spectrum with savgol filter with 51 window size and 3rd order polynomial + smoothed_spectrum = scipy.signal.savgol_filter(spectrum, 51, 3) + + # check wether spectrum has only noise. the average counts per pixel at the peak + # should be larger than 1.5 to be considered as having real signals. + minimum, maximum = smoothed_spectrum.min(), smoothed_spectrum.max() + amplitude = maximum - minimum + skip = True + if amplitude > nrows * 1.5: + skip = False + # gaussian fitting + offset, amplitude, center, sigma = functions.gauss_fit_psss(smoothed_spectrum[::2], axis[::2], + offset=minimum, amplitude=amplitude, skip=skip, maxfev=20) + + # outputs + processed_data[epics_pv_name_prefix + ":SPECTRUM_Y"] = spectrum + processed_data[epics_pv_name_prefix + ":SPECTRUM_X"] = axis + processed_data[epics_pv_name_prefix + ":SPECTRUM_CENTER"] = numpy.float64(center) + processed_data[epics_pv_name_prefix + ":SPECTRUM_FWHM"] = numpy.float64(2.355 * sigma) + if epics_lock.acquire(False): + try: + if pulse_id > sent_pid: + sent_pid = pulse_id + if output_pv and output_pv.connected: + output_pv.put(processed_data[epics_pv_name_prefix + ":SPECTRUM_Y"]) + #_logger.debug("caput on %s for pulse_id %s", output_pv, pulse_id) + + if center_pv and center_pv.connected: + center_pv.put(processed_data[epics_pv_name_prefix + ":SPECTRUM_CENTER"]) + + if fwhm_pv and fwhm_pv.connected: + fwhm_pv.put(processed_data[epics_pv_name_prefix + ":SPECTRUM_FWHM"]) + finally: + epics_lock.release() + + return processed_data + + diff --git a/configuration/user_scripts/pprm_simple.py b/configuration/user_scripts/pprm_simple.py index 8824c4f..80beab8 100644 --- a/configuration/user_scripts/pprm_simple.py +++ b/configuration/user_scripts/pprm_simple.py @@ -1,11 +1,26 @@ from collections import OrderedDict from cam_server.pipeline.data_processing import functions, processor +from logging import getLogger +import numpy as np + +_logger = getLogger(__name__) def process_image(image, pulse_id, timestamp, x_axis, y_axis, parameters, bsdata): r = processor.process_image(image, pulse_id, timestamp, x_axis, y_axis, parameters, bsdata) ret = OrderedDict() - channels = ["x_center_of_mass","y_center_of_mass"] + channels = ["intensity","x_fit_mean","y_fit_mean"] prefix = parameters["camera_name"] for c in channels: - ret[prefix+":"+c] = r[c] + value = r[c] + if value is None: + _logger.warning("None:" + str(c)) + return None + if value == float('nan'): + _logger.warning("NAN:" + str(c)) + return None + if isinstance(value,np.floating): + value=float(value) + if isinstance(value,np.integer): + value=int(value) + ret[prefix+":"+c] = value return ret diff --git a/configuration/user_scripts/single_photon.c b/configuration/user_scripts/single_photon.c new file mode 100644 index 0000000..29c3a3f --- /dev/null +++ b/configuration/user_scripts/single_photon.c @@ -0,0 +1,214 @@ +#include "module.c" +#include +#include +#include +#include +#include + + +const char *CHANNEL_NAMES[] = {"EVENT_NUM", "EVENT_I", "EVENT_J", "EVENT_CHARGE", "EVENT_ETA_X", "EVENT_ETA_Y", "EVENT_I_INTERP", "EVENT_J_INTERP"}; + + +const int MAX_NUM_EVENTS= 1000; // max number of events per frame +const int EVENT_CHANNELS = 7; + + +struct events_double func_ph_1d_double( double *frame, int i_dim, int j_dim, double *th_m); +//struct decl. +struct events_double { + double **evnt_ijc; + int evnt_num; +}; + + + +//def process_image(image, pulse_id, timestamp, x_axis, y_axis, parameters, bsdata=None): +PyObject *process(PyObject *self, PyObject *args) +{ + PyArrayObject *image; + long pulse_id; + PyObject /*double*/ *timestamp; + long seconds, nanos; + PyArrayObject *x_axis; + PyArrayObject *y_axis; + PyObject *pars; + PyObject *bsdata; + + //if (!PyArg_ParseTuple(args, "OldOOO|O", &image, &pulse_id, ×tamp, &x_axis, &y_axis, &pars, &bsdata)) + if ( !PyArg_ParseTuple(args, "OlOOOO|O", &image, &pulse_id, ×tamp, &x_axis, &y_axis, &pars, &bsdata) || + !PyArg_ParseTuple(timestamp, "ll", &seconds, &nanos) ) + return NULL; + + if (pulse_id < 0) { + PyErr_SetString(moduleErr, "Invalid Pulse ID"); + return NULL; + } + + //Acessing image + int element_size = image->descr->elsize; + int dims = image->nd; + int size_x = image->dimensions[1]; + int size_y = image->dimensions[0]; + unsigned short* img_data = (unsigned short*)image->data; + + + int i,j,l; + int i_dim=size_y; + int j_dim=size_x; + + double *threshold = malloc(i_dim*j_dim*sizeof(double)); + for(i=0; i=MAX_NUM_EVENTS){ + break; + } + for(j=0;j=MAX_NUM_EVENTS){ + break; + } + + + // 2x2 version + charge = frame[i*j_dim+j]+frame[(i+1)*j_dim+j] + frame[i*j_dim+(j+1)]+frame[(i+1)*j_dim+j+1]; + + //pixel by pixel threshold + th = th_m[i*j_dim +j]; + + //check if charge above threshold + if(charge>th) { + eta_x = (frame[(i+1)*j_dim + j ]+frame[(i+1)*j_dim + (j+1)])/charge; + eta_y = (frame[ i*j_dim + (j+1)]+frame[(i+1)*j_dim + (j+1)])/charge; + i_interp = i + (C[0] + C[1]*eta_x+ C[2]*pow(eta_x,2) + C[3]*pow(eta_x,3) + C[4]*pow(eta_x,4)+ C[5]*pow(eta_x,5) + C[6]*pow(eta_x,6) + C[7]*pow(eta_x,7)); + j_interp = j + (D[0] + D[1]*eta_y+ D[2]*pow(eta_y,2) + D[3]*pow(eta_y,3) + D[4]*pow(eta_y,4)+ D[5]*pow(eta_y,5) + D[6]*pow(eta_y,6) + D[7]*pow(eta_y,7)); + + // 1st case: first event + if(evt_i==0){ + evt_p[0][evt_i] = i; + evt_p[1][evt_i] = j; + evt_p[2][evt_i] = charge; + evt_p[3][evt_i] = eta_x; + evt_p[4][evt_i] = eta_y; + evt_p[5][evt_i] = i_interp; // + evt_p[6][evt_i] = j_interp; // + evt_i++; + + } else { + // 2nd case: not 1st event. we check if it is a neighbourg of the previos events and if charge is larger + n=0; + evt_m_i = evt_i; + for(m=0; m