From f33f5f68f65e5da41c6718b6d4c71e2315fa5f69 Mon Sep 17 00:00:00 2001 From: Edward Wall Date: Thu, 23 Apr 2026 17:33:23 +0200 Subject: [PATCH] draft of extra sanity checking when placing a beamstop --- Makefile | 16 +- beamstop/beamstop_motors.proto | 23 ++ {scripts => beamstop}/sans_llb_beamstop.cmd | 2 +- {db => beamstop}/sans_llb_beamstop.db | 202 +++++++++++++++++- .../sans_llb_beamstop.substitutions | 0 {scripts => shutter}/shutter.cmd | 0 {db => shutter}/shutter.db | 0 {templates => shutter}/shutter.substitutions | 0 test/beamstop.log | 70 ++++++ test/beamstop.sh | 13 ++ 10 files changed, 314 insertions(+), 12 deletions(-) create mode 100644 beamstop/beamstop_motors.proto rename {scripts => beamstop}/sans_llb_beamstop.cmd (89%) rename {db => beamstop}/sans_llb_beamstop.db (53%) rename {templates => beamstop}/sans_llb_beamstop.substitutions (100%) rename {scripts => shutter}/shutter.cmd (100%) rename {db => shutter}/shutter.db (100%) rename {templates => shutter}/shutter.substitutions (100%) create mode 100644 test/beamstop.log create mode 100755 test/beamstop.sh diff --git a/Makefile b/Makefile index 3772b5a..875c952 100644 --- a/Makefile +++ b/Makefile @@ -18,12 +18,14 @@ TEMPLATES += db/readstring.db TEMPLATES += db/writeusint.db TEMPLATES += db/readusint.db -# Specific devices to include in the release -TEMPLATES += db/shutter.db -TEMPLATES += templates/shutter.substitutions -SCRIPTS += scripts/shutter.cmd +# Shutter Specific +TEMPLATES += shutter/shutter.db +TEMPLATES += shutter/shutter.substitutions +SCRIPTS += shutter/shutter.cmd SCRIPTS += sim/shutter_sim.py -TEMPLATES += db/sans_llb_beamstop.db -TEMPLATES += templates/sans_llb_beamstop.substitutions -SCRIPTS += scripts/sans_llb_beamstop.cmd +# Beamstop Specific +TEMPLATES += beamstop/sans_llb_beamstop.db +TEMPLATES += beamstop/beamstop_motors.proto +TEMPLATES += beamstop/sans_llb_beamstop.substitutions +SCRIPTS += beamstop/sans_llb_beamstop.cmd diff --git a/beamstop/beamstop_motors.proto b/beamstop/beamstop_motors.proto new file mode 100644 index 0000000..18e7deb --- /dev/null +++ b/beamstop/beamstop_motors.proto @@ -0,0 +1,23 @@ +ReplyTimeout = 1000; +ReadTimeout = 100; + +pmac_get { + InTerminator = CR ACK; + out "\$1"; + in "%d"; +} + +st { + InTerminator = CR ACK; + out "P553 Q401 Q501"; + in "%(A)d%*[ ]%(B)f%*[ ]%(C)f"; + # Multi Record Version + # out "P553Q401 Q501"; + # in "%d%*[ ]%(\$1:BS:TARGET_X)f%*[ ]%(\$1:BS:TARGET_Y)f"; +} + +stop { + InTerminator = CR ACK; + out "M04=8 M05=8"; + in "%*s"; +} diff --git a/scripts/sans_llb_beamstop.cmd b/beamstop/sans_llb_beamstop.cmd similarity index 89% rename from scripts/sans_llb_beamstop.cmd rename to beamstop/sans_llb_beamstop.cmd index d3728de..5a1c1fc 100644 --- a/scripts/sans_llb_beamstop.cmd +++ b/beamstop/sans_llb_beamstop.cmd @@ -24,4 +24,4 @@ dbLoadRecords("$(sinqSPS_DB)/sps_status.db", "INSTR=$(INSTR), SPS_REGISTER_NAME= dbLoadTemplate("$(sinqSPS_DB)/sans_llb_beamstop.substitutions", "INSTR=$(INSTR), SPS_REGISTER_NAME=$(SPS_REGISTER_NAME), STATUS_FLNK=$(INSTR)$(SPS_REGISTER_NAME):MAP-STATUS") # Additional Mapping PVs -dbLoadRecords("$(sinqSPS_DB)/sans_llb_beamstop.db", "INSTR=$(INSTR), SPS_REGISTER_NAME=$(SPS_REGISTER_NAME), BSX_MOT=$(BSX_MOT), BSY_MOT=$(BSY_MOT)") +dbLoadRecords("$(sinqSPS_DB)/sans_llb_beamstop.db", "INSTR=$(INSTR), SPS_REGISTER_NAME=$(SPS_REGISTER_NAME), BS_MCU=$(BS_MCU), BS_MCU_ASYN_PORT=$(BS_MCU_ASYN_PORT), PROTO=$(sinqSPS_DB)beamstop_motors.proto") diff --git a/db/sans_llb_beamstop.db b/beamstop/sans_llb_beamstop.db similarity index 53% rename from db/sans_llb_beamstop.db rename to beamstop/sans_llb_beamstop.db index f2651b7..cf7bbc5 100644 --- a/db/sans_llb_beamstop.db +++ b/beamstop/sans_llb_beamstop.db @@ -1,3 +1,7 @@ +################################################################################ +# Beamstop Changer +################################################################################ + record(longout, "$(INSTR)$(SPS_REGISTER_NAME):BEAMSTOP-INIT") { field(DESC, "Initialises BEAMSTOP PV") @@ -195,10 +199,10 @@ record(calcout, "$(INSTR)$(SPS_REGISTER_NAME):BLOCK-BSX") { field(DESC, "Disable BSX during change") field(INPA, "$(INSTR)$(SPS_REGISTER_NAME):STATUS NPP") - field(INPB, "$(BSX_MOT).DISA NPP") + field(INPB, "$(BS_MCU):bsx.DISA NPP") field(CALC, "A=0?!B:B") field(DOPT, "Use CALC") - field(OUT, "$(BSX_MOT).DISV PP") + field(OUT, "$(BS_MCU):bsx.DISV PP") field(FLNK, "$(INSTR)$(SPS_REGISTER_NAME):BLOCK-BSY") } @@ -206,8 +210,198 @@ record(calcout, "$(INSTR)$(SPS_REGISTER_NAME):BLOCK-BSY") { field(DESC, "Disable BSY during change") field(INPA, "$(INSTR)$(SPS_REGISTER_NAME):STATUS NPP") - field(INPB, "$(BSY_MOT).DISA NPP") + field(INPB, "$(BS_MCU):bsy.DISA NPP") field(CALC, "A=0?!B:B") field(DOPT, "Use CALC") - field(OUT, "$(BSY_MOT).DISV PP") + field(OUT, "$(BS_MCU):bsy.DISV PP") } + +################################################################################ +# Beamstop Motors and Collision Detection +################################################################################ + +record(longin, "$(BS_MCU):BS:X_0") { + field(DESC, "X-Position of Beamstop 0") + field(DTYP, "stream") + field(INP , "@$(PROTO) pmac_get(Q453) $(BS_MCU_ASYN_PORT) 0") + field(PINI, "YES") +} + +record(longin, "$(BS_MCU):BS:X_1") { + field(DESC, "X-Position of Beamstop 1") + field(DTYP, "stream") + field(INP , "@$(PROTO) pmac_get(Q454) $(BS_MCU_ASYN_PORT) 0") + field(PINI, "YES") +} + +record(longin, "$(BS_MCU):BS:X_2") { + field(DESC, "X-Position of Beamstop 2") + field(DTYP, "stream") + field(INP , "@$(PROTO) pmac_get(Q455) $(BS_MCU_ASYN_PORT) 0") + field(PINI, "YES") +} + +record(longin, "$(BS_MCU):BS:X_3") { + field(DESC, "X-Position of Beamstop 3") + field(DTYP, "stream") + field(INP , "@$(PROTO) pmac_get(Q456) $(BS_MCU_ASYN_PORT) 0") + field(PINI, "YES") +} + +record(longin, "$(BS_MCU):BS:Y_GET") { + field(DESC, "Y Position for picking up Beamstop") + field(DTYP, "stream") + field(INP , "@$(PROTO) pmac_get(Q553) $(BS_MCU_ASYN_PORT) 0") + field(PINI, "YES") +} + +record(longin, "$(BS_MCU):BS:Y_PUT") { + field(DESC, "Y Position under beamstops") + field(DTYP, "stream") + field(INP , "@$(PROTO) pmac_get(Q554) $(BS_MCU_ASYN_PORT) 0") + field(PINI, "YES") +} + +record(calcout, "$(BS_MCU):BS:ST") { + field(DESC, "Monitors beamstop changing") + field(DTYP, "stream") + field(OUT , "@$(PROTO) st() $(BS_MCU_ASYN_PORT) 0") + field(CALC, "0") + field(SCAN, ".1 second") + field(FLNK, "$(BS_MCU):BS:ST_FANOUT") +} + +record(fanout, "$(BS_MCU):BS:ST_FANOUT1") { + field(LNK1, "$(BS_MCU):BS:TARGET") + field(LNK2, "$(BS_MCU):BS:TARGET_X") + field(LNK3, "$(BS_MCU):BS:TARGET_Y") + field(LNK5, "$(BS_MCU):BS:TARGET_BS_RAW") + field(LNK6, "$(BS_MCU):BS:TARGET_BS") + field(LNK7, "$(BS_MCU):BS:ST_FANOUT2") + field(SCAN, ".1 second") +} + +record(fanout, "$(BS_MCU):BS:ST_FANOUT2") { + field(LNK1, "$(BS_MCU):BS:TARGET_RANGE_RAW") + field(LNK2, "$(BS_MCU):BS:TARGET_RANGE") + field(LNK3, "$(BS_MCU):BS:LOADED_RAW") + field(LNK4, "$(BS_MCU):BS:INVALID") +} + +record(longin, "$(BS_MCU):BS:TARGET") { + field(DESC, "Beamstop position being driven to") + field(INP, "$(BS_MCU):BS:ST.A NPP MS") +} + +record(ai, "$(BS_MCU):BS:TARGET_X") { + field(DESC, "X Position being driven to") + field(INP, "$(BS_MCU):BS:ST.B NPP MS") +} + +record(ai, "$(BS_MCU):BS:TARGET_Y") { + field(DESC, "Y Position being driven to") + field(INP, "$(BS_MCU):BS:ST.C NPP MS") +} + +record(calc, "$(BS_MCU):BS:TARGET_BS_RAW") { + field(DESC, "Beamstop == TARGET_X") + # Dynamic Inputs + field(INPA, "$(BS_MCU):BS:TARGET_X NPP MS") + # Static Inputs + field(INPI, "$(BS_MCU):BS:X_0 NPP MS") + field(INPJ, "$(BS_MCU):BS:X_1 NPP MS") + field(INPK, "$(BS_MCU):BS:X_2 NPP MS") + field(INPL, "$(BS_MCU):BS:X_3 NPP MS") + # Maybe having a tolerance isn't really necessary? + # they get set exactly to the value in the MCU + field(CALC, "ABS(A-I)<1?0:ABS(A-J)<1?1:ABS(A-K)<1?2:ABS(A-L)<1?3:4") + # field(CALC, "A=I?0:A=J?1:A=K?2:A=L?3:4") +} + +record(mbbi, "$(BS_MCU):BS:TARGET_BS") { + field(DESC, "Target Beamstop Holder") + field(DTYP, "Soft Channel") + field(INP, "$(BS_MCU):BS:TARGET_BS_RAW NPP MS") + field(ZRST, "No Beamstop") + field(ONST, "Beamstop 1") + field(TWST, "Beamstop 2") + field(THST, "Beamstop 3") + field(FRST, "User Mode") +} + +record(calc, "$(BS_MCU):BS:TARGET_RANGE_RAW") { + field(DESC, "Beamstop target y-range") + # Dynamic Inputs + field(INPA, "$(BS_MCU):BS:TARGET_Y NPP MS") + # Static Inputs + field(INPK, "$(BS_MCU):BS:Y_GET NPP MS") + field(INPL, "$(BS_MCU):BS:Y_PUT NPP MS") + # Maybe having a tolerance isn't really necessary? + # they get set exactly to the value in the MCU + field(CALC, "ABS(A-K)<1?1:ABS(A-L)<1?2:0") +} + +record(mbbi, "$(BS_MCU):BS:TARGET_RANGE") { + field(DESC, "Beamstop target y-range") + field(DTYP, "Soft Channel") + field(INP, "$(BS_MCU):BS:TARGET_RANGE_RAW NPP MS") + field(ZRST, "User Mode") + field(ONST, "Level with Beamstops") + field(TWST, "Under Beamstops") +} + +record(calcout, "$(BS_MCU):BS:LOADED_RAW") +{ + field(INPA, "$(BS_MCU):BS:TARGET_BS NPP MS") + field(INPB, "$(BS_MCU):BS:TARGET_RANGE NPP MS") + field(CALC, "B=2") + field(OOPT, "Transition To Zero") + field(DOPT, "Use OCAL") + field(OCAL, "A") + field(OUT, "$(BS_MCU):BS:LOADED PP") +} + +record(longout, "$(INSTR)$(SPS_REGISTER_NAME):LOADED-INIT") +{ + field(DESC, "Initialises LOADED PV") + field(DOL, "$(INSTR)$(SPS_REGISTER_NAME):BEAMSTOP_RBV NPP") + field(OUT, "$(BS_MCU):BS:LOADED NPP") + field(OMSL, "closed_loop") + field(PINI, "YES") +} + +record(mbbi, "$(BS_MCU):BS:LOADED") +{ + field(DESC, "Most recently lifted beamstop") + field(ZRST, "No Beamstop") + field(ONST, "Beamstop 1") + field(TWST, "Beamstop 2") + field(THST, "Beamstop 3") +} + +record(calcout, "$(BS_MCU):BS:INVALID") { + field(DESC, "Invalid Move STOP MOTORS!") + # Dynamic Inputs + field(INPA, "$(BS_MCU):BS:TARGET_BS NPP MS") + field(INPB, "$(BS_MCU):BS:TARGET_RANGE NPP MS") + field(INPC, "$(BS_MCU):BS:LOADED NPP MS") + field(CALC, "A<4 & B=1 & A#C") + field(OOPT, "When Non-zero") + field(OUT, "$(BS_MCU):BS:IMMEDIATE_STOP.PROC PP") +} + +record(longout, "$(BS_MCU):BS:IMMEDIATE_STOP") { + field(DESC, "Invalid Move STOP MOTORS!") + field(PINI, "NO") + field(OMSL, "closed_loop") + field(DOL, "1") + # For Test + # field(OUT, "TEST_RECORD PP") + # FOR REAL + field(DTYP, "stream") + field(OUT , "@$(PROTO) stop() $(BS_MCU_ASYN_PORT) 0") +} + +# record(longin, "TEST_RECORD") { +# field(VAL, 0) +# } diff --git a/templates/sans_llb_beamstop.substitutions b/beamstop/sans_llb_beamstop.substitutions similarity index 100% rename from templates/sans_llb_beamstop.substitutions rename to beamstop/sans_llb_beamstop.substitutions diff --git a/scripts/shutter.cmd b/shutter/shutter.cmd similarity index 100% rename from scripts/shutter.cmd rename to shutter/shutter.cmd diff --git a/db/shutter.db b/shutter/shutter.db similarity index 100% rename from db/shutter.db rename to shutter/shutter.db diff --git a/templates/shutter.substitutions b/shutter/shutter.substitutions similarity index 100% rename from templates/shutter.substitutions rename to shutter/shutter.substitutions diff --git a/test/beamstop.log b/test/beamstop.log new file mode 100644 index 0000000..59ae3e3 --- /dev/null +++ b/test/beamstop.log @@ -0,0 +1,70 @@ +SQ:SANS-LLB:turboPmac3:BS:TARGET_X 2026-04-17 11:09:32.656133 -20.0007 +SQ:SANS-LLB:turboPmac3:BS:TARGET_Y 2026-04-17 11:09:32.659449 -19.9995 +SQ:SANS-LLB:turboPmac3:BS:TARGET_X 2026-04-17 14:54:23.954702 0 +SQ:SANS-LLB:turboPmac3:BS:TARGET_Y 2026-04-17 14:54:23.958820 -150 +SQ:SANS-LLB:turboPmac3:BS:TARGET_Y 2026-04-17 14:54:31.059702 -200 +SQ:SANS-LLB:turboPmac3:BS:TARGET_X 2026-04-17 14:54:36.454703 -356 +SQ:SANS-LLB:turboPmac3:BS:TARGET 2026-04-17 14:54:36.459712 3 +SQ:SANS-LLB:turboPmac3:BS:TARGET_Y 2026-04-17 14:54:52.464797 -150 +SQ:SANS-LLB:turboPmac3:BS:TARGET_X 2026-04-17 14:54:58.055078 -10.0007 +SQ:SANS-LLB:turboPmac3:BS:TARGET_Y 2026-04-17 14:54:58.058422 -19.9995 +SQ:SANS-LLB:turboPmac3:BS:TARGET_X 2026-04-17 14:55:25.855989 -356 +SQ:SANS-LLB:turboPmac3:BS:TARGET_Y 2026-04-17 14:55:25.960081 -150 +SQ:SANS-LLB:turboPmac3:BS:TARGET_Y 2026-04-17 14:55:41.461015 -200 +SQ:SANS-LLB:turboPmac3:BS:TARGET_X 2026-04-17 14:55:46.955108 -226 +SQ:SANS-LLB:turboPmac3:BS:TARGET 2026-04-17 14:55:46.962014 2 +SQ:SANS-LLB:turboPmac3:BS:TARGET_Y 2026-04-17 14:55:53.960696 -150 +SQ:SANS-LLB:turboPmac3:BS:TARGET_X 2026-04-17 14:55:59.456495 -10.0007 +SQ:SANS-LLB:turboPmac3:BS:TARGET_Y 2026-04-17 14:55:59.460360 -20.002 +SQ:SANS-LLB:turboPmac3:BS:TARGET_X 2026-04-17 14:56:24.678117 -226 +SQ:SANS-LLB:turboPmac3:BS:TARGET_Y 2026-04-17 14:56:24.681708 -150 +SQ:SANS-LLB:turboPmac3:BS:TARGET_Y 2026-04-17 14:56:35.059603 -200 +SQ:SANS-LLB:turboPmac3:BS:TARGET_X 2026-04-17 14:56:40.455381 -96 +SQ:SANS-LLB:turboPmac3:BS:TARGET 2026-04-17 14:56:40.462485 1 +SQ:SANS-LLB:turboPmac3:BS:TARGET_Y 2026-04-17 14:56:47.458093 -150 +SQ:SANS-LLB:turboPmac3:BS:TARGET_Y 2026-04-17 14:56:52.858578 -20.002 +SQ:SANS-LLB:turboPmac3:BS:TARGET_X 2026-04-17 14:56:52.958942 -10.0007 +SQ:SANS-LLB:turboPmac3:BS:TARGET_X 2026-04-17 14:57:14.855467 -96 +SQ:SANS-LLB:turboPmac3:BS:TARGET_Y 2026-04-17 14:57:14.959653 -150 +SQ:SANS-LLB:turboPmac3:BS:TARGET_Y 2026-04-17 14:57:21.956792 -200 +SQ:SANS-LLB:turboPmac3:BS:TARGET_X 2026-04-17 14:57:27.456472 -356 +SQ:SANS-LLB:turboPmac3:BS:TARGET 2026-04-17 14:57:27.463668 3 +SQ:SANS-LLB:turboPmac3:BS:TARGET_Y 2026-04-17 14:57:39.559147 -150 +SQ:SANS-LLB:turboPmac3:BS:TARGET_X 2026-04-17 14:57:45.155695 -10.0007 +SQ:SANS-LLB:turboPmac3:BS:TARGET_Y 2026-04-17 14:57:45.160185 -20.002 +SQ:SANS-LLB:turboPmac3:BS:TARGET_X 2026-04-17 14:58:16.755069 -356 +SQ:SANS-LLB:turboPmac3:BS:TARGET_Y 2026-04-17 14:58:16.757927 -150 +SQ:SANS-LLB:turboPmac3:BS:TARGET_Y 2026-04-17 14:58:32.359963 -200 +SQ:SANS-LLB:turboPmac3:BS:TARGET_X 2026-04-17 14:58:37.756299 -226 +SQ:SANS-LLB:turboPmac3:BS:TARGET 2026-04-17 14:58:37.763502 2 +SQ:SANS-LLB:turboPmac3:BS:TARGET_Y 2026-04-17 14:58:44.758396 -150 +SQ:SANS-LLB:turboPmac3:BS:TARGET_X 2026-04-17 14:58:50.255358 -10.0007 +SQ:SANS-LLB:turboPmac3:BS:TARGET_Y 2026-04-17 14:58:50.259949 -20.002 +SQ:SANS-LLB:turboPmac3:BS:TARGET_X 2026-04-17 14:59:56.755610 -226 +SQ:SANS-LLB:turboPmac3:BS:TARGET_Y 2026-04-17 14:59:56.858744 -150 +SQ:SANS-LLB:turboPmac3:BS:TARGET_Y 2026-04-17 15:00:07.159971 -200 +SQ:SANS-LLB:turboPmac3:BS:TARGET_X 2026-04-17 15:00:12.555471 -356 +SQ:SANS-LLB:turboPmac3:BS:TARGET 2026-04-17 15:00:12.561718 3 +SQ:SANS-LLB:turboPmac3:BS:TARGET_Y 2026-04-17 15:00:19.560666 -150 +SQ:SANS-LLB:turboPmac3:BS:TARGET_Y 2026-04-17 15:00:25.059011 -20.002 +SQ:SANS-LLB:turboPmac3:BS:TARGET_X 2026-04-17 15:00:25.155561 -10.0007 +SQ:SANS-LLB:turboPmac3:BS:TARGET_X 2026-04-17 15:01:27.755497 -356 +SQ:SANS-LLB:turboPmac3:BS:TARGET_Y 2026-04-17 15:01:27.858174 -150 +SQ:SANS-LLB:turboPmac3:BS:TARGET_Y 2026-04-17 15:01:43.359424 -200 +SQ:SANS-LLB:turboPmac3:BS:TARGET_X 2026-04-17 15:01:48.757375 -96 +SQ:SANS-LLB:turboPmac3:BS:TARGET 2026-04-17 15:01:48.763274 1 +SQ:SANS-LLB:turboPmac3:BS:TARGET_X 2026-04-17 15:02:03.153618 0 +SQ:SANS-LLB:turboPmac3:BS:TARGET_Y 2026-04-17 15:02:17.959320 -150 +SQ:SANS-LLB:turboPmac3:BS:TARGET_X 2026-04-17 15:02:22.055431 -10.0007 +SQ:SANS-LLB:turboPmac3:BS:TARGET_Y 2026-04-17 15:02:22.059497 -20.002 +SQ:SANS-LLB:turboPmac3:BS:TARGET_X 2026-04-17 15:02:56.855467 0 +SQ:SANS-LLB:turboPmac3:BS:TARGET 2026-04-17 15:02:56.862398 0 +SQ:SANS-LLB:turboPmac3:BS:TARGET_Y 2026-04-17 15:02:56.958718 -150 +SQ:SANS-LLB:turboPmac3:BS:TARGET_Y 2026-04-17 15:03:03.964312 -200 +SQ:SANS-LLB:turboPmac3:BS:TARGET_X 2026-04-17 15:03:09.455238 -356 +SQ:SANS-LLB:turboPmac3:BS:TARGET 2026-04-17 15:03:09.462565 3 +SQ:SANS-LLB:turboPmac3:BS:TARGET_Y 2026-04-17 15:03:25.459099 -150 +SQ:SANS-LLB:turboPmac3:BS:TARGET_X 2026-04-17 15:04:08.355614 -10.0007 +SQ:SANS-LLB:turboPmac3:BS:TARGET_Y 2026-04-17 15:04:08.359484 -20.002 +SQ:SANS-LLB:turboPmac3:BS:TARGET_X 2026-04-17 15:01:27.755497 -226 +SQ:SANS-LLB:turboPmac3:BS:TARGET_Y 2026-04-17 15:01:27.858174 -150 diff --git a/test/beamstop.sh b/test/beamstop.sh new file mode 100755 index 0000000..3667ae2 --- /dev/null +++ b/test/beamstop.sh @@ -0,0 +1,13 @@ +#!/bin/bash +set -euo pipefail +IFS=$'\n\t' + +SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) + +# Last two lines of the log file were added to produce an error state + +while IFS=' ' read -r pv val; do + echo "caput ${pv} ${val}" + caput ${pv} ${val} > /dev/null 2>&1 + sleep 4 +done < <(cut -d' ' -f 1,4 "${SCRIPT_DIR}/beamstop.log")