From 8b6e4dad4b077b5f2b8f0933e44753cae62b2c0c Mon Sep 17 00:00:00 2001
From: mwyman <mwyman@anl.gov>
Date: Fri, 15 Nov 2024 16:13:13 -0600
Subject: [PATCH] CRL refactor continues

---
 100idPyApp/Db/pyDevCRLdouble.db             | 339 ------------
 100idPyApp/Db/pyDevCRLsingle.db             | 325 ------------
 100idPyApp/python/pyTransfocator_general.py | 548 --------------------
 100idPyApp/python/pyTransfocator_single.py  | 500 ------------------
 4 files changed, 1712 deletions(-)
 delete mode 100644 100idPyApp/Db/pyDevCRLdouble.db
 delete mode 100644 100idPyApp/Db/pyDevCRLsingle.db
 delete mode 100644 100idPyApp/python/pyTransfocator_general.py
 delete mode 100644 100idPyApp/python/pyTransfocator_single.py

diff --git a/100idPyApp/Db/pyDevCRLdouble.db b/100idPyApp/Db/pyDevCRLdouble.db
deleted file mode 100644
index 7f8405b..0000000
--- a/100idPyApp/Db/pyDevCRLdouble.db
+++ /dev/null
@@ -1,339 +0,0 @@
-# Select the source field for the energy
-record(bo, "$(P)$(CRLID):EnergySelect") {
-  field(DESC, "energy selection")
-  field(DTYP, "Soft Channel")
-  field(ZNAM, "Mono")
-  field(ONAM, "Local")
-  field(VAL, "1")
-  field(FLNK, "$(P)$(CRLID):EnergyCalc")
-}
-
-# The local energy
-record(ao, "$(P)$(CRLID):EnergyLocal") {
-  field(DESC, "local energy")
-  field(VAL,  "12.398")
-  field(PREC, "4")
-  field(EGU, "keV")
-  field(FLNK, "$(P)$(CRLID):EnergyCalc")
-}
-
-# The beamline energy
-record(ao, "$(P)$(CRLID):EnergyBeamline") {
-  field(DESC, "beamline energy")
-  field(DOL,  "$(KEV) CP")
-  field(OMSL, "closed_loop")
-  field(PREC, "4")
-  field(EGU, "keV")
-  field(FLNK, "$(P)$(CRLID):EnergyCalc")
-}
-
-# Calculate the energy to be used
-record(calcout, "$(P)$(CRLID):EnergyCalc"){
-  field(DESC, "Energy select calc")
-  field(SCAN, "Passive")
-  field(INPA, "$(P)$(CRLID):EnergySelect.RVAL")
-  field(INPB, "$(P)$(CRLID):EnergyBeamline")
-  field(INPC, "$(P)$(CRLID):EnergyLocal")
-  field(CALC, "(A==0)?B:C")
-  field(OUT, "$(P)$(CRLID):energy PP")
-  field(PREC, "4")
-  field(SCAN, "Passive")
-}
-
-record(ao, "$(P)$(CRLID):energy"){
-	field(EGU, "keV")
-    field(DOL,  "$(KEV) CP")
-    field(OMSL, "closed_loop")
-	field(DTYP, "pydev")
-	field(OUT, "@$(OBJ).updateE(VAL)")
-	field(FLNK, "$(P)$(CRLID):recalc_table.PROC CA")
-}
-
-record(ai, "$(P)$(CRLID):energy_RBV"){
-  field(DTYP, "pydev")
-  field(INP,  "@pydev.iointr('updated_E')")
-  field(SCAN, "I/O Intr")
-  field(PREC, "5")
-}
-
-
-record(ao, "$(P)$(CRLID):focalSize"){
-	field(EGU, "m")
-	field(DTYP, "pydev")
-	field(OUT, "@$(OBJ).updateFsize(VAL)")
-}
-
-record(calcout, "$(P)$(CRLID):fSize_twk_up"){
-	field(INPA, "$(P)$(CRLID):sortedIndex_RBV")
-	field(CALC, "MIN(A+1,$(ELEM)-1)")
-	field(OUT, "$(P)$(CRLID):sortedIndex PP")
-}
-
-record(calcout, "$(P)$(CRLID):fSize_twk_dn"){
-	field(INPA, "$(P)$(CRLID):sortedIndex_RBV")
-	field(CALC, "MAX(0,A-1)")
-	field(OUT, "$(P)$(CRLID):sortedIndex PP")
-}
-
-
-
-record(bo, "$(P)$(CRLID):recalc_enable"){
-	field(DESC, "Lookup table calc enable")
-	field(SCAN, "Passive")
-	field(ZNAM, "Disabled")
-	field(ONAM, "Enabled")
-}
-
-# Not sure this would work -- how to get a PV to simply trigger code?
-record(bo, "$(P)$(CRLID):recalc_table"){
-	field(DTYP, "pydev")
-	field(OUT, "@$(OBJ).construct_lookup_table()")
-	field(FLNK, "$(P)$(CRLID):refind_config.PROC CA")
-	field(SDIS, "$(P)$(CRLID):recalc_enable")
-	field(DISV, "0")
-}
-
-# Not sure this would work -- how to get a PV to simply trigger code?
-record(bo, "$(P)$(CRLID):refind_config"){
-	field(DTYP, "pydev")
-	field(OUT, "@$(OBJ).find_config()")
-}
-
-record(bo, "$(P)$(CRLID):thickerr_flag"){
-	field(DTYP, "pydev")
-	field(ZNAM, "Off")
-	field(ONAM, "On")
-	field(OUT, "@$(OBJ).setThickerrFlag(VAL)")
-    field(FLNK, "$(P)$(CRLID):recalc_table.PROC CA")
-}
-
-record(bi, "$(P)$(CRLID):thickerr_flag_RBV"){
-	field(DTYP, "pydev")
-    field(INP,  "@pydev.iointr('updated_thickerr_Flag')")
-    field(SCAN, "I/O Intr")
-}
-
-#-------------------------------------------------------------------------------
-# CRL 1 config/encode/decode
-
-record(longin, "$(P)$(CRLID):1:lenses") {
-  field(DTYP, "pydev")
-  field(INP,  "@pydev.iointr('new_lenses_1')")
-  field(SCAN, "I/O Intr")
-  field(FLNK, "$(P)$(CRLID):1:lens_decode.PROC CA")
-}
-
-record(transform, "$(P)$(CRLID):1:lens_decode"){
-	field(INPA, "$(P)$(CRLID):1:lenses PP")
-	field(CLCB, "A % 2")
-	field(CLCC, "(A >> 1) % 2")
-	field(CLCD, "(A >> 2) % 2")
-	field(CLCE, "(A >> 3) % 2")
-	field(CLCF, "(A >> 4) % 2")
-	field(CLCG, "(A >> 5) % 2")
-	field(CLCH, "(A >> 6) % 2")
-	field(CLCI, "(A >> 7) % 2")
-	field(CLCJ, "(A >> 8) % 2")
-	field(CLCK, "(A >> 9) % 2")
-#	field(CLCL, "(A >> 10) % 2")
-#	field(CLCM, "(A >> 11) % 2")
-}
-
-record(calcout, "$(P)$(CRLID):1:lens_encode"){
-	field(OUT, "$(P)$(CRLID):1:lensConfig_BW PP")
-	field(CALC, "A+B*2+C*4+D*8+E*16+F*32+G*64+H*128+I*256+J*512")
-} 
-
-record(calcout, "$(P)$(CRLID):1:lens_RBV_encode"){
-	field(OUT, "$(P)$(CRLID):1:lensConfig_RBV PP")
-	field(CALC, "A+B*2+C*4+D*8+E*16+F*32+G*64+H*128+I*256+J*512")
-} 
-
-record(longin, "$(P)$(CRLID):1:lensConfig_RBV") {
-}
-
-record(longout, "$(P)$(CRLID):1:lensConfig_BW") {
-  field(DTYP, "pydev")
-  field(OUT, "@$(OBJ).updateConfig1(VAL)")
-}
-
-#-------------------------------------------------------------------------------
-# CRL 2 config/encode/decode
-
-record(longin, "$(P)$(CRLID):2:lenses") {
-  field(DTYP, "pydev")
-  field(INP,  "@pydev.iointr('new_lenses_2')")
-  field(SCAN, "I/O Intr")
-  field(FLNK, "$(P)$(CRLID):2:lens_decode.PROC CA")
-}
-
-record(transform, "$(P)$(CRLID):2:lens_decode"){
-	field(INPA, "$(P)$(CRLID):2:lenses PP")
-	field(CLCB, "A % 2")
-	field(CLCC, "(A >> 1) % 2")
-	field(CLCD, "(A >> 2) % 2")
-	field(CLCE, "(A >> 3) % 2")
-	field(CLCF, "(A >> 4) % 2")
-	field(CLCG, "(A >> 5) % 2")
-	field(CLCH, "(A >> 6) % 2")
-	field(CLCI, "(A >> 7) % 2")
-	field(CLCJ, "(A >> 8) % 2")
-	field(CLCK, "(A >> 9) % 2")
-#	field(CLCL, "(A >> 10) % 2")
-#	field(CLCM, "(A >> 11) % 2")
-}
-
-record(calcout, "$(P)$(CRLID):2:lens_encode"){
-	field(OUT, "$(P)$(CRLID):2:lensConfig_BW PP")
-	field(CALC, "A+B*2+C*4+D*8+E*16+F*32+G*64+H*128+I*256+J*512")
-} 
-
-record(calcout, "$(P)$(CRLID):2:lens_RBV_encode"){
-	field(OUT, "$(P)$(CRLID):2:lensConfig_RBV PP")
-	field(CALC, "A+B*2+C*4+D*8+E*16+F*32+G*64+H*128+I*256+J*512")
-} 
-
-record(longin, "$(P)$(CRLID):2:lensConfig_RBV") {
-}
-
-record(longout, "$(P)$(CRLID):2:lensConfig_BW") {
-  field(DTYP, "pydev")
-  field(OUT, "@$(OBJ).updateConfig2(VAL)")
-}
-
-#-------------------------------------------------------------------------------
-
-record(ai, "$(P)$(CRLID):fSize_actual"){
-  field(DTYP, "pydev")
-  field(INP,  "@pydev.iointr('new_fSize')")
-  field(SCAN, "I/O Intr")
-  field(PREC, "5")
-}
-
-record(longout, "$(P)$(CRLID):sortedIndex") {
-  field(DTYP, "pydev")
-  field(OUT, "@$(OBJ).updateIndex(VAL)")
-}
-
-record(longin, "$(P)$(CRLID):sortedIndex_RBV") {
-  field(DTYP, "pydev")
-  field(INP,  "@pydev.iointr('new_index')")
-  field(SCAN, "I/O Intr")
-}
-
-record(longout, "$(P)$(CRLID):previewIndex") {
-  field(DTYP, "pydev")
-  field(OUT, "@$(OBJ).getPreviewFocalSize(VAL)")
-}
-
-record(ai, "$(P)$(CRLID):fSize_preview"){
-  field(DTYP, "pydev")
-  field(INP,  "@pydev.iointr('new_preview')")
-  field(SCAN, "I/O Intr")
-  field(PREC, "6")
-}
-
-record(bo, "$(P)$(CRLID):verbosity"){
-	field(DTYP, "pydev")
-	field(OUT, "@$(OBJ).updateVerbosity(VAL)")
-	field(ZNAM, "Off")
-	field(ONAM, "On")
-	
-}
-
-record(waveform, "$(P)$(CRLID):fSizes"){
-  field(DTYP, "pydev")
-  field(INP,  "@pydev.iointr('new_lookupTable')")
-  field(SCAN, "I/O Intr")
-  field(PREC, "6")
-  field(FTVL, "DOUBLE")
-  field(NELM, "$(ELEM)")
-}
-
-record(waveform, "$(P)$(CRLID):invF_indices"){
-  field(DTYP, "pydev")
-  field(INP,  "@pydev.iointr('new_invFind_list')")
-  field(SCAN, "I/O Intr")
-  field(PREC, "6")
-  field(FTVL, "DOUBLE")
-  field(NELM, "$(ELEM)")
-}
-
-record(waveform, "$(P)$(CRLID):invF"){
-  field(DTYP, "pydev")
-  field(INP,  "@pydev.iointr('new_invF_list')")
-  field(SCAN, "I/O Intr")
-  field(PREC, "6")
-  field(FTVL, "DOUBLE")
-  field(NELM, "$(ELEM)")
-}
-
-record(waveform, "$(P)$(CRLID):configs"){
-  field(DTYP, "pydev")
-  field(INP,  "@pydev.iointr('new_configs')")
-  field(SCAN, "I/O Intr")
-  field(PREC, "6")
-  field(FTVL, "LONG")
-  field(NELM, "$(ELEM)")
-  }
-
-# The commented out records below were meant to replicate the lock feature used
-# in filter control.  BL staff indicated not required but kept in case needed.
-# Will also have to update python code (in/out masks, culled tables/indices need
-# to be uncommented).
-# MW 2024.09.04
-
-#!record(calcout, "$(P)$(CRLID):outMask_encode"){
-#!	field(OUT, "$(P)$(CRLID):outMask PP")
-#!	field(CALC, "A+B*2+C*4+D*8+E*16+F*32+G*64+H*128+I*256+J*512")
-#!}
-#!
-#!record(longout, "$(P)$(CRLID):outMask") {
-#!  field(DTYP, "pydev")
-#!  field(DESC, "Fixed-out lens mask")
-#!  field(OUT, "@$(OBJ).setOutMask(VAL)")
-#!}
-#!
-#!record(calcout, "$(P)$(CRLID):inMask_encode"){
-#!	field(OUT, "$(P)$(CRLID):inMask PP")
-#!	field(CALC, "A+B*2+C*4+D*8+E*16+F*32+G*64+H*128+I*256+J*512")
-#!}
-#!
-#!record(longout, "$(P)$(CRLID):inMask") {
-#!  field(DTYP, "pydev")
-#!  field(DESC, "Fixed-in lens mask")
-#!  field(OUT, "@$(OBJ).setInMask(VAL)")
-#!}
-
-
-
-
-#!record(longin, "$(P)$(CRLID):inMask_RBV") {
-#!  field(DTYP, "pydev")
-#!  field(INP,  "@pydev.iointr('new_inMask')")
-#!  field(SCAN, "I/O Intr")
-#!}
-#!
-#!record(longin, "$(P)$(CRLID):outMask_RBV") {
-#!  field(DTYP, "pydev")
-#!  field(INP,  "@pydev.iointr('new_outMask')")
-#!  field(SCAN, "I/O Intr")
-#!}
-
-
-#! record(waveform, "$(P)$(CRLID):fSizes_culled"){
-#!   field(DTYP, "pydev")
-#!   field(INP,  "@pydev.iointr('new_culledTable')")
-#!   field(SCAN, "I/O Intr")
-#!   field(PREC, "6")
-#!   field(FTVL, "DOUBLE")
-#!   field(NELM, "$(ELEM)")
-#! }
-#! record(waveform, "$(P)$(CRLID):configs_culled"){
-#!   field(DTYP, "pydev")
-#!   field(INP,  "@pydev.iointr('new_culledConfigs')")
-#!   field(SCAN, "I/O Intr")
-#!   field(PREC, "6")
-#!   field(FTVL, "LONG")
-#!   field(NELM, "$(ELEM)")
-#! }
diff --git a/100idPyApp/Db/pyDevCRLsingle.db b/100idPyApp/Db/pyDevCRLsingle.db
deleted file mode 100644
index b2e60b4..0000000
--- a/100idPyApp/Db/pyDevCRLsingle.db
+++ /dev/null
@@ -1,325 +0,0 @@
-# Select the source field for the energy
-record(bo, "$(P)$(CRLID):EnergySelect") {
-  field(DESC, "energy selection")
-  field(DTYP, "Soft Channel")
-  field(ZNAM, "Mono")
-  field(ONAM, "Local")
-  field(VAL, "1")
-  field(FLNK, "$(P)$(CRLID):EnergyCalc")
-}
-
-# The local energy
-record(ao, "$(P)$(CRLID):EnergyLocal") {
-  field(DESC, "local energy")
-  field(VAL,  "12.398")
-  field(PREC, "4")
-  field(EGU, "keV")
-  field(FLNK, "$(P)$(CRLID):EnergyCalc")
-}
-
-# The beamline energy
-record(ao, "$(P)$(CRLID):EnergyBeamline") {
-  field(DESC, "beamline energy")
-  field(DOL,  "$(KEV) CP")
-  field(OMSL, "closed_loop")
-  field(PREC, "4")
-  field(EGU, "keV")
-  field(FLNK, "$(P)$(CRLID):EnergyCalc")
-}
-
-# Calculate the energy to be used
-record(calcout, "$(P)$(CRLID):EnergyCalc"){
-  field(DESC, "Energy select calc")
-  field(SCAN, "Passive")
-  field(INPA, "$(P)$(CRLID):EnergySelect.RVAL")
-  field(INPB, "$(P)$(CRLID):EnergyBeamline")
-  field(INPC, "$(P)$(CRLID):EnergyLocal")
-  field(CALC, "(A==0)?B:C")
-  field(OUT, "$(P)$(CRLID):energy PP")
-  field(PREC, "4")
-  field(SCAN, "Passive")
-}
-
-record(ao, "$(P)$(CRLID):energy"){
-	field(EGU, "keV")
-    field(DOL,  "$(KEV) CP")
-    field(OMSL, "closed_loop")
-	field(DTYP, "pydev")
-	field(OUT, "@$(OBJ).updateE(VAL)")
-	field(FLNK, "$(P)$(CRLID):recalc_table.PROC CA")
-}
-
-record(ai, "$(P)$(CRLID):energy_RBV"){
-  field(DTYP, "pydev")
-  field(INP,  "@pydev.iointr('updated_E')")
-  field(SCAN, "I/O Intr")
-  field(PREC, "5")
-}
-
-
-record(ao, "$(P)$(CRLID):focalSize"){
-	field(EGU, "m")
-	field(DTYP, "pydev")
-	field(OUT, "@$(OBJ).updateFsize(VAL)")
-}
-
-record(calcout, "$(P)$(CRLID):fSize_twk_up"){
-	field(INPA, "$(P)$(CRLID):sortedIndex_RBV")
-	field(CALC, "MIN(A+1,$(ELEM)-1)")
-	field(OUT, "$(P)$(CRLID):sortedIndex PP")
-}
-
-record(calcout, "$(P)$(CRLID):fSize_twk_dn"){
-	field(INPA, "$(P)$(CRLID):sortedIndex_RBV")
-	field(CALC, "MAX(0,A-1)")
-	field(OUT, "$(P)$(CRLID):sortedIndex PP")
-}
-
-record(ao, "$(P)$(CRLID):slitSize_H"){
-	field(EGU, "m")
-    field(DOL,  "$(SLITH) CP")
-    field(OMSL, "closed_loop")
-	field(DTYP, "pydev")
-	field(OUT, "@$(OBJ).updateSlitSize(VAL, 'hor')")
-	field(FLNK, "$(P)$(CRLID):recalc_table.PROC CA")
-	field(PREC, "6")
-}
-
-record(ai, "$(P)$(CRLID):slitSize_H_RBV"){
-  field(DTYP, "pydev")
-  field(INP,  "@pydev.iointr('updated_slitSize_H')")
-  field(SCAN, "I/O Intr")
-  field(PREC, "6")
-  field(EGU, "m")
-}
-
-record(ao, "$(P)$(CRLID):slitSize_V"){
-	field(EGU, "m")
-    field(DOL,  "$(SLITV) CP")
-    field(OMSL, "closed_loop")
-	field(DTYP, "pydev")
-	field(OUT, "@$(OBJ).updateSlitSize(VAL, 'vert')")
-	field(FLNK, "$(P)$(CRLID):recalc_table.PROC CA")
-	field(PREC, "6")
-}
-
-record(ai, "$(P)$(CRLID):slitSize_V_RBV"){
-  field(DTYP, "pydev")
-  field(INP,  "@pydev.iointr('updated_slitSize_V')")
-  field(SCAN, "I/O Intr")
-  field(PREC, "6")
-  field(EGU, "m")
-}
-
-record(bo, "$(P)$(CRLID):recalc_enable"){
-	field(DESC, "Lookup table calc enable")
-	field(SCAN, "Passive")
-	field(ZNAM, "Disabled")
-	field(ONAM, "Enabled")
-}
-
-# Not sure this would work -- how to get a PV to simply trigger code?
-record(bo, "$(P)$(CRLID):recalc_table"){
-	field(DTYP, "pydev")
-	field(OUT, "@$(OBJ).construct_lookup_table()")
-	field(FLNK, "$(P)$(CRLID):refind_config.PROC CA")
-	field(SDIS, "$(P)$(CRLID):recalc_enable")
-	field(DISV, "0")
-}
-
-# Not sure this would work -- how to get a PV to simply trigger code?
-record(bo, "$(P)$(CRLID):refind_config"){
-	field(DTYP, "pydev")
-	field(OUT, "@$(OBJ).find_config()")
-}
-
-record(bo, "$(P)$(CRLID):thickerr_flag"){
-	field(DTYP, "pydev")
-	field(ZNAM, "Off")
-	field(ONAM, "On")
-	field(OUT, "@$(OBJ).setThickerrFlag(VAL)")
-    field(FLNK, "$(P)$(CRLID):recalc_table.PROC CA")
-}
-
-record(bi, "$(P)$(CRLID):thickerr_flag_RBV"){
-	field(DTYP, "pydev")
-    field(INP,  "@pydev.iointr('updated_thickerr_Flag')")
-    field(SCAN, "I/O Intr")
-}
-
-
-record(longin, "$(P)$(CRLID):lenses") {
-  field(DTYP, "pydev")
-  field(INP,  "@pydev.iointr('new_lenses')")
-  field(SCAN, "I/O Intr")
-  field(FLNK, "$(P)$(CRLID):lens_decode.PROC CA")
-}
-
-record(transform, "$(P)$(CRLID):lens_decode"){
-	field(INPA, "$(P)$(CRLID):lenses PP")
-	field(CLCB, "A % 2")
-	field(CLCC, "(A >> 1) % 2")
-	field(CLCD, "(A >> 2) % 2")
-	field(CLCE, "(A >> 3) % 2")
-	field(CLCF, "(A >> 4) % 2")
-	field(CLCG, "(A >> 5) % 2")
-	field(CLCH, "(A >> 6) % 2")
-	field(CLCI, "(A >> 7) % 2")
-	field(CLCJ, "(A >> 8) % 2")
-	field(CLCK, "(A >> 9) % 2")
-#	field(CLCL, "(A >> 10) % 2")
-#	field(CLCM, "(A >> 11) % 2")
-}
-
-record(calcout, "$(P)$(CRLID):lens_encode"){
-	field(OUT, "$(P)$(CRLID):lensConfig_BW PP")
-	field(CALC, "A+B*2+C*4+D*8+E*16+F*32+G*64+H*128+I*256+J*512")
-} 
-
-record(calcout, "$(P)$(CRLID):lens_RBV_encode"){
-	field(OUT, "$(P)$(CRLID):lensConfig_RBV PP")
-	field(CALC, "A+B*2+C*4+D*8+E*16+F*32+G*64+H*128+I*256+J*512")
-} 
-
-record(longin, "$(P)$(CRLID):lensConfig_RBV") {
-}
-
-record(longout, "$(P)$(CRLID):lensConfig_BW") {
-  field(DTYP, "pydev")
-  field(OUT, "@$(OBJ).updateConfig(VAL)")
-}
-
-record(ai, "$(P)$(CRLID):fSize_actual"){
-  field(DTYP, "pydev")
-  field(INP,  "@pydev.iointr('new_fSize')")
-  field(SCAN, "I/O Intr")
-  field(PREC, "5")
-}
-
-record(longout, "$(P)$(CRLID):sortedIndex") {
-  field(DTYP, "pydev")
-  field(OUT, "@$(OBJ).updateIndex(VAL)")
-}
-
-record(longin, "$(P)$(CRLID):sortedIndex_RBV") {
-  field(DTYP, "pydev")
-  field(INP,  "@pydev.iointr('new_index')")
-  field(SCAN, "I/O Intr")
-}
-
-record(longout, "$(P)$(CRLID):previewIndex") {
-  field(DTYP, "pydev")
-  field(OUT, "@$(OBJ).getPreviewFocalSize(VAL)")
-}
-
-record(ai, "$(P)$(CRLID):fSize_preview"){
-  field(DTYP, "pydev")
-  field(INP,  "@pydev.iointr('new_preview')")
-  field(SCAN, "I/O Intr")
-  field(PREC, "6")
-}
-
-record(bo, "$(P)$(CRLID):verbosity"){
-	field(DTYP, "pydev")
-	field(OUT, "@$(OBJ).updateVerbosity(VAL)")
-	field(ZNAM, "Off")
-	field(ONAM, "On")
-	
-}
-
-record(waveform, "$(P)$(CRLID):fSizes"){
-  field(DTYP, "pydev")
-  field(INP,  "@pydev.iointr('new_lookupTable')")
-  field(SCAN, "I/O Intr")
-  field(PREC, "6")
-  field(FTVL, "DOUBLE")
-  field(NELM, "$(ELEM)")
-}
-
-record(waveform, "$(P)$(CRLID):invF_indices"){
-  field(DTYP, "pydev")
-  field(INP,  "@pydev.iointr('new_invFind_list')")
-  field(SCAN, "I/O Intr")
-  field(PREC, "6")
-  field(FTVL, "DOUBLE")
-  field(NELM, "$(ELEM)")
-}
-
-record(waveform, "$(P)$(CRLID):invF"){
-  field(DTYP, "pydev")
-  field(INP,  "@pydev.iointr('new_invF_list')")
-  field(SCAN, "I/O Intr")
-  field(PREC, "6")
-  field(FTVL, "DOUBLE")
-  field(NELM, "$(ELEM)")
-}
-
-record(waveform, "$(P)$(CRLID):configs"){
-  field(DTYP, "pydev")
-  field(INP,  "@pydev.iointr('new_configs')")
-  field(SCAN, "I/O Intr")
-  field(PREC, "6")
-  field(FTVL, "LONG")
-  field(NELM, "$(ELEM)")
-  }
-
-# The commented out records below were meant to replicate the lock feature used
-# in filter control.  BL staff indicated not required but kept in case needed.
-# Will also have to update python code (in/out masks, culled tables/indices need
-# to be uncommented).
-# MW 2024.09.04
-
-#!record(calcout, "$(P)$(CRLID):outMask_encode"){
-#!	field(OUT, "$(P)$(CRLID):outMask PP")
-#!	field(CALC, "A+B*2+C*4+D*8+E*16+F*32+G*64+H*128+I*256+J*512")
-#!}
-#!
-#!record(longout, "$(P)$(CRLID):outMask") {
-#!  field(DTYP, "pydev")
-#!  field(DESC, "Fixed-out lens mask")
-#!  field(OUT, "@$(OBJ).setOutMask(VAL)")
-#!}
-#!
-#!record(calcout, "$(P)$(CRLID):inMask_encode"){
-#!	field(OUT, "$(P)$(CRLID):inMask PP")
-#!	field(CALC, "A+B*2+C*4+D*8+E*16+F*32+G*64+H*128+I*256+J*512")
-#!}
-#!
-#!record(longout, "$(P)$(CRLID):inMask") {
-#!  field(DTYP, "pydev")
-#!  field(DESC, "Fixed-in lens mask")
-#!  field(OUT, "@$(OBJ).setInMask(VAL)")
-#!}
-
-
-
-
-#!record(longin, "$(P)$(CRLID):inMask_RBV") {
-#!  field(DTYP, "pydev")
-#!  field(INP,  "@pydev.iointr('new_inMask')")
-#!  field(SCAN, "I/O Intr")
-#!}
-#!
-#!record(longin, "$(P)$(CRLID):outMask_RBV") {
-#!  field(DTYP, "pydev")
-#!  field(INP,  "@pydev.iointr('new_outMask')")
-#!  field(SCAN, "I/O Intr")
-#!}
-
-
-#! record(waveform, "$(P)$(CRLID):fSizes_culled"){
-#!   field(DTYP, "pydev")
-#!   field(INP,  "@pydev.iointr('new_culledTable')")
-#!   field(SCAN, "I/O Intr")
-#!   field(PREC, "6")
-#!   field(FTVL, "DOUBLE")
-#!   field(NELM, "$(ELEM)")
-#! }
-#! record(waveform, "$(P)$(CRLID):configs_culled"){
-#!   field(DTYP, "pydev")
-#!   field(INP,  "@pydev.iointr('new_culledConfigs')")
-#!   field(SCAN, "I/O Intr")
-#!   field(PREC, "6")
-#!   field(FTVL, "LONG")
-#!   field(NELM, "$(ELEM)")
-#! }
diff --git a/100idPyApp/python/pyTransfocator_general.py b/100idPyApp/python/pyTransfocator_general.py
deleted file mode 100644
index a8c3fc5..0000000
--- a/100idPyApp/python/pyTransfocator_general.py
+++ /dev/null
@@ -1,548 +0,0 @@
-import numpy as np
-import tomllib
-import xraylib
-from transfocator_calcs import lookup_diameter, materials_to_deltas, materials_to_linear_attenuation
-from transfocator_calcs import find_levels, calc_lookup_table, get_densities
-
-
-MAT_MACRO = 'MAT'
-NLENS_MACRO = 'NUMLENS'
-RADIUS_MACRO = 'RADIUS'
-LOC_MACRO = 'LOC'
-THICKERR_MACRO = 'THICKERR'
-
-'''
-Config variables
-
-Beam Properties
-        energy      : energy in keV
-        L_und       : undulator length in m
-        sigmaH_e    : Sigma electron source size in H direction in m
-        sigmaV_e    : Sigma electron source size in V direction in m
-        sigmaHp     : Sigma electron divergence in H direction in rad
-        sigmaVp_e   : Sigma electron divergence in V direction in rad
-Beamline properties
-        d_StoL1 : Source-to-CRL1 distance, in m
-        d_StoL2 : Source-to-CRL2 distance, in m
-        d_Stof  : Source-to-focus distance, in m
-CRL properties
-        d_min   : Minimum thickness at the apex in m
-        stack_d : Stack thickness in m
-'''
-DEFAULT_CONFIG = {'beam':{'energy': 15, 'L_und': 4.7, 'sigmaH_e': 14.8e-6,
-                          'sigmaV_e': 3.7e-6, 'sigmaHp_e': 2.8e-6, 'sigmaVp_e': 1.5e-6},
-                  'beamline': {'d_StoL1': 51.9, 'd_StoL2': 62.1, 'd_Stof': 66.2},
-                  'crl':{'stack_d': 50.0e-3, 'd_min': 3.0e-5}}
-
-
-class transfocator():
-    
-    
-    def __init__(self, crl_setup = None, beam_config = DEFAULT_CONFIG['beam'], 
-                 beamline_config = DEFAULT_CONFIG['beamline'], 
-                 crl_config = DEFAULT_CONFIG['crl']):
-
-        self.verbose = True
-
-        if crl_setup is None:
-            beam = beam_config
-            beamline = beamline_config
-            crl = crl_config
-#            slits = slits_config
-        else:
-            with open(crl_setup, "rb") as f:
-                config = tomllib.load(f)
-            beam = config['beam']
-            beamline = config['beamline']
-            crl = config['crl']
- #           slits = config['slits'] 
-
-        self.beam = {}
-        self.setupSource(beam)
-        
-        self.bl = {}
-        self.setupBeamline(beamline)
-        
-        self.crl = {}
-        self.setupCRL(crl)
-        
-        self.slits = [{'H':0,'V':0}]
-        
-#        self.slit1_H = 0
-#        self.slit1_V = 0
-                
-        # Initialize lens variables -- TODO -- this is done via a subs file -- are any of these needed prior to that loading?
-        self.numlens        = np.array([1,      1,      1,      1,      1,      1,      2,      4,      8,      16])                # CRL1 number of lenses in each stack (was L1_n)
-        self.radius         = np.array([2.0e-3, 1.0e-3, 5.0e-4, 3.0e-4, 2.0e-4, 1.0e-4, 1.0e-4, 1.0e-4, 1.0e-4, 1.0e-4])            # CRL1 lens radius in each stack (was L1_R)
-        self.materials      = np.array(["Be",   "Be",   "Be",   "Be",   "Be",   "Be",   "Be",   "Be",   "Be",   "Be"])              # CRL1 lens material in each stack (was L1_mater)
-        self.lens_loc       = np.array([4.5,    3.5,    2.5,    1.5,    0.5,    -0.5,   -1.5,   -2.5,   -3.5,   -4.5])*self.crl['stack_d']      # CRL1 lens stack location relative to center stack, positive means upstream (was L1_Loc)
-        self.lens_thickerr  = np.array([1.0e-6, 1.0e-6, 1.0e-6, 1.0e-6, 1.0e-6, 1.0e-6, 1.4e-6, 2.0e-6, 2.8e-6, 4.0e-6])            # CRL1 lens RMS thickness error (was L1_HE)
-
-
-        self.Lens_diameter_table = [
-                                    (50, 450.0),
-                                    (100, 632.0),
-                                    (200, 894.0),
-                                    (300, 1095.0),
-                                    (500, 1414.0),
-                                    (1000, 2000.0),
-                                    (1500, 2450.0),
-                                ]
-        # Convert the lookup table to a dictionary for faster lookup        
-        self.Lens_diameter_dict = {int(col1): col2 for col1, col2 in self.Lens_diameter_table}
-        
-        self.energy = 0  # gets value from an ao (incoming beam energy)
-        self.focalSize = 0 # get value from an ao (desired focal length)
-        self.lenses = 0 # sets integer (2^10) whose binary representation indicates which lenses are in or out
-        
-        self.num_stacks = 10 # Number of lenses in system
-        
-        self.lookupTable = []
-        
-        self.thickerr_flag = True
-                
-    def setupSource(self, beam_properties):
-        '''
-        Beam properties can have entries for the following
-        
-        energy      : energy in keV
-        L_und       : undulator length in m
-        sigmaH_e    : Sigma electron source size in H direction in m
-        sigmaV_e    : Sigma electron source size in V direction in m
-        sigmaHp_e   : Sigma electron divergence in H direction in rad
-        sigmaVp_e   : Sigma electron divergence in V direction in rad
-        '''
-        
-        self.setEnergy(beam_properties['energy'])
-        self.L_und = beam_properties['L_und']
-        self.sigmaH_e = beam_properties['sigmaH_e']
-        self.sigmaV_e = beam_properties['sigmaV_e']
-        self.sigmaHp_e = beam_properties['sigmaHp_e']
-        self.sigmaVp_e = beam_properties['sigmaVp_e']
-        
-        self.setupSourceEnergyDependent()
-    
-    def setupSourceEnergyDependent(self):
-        '''
-        Fill in later
-        '''    
-        self.beam['sigmaH'] =  (self.sigmaH_e**2 +  self.wl*self.L_und/2/np.pi/np.pi)**0.5
-        self.beam['sigmaV'] =  (self.sigmaV_e**2 +  self.wl*self.L_und/2/np.pi/np.pi)**0.5
-        self.beam['sigmaHp'] = (self.sigmaHp_e**2 + self.wl/self.L_und/2)**0.5
-        self.beam['sigmaVp'] = (self.sigmaVp_e**2 + self.wl/self.L_und/2)**0.5
-        
-    def setupBeamline(self, beamline_properties, num=1):
-        '''
-        Beamline properties can contain entries for the following
-        
-        d_StoL1 : Source-to-CRL1 distance, in m
-        d_Stof  : Source-to-sample distance, in m
-        '''            
-        
-        self.bl['d_StoL1'] = beamline_properties['d_StoL1']
-        self.bl['d_Stof'] = beamline_properties['d_Stof']
-            
-            
-    def setupCRL(self, crl_properties):
-        '''
-        CRL properties can contiain entries for the following
-        
-        d_min   : Minimum thickness at the apex in m
-        stack_d : Stack thickness in m
-        '''
-        self.crl['d_min'] = crl_properties['d_min'] 
-        self.crl['stack_d'] = crl_properties['stack_d']
-
-    def setupSlits(self, slit_properties):
-        '''
-        Slit properties can contain entries for the following
-        
-        '''
-        pass 
-                
-    def setupLookupTable(self, subs_file, n_lenses):
-        '''
-        lookup table created after IOC startup
-        energy and slit size are updated before this is called
-        '''
-        print(80*'#')
-        print('Setting up lens control...')
-        
-        self.num_stacks = n_lenses
-        self.num_configs = 2**self.num_stacks
-        self.configs = np.arange(self.num_configs)
-        
-#       self.energy = energy
-        
-        #read in substitutions file
-        try:
-            subsFile = open(subs_file,"r")
-        except:
-            raise RuntimeError(f"Substiution file ({subsFile}) not found.")
-        subsFileContent = subsFile.readlines()
-        subsFile.close()
-        
-        macros = subsFileContent[2].replace('{','').replace('}','').replace(',','').split()
-        lens_properties = {key: [] for key in macros} # dictionary of lists
-        for i in range(self.num_stacks):
-            try:
-                xx = subsFileContent[3+i].replace('{','').replace('}','').replace(',','').replace('"','').split()
-                lens_properties[macros[0]].append(xx[0])
-                lens_properties[macros[1]].append(xx[1])
-                lens_properties[macros[2]].append(xx[2])
-                lens_properties[macros[3]].append(xx[3])
-                lens_properties[macros[4]].append(xx[4])
-                lens_properties[macros[5]].append(xx[5])
-                lens_properties[macros[6]].append(xx[6])
-            except:
-                raise RuntimeError(f"Number of lenses ({self.num_stacks}) doesn't match substitution file")
-        
-        self.numlens = []
-        self.radius = []
-        self.materials = []
-        self.lens_loc = []
-        self.lens_thickerr = []
-            
-        # get number of lens for each lens stack from lens properties dictionary-list
-        print('Getting lens materials...')
-        if NLENS_MACRO in macros:
-            self.numlens = np.array([int(i) for i in lens_properties[NLENS_MACRO]])
-            print('Number of lens read in.\n')
-        else:
-            raise RuntimeError(f"Number of lenses macro ({NLENS_MACRO}) not found in substituion file")
-
-        # get radii for each lens from lens properties dictionary-list
-        print('Getting lens\' radii...')
-        if RADIUS_MACRO in macros:
-            self.radius = np.array([float(i) for i in lens_properties[RADIUS_MACRO]])
-            print('Radius of lenses read in.\n')
-        else:
-            raise RuntimeError(f"Radius macro ({RADIUS_MACRO}) not found in substituion file")
-
-        # get materials from lens properties dictionary-list
-        print('Getting lens materials...')
-        if MAT_MACRO in macros:
-            self.materials = lens_properties[MAT_MACRO]
-            print('Lens material read in.\n')
-        else:
-            raise RuntimeError(f"Material macro ({MAT_MACRO}) not found in substituion file")
-        
-        # get densities from local definition (for compounds) or from xraylib (for elements)
-        densities = get_densities(self.materials)
-        self.densities = np.array([densities[material] for material in self.materials])
-
-        # get location of each lens from lens properties dictionary-list
-        print('Getting lens\' locations...')
-        if LOC_MACRO in macros:
-            self.lens_loc = np.array([float(i)*self.crl['stack_d'] for i in lens_properties[LOC_MACRO]])
-            print('Location of lenses read in.\n')
-        else:
-            raise RuntimeError(f"Location macro ({LOC_MACRO}) not found in substituion file")
-
-        # get thicknesses errprfrom lens properties dictionary-list
-        print('Getting lens thickness error...')
-        if THICKERR_MACRO in macros:
-            self.lens_thickerr = np.array([float(i) for i in lens_properties[THICKERR_MACRO]])
-            print('Lens thickness errors read in.\n')
-        else:
-            raise RuntimeError(f"Thickness errors macro ({THICKERR_MACRO}) not found in substituion file")
-
-        print('Constructing lookup table...')
-        self.construct_lookup_table()
-        print('Lookup table calculation complete.\n')
-        
-        print('Transfocator control setup complete.')
-        print(80*'#')
-
-    def construct_lookup_table(self):
-        arr_a, arr_b, arr_c = calc_lookup_table(self.num_configs, self.radius, 
-                                                self.materials, self.energy, self.wl,
-                                                self.numlens, 
-                                                self.lens_loc, self.beam, self.bl,
-                                                self.crl, self.slits[0]['H'], self.slits[0]['V'],
-                                                self.lens_thickerr, flag_HE = self.thickerr_flag,
-                                                verbose = self.verbose)
-        self.lookupTable = arr_a
-        self.sorted_invF_index = arr_b
-        self.sorted_invF = arr_c                                                            
-                                                                    
-#        self.sort_lookup_table()
-        self.updateEnergyRBV()
-        self.updateSlitSizeRBV('hor')
-        self.updateSlitSizeRBV('vert')
-        self.updateLookupWaveform()
-        self.updateInvFWaveform()
-        self.updateLookupConfigs()
-
-        
-    def setFocalSizeActual(self):
-        '''
-        
-        '''
-#        self.focalSize_actual = self.culledTable[self.culledIndex] 
-        self.focalSize_actual = self.lookupTable[self.indexSorted] 
-
-    def find_config(self):
-        ''' 
-        User selected focal size, this function finds nearest acheivable focal 
-        size from the lookup table
-        '''
-        # Code to search lookup table for nearest focal size to desired; note the
-        # lookup table is already sorted by 1/f
-        if self.verbose: print(f'Searching for config closest to {self.focalSize}')
-#       simple approach
-#        self.indexSorted = np.argmin(np.abs(self.lookupTable - self.focalSize))
-
-        # XS approach -- can handle nan but in pydev application don't have a good
-        # way to "transmit" errors (i.e. no solution found) to user.
-        indices, _ = find_levels(self.lookupTable, self.focalSize, direction='forward')[0]
-        self.indexSorted = indices[0]
-        
-
-        if self.verbose: print(f'1/f-sorted config index found at {self.indexSorted}')
-
-        self.index = self.sorted_invF_index[self.indexSorted]
-        if self.verbose: print(f'Config index found at {self.index}')
-
-        # Update PVs
-        self.setFocalSizeActual()
-        self.updateLensConfigPV()
-        self.updateLensRBV()
-        self.updateFocalSizeRBVs()      
-
-    def getPreviewFocalSize(self, sortedIndex):
-        '''
-        
-        '''
-        fSize_preview = self.lookupTable[sortedIndex]
-        if self.verbose: print(f'Preview focal sizes for {sortedIndex} is {fSize_preview}')
-        pydev.iointr('new_preview', fSize_preview)
-    
-    def setSlitSize(self, size, slit):
-        '''
-        Update proper slit size
-        '''
-        
-        if slit == 'hor':
-#            self.slit1_H = float(size)     # H slit size before CRL 1
-            self.slits[0]['H'] = float(size)     # H slit size before CRL 1
-        elif slit == 'vert':
-#            self.slit1_V = float(size)     # V slit size before CRL 1
-            self.slits[0]['V'] = float(size)     # V slit size before CRL 1
-        else: 
-            raise RuntimeError(f"Slit identifier ({slit}) not recognized. Should be 'hor' or 'vert'")
-           
-                    
-    def updateSlitSize(self, size, slit):
-        '''
-        Slit size updates are propagated to CRL object from EPICS.  The beam
-        size lookup table is then recalculated.
-        '''
-        self.setSlitSize(size, slit)
-        
-        if self.verbose: 
-            if slit == 'hor':
-#                print(f'Horizontal slit size updated to {self.slit1_H} m')
-                print(f"Horizontal slit size updated to {self.slits[0]['H']} m")
-            elif slit == 'vert':
-#                print(f'Vertical slit size updated to {self.slit1_V} m')
-                print(f"Vertical slit size updated to {self.slits[0]['V']} m")
-        
-        
-    def setEnergy(self, energy):
-        '''
-        Sets various forms of energy
-        '''
-        if energy > 0.0001:
-            self.energy = float(energy)
-            self.energy_eV = self.energy*1000.0  # Energy in keV
-            self.wl = 1239.84 / (self.energy_eV * 10**9)    #Wavelength in nm(?)
-            if self.verbose: print(f'Setting energy to {self.energy} keV')
-            
-    def updateE(self, energy):
-        '''
-        Beam energy updates are propagated to CRL object from EPICS. The beam
-        size lookup table is then recalculated.
-        '''
-
-        if energy > 0.0001:
-            # Energy variable sent from IOC as a string
-            self.setEnergy(energy)
-            # Update beam properties that are dependent on energy
-            self.setupSourceEnergyDependent()
-        else:
-            if verbose: print(f'Invalid energy setting: {energy} kev; staying at {self.energy} keV')
-            
-    def updateFsize(self, focalSize):
-        '''
-        User updates desired focal size. Lookup table is traversed to find nearest
-        to desired.
-        '''
-        # focalPoint variable sent from IOC as a string
-        self.focalSize = float(focalSize)
-        self.find_config()
-        
-    def updateIndex(self, sortedIndex):
-        '''
-        User has updated desired sorted index
-        '''
-        self.indexSorted = int(sortedIndex)
-        self.index = self.sorted_invF_index[self.indexSorted]
-
-        # Update PVs
-        self.setFocalSizeActual()
-        self.updateLensConfigPV()
-        self.updateLensRBV()
-        self.updateFocalSizeRBVs()    
-
-    def setThickerrFlag(self, flag):
-        '''
-        User has updated thickness error flag so that ...
-        '''
-        self.thickerr_flag = int(flag)
-        if self.verbose: print(f'Thickness Error Flag set to {flag}')
-        self.updateThickerrFlagRBV()
-
-    def updateThickerrFlagRBV(self):
-        '''
-        Thickness error flag has been updated
-        '''
-        if self.verbose: print(f'Thickness Error Flag RBV set to {self.thickerr_flag}')
-        pydev.iointr('updated_thickerr_Flag', self.thickerr_flag)
-
-        
-    def updateLensConfigPV(self):
-        '''
-        
-        '''
-        self.config = self.configs[self.index]
-        pydev.iointr('new_lenses', int(self.config))
-
-    def updateLensRBV(self):
-        '''
-        
-        '''
-        pydev.iointr('new_index', int(self.indexSorted))
-
-    def updateEnergyRBV(self):
-        '''
-        
-        '''
-        pydev.iointr('updated_E', float(self.energy))
-
-    def updateSlitSizeRBV(self, slit):
-        '''
-        Update proper slit size
-        '''
-        
-        if slit == 'hor':
-#            pydev.iointr('updated_slitSize_H', float(self.slit1_H))
-#            if self.verbose: print(f'Horizontal slit size RBV updated to {self.slit1_H} m')
-            pydev.iointr('updated_slitSize_H', float(self.slits[0]['H']))
-            if self.verbose: print(f"Horizontal slit size RBV updated to {self.slits[0]['H']} m")
-        elif slit == 'vert':
-#            pydev.iointr('updated_slitSize_V', float(self.slit1_V))
-#            if self.verbose: print(f'Vertical slit size RBV updated to {self.slit1_V} m')
-            pydev.iointr('updated_slitSize_V', float(self.slits[0]['V']))
-            if self.verbose: print(f"Vertical slit size RBV updated to {self.slits[0]['V']} m")
-            
-
-        
-    def updateFocalSizeRBVs(self):
-        '''
-        
-        '''
-        pydev.iointr('new_fSize', self.focalSize_actual)
-        
-    def updateVerbosity(self, verbosity):
-        '''
-        Turn on minor printing
-        '''
-        print(f'Verbosity set to {verbosity}')
-        self.verbose = int(verbosity)
-
-    def updateLookupWaveform(self):
-        '''
-        Puts lookup table focal sizes into waveform PV
-        '''
-        pydev.iointr('new_lookupTable', self.lookupTable.tolist())
-
-    def updateInvFWaveform(self):
-        '''
-        Puts invF list into waveform PV
-        '''
-        pydev.iointr('new_invFind_list', self.sorted_invF_index.tolist())
-        pydev.iointr('new_invF_list', self.sorted_invF.tolist())
-
-    
-    def updateLookupConfigs(self):
-        '''
-        Puts lookup table config integers into waveform PV
-        '''
-        pydev.iointr('new_configs', self.configs.tolist())
-
-        
-class singleTF(transfocator):
-    def __init__(self, crl_setup = None, beam_config = DEFAULT_CONFIG['beam'], 
-                 beamline_config = DEFAULT_CONFIG['beamline'], 
-                 crl_config = DEFAULT_CONFIG['crl']):
-					 
-		super().__init__(crl_setup = crl_setup, beam_config = beam_config, 
-                 beamline_config = beamline_config, crl_config = crl_config)
-
-    def updateConfig(self, config_BW):
-        '''
-        When user manually changes lenses, this gets focal size and displays it
-        along with updated RBVs but it doesn't set the config PV
-        '''
-        self.index = int(config_BW)
-        # Find the configuration in the 1/f sorted list
-        self.indexSorted = self.sorted_invF_index.tolist().index(self.index)
-
-        self.setFocalSizeActual()
-        self.updateLensRBV()
-        self.updateFocalSizeRBVs()      
-	
-class doubleTF(transfocator):
-    def __init__(self, crl_setup = None, beam_config = DEFAULT_CONFIG['beam'], 
-                 beamline_config = DEFAULT_CONFIG['beamline'], 
-                 crl_config = DEFAULT_CONFIG['crl']):
-					 
-		super().__init__(crl_setup = crl_setup, beam_config = beam_config, 
-                 beamline_config = beamline_config, crl_config = crl_config)
-                 
-                 
-                 
-    def updateConfig1(self, config_BW):
-        '''
-        When user manually changes lenses, this gets focal size and displays it
-        along with updated RBVs but it doesn't set the config PV
-        '''
-        self.index = int(config_BW)
-        # Find the configuration in the 1/f sorted list
-        #TODO how to find in double-list? ?????
-        self.indexSorted = self.sorted_invF_index.tolist().index(self.index)
-
-        self.setFocalSizeActual()
-        self.updateLensRBV()
-        self.updateFocalSizeRBVs()
-        
-    def updateConfig2(self, config_BW):
-        '''
-        When user manually changes lenses, this gets focal size and displays it
-        along with updated RBVs but it doesn't set the config PV
-        '''
-        self.index = int(config_BW)
-        # Find the configuration in the 1/f sorted list
-        #TODO how to find in double-list? ?????
-        self.indexSorted = self.sorted_invF_index.tolist().index(self.index)
-
-        self.setFocalSizeActual()
-        self.updateLensRBV()
-        self.updateFocalSizeRBVs()       
-
-
-    
-class singeTFandKB(transfocator):
-    pass
-
diff --git a/100idPyApp/python/pyTransfocator_single.py b/100idPyApp/python/pyTransfocator_single.py
deleted file mode 100644
index e8e6110..0000000
--- a/100idPyApp/python/pyTransfocator_single.py
+++ /dev/null
@@ -1,500 +0,0 @@
-import numpy as np
-import tomllib
-import xraylib
-from transfocator_calcs import lookup_diameter, materials_to_deltas, materials_to_linear_attenuation
-from transfocator_calcs import find_levels, calc_lookup_table, get_densities
-
-MAT_MACRO = 'MAT'
-NLENS_MACRO = 'NUMLENS'
-RADIUS_MACRO = 'RADIUS'
-LOC_MACRO = 'LOC'
-THICKERR_MACRO = 'THICKERR'
-
-'''
-Config variables
-
-Beam Properties
-        energy      : energy in keV
-        L_und       : undulator length in m
-        sigmaH_e    : Sigma electron source size in H direction in m
-        sigmaV_e    : Sigma electron source size in V direction in m
-        sigmaHp     : Sigma electron divergence in H direction in rad
-        sigmaVp_e   : Sigma electron divergence in V direction in rad
-Beamline properties
-        d_StoL1 : Source-to-CRL1 distance, in m
-        d_Stof  : Source-to-sample distance, in m
-CRL properties
-        d_min   : Minimum thickness at the apex in m
-        stack_d : Stack thickness in m
-'''
-DEFAULT_CONFIG = {'beam':{'energy': 15, 'L_und': 4.7, 'sigmaH_e': 14.8e-6,
-                          'sigmaV_e': 3.7e-6, 'sigmaHp_e': 2.8e-6, 'sigmaVp_e': 1.5e-6},
-                  'beamline': {'d_StoL1': 51.9, 'd_Stof': 66.2},
-                  'crl':{'stack_d': 50.0e-3, 'd_min': 3.0e-5}}
-
-class singleTF():
-    
-    def __init__(self, crl_setup = None, beam_config = DEFAULT_CONFIG['beam'], 
-                 beamline_config = DEFAULT_CONFIG['beamline'], 
-                 crl_config = DEFAULT_CONFIG['crl']):
-
-        self.verbose = True
-
-        if crl_setup is None:
-            beam = beam_config
-            beamline = beamline_config
-            crl = crl_config
-#            slits = slits_config
-        else:
-            with open(crl_setup, "rb") as f:
-                config = tomllib.load(f)
-            beam = config['beam']
-            beamline = config['beamline']
-            crl = config['crl']
- #           slits = config['slits'] 
-
-        self.beam = {}
-        self.setupSource(beam)
-        
-        self.bl = {}
-        self.setupBeamline(beamline)
-        
-        self.crl = {}
-        self.setupCRL(crl)
-        
-        self.slits = [{'H':0,'V':0}]
-        
-#        self.slit1_H = 0
-#        self.slit1_V = 0
-                
-        # Initialize lens variables -- TODO -- this is done via a subs file -- are any of these needed prior to that loading?
-        self.numlens        = np.array([1,      1,      1,      1,      1,      1,      2,      4,      8,      16])                # CRL1 number of lenses in each stack (was L1_n)
-        self.radius         = np.array([2.0e-3, 1.0e-3, 5.0e-4, 3.0e-4, 2.0e-4, 1.0e-4, 1.0e-4, 1.0e-4, 1.0e-4, 1.0e-4])            # CRL1 lens radius in each stack (was L1_R)
-        self.materials      = np.array(["Be",   "Be",   "Be",   "Be",   "Be",   "Be",   "Be",   "Be",   "Be",   "Be"])              # CRL1 lens material in each stack (was L1_mater)
-        self.lens_loc       = np.array([4.5,    3.5,    2.5,    1.5,    0.5,    -0.5,   -1.5,   -2.5,   -3.5,   -4.5])*self.crl['stack_d']      # CRL1 lens stack location relative to center stack, positive means upstream (was L1_Loc)
-        self.lens_thickerr  = np.array([1.0e-6, 1.0e-6, 1.0e-6, 1.0e-6, 1.0e-6, 1.0e-6, 1.4e-6, 2.0e-6, 2.8e-6, 4.0e-6])            # CRL1 lens RMS thickness error (was L1_HE)
-
-
-        self.Lens_diameter_table = [
-                                    (50, 450.0),
-                                    (100, 632.0),
-                                    (200, 894.0),
-                                    (300, 1095.0),
-                                    (500, 1414.0),
-                                    (1000, 2000.0),
-                                    (1500, 2450.0),
-                                ]
-        # Convert the lookup table to a dictionary for faster lookup        
-        self.Lens_diameter_dict = {int(col1): col2 for col1, col2 in self.Lens_diameter_table}
-        
-        self.energy = 0  # gets value from an ao (incoming beam energy)
-        self.focalSize = 0 # get value from an ao (desired focal length)
-        self.lenses = 0 # sets integer (2^10) whose binary representation indicates which lenses are in or out
-        
-        self.num_stacks = 10 # Number of lenses in system
-        
-        self.lookupTable = []
-        
-        self.thickerr_flag = True
-                
-    def setupSource(self, beam_properties):
-        '''
-        Beam properties can have entries for the following
-        
-        energy      : energy in keV
-        L_und       : undulator length in m
-        sigmaH_e    : Sigma electron source size in H direction in m
-        sigmaV_e    : Sigma electron source size in V direction in m
-        sigmaHp_e   : Sigma electron divergence in H direction in rad
-        sigmaVp_e   : Sigma electron divergence in V direction in rad
-        '''
-        
-        self.setEnergy(beam_properties['energy'])
-        self.L_und = beam_properties['L_und']
-        self.sigmaH_e = beam_properties['sigmaH_e']
-        self.sigmaV_e = beam_properties['sigmaV_e']
-        self.sigmaHp_e = beam_properties['sigmaHp_e']
-        self.sigmaVp_e = beam_properties['sigmaVp_e']
-        
-        self.setupSourceEnergyDependent()
-    
-    def setupSourceEnergyDependent(self):
-        '''
-        Fill in later
-        '''    
-        self.beam['sigmaH'] =  (self.sigmaH_e**2 +  self.wl*self.L_und/2/np.pi/np.pi)**0.5
-        self.beam['sigmaV'] =  (self.sigmaV_e**2 +  self.wl*self.L_und/2/np.pi/np.pi)**0.5
-        self.beam['sigmaHp'] = (self.sigmaHp_e**2 + self.wl/self.L_und/2)**0.5
-        self.beam['sigmaVp'] = (self.sigmaVp_e**2 + self.wl/self.L_und/2)**0.5
-        
-    def setupBeamline(self, beamline_properties, num=1):
-        '''
-        Beamline properties can contain entries for the following
-        
-        d_StoL1 : Source-to-CRL1 distance, in m
-        d_Stof  : Source-to-sample distance, in m
-        '''            
-        
-        self.bl['d_StoL1'] = beamline_properties['d_StoL1']
-        self.bl['d_Stof'] = beamline_properties['d_Stof']
-            
-            
-    def setupCRL(self, crl_properties):
-        '''
-        CRL properties can contiain entries for the following
-        
-        d_min   : Minimum thickness at the apex in m
-        stack_d : Stack thickness in m
-        '''
-        self.crl['d_min'] = crl_properties['d_min'] 
-        self.crl['stack_d'] = crl_properties['stack_d']
-
-    def setupSlits(self, slit_properties):
-        '''
-        Slit properties can contain entries for the following
-        
-        '''
-        pass 
-                
-    def setupLookupTable(self, subs_file, n_lenses):
-        '''
-        lookup table created after IOC startup
-        energy and slit size are updated before this is called
-        '''
-        print(80*'#')
-        print('Setting up lens control...')
-        
-        self.num_stacks = n_lenses
-        self.num_configs = 2**self.num_stacks
-        self.configs = np.arange(self.num_configs)
-        
-#       self.energy = energy
-        
-        #read in substitutions file
-        try:
-            subsFile = open(subs_file,"r")
-        except:
-            raise RuntimeError(f"Substiution file ({subsFile}) not found.")
-        subsFileContent = subsFile.readlines()
-        subsFile.close()
-        
-        macros = subsFileContent[2].replace('{','').replace('}','').replace(',','').split()
-        lens_properties = {key: [] for key in macros} # dictionary of lists
-        for i in range(self.num_stacks):
-            try:
-                xx = subsFileContent[3+i].replace('{','').replace('}','').replace(',','').replace('"','').split()
-                lens_properties[macros[0]].append(xx[0])
-                lens_properties[macros[1]].append(xx[1])
-                lens_properties[macros[2]].append(xx[2])
-                lens_properties[macros[3]].append(xx[3])
-                lens_properties[macros[4]].append(xx[4])
-                lens_properties[macros[5]].append(xx[5])
-                lens_properties[macros[6]].append(xx[6])
-            except:
-                raise RuntimeError(f"Number of lenses ({self.num_stacks}) doesn't match substitution file")
-        
-        self.numlens = []
-        self.radius = []
-        self.materials = []
-        self.lens_loc = []
-        self.lens_thickerr = []
-            
-        # get number of lens for each lens stack from lens properties dictionary-list
-        print('Getting lens materials...')
-        if NLENS_MACRO in macros:
-            self.numlens = np.array([int(i) for i in lens_properties[NLENS_MACRO]])
-            print('Number of lens read in.\n')
-        else:
-            raise RuntimeError(f"Number of lenses macro ({NLENS_MACRO}) not found in substituion file")
-
-        # get radii for each lens from lens properties dictionary-list
-        print('Getting lens\' radii...')
-        if RADIUS_MACRO in macros:
-            self.radius = np.array([float(i) for i in lens_properties[RADIUS_MACRO]])
-            print('Radius of lenses read in.\n')
-        else:
-            raise RuntimeError(f"Radius macro ({RADIUS_MACRO}) not found in substituion file")
-
-        # get materials from lens properties dictionary-list
-        print('Getting lens materials...')
-        if MAT_MACRO in macros:
-            self.materials = lens_properties[MAT_MACRO]
-            print('Lens material read in.\n')
-        else:
-            raise RuntimeError(f"Material macro ({MAT_MACRO}) not found in substituion file")
-        
-        # get densities from local definition (for compounds) or from xraylib (for elements)
-        densities = get_densities(self.materials)
-        self.densities = np.array([densities[material] for material in self.materials])
-
-        # get location of each lens from lens properties dictionary-list
-        print('Getting lens\' locations...')
-        if LOC_MACRO in macros:
-            self.lens_loc = np.array([float(i)*self.crl['stack_d'] for i in lens_properties[LOC_MACRO]])
-            print('Location of lenses read in.\n')
-        else:
-            raise RuntimeError(f"Location macro ({LOC_MACRO}) not found in substituion file")
-
-        # get thicknesses errprfrom lens properties dictionary-list
-        print('Getting lens thickness error...')
-        if THICKERR_MACRO in macros:
-            self.lens_thickerr = np.array([float(i) for i in lens_properties[THICKERR_MACRO]])
-            print('Lens thickness errors read in.\n')
-        else:
-            raise RuntimeError(f"Thickness errors macro ({THICKERR_MACRO}) not found in substituion file")
-
-        print('Constructing lookup table...')
-        self.construct_lookup_table()
-        print('Lookup table calculation complete.\n')
-        
-        print('Transfocator control setup complete.')
-        print(80*'#')
-
-    def construct_lookup_table(self):
-        arr_a, arr_b, arr_c = calc_lookup_table(self.num_configs, self.radius, 
-                                                self.materials, self.energy, self.wl,
-                                                self.numlens, 
-                                                self.lens_loc, self.beam, self.bl,
-                                                self.crl, self.slits[0]['H'], self.slits[0]['V'],
-                                                self.lens_thickerr, flag_HE = self.thickerr_flag,
-                                                verbose = self.verbose)
-        self.lookupTable = arr_a
-        self.sorted_invF_index = arr_b
-        self.sorted_invF = arr_c                                                            
-                                                                    
-#        self.sort_lookup_table()
-        self.updateEnergyRBV()
-        self.updateSlitSizeRBV('hor')
-        self.updateSlitSizeRBV('vert')
-        self.updateLookupWaveform()
-        self.updateInvFWaveform()
-        self.updateLookupConfigs()
-
-        
-#    def sort_lookup_table(self):
-#        '''
-#        
-#        '''
-#        if self.verbose: print(f'Sorting lookup table of length {len(self.lookupTable)}')        
-#        self.sorted_L_index = np.argsort(self.lookupTable)
-
-    def updateConfig(self, config_BW):
-        '''
-        When user manually changes lenses, this gets focal size and displays it
-        along with updated RBVs but it doesn't set the config PV
-        '''
-        self.index = int(config_BW)
-        # Find the configuration in the 1/f sorted list
-        self.indexSorted = self.sorted_invF_index.tolist().index(self.index)
-
-        self.setFocalSizeActual()
-        self.updateLensRBV()
-        self.updateFocalSizeRBVs()      
-
-
-
-    def setFocalSizeActual(self):
-        '''
-        
-        '''
-#        self.focalSize_actual = self.culledTable[self.culledIndex] 
-        self.focalSize_actual = self.lookupTable[self.indexSorted] 
-
-    def find_config(self):
-        ''' 
-        User selected focal size, this function finds nearest acheivable focal 
-        size from the lookup table
-        '''
-        # Code to search lookup table for nearest focal size to desired; note the
-        # lookup table is already sorted by 1/f
-        if self.verbose: print(f'Searching for config closest to {self.focalSize}')
-#       simple approach
-#        self.indexSorted = np.argmin(np.abs(self.lookupTable - self.focalSize))
-
-        # XS approach -- can handle nan but in pydev application don't have a good
-        # way to "transmit" errors (i.e. no solution found) to user.
-        indices, _ = find_levels(self.lookupTable, self.focalSize, direction='forward')[0]
-        self.indexSorted = indices[0]
-        
-
-        if self.verbose: print(f'1/f-sorted config index found at {self.indexSorted}')
-
-        self.index = self.sorted_invF_index[self.indexSorted]
-        if self.verbose: print(f'Config index found at {self.index}')
-
-        # Update PVs
-        self.setFocalSizeActual()
-        self.updateLensConfigPV()
-        self.updateLensRBV()
-        self.updateFocalSizeRBVs()      
-
-    def getPreviewFocalSize(self, sortedIndex):
-        '''
-        
-        '''
-        fSize_preview = self.lookupTable[sortedIndex]
-        if self.verbose: print(f'Preview focal sizes for {sortedIndex} is {fSize_preview}')
-        pydev.iointr('new_preview', fSize_preview)
-    
-    def setSlitSize(self, size, slit):
-        '''
-        Update proper slit size
-        '''
-        
-        if slit == 'hor':
-#            self.slit1_H = float(size)     # H slit size before CRL 1
-            self.slits[0]['H'] = float(size)     # H slit size before CRL 1
-        elif slit == 'vert':
-#            self.slit1_V = float(size)     # V slit size before CRL 1
-            self.slits[0]['V'] = float(size)     # V slit size before CRL 1
-        else: 
-            raise RuntimeError(f"Slit identifier ({slit}) not recognized. Should be 'hor' or 'vert'")
-           
-                    
-    def updateSlitSize(self, size, slit):
-        '''
-        Slit size updates are propagated to CRL object from EPICS.  The beam
-        size lookup table is then recalculated.
-        '''
-        self.setSlitSize(size, slit)
-        
-        if self.verbose: 
-            if slit == 'hor':
-#                print(f'Horizontal slit size updated to {self.slit1_H} m')
-                print(f"Horizontal slit size updated to {self.slits[0]['H']} m")
-            elif slit == 'vert':
-#                print(f'Vertical slit size updated to {self.slit1_V} m')
-                print(f"Vertical slit size updated to {self.slits[0]['V']} m")
-        
-        
-    def setEnergy(self, energy):
-        '''
-        Sets various forms of energy
-        '''
-        if energy > 0.0001:
-            self.energy = float(energy)
-            self.energy_eV = self.energy*1000.0  # Energy in keV
-            self.wl = 1239.84 / (self.energy_eV * 10**9)    #Wavelength in nm(?)
-            if self.verbose: print(f'Setting energy to {self.energy} keV')
-            
-    def updateE(self, energy):
-        '''
-        Beam energy updates are propagated to CRL object from EPICS. The beam
-        size lookup table is then recalculated.
-        '''
-
-        if energy > 0.0001:
-            # Energy variable sent from IOC as a string
-            self.setEnergy(energy)
-            # Update beam properties that are dependent on energy
-            self.setupSourceEnergyDependent()
-        else:
-            if verbose: print(f'Invalid energy setting: {energy} kev; staying at {self.energy} keV')
-            
-    def updateFsize(self, focalSize):
-        '''
-        User updates desired focal size. Lookup table is traversed to find nearest
-        to desired.
-        '''
-        # focalPoint variable sent from IOC as a string
-        self.focalSize = float(focalSize)
-        self.find_config()
-        
-    def updateIndex(self, sortedIndex):
-        '''
-        User has updated desired sorted index
-        '''
-        self.indexSorted = int(sortedIndex)
-        self.index = self.sorted_invF_index[self.indexSorted]
-
-        # Update PVs
-        self.setFocalSizeActual()
-        self.updateLensConfigPV()
-        self.updateLensRBV()
-        self.updateFocalSizeRBVs()    
-
-    def setThickerrFlag(self, flag):
-        '''
-        User has updated thickness error flag so that ...
-        '''
-        self.thickerr_flag = int(flag)
-        if self.verbose: print(f'Thickness Error Flag set to {flag}')
-        self.updateThickerrFlagRBV()
-
-    def updateThickerrFlagRBV(self):
-        '''
-        Thickness error flag has been updated
-        '''
-        if self.verbose: print(f'Thickness Error Flag RBV set to {self.thickerr_flag}')
-        pydev.iointr('updated_thickerr_Flag', self.thickerr_flag)
-
-        
-    def updateLensConfigPV(self):
-        '''
-        
-        '''
-        self.config = self.configs[self.index]
-        pydev.iointr('new_lenses', int(self.config))
-
-    def updateLensRBV(self):
-        '''
-        
-        '''
-        pydev.iointr('new_index', int(self.indexSorted))
-
-    def updateEnergyRBV(self):
-        '''
-        
-        '''
-        pydev.iointr('updated_E', float(self.energy))
-
-    def updateSlitSizeRBV(self, slit):
-        '''
-        Update proper slit size
-        '''
-        
-        if slit == 'hor':
-#            pydev.iointr('updated_slitSize_H', float(self.slit1_H))
-#            if self.verbose: print(f'Horizontal slit size RBV updated to {self.slit1_H} m')
-            pydev.iointr('updated_slitSize_H', float(self.slits[0]['H']))
-            if self.verbose: print(f"Horizontal slit size RBV updated to {self.slits[0]['H']} m")
-        elif slit == 'vert':
-#            pydev.iointr('updated_slitSize_V', float(self.slit1_V))
-#            if self.verbose: print(f'Vertical slit size RBV updated to {self.slit1_V} m')
-            pydev.iointr('updated_slitSize_V', float(self.slits[0]['V']))
-            if self.verbose: print(f"Vertical slit size RBV updated to {self.slits[0]['V']} m")
-            
-
-        
-    def updateFocalSizeRBVs(self):
-        '''
-        
-        '''
-        pydev.iointr('new_fSize', self.focalSize_actual)
-        
-    def updateVerbosity(self, verbosity):
-        '''
-        Turn on minor printing
-        '''
-        print(f'Verbosity set to {verbosity}')
-        self.verbose = int(verbosity)
-
-    def updateLookupWaveform(self):
-        '''
-        Puts lookup table focal sizes into waveform PV
-        '''
-        pydev.iointr('new_lookupTable', self.lookupTable.tolist())
-
-    def updateInvFWaveform(self):
-        '''
-        Puts invF list into waveform PV
-        '''
-        pydev.iointr('new_invFind_list', self.sorted_invF_index.tolist())
-        pydev.iointr('new_invF_list', self.sorted_invF.tolist())
-
-    
-    def updateLookupConfigs(self):
-        '''
-        Puts lookup table config integers into waveform PV
-        '''
-        pydev.iointr('new_configs', self.configs.tolist())
-- 
GitLab