From 87ada0d454414d48c1f1ed3ac2223003dc2bf9fc Mon Sep 17 00:00:00 2001 From: vshekar1 Date: Fri, 23 May 2025 12:29:32 -0400 Subject: [PATCH 1/4] Removed NYX related code --- beamline_support.py | 8 +- bin/lsdcGui_nyx | 10 - bin/lsdcServer_nyx.cmd | 14 - config_params.py | 19 +- daq_lib.py | 193 ++----- daq_macros.py | 977 +------------------------------- daq_main_common.py | 6 +- daq_utils.py | 6 +- gon_lib.py | 8 - gov_lib.py | 14 +- gui/control_main.py | 387 ++++--------- gui/dialog/user_screen.py | 11 - gui/vector.py | 2 - mxbluesky/devices/md2.py | 392 ------------- mxbluesky/devices/md2_flyers.py | 284 ---------- start_bs.py | 81 --- 16 files changed, 194 insertions(+), 2218 deletions(-) delete mode 100755 bin/lsdcGui_nyx delete mode 100755 bin/lsdcServer_nyx.cmd delete mode 100644 mxbluesky/devices/md2.py delete mode 100644 mxbluesky/devices/md2_flyers.py diff --git a/beamline_support.py b/beamline_support.py index 0d8a926d..6693ddae 100644 --- a/beamline_support.py +++ b/beamline_support.py @@ -319,14 +319,8 @@ def read_db(): def init_motors(): global motor_channel_dict - md2_motors = ["omega","sampleX","sampleY","sampleZ", "finex", "finey", "finez"] - for key in list(motor_dict.keys()): - if beamline_designation == "XF:19ID" and key in md2_motors: - from mxbluesky.devices.md2 import MD2Positioner - motor_channel_dict[motor_dict[key]] = MD2Positioner(motor_dict[key],name = key) - else: - motor_channel_dict[motor_dict[key]] = EpicsMotor(motor_dict[key],name = key) + motor_channel_dict[motor_dict[key]] = EpicsMotor(motor_dict[key],name = key) def initControlPVs(): diff --git a/bin/lsdcGui_nyx b/bin/lsdcGui_nyx deleted file mode 100755 index 55d2122d..00000000 --- a/bin/lsdcGui_nyx +++ /dev/null @@ -1,10 +0,0 @@ -export PROJDIR=/nsls2/software/mx/daq/ -export CONFIGDIR=${PROJDIR}bnlpx_config/ -export LSDCHOME=${PROJDIR}lsdc_nyx -export EPICS_CA_AUTO_ADDR_LIST=NO -export EPICS_CA_ADDR_LIST=10.67.147.255 - -export PATH=/usr/local/bin:/usr/bin:/bin -export PYTHONPATH=".:${CONFIGDIR}:/opt/dectris/albula/4.0/python:/usr/local/crys/edna-mx/mxv1/src:/usr/local/crys/edna-mx/kernel/src:${LSDCHOME}" -source ${CONFIGDIR}daq_env_nyx.txt -/opt/conda_envs/lsdc-gui-2023-2-latest/bin/python $LSDCHOME/lsdcGui.py& diff --git a/bin/lsdcServer_nyx.cmd b/bin/lsdcServer_nyx.cmd deleted file mode 100755 index 47fe7b11..00000000 --- a/bin/lsdcServer_nyx.cmd +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/bash -l -export PROJDIR=/nsls2/software/mx/daq/ -export CONFIGDIR=${PROJDIR}bnlpx_config/ -export LSDCHOME=${PROJDIR}lsdc_nyx -#export EPICS_CA_AUTO_ADDR_LIST=NO -export PYTHONPATH=".:${CONFIGDIR}:/usr/lib64/edna-mx/mxv1/src:/usr/lib64/edna-mx/kernel/src:${LSDCHOME}:${PROJDIR}/RobotControlLib" -export PATH=/usr/local/bin:/usr/bin:/bin:${PROJDIR}/software/bin:/opt/ccp4/bin -source ${CONFIGDIR}daq_env_nyx.txt -export matlab_distrib=${PROJDIR}/software/c3d/matlab_distrib -export LD_LIBRARY_PATH=$matlab_distrib/bin/glnx86:$matlab_distrib/toolbox -export PINALIGNDIR=${PROJDIR}pinAlign/pin_align-master/ -export MXPROCESSINGSCRIPTSDIR=${PROJDIR}lsdc-processing/ -conda activate lsdc-server-2023-2-latest -$LSDCHOME/lsdcServer diff --git a/config_params.py b/config_params.py index 97425456..79cdecdf 100644 --- a/config_params.py +++ b/config_params.py @@ -85,40 +85,36 @@ class OnMountAvailOptions(Enum): DETECTOR_OBJECT_TYPE_OPHYD = "ophyd" # instantiated in start_bs, using Bluesky scans DETECTOR_OBJECT_TYPE = "detectorObjectType" -DETECTOR_SAFE_DISTANCE = {"fmx": 200.0, "amx": 180.0, "nyx": 200.0} +DETECTOR_SAFE_DISTANCE = {"fmx": 200.0, "amx": 180.0} GOVERNOR_TIMEOUT = 120 # seconds for a governor move -DEWAR_SECTORS = {'amx':8, 'fmx':8, 'nyx':8} -PUCKS_PER_DEWAR_SECTOR = {'amx':3, 'fmx':3, 'nyx':3} +DEWAR_SECTORS = {'amx':8, 'fmx':8} +PUCKS_PER_DEWAR_SECTOR = {'amx':3, 'fmx':3} -cryostreamTempPV = {"amx": "XF:17ID1:CS700:TEMP", "fmx": "XF:17ID2:CS700:TEMP", "nyx":"XF:19ID2:CS700:TEMP"} +cryostreamTempPV = {"amx": "XF:17ID1:CS700:TEMP", "fmx": "XF:17ID2:CS700:TEMP"} VALID_EXP_TIMES = { "amx": {"min": 0.005, "max": 1, "digits": 3}, "fmx": {"min": 0.01, "max": 10, "digits": 3}, - "nyx": {"min": 0.002, "max": 10, "digits": 4}, } VALID_DET_DIST = { "amx": {"min": 100, "max": 500, "digits": 3}, "fmx": {"min": 137, "max": 2000, "digits": 2}, - "nyx": {"min": 100, "max": 500, "digits": 3}, } VALID_TOTAL_EXP_TIMES = { "amx": {"min": 0.005, "max": 300, "digits": 3}, "fmx": {"min": 0.01, "max": 300, "digits": 3}, - "nyx": {"min": 0.01, "max": 1000, "digits": 3}, } VALID_PREFIX_LENGTH = 25 # TODO centralize with spreadsheet validation? VALID_PREFIX_NAME = "[0-9a-zA-Z-_]{0,%s}" % VALID_PREFIX_LENGTH VALID_TRANSMISSION = { "amx": {"min": 0.001, "max": 1.0, "digits": 3}, "fmx": {"min": 0.001, "max": 1.0, "digits": 3}, - "nyx": {"min": 0.001, "max": 0.999, "digits": 3}, } -MINIMUM_RASTER_SIZE = {"amx": 6, "fmx": 6, "nyx": 2} +MINIMUM_RASTER_SIZE = {"amx": 6, "fmx": 6} -LSDC_SERVICE_USERS = ("lsdc-amx", "lsdc-fmx", "lsdc-nyx") +LSDC_SERVICE_USERS = ("lsdc-amx", "lsdc-fmx") IS_STAFF = ( True if os.environ.get("STAFF_GROUP") is not None and os.environ["STAFF_GROUP"] in [grp.getgrgid(g).gr_name for g in os.getgroups()] @@ -154,8 +150,6 @@ def get_text(cls, enum_value): } return text_values.get(enum_value, "\n(Unknown State)") -OPHYD_COLLECTIONS = {"amx": False, "fmx": False, "nyx": True} - class CollectionProtocols(str, Enum): STANDARD = "standard" RASTER = "raster" @@ -176,7 +170,6 @@ def get_beamline_options(cls, beamline): cls.STEP_RASTER, cls.STEP_VECTOR, cls.MULTI_COL, cls.CHARACTERIZE, cls.EDNA_COL) beamline_options = { - "nyx": (cls.STANDARD, cls.RASTER, cls.VECTOR), "amx": all_protocols, "fmx": all_protocols } diff --git a/daq_lib.py b/daq_lib.py index 172a685b..12e62ec6 100644 --- a/daq_lib.py +++ b/daq_lib.py @@ -659,60 +659,9 @@ def collectData(currentRequest): sweep_start = reqObj["sweep_start"] daq_macros.setTrans(attenuation) - if (reqObj["protocol"] in (CollectionProtocols.CHARACTERIZE, CollectionProtocols.EDNA_COL)): - characterizationParams = reqObj["characterizationParams"] - index_success = daq_macros.dna_execute_collection3(0.0,img_width,2,exposure_period,data_directory_name+"/",file_prefix,1,-89.0,1,currentRequest) - if (index_success): - resultsList = db_lib.getResultsforRequest(currentRequest["uid"]) # because for testing I keep running the same request. Probably not in usual use. - results = None - for i in range(0,len(resultsList)): - if (resultsList[i]['result_type'] == 'characterizationStrategy'): - results = resultsList[i] - break - if (results != None): - - strategyResults = results["result_obj"]["strategy"] - stratStart = strategyResults["start"] - stratEnd = strategyResults["end"] - stratWidth = strategyResults["width"] - stratExptime = strategyResults["exptime"] - stratTrans = strategyResults["transmission"] - stratDetDist = strategyResults["detDist"] - sampleID = currentRequest["sample"] - tempnewStratRequest = daq_utils.createDefaultRequest(sampleID) - newReqObj = tempnewStratRequest["request_obj"] - newReqObj["sweep_start"] = stratStart - newReqObj["sweep_end"] = stratEnd - newReqObj["img_width"] = stratWidth - newReqObj["exposure_time"] = stratExptime - newReqObj["attenuation"] = stratTrans - newReqObj["detDist"] = stratDetDist - newReqObj["directory"] = data_directory_name - newReqObj["pos_x"] = beamline_lib.motorPosFromDescriptor("sampleX") - newReqObj["pos_y"] = beamline_lib.motorPosFromDescriptor("sampleY") - newReqObj["pos_z"] = beamline_lib.motorPosFromDescriptor("sampleZ") - newReqObj["fastDP"] = True # this is where you might want a "new from old" request to carry over stuff like this. - newReqObj["fastEP"] = reqObj["fastEP"] - newReqObj["dimple"] = reqObj["dimple"] - newReqObj["xia2"] = reqObj["xia2"] - runNum = db_lib.incrementSampleRequestCount(sampleID) - newReqObj["runNum"] = runNum - newStratRequest = db_lib.addRequesttoSample(sampleID,newReqObj["protocol"],daq_utils.owner,newReqObj,priority=0,proposalID=daq_utils.getProposalID()) - if (reqObj["protocol"] == CollectionProtocols.EDNA_COL): - logger.info("new strat req = ") - logger.info(newStratRequest) - db_lib.updatePriority(currentRequest["uid"],-1) - refreshGuiTree() - collectData(db_lib.getRequestByID(newStratRequest)) - return 1 - else: #standard - logger.info("moving omega to start " + str(time.time())) - if daq_utils.beamline == "nyx": - direction = (sweep_end - sweep_start) / abs(sweep_end - sweep_start) - beamline_lib.mvaDescriptor("omega",sweep_start - direction*0.05) - else: - beamline_lib.mvaDescriptor("omega",sweep_start) - collect_detector_seq_hw(sweep_start,range_degrees,img_width,exposure_period,file_prefix,data_directory_name,file_number_start,currentRequest) + logger.info("moving omega to start " + str(time.time())) + beamline_lib.mvaDescriptor("omega",sweep_start) + collect_detector_seq_hw(sweep_start,range_degrees,img_width,exposure_period,file_prefix,data_directory_name,file_number_start,currentRequest) try: if (logMe) and prot == CollectionProtocols.RASTER: logMxRequestParams(currentRequest,wait=False) @@ -729,50 +678,49 @@ def collectData(currentRequest): if reqObj["protocol"] in (CollectionProtocols.STANDARD, CollectionProtocols.VECTOR, CollectionProtocols.RASTER): send_kafka_message(topic=f'{daq_utils.beamline}.lsdc.documents', event='stop', uuid=currentRequest['uid'], protocol=reqObj["protocol"]) if prot in (CollectionProtocols.VECTOR, CollectionProtocols.STANDARD, CollectionProtocols.STEP_VECTOR): - if daq_utils.beamline != "nyx": - seqNum = flyer.detector.cam.sequence_id.get() - comm_s = os.environ["LSDCHOME"] + "/runSpotFinder4syncW.py " + data_directory_name + " " + file_prefix + " " + str(currentRequest["uid"]) + " " + str(seqNum) + " " + str(currentIspybDCID)+ "&" - logger.info(f"NOT running spotfinding for per-image analysis in Synchweb: {comm_s}") - #os.system(comm_s) - filename = f"{data_directory_name}/{file_prefix}_{seqNum}_master.h5" - logger.info(f"Checking integrity of {filename}") - timeout_index = 0 - while not validation.validate_master_HDF5_file(filename): - timeout_index += 1 - time.sleep(3) - if timeout_index > 15: - logger.error(f"Unable to verify master file after {timeout_index} tries, not proceeding with processing") - return - if img_width > 0: #no dataset processing in stills mode - if (reqObj["fastDP"]): - if (reqObj["fastEP"]): - fastEPFlag = 1 - else: - fastEPFlag = 0 - if (reqObj["dimple"]): - dimpleFlag = 1 - else: - dimpleFlag = 0 - nodeName = "fastDPNode" + str((fastDPNodeCounter%fastDPNodeCount)+1) - fastDPNodeCounter+=1 - node = getBlConfig(nodeName) - dimpleNode = getBlConfig("dimpleNode") - if (daq_utils.detector_id == "EIGER-16"): - seqNum = flyer.detector.cam.sequence_id.get() - comm_s = os.environ["LSDCHOME"] + "/runFastDPH5.py " + data_directory_name + " " + str(seqNum) + " " + str(currentRequest["uid"]) + " " + str(fastEPFlag) + " " + node + " " + str(dimpleFlag) + " " + dimpleNode + " " + str(currentIspybDCID)+ "&" - else: - comm_s = os.environ["LSDCHOME"] + "/runFastDP.py " + data_directory_name + " " + file_prefix + " " + str(file_number_start) + " " + str(int(round(range_degrees/img_width))) + " " + str(currentRequest["uid"]) + " " + str(fastEPFlag) + " " + node + " " + str(dimpleFlag) + " " + dimpleNode + "&" - logger.info(f'Running fastdp command: {comm_s}') - if daq_utils.beamline in ("amx", "fmx"): - visitName = daq_utils.getVisitName() - if (not os.path.exists(visitName + "/fast_dp_dir")) or subprocess.run(['pgrep', '-f', 'loop-fdp-dple-populate'], stdout=subprocess.PIPE).returncode == 1: # for pgrep, return of 1 means string not found - os.system("killall -KILL loop-fdp-dple-populate") - logger.info('starting fast dp result gathering script') - os.system("cd " + visitName + ";${LSDCHOME}/bin/loop-fdp-dple-populate.sh&") - os.system(comm_s) - if (reqObj["xia2"]): - comm_s = f"ssh -q xf17id2-srv1 \"{os.environ['MXPROCESSINGSCRIPTSDIR']}xia2.sh {currentRequest['uid']} \"&" - os.system(comm_s) + seqNum = flyer.detector.cam.sequence_id.get() + comm_s = os.environ["LSDCHOME"] + "/runSpotFinder4syncW.py " + data_directory_name + " " + file_prefix + " " + str(currentRequest["uid"]) + " " + str(seqNum) + " " + str(currentIspybDCID)+ "&" + logger.info(f"NOT running spotfinding for per-image analysis in Synchweb: {comm_s}") + #os.system(comm_s) + filename = f"{data_directory_name}/{file_prefix}_{seqNum}_master.h5" + logger.info(f"Checking integrity of {filename}") + timeout_index = 0 + while not validation.validate_master_HDF5_file(filename): + timeout_index += 1 + time.sleep(3) + if timeout_index > 15: + logger.error(f"Unable to verify master file after {timeout_index} tries, not proceeding with processing") + return + if img_width > 0: #no dataset processing in stills mode + if (reqObj["fastDP"]): + if (reqObj["fastEP"]): + fastEPFlag = 1 + else: + fastEPFlag = 0 + if (reqObj["dimple"]): + dimpleFlag = 1 + else: + dimpleFlag = 0 + nodeName = "fastDPNode" + str((fastDPNodeCounter%fastDPNodeCount)+1) + fastDPNodeCounter+=1 + node = getBlConfig(nodeName) + dimpleNode = getBlConfig("dimpleNode") + if (daq_utils.detector_id == "EIGER-16"): + seqNum = flyer.detector.cam.sequence_id.get() + comm_s = os.environ["LSDCHOME"] + "/runFastDPH5.py " + data_directory_name + " " + str(seqNum) + " " + str(currentRequest["uid"]) + " " + str(fastEPFlag) + " " + node + " " + str(dimpleFlag) + " " + dimpleNode + " " + str(currentIspybDCID)+ "&" + else: + comm_s = os.environ["LSDCHOME"] + "/runFastDP.py " + data_directory_name + " " + file_prefix + " " + str(file_number_start) + " " + str(int(round(range_degrees/img_width))) + " " + str(currentRequest["uid"]) + " " + str(fastEPFlag) + " " + node + " " + str(dimpleFlag) + " " + dimpleNode + "&" + logger.info(f'Running fastdp command: {comm_s}') + if daq_utils.beamline in ("amx", "fmx"): + visitName = daq_utils.getVisitName() + if (not os.path.exists(visitName + "/fast_dp_dir")) or subprocess.run(['pgrep', '-f', 'loop-fdp-dple-populate'], stdout=subprocess.PIPE).returncode == 1: # for pgrep, return of 1 means string not found + os.system("killall -KILL loop-fdp-dple-populate") + logger.info('starting fast dp result gathering script') + os.system("cd " + visitName + ";${LSDCHOME}/bin/loop-fdp-dple-populate.sh&") + os.system(comm_s) + if (reqObj["xia2"]): + comm_s = f"ssh -q xf17id2-srv1 \"{os.environ['MXPROCESSINGSCRIPTSDIR']}xia2.sh {currentRequest['uid']} \"&" + os.system(comm_s) logger.info('processing should be triggered') db_lib.updatePriority(currentRequest["uid"],-1) @@ -810,28 +758,18 @@ def collect_detector_seq_hw(sweep_start,range_degrees,image_width,exposure_perio logger.info("collect %f degrees for %f seconds %d images exposure_period = %f exposure_time = %f" % (range_degrees,range_seconds,number_of_images,exposure_period,exposure_time)) - if OPHYD_COLLECTIONS[daq_utils.beamline]: - logger.info("ophyd collections enabled") - if (protocol == CollectionProtocols.STANDARD): - RE(daq_macros.standard_plan_wrapped(currentRequest)) - elif (protocol == CollectionProtocols.VECTOR): - RE(daq_macros.vector_plan_wrapped(currentRequest)) - else: - if (protocol in (CollectionProtocols.STANDARD, CollectionProtocols.CHARACTERIZE, - CollectionProtocols.EDNA_COL, CollectionProtocols.BURN)): - logger.info("vectorSync " + str(time.time())) - daq_macros.vectorSync() - logger.info("zebraDaq " + str(time.time())) - - vector_params = daq_macros.gatherStandardVectorParams() - logger.debug(f"vector_params: {vector_params}") - RE(daq_macros.standard_zebra_plan(flyer,angleStart,number_of_images,range_degrees,image_width,exposure_period,file_prefix_minus_directory,data_directory_name,file_number, vector_params, file_prefix_minus_directory)) - elif (protocol == CollectionProtocols.VECTOR): - RE(daq_macros.vectorZebraScan(currentRequest)) - elif (protocol == CollectionProtocols.STEP_VECTOR): - daq_macros.vectorZebraStepScan(currentRequest) - else: - pass + if (protocol in (CollectionProtocols.STANDARD, CollectionProtocols.BURN): + logger.info("vectorSync " + str(time.time())) + daq_macros.vectorSync() + logger.info("zebraDaq " + str(time.time())) + + vector_params = daq_macros.gatherStandardVectorParams() + logger.debug(f"vector_params: {vector_params}") + RE(daq_macros.standard_zebra_plan(flyer,angleStart,number_of_images,range_degrees,image_width,exposure_period,file_prefix_minus_directory,data_directory_name,file_number, vector_params, file_prefix_minus_directory)) + elif (protocol == CollectionProtocols.VECTOR): + RE(daq_macros.vectorZebraScan(currentRequest)) + elif (protocol == CollectionProtocols.STEP_VECTOR): + daq_macros.vectorZebraStepScan(currentRequest) return @@ -884,21 +822,6 @@ def center_on_click(x,y,fovx,fovy,source="screen",maglevel=0,jog=0,viewangle=daq #source=screen = from screen click, otherwise from macro with full pixel dimensions #viewangle=daq_utils.CAMERA_ANGLE_BEAM, default camera angle is in-line with the beam - if daq_utils.beamline == "nyx": - logger.info("center_on_click: %s" % str((x,y))) - lsdc_x = daq_utils.screenPixX - lsdc_y = daq_utils.screenPixY - md2_x = getPvDesc("md2CenterPixelX") * 2 - md2_y = getPvDesc("md2CenterPixelY") * 2 - scale_x = md2_x / lsdc_x - scale_y = md2_y / lsdc_y - x = x * scale_x - y = y * scale_y - str_coords = f'{x} {y}' - logger.info(f'center_on_click: {str_coords}') - setPvDesc("MD2C2C", str_coords) - return - if (getBlConfig('robot_online')): #so that we don't move things when robot moving? robotGovState = (getPvDesc("robotSaActive") or getPvDesc("humanSaActive")) if (not robotGovState): diff --git a/daq_macros.py b/daq_macros.py index 7045ed93..d276ac60 100644 --- a/daq_macros.py +++ b/daq_macros.py @@ -980,10 +980,7 @@ def makeDozorInputFile(directory,prefix,rowIndex,rowCellCount,seqNum,rasterReqOb src = Template(inputTemplate.read()) dozorRowDir = makeDozorRowDir(directory,rowIndex) dozorSpotLevel = getBlConfig(RASTER_DOZOR_SPOT_LEVEL) - if daq_utils.beamline == "nyx": - dozorPlugin = "/nsls2/software/mx/nyx/bin/dectris-neggia.so" - else: - dozorPlugin = "/usr/lib64/dectris-neggia.so" + dozorPlugin = "/usr/lib64/dectris-neggia.so" templateDict = {"detector": detector, "nx": nx, "ny": ny, @@ -1085,9 +1082,6 @@ def runDozorThread(directory, global rasterRowResultsList,processedRasterRowCount file_writing_delay = 0.5 node = getNodeName("spot", rowIndex, 8) - if daq_utils.beamline == 'nyx': - file_writing_delay = 10 - node = "titania-cpu00"+str((rowIndex%4)+1) time.sleep(file_writing_delay) #allow for file writing if (seqNum>-1): #eiger @@ -1293,606 +1287,8 @@ def getNodeName(node_type, row_index, num_nodes=8): #calculate node name based o return getBlConfig(node_config_name) def snakeRaster(rasterReqID,grain=""): - scannerType = getBlConfig("scannerType") - if (scannerType == "PI"): - snakeRasterFine(rasterReqID,grain) - else: - if daq_utils.beamline == "nyx": - yield from raster_plan_wrapped(rasterReqID) - else: - finalize_plan = finalize_wrapper(snakeRasterBluesky(rasterReqID,grain), bps.mv(raster_flyer.detector.cam.acquire, 0)) - yield from finalize_plan - #RE(snakeRasterBluesky(rasterReqID,grain)) - -def snakeRasterNoTile(rasterReqID,grain=""): - global dialsResultDict,rasterRowResultsList,processedRasterRowCount - - gov_status = gov_lib.setGovRobot(gov_robot, 'DA') - if not gov_status.success: - return - - rasterRequest = db_lib.getRequestByID(rasterReqID) - reqObj = rasterRequest["request_obj"] - parentReqID = reqObj["parentReqID"] - parentReqProtocol = "" - - if (parentReqID != -1): - parentRequest = db_lib.getRequestByID(parentReqID) - parentReqObj = parentRequest["request_obj"] - parentReqProtocol = parentReqObj["protocol"] - detDist = parentReqObj["detDist"] - data_directory_name = str(reqObj["directory"]) - os.system("mkdir -p " + data_directory_name) - filePrefix = str(reqObj["file_prefix"]) - file_number_start = reqObj["file_number_start"] - dataFilePrefix = reqObj["directory"]+"/"+reqObj["file_prefix"] - exptimePerCell = reqObj["exposure_time"] - img_width_per_cell = reqObj["img_width"] - wave = reqObj["wavelength"] - xbeam = getPvDesc("beamCenterX") * 0.075 - ybeam = getPvDesc("beamCenterY") * 0.075 - rasterDef = reqObj["rasterDef"] - stepsize = float(rasterDef["stepsize"]) - omega = float(rasterDef["omega"]) - rasterStartX = float(rasterDef["x"]) #these are real sample motor positions - rasterStartY = float(rasterDef["y"]) - rasterStartZ = float(rasterDef["z"]) - omegaRad = math.radians(omega) - rowCount = len(rasterDef["rowDefs"]) - rasterRowResultsList = [{} for i in range(0,rowCount)] - processedRasterRowCount = 0 - rasterEncoderMap = {} - totalImages = 0 -#get the center of the raster, in screen view, mm, relative to center - rows = rasterDef["rowDefs"] - numrows = len(rows) - rasterCenterScreenX = (rows[0]["start"]["x"]+rows[0]["end"]["x"])/2.0 - rasterCenterScreenY = ((rows[-1]["start"]["y"]+rows[0]["start"]["y"])/2.0)+(stepsize/2.0) - xRelativeMove = rasterCenterScreenX - yzRelativeMove = -(rasterCenterScreenY*math.sin(omegaRad)) - yyRelativeMove = -(rasterCenterScreenY*math.cos(omegaRad)) - - xMotAbsoluteMove = rasterStartX+xRelativeMove #note we convert relative to absolute moves, using the raster center that was saved in x,y,z - yMotAbsoluteMove = rasterStartY+yyRelativeMove - zMotAbsoluteMove = rasterStartZ+yzRelativeMove - - - beamline_lib.mvaDescriptor("sampleX",xMotAbsoluteMove,"sampleY",yMotAbsoluteMove,"sampleZ",zMotAbsoluteMove) - - #raster centered, now zero motors - beamline_lib.mvaDescriptor("fineX",0,"fineY",0,"fineZ",0) - for i in range(len(rasterDef["rowDefs"])): - numsteps = int(rasterDef["rowDefs"][i]["numsteps"]) - totalImages = totalImages+numsteps - rasterFilePrefix = dataFilePrefix + "_Raster" - - det_lib.detector_set_num_triggers(totalImages) - det_lib.detector_set_trigger_mode(3) - det_lib.detector_setImagesPerFile(numsteps) - daq_lib.detectorArm(omega,img_width_per_cell,totalImages,exptimePerCell,rasterFilePrefix,data_directory_name,file_number_start) #this waits - - zebraVecDaqSetup(omega,img_width_per_cell,exptimePerCell,totalImages,rasterFilePrefix,data_directory_name,file_number_start) - procFlag = int(getBlConfig("rasterProcessFlag")) - generateRasterCoords4Traj(rasterRequest) - total_exposure_time = exptimePerCell*totalImages - - setPvDesc("zebraPulseMax",totalImages) - vectorSync() - setPvDesc("vectorStartOmega",omega) - setPvDesc("vectorEndOmega",(img_width_per_cell*totalImages)+omega) - setPvDesc("vectorframeExptime",exptimePerCell*1000.0) - setPvDesc("vectorNumFrames",totalImages) - rasterFilePrefix = dataFilePrefix + "_Raster_" + str(i) - Gen_Commands.go_all() - setPvDesc("vectorGo",1) - vectorActiveWait() - vectorWait() - zebraWait() - #delete these - time.sleep(2.0) - det_lib.detector_stop_acquire() - det_lib.detector_wait() - beamline_lib.mvaDescriptor("fineX",0,"fineY",0,"fineZ",0) - if (daq_utils.beamline == "amxz"): - setPvDesc("zebraReset",1) - - if (procFlag): - if (daq_utils.beamline == "amx"): - rasterRowEncoderVals = {"x":getPvDesc("zebraEncX"),"y":getPvDesc("zebraEncY"),"z":getPvDesc("zebraEncZ"),"omega":getPvDesc("zebraEncOmega")} - for j in range (0,numsteps): - dataFileName = "%s_%06d.cbf" % (reqObj["directory"]+"/cbf/"+reqObj["file_prefix"]+"_Raster_"+str(i),(i*numsteps)+j+1) - imIndexStr = str((i*numsteps)+j+1) - rasterEncoderMap[dataFileName[:-4]] = {"x":rasterRowEncoderVals["x"][j],"y":rasterRowEncoderVals["y"][j],"z":rasterRowEncoderVals["z"][j],"omega":rasterRowEncoderVals["omega"][j]} - seqNum = int(det_lib.detector_get_seqnum()) - for i in range(len(rasterDef["rowDefs"])): - _thread.start_new_thread(runDialsThread,(rasterRequest["uid"], data_directory_name,filePrefix+"_Raster",i,numsteps,seqNum)) - else: - rasterRequestID = rasterRequest["uid"] - db_lib.updateRequest(rasterRequest) - db_lib.updatePriority(rasterRequestID,-1) - if (lastOnSample()): - gov_lib.setGovRobot(gov_robot, 'SA') - return 1 - - rasterTimeout = 600 - timerCount = 0 - while (1): - timerCount +=1 - if (timerCount>rasterTimeout): - break - time.sleep(1) - logger.info('rastering row processed: %s' % processedRasterRowCount) - if (processedRasterRowCount == rowCount): - break - if (daq_utils.beamline == "amx"): - rasterResult = generateGridMap(rasterRequest,rasterEncoderMap) #I think rasterRequest is entire request, of raster type - else: - rasterResult = generateGridMap(rasterRequest) - rasterRequest["request_obj"]["rasterDef"]["status"] = 2 - protocol = reqObj["protocol"] - logger.info("protocol = " + protocol) - if (protocol == CollectionProtocols.MULTI_COL or - parentReqProtocol == CollectionProtocols.MULTI_COL_Q): - if (parentReqProtocol == CollectionProtocols.MULTI_COL_Q): - multiColThreshold = parentReqObj["diffCutoff"] - else: - multiColThreshold = reqObj["diffCutoff"] - gotoMaxRaster(rasterResult,multiColThreshold=multiColThreshold) - rasterRequestID = rasterRequest["uid"] - db_lib.updateRequest(rasterRequest) - - db_lib.updatePriority(rasterRequestID,-1) - daq_lib.set_field("xrecRasterFlag",rasterRequest["uid"]) - if (lastOnSample()): - gov_lib.setGovRobot(gov_robot, 'SA') - return 1 - - - -def snakeRasterFine(rasterReqID,grain=""): #12/19 - This is for the PI scanner. It was challenging to write. It was working the last time the scanner was on. - global dialsResultDict,rasterRowResultsList,processedRasterRowCount - - gov_status = gov_lib.setGovRobot(gov_robot, 'DA') - if not gov_status.success: - return - - rasterRequest = db_lib.getRequestByID(rasterReqID) - reqObj = rasterRequest["request_obj"] - rasterDef = reqObj["rasterDef"] - stepsize = float(rasterDef["stepsize"]) - data_directory_name = str(reqObj["directory"]) - filePrefix = str(reqObj["file_prefix"]) - file_number_start = reqObj["file_number_start"] - dataFilePrefix = reqObj["directory"]+"/"+reqObj["file_prefix"] - wave = reqObj["wavelength"] - xbeam = getPvDesc("beamCenterX") - ybeam = getPvDesc("beamCenterY") - processedRasterRowCount = 0 - totalImages = 0 -#get the center of the raster, in screen view, mm, relative to center - rows = rasterDef["rowDefs"] - numrows = len(rows) - origRasterCenterScreenX = (rows[0]["start"]["x"]+rows[0]["end"]["x"])/2.0 - origRasterCenterScreenY = ((rows[-1]["start"]["y"]+rows[0]["start"]["y"])/2.0)+(stepsize/2.0) - beamline_lib.mvaDescriptor("fineX",0,"fineY",0,"fineZ",0) - exptimePerCell = reqObj["exposure_time"] - img_width_per_cell = reqObj["img_width"] - omega = float(rasterDef["omega"]) - rasterStartX = float(rasterDef["x"]) - rasterStartY = float(rasterDef["y"]) - rasterStartZ = float(rasterDef["z"]) - omegaRad = math.radians(omega) - firstRow = rasterDef["rowDefs"][0] - lastRow= rasterDef["rowDefs"][-1] - sx1 = firstRow["start"]["x"] #startX - sy1 = firstRow["start"]["y"] - ex1 = lastRow["end"]["x"] #endX - ey1 = lastRow["end"]["y"] - rasterLenX = ex1-sx1 - rasterLenY = ey1-sy1 - omegaLimit = 40.0 - xLimit = 180.0 - yLimit = 120.0 - if (rasterLenXrasterTimeout): - break - time.sleep(1) - logger.info(processedRasterRowCount) - if (processedRasterRowCount == numberOfSubrasters): - break - rasterResult = generateGridMapFine(rasterRequest,rowsOfSubrasters=rowsOfSubrasters,columnsOfSubrasters=columnsOfSubrasters,rowsPerSubraster=rowsPerSubraster,cellsPerSubrasterRow=subrasterColumns) - - rasterRequest["request_obj"]["rasterDef"]["status"] = 2 - rasterRequestID = rasterRequest["uid"] - db_lib.updateRequest(rasterRequest) #so that it will fill heatmap? - db_lib.updatePriority(rasterRequestID,-1) - daq_lib.set_field("xrecRasterFlag",rasterRequest["uid"]) - if (lastOnSample()): - gov_lib.setGovRobot(gov_robot, 'SA') - return 1 - - - -def snakeRasterNormal(rasterReqID,grain=""): - global rasterRowResultsList,processedRasterRowCount - - if (daq_utils.beamline == "fmx"): - setPvDesc("sampleProtect",0) - setPvDesc("vectorGo", 0) #set to 0 to allow easier camonitoring vectorGo - gov_lib.setGovRobot(gov_robot, "DA") - rasterRequest = db_lib.getRequestByID(rasterReqID) - reqObj = rasterRequest["request_obj"] - parentReqID = reqObj["parentReqID"] - parentReqProtocol = "" - - data_directory_name, filePrefix, file_number_start, dataFilePrefix, exptimePerCell, img_width_per_cell, wave, detDist, rasterDef, stepsize, omega, rasterStartX, rasterStartY, rasterStartZ, omegaRad, rowCount, numsteps, totalImages = params_from_raster_req_id(rasterReqID) - - rasterRowResultsList = [{} for i in range(0,rowCount)] - processedRasterRowCount = 0 - rasterEncoderMap = {} - - # a couple of items we can get independent of rasterReqID - xbeam = getPvDesc("beamCenterX") - ybeam = getPvDesc("beamCenterY") - - if (parentReqID != -1): - parentRequest = db_lib.getRequestByID(parentReqID) - parentReqObj = parentRequest["request_obj"] - parentReqProtocol = parentReqObj["protocol"] - detDist = parentReqObj["detDist"] - - # now we do stuff with that info - rasterFilePrefix = dataFilePrefix + "_Raster" - total_exposure_time = exptimePerCell*totalImages - # TODO decide - put everything below here into a function? how should the processing be handled? - det_lib.detector_set_num_triggers(totalImages) - det_lib.detector_set_trigger_mode(3) - det_lib.detector_setImagesPerFile(numsteps) - daq_lib.detectorArm(omega,img_width_per_cell,totalImages,exptimePerCell,rasterFilePrefix,data_directory_name,file_number_start) #this waits - try: - gov_status = gov_lib.setGovRobot(gov_robot, 'DA') - if not gov_status.success: - if (daq_utils.beamline == "fmx"): - setPvDesc("sampleProtect",1) - raise Exception('not in DA state') - zebraVecDaqSetup(omega,img_width_per_cell,exptimePerCell,numsteps,rasterFilePrefix,data_directory_name,file_number_start) #TODO set up a bunch of stuff? - procFlag = int(getBlConfig("rasterProcessFlag")) - - spotFindThreadList = [] - for i in range(len(rasterDef["rowDefs"])): - if (daq_lib.abort_flag == 1): # TODO better to do this in a catch/finally block? - gov_lib.setGovRobot(gov_robot, 'SA') - if (daq_utils.beamline == "fmx"): - setPvDesc("sampleProtect",1) - raise Exception('raster aborted') - # TODO surprisingly, no direct move to start position - numsteps = int(rasterDef["rowDefs"][i]["numsteps"]) - startX = rasterDef["rowDefs"][i]["start"]["x"] - endX = rasterDef["rowDefs"][i]["end"]["x"] - startY = rasterDef["rowDefs"][i]["start"]["y"] - endY = rasterDef["rowDefs"][i]["end"]["y"] - deltaX = abs(endX-startX) - deltaY = abs(endY-startY) - if ((deltaX != 0) and (deltaX>deltaY or not getBlConfig("vertRasterOn"))): #horizontal raster - startY = startY + (stepsize/2.0) - endY = startY - else: #vertical raster - startX = startX + (stepsize/2.0) - endX = startX - - # TODO move all of this calculation stuff out - xRelativeMove = startX - - yzRelativeMove = startY*math.sin(omegaRad) - yyRelativeMove = startY*math.cos(omegaRad) - logger.info("x rel move = " + str(xRelativeMove)) - xMotAbsoluteMove = rasterStartX+xRelativeMove #note we convert relative to absolute moves, using the raster center that was saved in x,y,z - yMotAbsoluteMove = rasterStartY-yyRelativeMove - zMotAbsoluteMove = rasterStartZ-yzRelativeMove - xRelativeMove = endX-startX - yRelativeMove = endY-startY - - yyRelativeMove = yRelativeMove*math.cos(omegaRad) - yzRelativeMove = yRelativeMove*math.sin(omegaRad) - - xEnd = xMotAbsoluteMove + xRelativeMove - yEnd = yMotAbsoluteMove - yyRelativeMove - zEnd = zMotAbsoluteMove - yzRelativeMove - - if (i%2 != 0): #this is to scan opposite direction for snaking - xEndSave = xEnd - yEndSave = yEnd - zEndSave = zEnd - xEnd = xMotAbsoluteMove - yEnd = yMotAbsoluteMove - zEnd = zMotAbsoluteMove - xMotAbsoluteMove = xEndSave - yMotAbsoluteMove = yEndSave - zMotAbsoluteMove = zEndSave - zebraVecBluesky() # just do the vector scan part - xMotAbsoluteMove, xEnd, yMotAbsoluteMove, yEnd, zMotAbsoluteMove, zEnd = raster_positions(rasterdef[i], stepsize, omegaRad, rasterStartX, rasterStartY, rasterStartZ, i) - setPvDesc("zebraPulseMax",numsteps) #moved this - setPvDesc("vectorStartOmega",omega) - if (img_width_per_cell != 0): - setPvDesc("vectorEndOmega",(img_width_per_cell*numsteps)+omega) - else: - setPvDesc("vectorEndOmega",omega) - setPvDesc("vectorStartX",xMotAbsoluteMove) - setPvDesc("vectorStartY",yMotAbsoluteMove) - setPvDesc("vectorStartZ",zMotAbsoluteMove) - setPvDesc("vectorEndX",xEnd) - setPvDesc("vectorEndY",yEnd) - setPvDesc("vectorEndZ",zEnd) - setPvDesc("vectorframeExptime",exptimePerCell*1000.0) - setPvDesc("vectorNumFrames",numsteps) - rasterFilePrefix = dataFilePrefix + "_Raster_" + str(i) - scanWidth = float(numsteps)*img_width_per_cell - logger.info('raster done setting up') - vectorWaitForGo(source="snakeRasterNormal") - vectorWait() - zebraWait() - zebraWaitDownload(numsteps) - logger.info('done raster') - - # processing - if (procFlag): - if (daq_utils.detector_id == "EIGER-16"): - seqNum = int(det_lib.detector_get_seqnum()) - else: - seqNum = -1 - logger.info('beginning raster processing with dozor spot_level at %s' - % getBlConfig(RASTER_DOZOR_SPOT_LEVEL)) - spotFindThread = Thread(target=runDozorThread,args=(data_directory_name, #TODO this can't move outside of the thread checking block - ''.join([filePrefix,"_Raster"]), - i, - numsteps, - seqNum, - reqObj, - rasterReqID)) - spotFindThread.start() - spotFindThreadList.append(spotFindThread) - send_kafka_message(f'{daq_utils.beamline}.lsdc.documents', event='event', uuid=rasterReqID, protocol=CollectionProtocols.RASTER, row=i, proc_flag=procFlag) - - - """governor transitions: - initiate transitions here allows for GUI sample/heat map image to update - after moving to known position""" - logger.debug(f'lastOnSample(): {lastOnSample()} autoRasterFlag: {autoRasterFlag}') - if (lastOnSample() and not autoRasterFlag): - govStatus = gov_lib.setGovRobot(gov_robot, 'SA', wait=False) # TODO standardize naming of govStatus and gov_status objects - targetGovState = 'SA' - else: - govStatus = gov_lib.setGovRobot(gov_robot, 'DI') - targetGovState = 'DI' - - # priorities: - # 1. make heat map visible to users correctly aligned with sample - # 2. take snapshot for ISPyB with heat map and sample visible (governor moved to - # a position with backlight in) and aligned - - #data acquisition is finished, now processing and sample positioning - if not procFlag: - #must go to known position to account for windup dist. - logger.info("moving to raster start") - gonio.put(rasterStartX, rasterStartY, rasterStartZ, omega) - logger.info("done moving to raster start") - - if (procFlag): - if daq_lib.abort_flag != 1: - [thread.join(timeout=120) for thread in spotFindThreadList] - else: - logger.info("raster aborted, do not wait for spotfind threads") - logger.info(str(processedRasterRowCount) + "/" + str(rowCount)) - rasterResult = generateGridMap(rasterRequest) - - logger.info(f'protocol = {reqObj["protocol"]}') - if (reqObj["protocol"] == CollectionProtocols.MULTI_COL or - parentReqProtocol == CollectionProtocols.MULTI_COL_Q): - if (parentReqProtocol == CollectionProtocols.MULTI_COL_Q): - multiColThreshold = parentReqObj["diffCutoff"] - else: - multiColThreshold = reqObj["diffCutoff"] - gotoMaxRaster(rasterResult,multiColThreshold=multiColThreshold) - else: - try: - # go to start omega for faster heat map display - gotoMaxRaster(rasterResult,omega=omega) - except ValueError: - #must go to known position to account for windup dist. - logger.info("moving to raster start") - beamline_lib.mvaDescriptor("sampleX",rasterStartX, - "sampleY",rasterStartY, - "sampleZ",rasterStartZ, - "omega",omega) - logger.info("done moving to raster start") - - """change request status so that GUI only fills heat map when - xrecRasterFlag PV is set""" - rasterRequest["request_obj"]["rasterDef"]["status"] = ( - RasterStatus.READY_FOR_FILL.value - ) - db_lib.updateRequest(rasterRequest) - daq_lib.set_field("xrecRasterFlag",rasterRequest["uid"]) - logger.info(f'setting xrecRasterFlag to: {rasterRequest["uid"]}') - except Exception as e: - logger.error(f'Exception while rastering: {e}') - return - finally: - #use this required pause to allow GUI time to fill map and for db update - logger.info('stopping detector') - det_lib.detector_stop_acquire() - det_lib.detector_wait() - logger.info('detector finished waiting') - - """change request status so that GUI only takes a snapshot of - sample plus heat map for ispyb when xrecRasterFlag PV is set""" - rasterRequestID = rasterRequest["uid"] - rasterRequest["request_obj"]["rasterDef"]["status"] = ( - RasterStatus.READY_FOR_SNAPSHOT.value - ) - db_lib.updateRequest(rasterRequest) - db_lib.updatePriority(rasterRequestID,-1) - - #ensure gov transitions have completed successfully - timeout = 20 - gov_lib.waitGov(govStatus, timeout) - if not(govStatus.success) or not(govs.gov.robot.state == targetGovState): - logger.error(f"gov status check failed, did not achieve {targetGovState}") - - if (procFlag): - """if sleep too short then black ispyb image, timing affected by speed - of governor transition. Sleep constraint can be relaxed with gov - transitions and concomitant GUI moved to an earlier stage.""" - if (rasterRequest["request_obj"]["rasterDef"]["numCells"] - > getBlConfig(RASTER_NUM_CELLS_DELAY_THRESHOLD)): - #larger rasters can delay GUI scene update - time.sleep(getBlConfig(RASTER_LONG_SNAPSHOT_DELAY)) - else: - time.sleep(getBlConfig(RASTER_SHORT_SNAPSHOT_DELAY)) - daq_lib.set_field("xrecRasterFlag",rasterRequest["uid"]) - time.sleep(getBlConfig(RASTER_POST_SNAPSHOT_DELAY)) - if (daq_utils.beamline == "fmx"): - setPvDesc("sampleProtect",1) - return 1 + finalize_plan = finalize_wrapper(snakeRasterBluesky(rasterReqID,grain), bps.mv(raster_flyer.detector.cam.acquire, 0)) + yield from finalize_plan def raster_positions(currentRow, stepsize, omegaRad, rasterStartX, rasterStartY, rasterStartZ, index): numsteps = int(currentRow["numsteps"]) @@ -3126,7 +2522,7 @@ def vectorZebraScanNormal(vecRequest): det_distance_m = beamline_lib.motorPosFromDescriptor("detectorDist") # TODO replace this area with gatherStandardVectorParams det_distance_m /= 1000 # on all beamlines, detectorDist is in mm so convert distance to m - if daq_utils.beamline in ("nyx", "fmx"): + if daq_utils.beamline in ("fmx",): transmission = getPvDesc("RI_Atten_SP") else: transmission = getPvDesc("transmissionRBV") @@ -3413,7 +2809,7 @@ def dna_execute_collection3(dna_startIgnore,dna_range,dna_number_of_images,dna_e return 1 def setTrans(transmission): #where transmission = 0.0-1.0 - if (daq_utils.beamline in ["fmx", "nyx"]): + if (daq_utils.beamline in ["fmx",]): if (getBlConfig("attenType") == "RI"): setPvDesc("RIattenEnergySP",beamline_lib.motorPosFromDescriptor("energy")) setPvDesc("RI_Atten_SP",transmission) @@ -3427,9 +2823,8 @@ def setTrans(transmission): #where transmission = 0.0-1.0 setPvDesc("transmissionSet",transmission) setPvDesc("transmissionGo",1) time.sleep(0.5) - if daq_utils.beamline != "nyx": # transmissionDone not available on NYX - while (not getPvDesc("transmissionDone")): - time.sleep(0.1) + while (not getPvDesc("transmissionDone")): + time.sleep(0.1) @@ -3573,12 +2968,7 @@ def loop_center_xrec(): pic_prefix = "findloop" output_file = 'xrec_result.txt' clean_up_files(pic_prefix, output_file) - if daq_utils.beamline=='nyx': - print('post clean') - xrec_no_zebra(0) - print('post no zebra') - else: - zebraCamDaq(0,360,40,.4,pic_prefix,getBlConfig("visitDirectory"),0) + zebraCamDaq(0,360,40,.4,pic_prefix,getBlConfig("visitDirectory"),0) comm_s = f'xrec {os.environ["CONFIGDIR"]}/xrec_360_40Fast.txt {output_file}' logger.info(comm_s) try: @@ -3718,7 +3108,7 @@ def gatherStandardVectorParams(): y_beam = getPvDesc("beamCenterY") wavelength = daq_utils.energy2wave(beamline_lib.motorPosFromDescriptor("energy"), digits=6) det_distance_m = beamline_lib.motorPosFromDescriptor("detectorDist") / 1000 - if daq_utils.beamline in ("nyx", "fmx"): + if daq_utils.beamline in ("fmx",): transmission = getPvDesc("RI_Atten_SP") else: transmission = getPvDesc("transmissionRBV") @@ -3733,341 +3123,6 @@ def standard_zebra_plan(flyer,angle_start,num_images,scanWidth,imgWidth,exposure final_plan = finalize_wrapper(zebraDaqBluesky(flyer, angle_start, num_images, scanWidth, imgWidth, exposurePeriodPerImage, filePrefix, data_directory_name, file_number_start, vector_params, data_path), bps.mv(flyer.detector.cam.acquire, 0)) yield from final_plan -def standard_plan_wrapped(currentRequest): - yield from finalize_wrapper(standardDaq(currentRequest), clean_up_collection()) - -def vector_plan_wrapped(currentRequest): - yield from finalize_wrapper(vectorDaq(currentRequest), clean_up_collection()) - -def raster_plan_wrapped(rasterReqID): - yield from finalize_wrapper(rasterDaq(rasterReqID), clean_up_collection()) - #time.sleep(15) - #rasterRequest = db_lib.getRequestByID(rasterReqID) - #rasterResult = generateGridMap(rasterRequest) - #rasterRequest["request_obj"]["rasterDef"]["status"] = ( - # RasterStatus.READY_FOR_SNAPSHOT.value - #) - #db_lib.updateRequest(rasterRequest) - #db_lib.updatePriority(rasterReqID,-1) - #daq_lib.set_field("xrecRasterFlag",rasterRequest["uid"]) - - - -def standardDaq(currentRequest): - # collect all parameters - # perform preparatory movements - # arm the detector - # perform governor and phase transitions - # update flyer parameters - # fly - x_beam = getPvDesc("beamCenterX") - y_beam = getPvDesc("beamCenterY") - wavelength = daq_utils.energy2wave(beamline_lib.motorPosFromDescriptor("energy"), digits=6) - det_distance_m = beamline_lib.motorPosFromDescriptor("detectorDist") / 1000 - reqObj = currentRequest["request_obj"] - file_prefix = str(reqObj["file_prefix"]) - data_directory_name = str(reqObj["directory"]) - file_number_start = reqObj["file_number_start"] - sweep_start_angle = reqObj["sweep_start"] - sweep_end_angle = reqObj["sweep_end"] - file_prefix = str(reqObj["file_prefix"]) - data_directory_name = str(reqObj["directory"]) - file_number_start = reqObj["file_number_start"] - img_width = reqObj["img_width"] - exposure_per_image = reqObj["exposure_time"] - total_num_images = int(round(((sweep_end_angle - sweep_start_angle) / img_width), 4)) - total_exposure_time = exposure_per_image * total_num_images - scan_range = float(total_num_images)*img_width - angle_start = sweep_start_angle - wavelength = daq_utils.energy2wave(beamline_lib.motorPosFromDescriptor("energy"), digits=6) - - yield from bps.mv(beamstop.distance_preset, 20.0) - md2.save_center() - if det_move_done.get() != 1: - def det_move_done_callback(value, old_value, **kwargs): - return (old_value!=1 and value ==1) - det_move_status = SubscriptionStatus(det_move_done, det_move_done_callback, run=False) - det_move_status.wait() - if flyer.detector.cam.armed.get() == 1: - daq_lib.gui_message('Detector is in armed state from previous collection! Stopping detector, but the user ' - 'should check the most recent collection to determine if it was successful. Cancelling' - 'this collection, retry when ready.') - logger.warning("Detector was in the armed state prior to this attempted collection.") - return 0 - start_time = time.time() - logger.info(f"Configuring detector for standard collection with file_prefix {file_prefix} and data_directory_name {data_directory_name}") - flyer.configure_detector(file_prefix, data_directory_name) - logger.info(f"Arming detector for standard collection with angle_start {angle_start}, img_width {img_width}, total_num_images {total_num_images}, exposure_per_image {exposure_per_image}, file_prefix {file_prefix}, data_directory_name {data_directory_name}, file_number_start {file_number_start}, x_beam {x_beam}, y_beam {y_beam}, wavelength {wavelength}, det_distance_m {det_distance_m}") - flyer.detector_arm(angle_start, img_width, total_num_images, exposure_per_image, - file_prefix, data_directory_name, file_number_start, x_beam, y_beam, - wavelength, det_distance_m) - def armed_callback(value, old_value, **kwargs): - return (old_value == 0 and value == 1) - arm_status = SubscriptionStatus(flyer.detector.cam.armed, armed_callback, run=False) - flyer.detector.cam.acquire.put(1) - govStatus = gov_lib.setGovRobot(gov_robot, "DA") - try: - arm_status.wait(timeout=20) - govStatus.wait(timeout=20) - except WaitTimeoutError: - logger.error("Timeout during arming or governor move, aborting collection") - return - logger.info(f"Governor move to DA and synchronous arming took {time.time()-start_time} seconds.") - if govStatus.exception(): - logger.error(f"Problem during start-of-collection governor move, aborting! exception: {govStatus.exception()}") - return - flyer.detector.stage() - start_time = time.time() - yield from bps.mv(md2.phase, 2) # TODO: Enum for MD2 phases and states - try: - md2.ready_status().wait(timeout=10) - except WaitTimeoutError: - logger.error("timeout: md2 failed to enter ready state, aborting collection") - return - logger.info(f"MD2 phase transition to 2-DataCollection took {time.time()-start_time} seconds.") - flyer.update_parameters(total_num_images, angle_start, scan_range, total_exposure_time) - logger.info(f"flyer handoff") - yield from bp.fly([flyer]) - logger.info(f"fly complete") - -def vectorDaq(currentRequest): - # collect all parameters - # perform preparatory movements - # arm the detector - # perform governor and phase transitions - # update flyer parameters - # fly - x_beam = getPvDesc("beamCenterX") - y_beam = getPvDesc("beamCenterY") - wavelength = daq_utils.energy2wave(beamline_lib.motorPosFromDescriptor("energy"), digits=6) - det_distance_m = beamline_lib.motorPosFromDescriptor("detectorDist") / 1000 - reqObj = currentRequest["request_obj"] - file_prefix = str(reqObj["file_prefix"]) - data_directory_name = str(reqObj["directory"]) - file_number_start = reqObj["file_number_start"] - sweep_start_angle = reqObj["sweep_start"] - sweep_end_angle = reqObj["sweep_end"] - file_prefix = str(reqObj["file_prefix"]) - data_directory_name = str(reqObj["directory"]) - file_number_start = reqObj["file_number_start"] - img_width = reqObj["img_width"] - exposure_per_image = reqObj["exposure_time"] - total_num_images = int(round(((sweep_end_angle - sweep_start_angle) / img_width), 4)) - total_exposure_time = reqObj["exposure_time"] * total_num_images - scan_range = float(total_num_images)*img_width - angle_start = sweep_start_angle - wavelength = daq_utils.energy2wave(beamline_lib.motorPosFromDescriptor("energy"), digits=6) - - vector_params = reqObj["vectorParams"] - start_y=vector_params["vecStart"]["y"] - start_z=vector_params["vecStart"]["z"] - start_cx=vector_params["vecStart"]["finex"] - start_cy=vector_params["vecStart"]["finey"] - stop_cx=vector_params["vecEnd"]["finex"] - stop_cy=vector_params["vecEnd"]["finey"] - stop_y=vector_params["vecEnd"]["y"] - stop_z=vector_params["vecEnd"]["z"] - if det_move_done.get() != 1: - def det_move_done_callback(value, old_value, **kwargs): - return (old_value!=1 and value ==1) - det_move_status = SubscriptionStatus(det_move_done, det_move_done_callback, run=False) - det_move_status.wait() - - md2.save_center() - yield from bps.mv(beamstop.distance_preset, 20.0) - - if vector_flyer.detector.cam.armed.get() == 1: - daq_lib.gui_message('Detector is in armed state from previous collection! Stopping detector, but the user ' - 'should check the most recent collection to determine if it was successful. Cancelling' - 'this collection, retry when ready.') - logger.warning("Detector was in the armed state prior to this attempted collection.") - return 0 - start_time = time.time() - vector_flyer.configure_detector(file_prefix, data_directory_name) - vector_flyer.detector_arm(angle_start, img_width, total_num_images, exposure_per_image, - file_prefix, data_directory_name, file_number_start, x_beam, y_beam, - wavelength, det_distance_m) - def armed_callback(value, old_value, **kwargs): - return (old_value == 0 and value == 1) - arm_status = SubscriptionStatus(vector_flyer.detector.cam.armed, armed_callback, run=False) - vector_flyer.detector.cam.acquire.put(1) - govStatus = gov_lib.setGovRobot(gov_robot, "DA") - try: - arm_status.wait(timeout=10) - govStatus.wait(timeout=20) - except WaitTimeoutError: - logger.error("Timeout reached during arming or governor move, aborting") - return - logger.info(f"Governor move to DA and synchronous arming took {time.time()-start_time} seconds.") - if govStatus.exception(): - logger.error(f"Problem during start-of-collection governor move, aborting! exception: {govStatus.exception()}") - return - flyer.detector.stage() - start_time = time.time() - yield from bps.mv(md2.phase, 2) # TODO: Enum for MD2 phases and states - try: - md2.ready_status().wait(timeout=10) - except WaitTimeoutError: - logger.error("timeout: md2 failed to reach ready state, aborting") - return - logger.info(f"MD2 phase transition to 2-DataCollection took {time.time()-start_time} seconds.") - vector_flyer.update_parameters(angle_start, scan_range, total_exposure_time, start_y, start_z, stop_y, stop_z, start_cx, start_cy, stop_cx, stop_cy) - yield from bp.fly([vector_flyer]) - -def rasterDaq(rasterReqID): - global rasterRowResultsList,processedRasterRowCount - data_directory_name, file_prefix, file_number_start, dataFilePrefix, exposure_per_image, img_width_per_cell, wavelength, detDist, rasterDef, stepsize, start_omega, start_x, start_y, start_z, omegaRad, number_of_lines, numsteps, total_num_images, rows = params_from_raster_req_id(rasterReqID) - rasterRowResultsList = [{} for i in range(0,number_of_lines)] - processedRasterRowCount = 0 - rasterRequest = db_lib.getRequestByID(rasterReqID) - reqObj = rasterRequest["request_obj"] - parentReqID = reqObj["parentReqID"] - - xbeam = getPvDesc("beamCenterX") - ybeam = getPvDesc("beamCenterY") - if (parentReqID != -1): - parentRequest = db_lib.getRequestByID(parentReqID) - parentReqObj = parentRequest["request_obj"] - detDist = parentReqObj["detDist"] - - rasterFilePrefix = dataFilePrefix # + "_Raster" - - logger.info(f"prepping raster with: {rasterFilePrefix}, {data_directory_name}, {file_number_start}, {dataFilePrefix}, {exposure_per_image}, {img_width_per_cell}, {wavelength}, {detDist}, {rasterDef}, {stepsize}, {start_omega}, {start_x}, {start_y}, {start_z}, {omegaRad}, {number_of_lines}, {numsteps}, {total_num_images}, {rows}") - #logger.info(f"req_obj: {reqObj}") - i = 0 - xMotAbsoluteMove, xEnd, yMotAbsoluteMove, yEnd, zMotAbsoluteMove, zEnd = raster_positions(rows[i], stepsize, (start_omega*0), start_x, start_y, start_z, i) - stepsize /= 1000 # MD2 wants mm - logger.info(f"move calculations: {xMotAbsoluteMove}, {xEnd}, {yMotAbsoluteMove}, {yEnd}, {zMotAbsoluteMove}, {zEnd}") - line_range = stepsize * numsteps - total_uturn_range = stepsize * number_of_lines - start_y = start_y - (xEnd / 1000) - start_z = start_z - (yMotAbsoluteMove / 1000) - #start_z = start_z - (xEnd / 1000) - start_cx = md2.cx.val()# + (xEnd/1000) - start_cy = md2.cy.val() - frames_per_line = numsteps - total_exposure_time = exposure_per_image * frames_per_line - invert_direction = False - use_centring_table = True - use_fast_mesh_scans = True - omega_range = 0 - logger.info(f"TASK INFO: {md2.task_info.get()}") - logger.info(f"TASK INFO[6]: {md2.task_info.get()[6]=='1'}") - logger.info(f"TASK OUTPUT: {md2.task_output}") - logger.info(f"omega_range = {omegaRad}") - logger.info(f"line_range = {line_range}") - logger.info(f"total_uturn_range = {total_uturn_range}") - logger.info(f"start_omega = {start_omega}") - logger.info(f"start_y = {start_y}") - logger.info(f"current yzcxcy: {md2.y.get()}, {md2.z.get()}, {md2.cx.get()}, {md2.cy.get()}") - logger.info(f"start_z = {start_z}") - logger.info(f"start_cx = {start_cx}") - logger.info(f"start_cy = {start_cy}") - logger.info(f"number_of_lines = {number_of_lines}") - logger.info(f"frames_per_line = {frames_per_line}") - logger.info(f"total_exposure_time = {total_exposure_time}") - logger.info(f"invert_direction = {invert_direction}") - logger.info(f"use_centring_table = {use_centring_table}") - logger.info(f"use_fast_mesh_scans = {use_fast_mesh_scans}") - if det_move_done.get() != 1: - def det_move_done_callback(value, old_value, **kwargs): - return (old_value!=1 and value ==1) - det_move_status = SubscriptionStatus(det_move_done, det_move_done_callback, run=False) - det_move_status.wait() - - md2.save_center() - yield from bps.mv(beamstop.distance_preset, 20.0) - - if raster_flyer.detector.cam.armed.get() == 1: - daq_lib.gui_message('Detector is in armed state from previous collection! Stopping detector, but the user ' - 'should check the most recent collection to determine if it was successful. Cancelling' - 'this collection, retry when ready.') - logger.warning("Detector was in the armed state prior to this attempted collection.") - return 0 - start_time = time.time() - raster_flyer.configure_detector(rasterFilePrefix, data_directory_name) - raster_flyer.detector_arm(start_omega, img_width_per_cell, total_num_images, exposure_per_image, - file_prefix, data_directory_name, file_number_start, xbeam, ybeam, - wavelength, detDist) - def armed_callback(value, old_value, **kwargs): - return (old_value == 0 and value == 1) - arm_status = SubscriptionStatus(raster_flyer.detector.cam.armed, armed_callback, run=False) - raster_flyer.detector.cam.acquire.put(1) - govStatus = gov_lib.setGovRobot(gov_robot, "DA") - try: - arm_status.wait(timeout=10) - govStatus.wait(timeout=20) - except WaitTimeoutError: - logger.error("arming or governor status failure") - return - logger.info(f"Governor move to DA and synchronous arming took {time.time()-start_time} seconds.") - if govStatus.exception(): - logger.error(f"Problem during start-of-collection governor move, aborting! exception: {govStatus.exception()}") - return - flyer.detector.stage() - start_time = time.time() - yield from bps.mv(md2.phase, 2) # TODO: Enum for MD2 phases and states - try: - md2.ready_status().wait(timeout=10) - except: - logger.error("md2 failed to reach ready state, aborting collection") - return - logger.info(f"MD2 phase transition to 2-DataCollection took {time.time()-start_time} seconds.") - raster_flyer.update_parameters(omega_range, line_range, total_uturn_range, start_omega, start_y, start_z, start_cx, start_cy, number_of_lines, frames_per_line, total_exposure_time, invert_direction, use_centring_table, use_fast_mesh_scans) - yield from bp.fly([raster_flyer]) - spotFindThreadList = [] - row_index = 1 - logger.info(f"raster prefix {rasterFilePrefix}") - rasterFilePrefix = rasterFilePrefix.split("/")[-1] - logger.info(f"raster prefix {rasterFilePrefix}") - for i in range(0, number_of_lines): - time.sleep(1.0) - row_index = i - logger.info(f'spot finding for row {i}') - seqNum = raster_flyer.detector.cam.sequence_id.get() - spotFindThread = Thread(target=runDozorThread,args=(data_directory_name, #TODO this can't move outside of the thread checking block - rasterFilePrefix, - row_index, - numsteps, - seqNum, - reqObj, - rasterReqID)) - spotFindThread.start() - spotFindThreadList.append(spotFindThread) - [thread.join(timeout=120) for thread in spotFindThreadList] - logger.info(str(processedRasterRowCount) + "/" + str(number_of_lines)) - rasterResult = generateGridMap(rasterRequest) - rasterRequestID = rasterRequest["uid"] - rasterRequest["request_obj"]["rasterDef"]["status"] = ( - RasterStatus.READY_FOR_SNAPSHOT.value - ) - db_lib.updateRequest(rasterRequest) - db_lib.updatePriority(rasterRequestID,-1) - if (rasterRequest["request_obj"]["rasterDef"]["numCells"] - > getBlConfig(RASTER_NUM_CELLS_DELAY_THRESHOLD)): - #larger rasters can delay GUI scene update - time.sleep(getBlConfig(RASTER_LONG_SNAPSHOT_DELAY)) - else: - time.sleep(getBlConfig(RASTER_SHORT_SNAPSHOT_DELAY)) - daq_lib.set_field("xrecRasterFlag",rasterRequest["uid"]) - - - - - -def clean_up_collection(): - # this is a plan that should will always be run after a collection is complete - start_time = time.time() - yield from bps.mv(flyer.detector.cam.acquire, 0) - flyer.detector.unstage() - if (lastOnSample()): - gov_status = gov_lib.setGovRobot(gov_robot, 'SA', wait=False) - gov_status.wait(timeout=30) - yield from bps.mv(md2.phase, 0) - md2.ready_status().wait(timeout= 20) - # trigger processing here - logger.info(f"clean_up took {time.time()-start_time} seconds.") - def zebraDaqBluesky(flyer, angle_start, num_images, scanWidth, imgWidth, exposurePeriodPerImage, filePrefix, data_directory_name, file_number_start, vector_params, data_path, scanEncoder=3, changeState=True): logger.info("in Zebra Daq Bluesky #1") @@ -4079,13 +3134,6 @@ def zebraDaqBluesky(flyer, angle_start, num_images, scanWidth, imgWidth, exposur x_vec_end=vector_params["vecEnd"]["x"] y_vec_end=vector_params["vecEnd"]["y"] z_vec_end=vector_params["vecEnd"]["z"] - if beamline == "nyx": - x_vec_start *= 1000 - y_vec_start *= 1000 - z_vec_start *= 1000 - x_vec_end *= 1000 - y_vec_end *= 1000 - z_vec_end *= 1000 try: detectorDeadTime=flyer.detector.cam.dead_time.get() @@ -4144,13 +3192,6 @@ def zebraDaqRasterBluesky(flyer, angle_start, num_images, scanWidth, imgWidth, e x_vec_end=vector["x"][1] y_vec_end=vector["y"][1] z_vec_end=vector["z"][1] - if beamline == "nyx": - x_vec_start *= 1000 - y_vec_start *= 1000 - z_vec_start *= 1000 - x_vec_end *= 1000 - y_vec_end *= 1000 - z_vec_end *= 1000 try: detectorDeadTime=flyer.detector.cam.dead_time.get() diff --git a/daq_main_common.py b/daq_main_common.py index dd459370..40a5df35 100755 --- a/daq_main_common.py +++ b/daq_main_common.py @@ -84,12 +84,10 @@ def setGovState(state): backoffDetector, enableMount, robotOn, - set_energy + set_energy, + anneal, ] -if daq_utils.beamline != "nyx": - functions = functions + [anneal] - whitelisted_functions: "Dict[str, Callable]" = { func.__name__: func for func in functions } diff --git a/daq_utils.py b/daq_utils.py index 526b46b3..602c0213 100644 --- a/daq_utils.py +++ b/daq_utils.py @@ -52,7 +52,7 @@ def setBlConfig(param, value, beamline=beamline): db_lib.setBeamlineConfigParam(beamline, param, value) def init_environment(): - global beamline,detector_id,mono_mot_code,has_beamline,has_xtalview,xtal_url,xtal_url_small,unitScaling,sampleCameraCount,xtalview_user,xtalview_pass,det_type,has_dna,beamstop_x_pvname,beamstop_y_pvname,camera_offset,det_radius,lowMagFOVx,lowMagFOVy,highMagFOVx,highMagFOVy,lowMagPixX,lowMagPixY,highMagPixX,highMagPixY,screenPixX,screenPixY,screenPixCenterX,screenPixCenterY,screenProtocol,screenPhist,screenPhiend,screenWidth,screenDist,screenExptime,screenWave,screenReso,gonioPvPrefix,searchParams,screenEnergy,detectorOffline,imgsrv_host,imgsrv_port,beamlineComm,primaryDewarName,lowMagCamURL,highMagZoomCamURL,lowMagZoomCamURL,highMagCamURL,owner,dewarPlateMap,mag1ViewAngle,mag2ViewAngle,mag3ViewAngle,mag4ViewAngle,exporter_enabled + global beamline,detector_id,mono_mot_code,has_beamline,has_xtalview,xtal_url,xtal_url_small,unitScaling,sampleCameraCount,xtalview_user,xtalview_pass,det_type,beamstop_x_pvname,beamstop_y_pvname,camera_offset,det_radius,lowMagFOVx,lowMagFOVy,highMagFOVx,highMagFOVy,lowMagPixX,lowMagPixY,highMagPixX,highMagPixY,screenPixX,screenPixY,screenPixCenterX,screenPixCenterY,screenProtocol,screenPhist,screenPhiend,screenWidth,screenDist,screenExptime,screenWave,screenReso,gonioPvPrefix,searchParams,screenEnergy,detectorOffline,imgsrv_host,imgsrv_port,beamlineComm,primaryDewarName,lowMagCamURL,highMagZoomCamURL,lowMagZoomCamURL,highMagCamURL,owner,dewarPlateMap,mag1ViewAngle,mag2ViewAngle,mag3ViewAngle,mag4ViewAngle owner = getpass.getuser() primaryDewarName = getBlConfig("primaryDewarName") @@ -72,10 +72,6 @@ def init_environment(): highMagPixY = float(getBlConfig("highMagPixY")) screenPixX = float(getBlConfig("screenPixX")) screenPixY = float(getBlConfig("screenPixY")) - if beamline == 'nyx': - exporter_enabled = bool(getBlConfig("exporterEnabled")) - else: - exporter_enabled = False try: unitScaling = float(getBlConfig("unitScaling")) diff --git a/gon_lib.py b/gon_lib.py index a42d4540..a4994b2b 100755 --- a/gon_lib.py +++ b/gon_lib.py @@ -4,17 +4,9 @@ from beamline_support import getPvValFromDescriptor as getPvDesc, setPvValFromDescriptor as setPvDesc import logging import daq_utils -if daq_utils.beamline == 'nyx': - from start_bs import back_light, back_light_range, md2 logger = logging.getLogger(__name__) BACK_LIGHT_STEP = 0.05 # percent of intensity range -def omegaMoveAbs(angle): - md2.omega.set(angle) - -def omegaMoveRel(angle): - md2.omega.set(md2.omega.get() + angle) - def backlightBrighter(): intensity = back_light.get() intensity += BACK_LIGHT_STEP * (back_light_range[1]-back_light_range[0]) diff --git a/gov_lib.py b/gov_lib.py index 09a7dba6..5f7a2915 100644 --- a/gov_lib.py +++ b/gov_lib.py @@ -49,11 +49,9 @@ def waitGovNoSleep(timeout=GOVERNOR_TIMEOUT): pass def toggleLowMagCameraSettings(stateCode): - - if daq_utils.beamline != "nyx": - if (stateCode == "DA"): - setPvDesc("lowMagGain", getBlConfig(LOW_MAG_GAIN_DA)) - setPvDesc("lowMagAcquireTime",getBlConfig(LOW_MAG_EXP_TIME_DA)) - else: - setPvDesc("lowMagGain", getBlConfig(LOW_MAG_GAIN)) - setPvDesc("lowMagAcquireTime",getBlConfig(LOW_MAG_EXP_TIME)) + if (stateCode == "DA"): + setPvDesc("lowMagGain", getBlConfig(LOW_MAG_GAIN_DA)) + setPvDesc("lowMagAcquireTime",getBlConfig(LOW_MAG_EXP_TIME_DA)) + else: + setPvDesc("lowMagGain", getBlConfig(LOW_MAG_GAIN)) + setPvDesc("lowMagAcquireTime",getBlConfig(LOW_MAG_EXP_TIME)) diff --git a/gui/control_main.py b/gui/control_main.py index 2995109e..7a9f8cf5 100644 --- a/gui/control_main.py +++ b/gui/control_main.py @@ -26,10 +26,7 @@ from qtpy.QtWidgets import QCheckBox, QFrame, QGraphicsPixmapItem, QApplication, QHBoxLayout import daq_utils -if daq_utils.beamline == 'nyx': - from mxbluesky.devices.md2 import GonioDevice, CameraDevice, MD2Device, LightDevice, MD2ApertureDevice -else: - from mxbluesky.devices.generic import GoniometerStack as GonioDevice +from mxbluesky.devices.generic import GoniometerStack as GonioDevice import db_lib import lsdcOlog from config_params import ( @@ -180,8 +177,7 @@ def __init__(self): self.redPen = QtGui.QPen(QtCore.Qt.red) self.bluePen = QtGui.QPen(QtCore.Qt.blue) self.yellowPen = QtGui.QPen(QtCore.Qt.yellow) - if daq_utils.beamline != "nyx": - self.albulaInterface = AlbulaInterface(ip=os.environ["EIGER_DCU_IP"], + self.albulaInterface = AlbulaInterface(ip=os.environ["EIGER_DCU_IP"], gov_message_pv_name=daq_utils.pvLookupDict["governorMessage"],) self.initUI() self.initOphyd() @@ -244,8 +240,6 @@ def __init__(self): "fineZ": self.sampFineZ_pv.get(), } self.staffScreenDialog = StaffScreenDialog(self, show=False) - if daq_utils.beamline == "nyx": # requires staffScreenDialog to be present - self.staffScreenDialog.fastDPCheckBox.setDisabled(True) if self.mountedPin_pv.get() == "": mountedPin = db_lib.beamlineInfo(daq_utils.beamline, "mountedSample")[ @@ -520,7 +514,7 @@ def createSampleTab(self): calcLifetimeButton.clicked.connect(self.calcLifetimeCB) self.sampleLifetimeReadback_ledit = QtWidgets.QLabel() self.calcLifetimeCB() - if daq_utils.beamline in ("fmx", "nyx"): + if daq_utils.beamline in ("fmx"): if getBlConfig("attenType") == "RI": self.transmissionReadback = QtEpicsPVLabel( daq_utils.pvLookupDict["RI_Atten_SP"], self, 60, 3 @@ -566,14 +560,9 @@ def createSampleTab(self): self.transmission_ledit.textChanged.connect(self.calcLifetimeCB) setTransButton = QtWidgets.QPushButton("Set Trans") setTransButton.clicked.connect(self.setTransCB) - beamsizeLabel = QtWidgets.QLabel("BeamSize:") - if daq_utils.beamline == "nyx": - # beamSizeOptionList = self.aperture.get_diameter_list() PV not working, needs investigation - beamSizeOptionList = ["10", "20", "30", "50", "100"] - current_index = self.aperture.current_index.get() - else: - beamSizeOptionList = BEAMSIZE_OPTIONS.keys() - current_index = int(self.beamSize_pv.get()) + self.beamsizeLabel = QtWidgets.QLabel("BeamSize:") + beamSizeOptionList = BEAMSIZE_OPTIONS.keys() + current_index = int(self.beamSize_pv.get()) self.beamsizeComboBox = QtWidgets.QComboBox(self) self.beamsizeComboBox.addItems(beamSizeOptionList) self.beamsizeComboBox.setCurrentIndex(current_index) @@ -606,10 +595,7 @@ def createSampleTab(self): colBeamHLabel.setAlignment(QtCore.Qt.AlignCenter) self.beamHeight_ledit = QtWidgets.QLineEdit() self.beamHeight_ledit.setFixedWidth(60) - if daq_utils.beamline == 'nyx': - self.beamWidth_ledit.setText(getBlConfig("screen_default_beamWidth")) - self.beamHeight_ledit.setText(getBlConfig("screen_default_beamHeight")) - hBoxColParams4.addWidget(colBeamWLabel) + hBoxColParams4.addWidget(self.colBeamWLabel) hBoxColParams4.addWidget(self.beamWidth_ledit) hBoxColParams4.addWidget(colBeamHLabel) hBoxColParams4.addWidget(self.beamHeight_ledit) @@ -619,10 +605,8 @@ def createSampleTab(self): self.resolution_ledit.setFixedWidth(60) self.resolution_ledit.setValidator(QtGui.QDoubleValidator()) self.resolution_ledit.textEdited[str].connect(self.resoTextChanged) - if daq_utils.beamline == "nyx": - self.resolution_ledit.setEnabled(False) - detDistLabel = QtWidgets.QLabel("Detector Dist.") - #detDistLabel.setAlignment(QtCore.Qt.AlignCenter) + self.detDistLabel = QtWidgets.QLabel("Detector Dist.") + #self.detDistLabel.setAlignment(QtCore.Qt.AlignCenter) detDistRBLabel = QtWidgets.QLabel("Readback:") self.detDistRBVLabel = QtEpicsPVLabel( daq_utils.motor_dict["detectorDist"] + ".RBV", self, 70 @@ -879,56 +863,7 @@ def createSampleTab(self): paramsGridGB = QtWidgets.QGroupBox() paramsGridGB.setTitle("Acquisition") - paramSubspace = QtWidgets.QGridLayout() - - - # Parameter Collection Column 1, Labels - colStartLabel.setAlignment(QtCore.Qt.AlignLeft) - paramSubspace.addWidget(colStartLabel,1,0, alignment=QtCore.Qt.AlignLeft) - self.colEndLabel.setAlignment(QtCore.Qt.AlignLeft) - paramSubspace.addWidget(self.colEndLabel,2,0, alignment=QtCore.Qt.AlignLeft) - colRangeLabel.setAlignment(QtCore.Qt.AlignLeft) - paramSubspace.addWidget(colRangeLabel,0,0, alignment=QtCore.Qt.AlignLeft) - colExptimeLabel.setAlignment(QtCore.Qt.AlignLeft) - paramSubspace.addWidget(colExptimeLabel,3,0, alignment=QtCore.Qt.AlignLeft) - totalExptimeLabel.setAlignment(QtCore.Qt.AlignLeft) - paramSubspace.addWidget(totalExptimeLabel,4,0, alignment=QtCore.Qt.AlignLeft) - if daq_utils.beamline in ['amx', 'fmx']: - paramSubspace.addWidget(sampleLifetimeLabel, 5, 0, alignment=QtCore.Qt.AlignLeft) - # Parameter Collection Column 2, Input Boxes - paramSubspace.addWidget(self.osc_start_ledit,1,1, alignment=QtCore.Qt.AlignLeft) - paramSubspace.addWidget(self.osc_end_ledit,2,1, alignment=QtCore.Qt.AlignLeft) - paramSubspace.addWidget(self.osc_range_ledit,0,1, alignment=QtCore.Qt.AlignLeft) - paramSubspace.addWidget(self.exp_time_ledit,3,1, alignment=QtCore.Qt.AlignLeft) - paramSubspace.addWidget(self.totalExptime_ledit,4,1, alignment=QtCore.Qt.AlignLeft) - # Parameter Collection Column 3, Labels - paramSubspace.addWidget(detDistLabel,0,2, alignment=QtCore.Qt.AlignLeft) - paramSubspace.addWidget(colResoLabel,1,2, alignment=QtCore.Qt.AlignLeft) - paramSubspace.addWidget(colEnergyLabel,2,2, alignment=QtCore.Qt.AlignLeft) - colTransmissionLabel.setAlignment(QtCore.Qt.AlignLeft) - paramSubspace.addWidget(colTransmissionLabel,3,2, alignment=QtCore.Qt.AlignLeft) - transmisionSPLabel.setAlignment(QtCore.Qt.AlignLeft) - paramSubspace.addWidget(beamsizeLabel,4,2, alignment=QtCore.Qt.AlignLeft) - if daq_utils.beamline in ['amx', 'fmx']: - paramSubspace.addWidget(self.sampleLifetimeReadback_ledit, 5, 1, alignment=QtCore.Qt.AlignLeft) - - # Parameter Collection Column 4, Input Boxes - paramSubspace.addWidget(self.detDistMotorEntry.getEntry(),0,3, alignment=QtCore.Qt.AlignLeft) - paramSubspace.addWidget(self.resolution_ledit,1,3, alignment=QtCore.Qt.AlignLeft) - if daq_utils.beamline == "fmx": - if getBlConfig(SET_ENERGY_CHECK): - paramSubspace.addWidget(moveEnergyButton,2,3, alignment=QtCore.Qt.AlignLeft) - else: - paramSubspace.addWidget(self.energy_ledit,2,3, alignment=QtCore.Qt.AlignLeft) - else: - paramSubspace.addWidget(self.energy_ledit,2,3, alignment=QtCore.Qt.AlignLeft) - paramSubspace.addWidget(self.transmission_ledit,3,3, alignment=QtCore.Qt.AlignLeft) - paramSubspace.addWidget(self.beamsizeComboBox,4,3, alignment=QtCore.Qt.AlignLeft) - - # Param Collection Column 5, RBV - paramSubspace.addWidget(self.energyReadback,2,4, alignment=QtCore.Qt.AlignLeft) - paramSubspace.addWidget(self.detDistRBVLabel.getEntry(),0,4, alignment=QtCore.Qt.AlignLeft) - paramSubspace.addWidget(self.transmissionReadback_ledit,3,4, alignment=QtCore.Qt.AlignLeft) + paramSubspace = self.amx_fmx_parameter_layout() improvedParamSpacing = QtWidgets.QVBoxLayout() improvedParamSpacing.addWidget(self.stillModeCheckBox) @@ -1486,10 +1421,7 @@ def createSampleTab(self): self.sampleExposedLabel = QtWidgets.QLabel("Sample Not Exposed") self.sampleExposedLabel.setStyleSheet("background-color: #99FF66;") gripperLabel = QtWidgets.QLabel("Gripper Temp (K):") - if daq_utils.beamline == "nyx": - self.gripperTempLabel = QtWidgets.QLabel("N/A") - else: - self.gripperTempLabel = QtWidgets.QLabel("%.1f" % self.gripTemp_pv.get()) + self.gripperTempLabel = QtWidgets.QLabel("%.1f" % self.gripTemp_pv.get()) cryostreamLabel = QtWidgets.QLabel("Cryostream Temp (K):") if getBlConfig(CRYOSTREAM_ONLINE): self.cryostreamTempLabel = QtWidgets.QLabel( @@ -1524,45 +1456,13 @@ def createSampleTab(self): # 12/19 - uncomment this to expose the PyMCA XRF interface. It's not connected to anything. self.zoomLevelToggledCB("Zoom1") - if daq_utils.beamline == "nyx": # hiding unused GUI elements - self.protoRasterRadio.setVisible(False) - self.protoStandardRadio.setVisible(False) - self.protoVectorRadio.setVisible(False) - self.protoOtherRadio.setVisible(False) - self.autoProcessingCheckBox.setVisible(False) - self.fastEPCheckBox.setVisible(False) - self.dimpleCheckBox.setVisible(False) - self.centeringComboBox.setVisible(False) - annealButton.setVisible(False) - centerLoopButton.setVisible(False) - clearGraphicsButton.setVisible(False) - saveCenteringButton.setVisible(False) - selectAllCenteringButton.setVisible(False) - snapshotButton.setVisible(False) - annealTimeLabel.setVisible(False) - self.annealTime_ledit.setVisible(False) - self.vidActionDefineCenterRadio.setVisible(False) - self.hideRastersCheckBox.setEnabled(True) - self.vidActionC2CRadio.setEnabled(True) - self.vidActionRasterExploreRadio.setEnabled(True) - self.vidActionRasterDefRadio.setEnabled(True) - - - - #self.captureLowMag = cv2.VideoCapture(daq_utils.lowMagCamURL) - #self.captureLowMag.set(cv2.CAP_PROP_BUFFERSIZE, 1) self.captureLowMag = daq_utils.lowMagCamURL self.capture = self.captureLowMag - if daq_utils.beamline == "nyx": - self.sampleCameraThread = VideoThread( - parent=self, delay=HUTCH_TIMER_DELAY, url=daq_utils.highMagCamURL - ) - else: - self.sampleCameraThread = VideoThread( - parent=self, delay=SAMPLE_TIMER_DELAY, mjpg_url=self.capture - ) - self.sampleZoomChangeSignal.connect(self.sampleCameraThread.updateCam) + self.sampleCameraThread = VideoThread( + parent=self, delay=SAMPLE_TIMER_DELAY, mjpg_url=self.capture + ) + self.sampleZoomChangeSignal.connect(self.sampleCameraThread.updateCam) self.sampleCameraThread.frame_ready.connect( lambda frame: self.updateCam(self.pixmap_item, frame) @@ -1597,6 +1497,68 @@ def updateCam(self, pixmapItem: "QGraphicsPixmapItem", frame): else: pixmapItem.setPixmap(frame) + def amx_fmx_parameter_layout(self): + + hBoxColParams1 = QtWidgets.QHBoxLayout() + if daq_utils.beamline == "fmx": + self.osc_end_ledit.textChanged.connect(self.calcLifetimeCB) + hBoxColParams1.addWidget(self.colStartLabel) + hBoxColParams1.addWidget(self.osc_start_ledit) + hBoxColParams1.addWidget(self.colEndLabel) + hBoxColParams1.addWidget(self.osc_end_ledit) + hBoxColParams2 = QtWidgets.QHBoxLayout() + hBoxColParams2.addWidget(self.colRangeLabel) + hBoxColParams2.addWidget(self.osc_range_ledit) + + hBoxColParams2.addWidget(self.colExptimeLabel) + hBoxColParams2.addWidget(self.exp_time_ledit) + hBoxColParams25 = QtWidgets.QHBoxLayout() + hBoxColParams25.addWidget(self.stillModeCheckBox) + hBoxColParams25.addWidget(self.totalExptimeLabel) + hBoxColParams25.addWidget(self.totalExptime_ledit) + # if (daq_utils.beamline == "fmx"): + # hBoxColParams25.addWidget(calcLifetimeButton) + hBoxColParams25.addWidget(self.sampleLifetimeLabel) + hBoxColParams25.addWidget(self.sampleLifetimeReadback_ledit) + hBoxColParams22 = QtWidgets.QHBoxLayout() + hBoxColParams3 = QtWidgets.QHBoxLayout() + + hBoxColParams3.addWidget(self.colEnergyLabel) + hBoxColParams3.addWidget(self.energyReadback) + hBoxColParams3.addWidget(self.energySPLabel) + if daq_utils.beamline == "fmx": + if getBlConfig(SET_ENERGY_CHECK): + hBoxColParams3.addWidget(self.moveEnergyButton) + else: + hBoxColParams3.addWidget(self.energy_ledit) + else: + hBoxColParams3.addWidget(self.energy_ledit) + + hBoxColParams22.addWidget(self.colTransmissionLabel) + hBoxColParams22.addWidget(self.transmissionReadback_ledit) + hBoxColParams22.addWidget(self.transmisionSPLabel) + hBoxColParams22.addWidget(self.transmission_ledit) + hBoxColParams22.insertSpacing(5, 100) + hBoxColParams22.addWidget(self.beamsizeLabel) + hBoxColParams22.addWidget(self.beamsizeComboBox) + hBoxColParams4 = QtWidgets.QHBoxLayout() + hBoxColParams4.addWidget(self.colBeamWLabel) + hBoxColParams4.addWidget(self.beamWidth_ledit) + hBoxColParams4.addWidget(self.colBeamHLabel) + hBoxColParams4.addWidget(self.beamHeight_ledit) + hBoxColParams3.addWidget(self.detDistLabel) + hBoxColParams3.addWidget(self.detDistRBVLabel.getEntry()) + hBoxColParams3.addWidget(self.detDistSPLabel) + hBoxColParams3.addWidget(self.detDistMotorEntry.getEntry()) + + paramSubspace = QtWidgets.QVBoxLayout() + paramSubspace.addLayout(hBoxColParams1) + paramSubspace.addLayout(hBoxColParams2) + paramSubspace.addLayout(hBoxColParams25) + paramSubspace.addLayout(hBoxColParams22) + paramSubspace.addLayout(hBoxColParams3) + return paramSubspace + def annealButtonCB(self): try: ftime = float(self.annealTime_ledit.text()) @@ -2232,20 +2194,12 @@ def processRingCurrent(self, ringCurrentVal): function is processThreClickCentering ''' def processThreeClickCentering(self, beamAvailVal): - if daq_utils.beamline == 'nyx': - if beamAvailVal == '0': - self.beamAvailLabel.setText("Beam Available") - self.beamAvailLabel.setStyleSheet("background-color: #99FF66;") - else: - self.beamAvailLabel.setText(beamAvailVal) - self.beamAvailLabel.setStyleSheet("background-color: yellow") - else: - if beamAvailVal == "1": - self.beamAvailLabel.setText("Beam Available") - self.beamAvailLabel.setStyleSheet("background-color: #99FF66;") - elif beamAvailVal == "0": - self.beamAvailLabel.setText("No Beam") - self.beamAvailLabel.setStyleSheet("background-color: red") + if beamAvailVal == "1": + self.beamAvailLabel.setText("Beam Available") + self.beamAvailLabel.setStyleSheet("background-color: #99FF66;") + elif beamAvailVal == "0": + self.beamAvailLabel.setText("No Beam") + self.beamAvailLabel.setStyleSheet("background-color: red") def processSampleExposed(self, sampleExposedVal): if int(sampleExposedVal) == 1: @@ -2638,11 +2592,7 @@ def protoRadioToggledCB(self, text): pass def beamsizeComboActivatedCB(self, text): - if daq_utils.beamline == "nyx": - index = self.beamsizeComboBox.findText(str(text)) - self.aperture.current_index.put(index) - else: - self.send_to_server("set_beamsize", BEAMSIZE_OPTIONS[text]) + self.send_to_server("set_beamsize", BEAMSIZE_OPTIONS[text]) def protoComboActivatedCB(self, text): self.showProtParams() @@ -3095,10 +3045,7 @@ def center3LoopCB(self): self.threeClickSignal.emit('{} more clicks'.format(str(4-self.threeClickCount))) #time.sleep(0.3) self.click3Button.setStyleSheet("background-color: yellow") - if(daq_utils.exporter_enabled): - self.md2.exporter.cmd("startManualSampleCentring", "") - else: - self.send_to_server("mvaDescriptor", ["omega", 0]) + self.send_to_server("mvaDescriptor", ["omega", 0]) def fillPolyRaster( self, rasterReq @@ -3166,10 +3113,7 @@ def fillPolyRaster( ) return # means a raster failure, and not enough data to cover raster, caused a gui crash - - if ( - lenX > 180 and self.scannerType == "PI" - ): # this is trying to figure out row direction + if i % 2 == 0: # this is trying to figure out row direction cellIndex = spotLineCounter else: if daq_utils.beamline == "nyx": @@ -3440,70 +3384,30 @@ def getCurrentFOV(self): return fov def screenXPixels2microns(self, pixels): - if daq_utils.beamline == 'nyx': - img_scale_factor = self.getMD2ImageXRatio() - pixels_per_mm = 1 / self.camera.scale_x.get() - pixels_per_micron = pixels_per_mm / 1000.0 - return float(pixels * img_scale_factor) / pixels_per_micron - else: - fov = self.getCurrentFOV() - fovX = fov["x"] - return float(pixels) * (fovX / daq_utils.screenPixX) + fov = self.getCurrentFOV() + fovX = fov["x"] + return float(pixels) * (fovX / daq_utils.screenPixX) def screenYPixels2microns(self, pixels): - if daq_utils.beamline == 'nyx': - pixels_per_mm = 1 / self.camera.scale_y.get() - pixels_per_micron = pixels_per_mm / 1000.0 - img_scale_factor = self.getMD2ImageYRatio() - return float(pixels * img_scale_factor) / pixels_per_micron - else: - fov = self.getCurrentFOV() - fovY = fov["y"] - return float(pixels) * (fovY / daq_utils.screenPixY) + fov = self.getCurrentFOV() + fovY = fov["y"] + return float(pixels) * (fovY / daq_utils.screenPixY) def screenXmicrons2pixels(self, microns): - if daq_utils.beamline == 'nyx': - pixels_per_mm = 1 / self.camera.scale_x.get() - pixels_per_micron = pixels_per_mm / 1000.0 - img_scale_factor = self.getMD2ImageXRatio() - return float(microns * pixels_per_micron) / img_scale_factor - else: - fov = self.getCurrentFOV() - fovX = fov["x"] - return int(round(microns * (daq_utils.screenPixX / fovX))) + fov = self.getCurrentFOV() + fovX = fov["x"] + return int(round(microns * (daq_utils.screenPixX / fovX))) def screenYmicrons2pixels(self, microns): - if daq_utils.beamline == 'nyx': - pixels_per_mm = 1 / self.camera.scale_y.get() - pixels_per_micron = pixels_per_mm / 1000.0 - img_scale_factor = self.getMD2ImageYRatio() - return float(microns * pixels_per_micron) / img_scale_factor - else: - fov = self.getCurrentFOV() - fovY = fov["y"] - return int(round(microns * (daq_utils.screenPixY / fovY))) - - def getMD2ImageXRatio(self): - md2_img_width = daq_utils.highMagPixX - lsdc_img_width = daq_utils.screenPixX - return float(md2_img_width) / float(lsdc_img_width) - - def getMD2ImageYRatio(self): - md2_img_height = daq_utils.highMagPixY - lsdc_img_height = daq_utils.screenPixY - return float(md2_img_height) / float(lsdc_img_height) - + fov = self.getCurrentFOV() + fovY = fov["y"] + return int(round(microns * (daq_utils.screenPixY / fovY))) + def getBeamCenterX(self): - if daq_utils.beamline == 'nyx': - return self.md2.center_pixel_x.get() / self.getMD2ImageXRatio() - else: - return daq_utils.screenPixCenterX + return daq_utils.screenPixCenterX def getBeamCenterY(self): - if daq_utils.beamline == 'nyx': - return self.md2.center_pixel_y.get() / self.getMD2ImageYRatio() - else: - return daq_utils.screenPixCenterY + return daq_utils.screenPixCenterY def definePolyRaster( self, raster_w, raster_h, stepsizeXPix, stepsizeYPix, point_x, point_y, stepsize @@ -3816,15 +3720,7 @@ def pixelSelect(self, event): penRed = QtGui.QPen(QtCore.Qt.red) ''' For three click centering, this if statement checks the omega state of the motor. - This ideally gives feedback on wether the MD2 is in the rotation portion of the three click centering - ''' - if daq_utils.beamline == 'nyx': - state = self.md2.exporter.read('OmegaState') - if state != 'Ready': - logger.info('waiting for motor rotation') - logger.info('Click not registered') - return if self.vidActionDefineCenterRadio.isChecked(): self.vidActionC2CRadio.setChecked( True @@ -3856,10 +3752,10 @@ def pixelSelect(self, event): return fov = self.getCurrentFOV() correctedC2C_x = self.getBeamCenterX() + ( - x_click - (self.centerMarker.x() - self.centerMarkerCharOffsetX) - 20 + x_click - (self.centerMarker.x() + self.centerMarkerCharOffsetX) ) correctedC2C_y = self.getBeamCenterY() + ( - y_click - (self.centerMarker.y() - self.centerMarkerCharOffsetY) - 40 + y_click - (self.centerMarker.y() + self.centerMarkerCharOffsetY) ) current_viewangle = daq_utils.mag1ViewAngle @@ -3881,36 +3777,7 @@ def pixelSelect(self, event): self.threeClickLines.append( self.scene.addLine(x_click, 0, x_click, 512, penGreen) ) - - - if daq_utils.exporter_enabled: - correctedC2C_x = x_click + 5 + ((daq_utils.screenPixX/2) - (self.centerMarker.x() + self.centerMarkerCharOffsetX)) - correctedC2C_y = y_click - 35 + ((daq_utils.screenPixY/2) - (self.centerMarker.y() + self.centerMarkerCharOffsetY)) - lsdc_x = daq_utils.screenPixX - lsdc_y = daq_utils.screenPixY - md2_x = self.md2.center_pixel_x.get() * 2 - md2_y = self.md2.center_pixel_y.get() * 2 - scale_x = md2_x / lsdc_x - scale_y = md2_y / lsdc_y - correctedC2C_x = correctedC2C_x * scale_x - correctedC2C_y = correctedC2C_y * scale_y - self.md2.centring_click.put(f"{correctedC2C_x} {correctedC2C_y}") - #logger.info('waiting for motor rotation') - #time.sleep(0.2) - #self.omegaMoveCheck(0.02,'OmegaState') - - if self.threeClickCount == 4: - self.threeClickCount = 0 - self.threeClickSignal.emit('0') - self.click3Button.setStyleSheet("background-color: None") - #removing drawing for three click centering - logger.info('Removing 3 click lines') - for i in range(len(self.threeClickLines)): - self.scene.removeItem(self.threeClickLines[i]) - self.threeClickLines = [] - return - else: - comm_s = ( + comm_s = ( "center_on_click", [ correctedC2C_x, @@ -3946,24 +3813,6 @@ def pixelSelect(self, event): return - ''' - Function to check if MD motors are rotating or not - ''' - def omegaMoveCheck(self, sleeptime,call='OmegaState'): - state = self.md2.exporter.read(call) - while(state == 'Moving'): - time.sleep(sleeptime) - state = self.md2.exporter.read(call) - #logger.info('\nIn Moving\n{}\n'.format(state)) - if state == 'Ready': - logger.info('ready for next click') - return state - else: - logger.info('\ndone moving, current state is: {}'.format(state)) - return state - - - def editScreenParamsCB(self): self.screenDefaultsDialog = ScreenDefaultsDialog(self) self.screenDefaultsDialog.show() @@ -4613,10 +4462,7 @@ def popUserScreenCB(self): self.popupServerMessage("You don't have control") def parkRobotCB(self): - if daq_utils.beamline == "nyx": - self.send_to_server("parkRobot()") - else: - self.send_to_server("parkGripper") + self.send_to_server("parkGripper") def closePhotonShutterCB(self): self.photonShutterClose_pv.put(1) @@ -4804,8 +4650,7 @@ def refreshCollectionParams(self, selectedSampleRequest, validate_hdf5=True): firstFilename = daq_utils.create_filename(prefix_long, fnumstart) if validate_hdf5: if validation.validate_master_HDF5_file(firstFilename): - if daq_utils.beamline != "nyx": - self.albulaInterface.open_file(firstFilename) + self.albulaInterface.open_file(firstFilename) else: QtWidgets.QMessageBox.information( self, @@ -5132,18 +4977,11 @@ def pauseButtonStateCB(self, value=None, char_value=None, **kw): self.pauseButtonStateSignal.emit(pauseButtonStateVar) def initOphyd(self): - if daq_utils.beamline == "nyx": - # initialize devices - self.gon = GonioDevice("XF:19IDC-ES{MD2}:", name="gonio") - self.camera = CameraDevice("XF:19IDC-ES{MD2}:", name="camera") - self.md2 = MD2Device("XF:19IDC-ES{MD2}:", name="md2") - self.front_light = LightDevice("XF:19IDC-ES{MD2}:Front", name="front_light") - self.back_light = LightDevice("XF:19IDC-ES{MD2}:Back", name="back_light") - self.aperture = MD2ApertureDevice("XF:19IDC-ES{MD2}:", name="aperture") - elif daq_utils.beamline == "amx": - self.gon = GonioDevice("XF:17IDB-ES:AMX{Gon:1", name="gonio") - elif daq_utils.beamline == "fmx": - self.gon = GonioDevice("XF:17IDC-ES:FMX{Gon:1", name="gonio") + if daq_utils.beamline = "amx": + ophyd_prefix = "XF:17IDB-ES:AMX" + else: + ophyd_prefix = "XF:17IDC-ES:FMX" + self.gon = GonioDevice(f"{ophyd_prefix}{{Gon:1", name="gonio") def initUI(self): self.tabs = QtWidgets.QTabWidget() @@ -5416,9 +5254,6 @@ def initCallbacks(self): self.omega_pv = PV(self.gon.omega.setpoint.pvname) self.omegaTweak_pv = PV(self.gon.omega.setpoint.pvname) self.sampyTweak_pv = PV(self.gon.y.setpoint.pvname) - #if daq_utils.beamline == "nyx": - # self.sampzTweak_pv = PV(self.gon.x.setpoint.pvname + ".RLV") - #else: self.sampzTweak_pv = PV(self.gon.z.setpoint.pvname) self.omegaRBV_pv = PV(self.gon.omega.readback.pvname) self.omegaRBV_pv.add_callback( diff --git a/gui/dialog/user_screen.py b/gui/dialog/user_screen.py index e7e54e04..f3a1552e 100644 --- a/gui/dialog/user_screen.py +++ b/gui/dialog/user_screen.py @@ -193,17 +193,6 @@ def __init__(self, parent: "ControlMain"): ) self.buttons.buttons()[0].clicked.connect(self.userScreenOKCB) - if daq_utils.beamline == "nyx": - self.openShutterButton.setDisabled(True) - self.unmountWarmButton.setDisabled(True) - self.testRobotButton.setDisabled(True) - self.recoverRobotButton.setDisabled(True) - self.dryGripperButton.setDisabled(True) - self.resetZebraButton.setDisabled(True) - self.rebootZebraButton.setDisabled(True) - self.stopDetButton.setDisabled(True) - self.rebootDetIocButton.setDisabled(True) - vBoxColParams1.addLayout(hBoxColParams1) vBoxColParams1.addLayout(hBoxColParams2) vBoxColParams1.addLayout(hBoxColParams25) diff --git a/gui/vector.py b/gui/vector.py index ef14a501..d41bd3f1 100644 --- a/gui/vector.py +++ b/gui/vector.py @@ -155,8 +155,6 @@ def get_length(self) -> "tuple[int, int, int, np.floating[typing.Any] | float]": vec_diff = vec_end - vec_start trans_total = np.linalg.norm(vec_diff) - if daq_utils.beamline == "nyx": - trans_total *= 1000 return x_vec, y_vec, z_vec, trans_total diff --git a/mxbluesky/devices/md2.py b/mxbluesky/devices/md2.py deleted file mode 100644 index 7fa98c59..00000000 --- a/mxbluesky/devices/md2.py +++ /dev/null @@ -1,392 +0,0 @@ -import os -import socket - -from ophyd import Component as Cpt -from ophyd import Device, EpicsSignal, EpicsSignalRO, PVPositioner -from ophyd.status import SubscriptionStatus - - -class MD2Positioner(PVPositioner): - setpoint = Cpt(EpicsSignal, "Position", name="setpoint") - readback = Cpt(EpicsSignal, "Position", name="readback") - state = Cpt(EpicsSignalRO, "State", name="state") - done = Cpt(EpicsSignalRO, "State", name="done") - precision = Cpt(EpicsSignalRO, "Precision", name="precision") - done_value = 4 # MD2 Enum, 4 = Ready - # TODO: Add limits, settle_time, timeout or defaults for each - - def val(self): - return self.get().readback - - -class ExporterComponent(Cpt): - def __init__(self, address, port, name, **kwargs): - super().__init__(self, **kwargs) - self.name = name - self.address = address - self.port = port - self.sock = None # socket.socket(socket.AF_INET, socket.SOCK_STREAM) - # self.sock.settimeout(5) - - def get(self): - return () - - def connect(self): - # for establishing connection, using context manager is preferred - self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - self.sock.connect((self.address, self.port)) - - def disconnect(self): - self.sock.close() - self.sock = None - - def send_data(self, data): - STX = chr(2) - ETX = chr(3) - data = STX + data + ETX - with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: - s.connect((self.address, self.port)) - s.sendto(data.encode(), (self.address, self.port)) - state = s.recv(4096) - print(f"state: {self.decipher_reply(state)}") - ret = None - while ret is None: - output = s.recv(4096) - output = self.decipher_reply(output) - ret = self.process_ret(output) - return ret - - def read_stream(self): - output = None - while output is None: - output, addr = self.sock.recvfrom(4096) - print(f"output:{self.decipher_reply(output)}") - output = None - - def write(self, attribute, value): - return self.send_data("WRTE " + attribute + " " + str(value)) - - def read(self, attribute): - return (self.send_data("READ " + attribute + " ")).split(" ")[0][4:] - - def cmd(self, method, parameters): - parameters = map(str, parameters) - params = "\t".join(parameters) - return self.send_data("EXEC " + method + " " + str(params)) - - def decipher_reply(self, reply): - # Specifically for decoding MD2 Exporter replies - reply = str(reply) - reply = reply.replace("\\x03", "") - reply = reply.replace("\\x1f", ", ") - reply = reply.replace("\\x02", "\n") - reply = reply.replace("\\t", " ") - return reply[2:-1] - - def process_ret(self, ret): - # Returns only when an error or return value is found, - # ignores events to ensure flyer kickoff functions as expected - for line in ret.split("\n"): - if "ERR:" in line: - print(f"error: {line}") - return line - elif "RET:" in line: - print(f"returned: {line}") - return line - elif "NULL" in line: - print(f"null error: {line}") - return line - elif "EVT:" in line: # print here if you want to see the events - pass # return self.process_evt(line) - - -class LightDevice(Device): - control = Cpt(EpicsSignal, "LightIsOn", name="control") - factor = Cpt(EpicsSignal, "LightFactor", name="factor") - level = Cpt(EpicsSignal, "LightLevel", name="level") - - def is_on(self): - return self.control.get() == 1 - - def turn_on(self): - self.control.set(1) - - def turn_off(self): - self.control.set(0) - - def set_factor(self, factor): - self.factor.set(factor) - - def set_level(self, level): - self.level.set(level) - - -class BeamstopDevice(Device): - distance = Cpt(MD2Positioner, "BeamstopDistance", name="distance") - distance_preset = Cpt(EpicsSignal, "BeamstopDistance", name="distance_preset") - x = Cpt(MD2Positioner, "BeamstopX", name="x") - y = Cpt(MD2Positioner, "BeamstopY", name="y") - z = Cpt(MD2Positioner, "BeamstopZ", name="z") - pos = Cpt(EpicsSignal, "BeamstopPosition", name="pos") - - -class MD2SimpleHVDevice(Device): - horizontal = Cpt(MD2Positioner, "HVHorizontal", name="horizontal") - vertical = Cpt(MD2Positioner, "HVVertical", name="vertical") - pos = Cpt(EpicsSignal, "HVPosition", name="pos") - # Current aperture/scintillator/capillary predifined position. - # Enum: the aperture position: - # 0: PARK, under cover. - # 1: BEAM, selected aperture aligned with beam. - # 2: OFF, just below the OAV. - # 3: UNKNOWN, not in a predefined position (this cannot be set). - - -class GonioDevice(Device): - omega = Cpt(MD2Positioner, "Omega", name="omega") - x = Cpt(MD2Positioner, "AlignmentX", name="x") - y = Cpt(MD2Positioner, "AlignmentY", name="y") - z = Cpt(MD2Positioner, "AlignmentZ", name="z") - cx = Cpt(MD2Positioner, "CentringX", name="cx") - cy = Cpt(MD2Positioner, "CentringY", name="cy") - - -class MD2Device(GonioDevice): - # TODO: Enum for MD2 phases and states - cx = Cpt(MD2Positioner, "CentringX", name="cx") - cy = Cpt(MD2Positioner, "CentringY", name="cy") - center_pixel_x = Cpt(EpicsSignalRO, "BeamPositionHorizontal", name="center_pixel_x") - center_pixel_y = Cpt(EpicsSignalRO, "BeamPositionVertical", name="center_pixel_y") - centring_click = Cpt(EpicsSignal, "setCentringClick", name="centring_click") - centring_save = Cpt(EpicsSignal, "saveCentringPositions", name="centring_save") - state = Cpt(EpicsSignalRO, "State", name="state") - phase = Cpt(EpicsSignal, "CurrentPhase", name="phase") - phase_index = Cpt(EpicsSignalRO, "CurrentPhaseIndex", name="phase_index") - detector_state = Cpt(EpicsSignal, "DetectorState", name="det_state") - detector_gate_pulse_enabled = Cpt( - EpicsSignal, "DetectorGatePulseEnabled", name="det_gate_pulse_enabled" - ) - exporter = Cpt( - ExporterComponent, - address=os.environ["EXPORTER_HOST"], - port=int(os.environ["EXPORTER_PORT"]), - name="exporter", - ) - - task_info = Cpt(EpicsSignalRO, "LastTaskInfo", name="task_info") - task_output = Cpt(EpicsSignalRO, "LastTaskOutput", name="task_output") - - def save_center(self): - self.centring_save.put("__EMPTY__") - - def task_complete(self): - return self.task_output == "true" - - def task_status(self): - def check_task(*, old_value, value, **kwargs): - "Return True when last task completes" - return value[6] == "1" - - return SubscriptionStatus(self.task_info, check_task) - - def is_ready(self): - return self.state.get() == 4 - - def ready_status(self): - # returns an ophyd status object that monitors the state pv for operations to complete - def check_ready(*, old_value, value, **kwargs): - "Return True when the MD2 is ready" - return value == 4 - - return SubscriptionStatus(self.state, check_ready) - - def phase_transition(self, phase): - # returns an ophyd status object that monitors the phase pv for operations to complete - self.phase.put(phase) - - def check_transition_state(*, old_value, value, **kwargs): - "Return True when the MD2 is ready" - return value == 4 and self.phase.get() == phase - - return SubscriptionStatus(self.state, check_transition_state) - - def standard_scan( - self, - frame_number=0, # int: frame ID just for logging purposes. - num_images=1, # int: number of frames. Needed solely when the detector use gate enabled trigger. - start_angle=0, # double: angle (deg) at which the shutter opens and omega speed is stable. - scan_range=0.1, # double: omega relative move angle (deg) before closing the shutter. - exposure_time=0.1, # double: exposure time (sec) to control shutter command. - num_passes=1, # int: number of moves forward and reverse between start angle and stop angle - ): - command = "startScanEx2" - if start_angle is None: - start_angle = self.omega.get() - return self.exporter.cmd( - command, - [ - frame_number, - num_images, - start_angle, - scan_range, - exposure_time, - num_passes, - ], - ) - - def vector_scan( - self, - start_angle=None, # double: angle (deg) at which the shutter opens and omega speed is stable. - scan_range=10, # double: omega relative move angle (deg) before closing the shutter. - exposure_time=1, # double: exposure time (sec) to control shutter command. - start_y=None, # double: PhiY axis position at the beginning of the exposure. - start_z=None, # double: PhiZ axis position at the beginning of the exposure. - start_cx=None, # double: CentringX axis position at the beginning of the exposure. - start_cy=None, # double: CentringY axis position at the beginning of the exposure. - stop_y=None, # double: PhiY axis position at the end of the exposure. - stop_z=None, # double: PhiZ axis position at the end of the exposure. - stop_cx=None, # double: CentringX axis position at the end of the exposure. - stop_cy=None, # double: CentringY axis position at the end of the exposure. - ): - command = "startScan4DEx" - if start_angle is None: - start_angle = self.omega.val() - if start_y is None: - start_y = self.y.val() - if start_z is None: - start_z = self.z.val() - if start_cx is None: - start_cx = self.cx.val() - if start_cy is None: - start_cy = self.cy.val() - if stop_y is None: - stop_y = self.y.val() - if stop_z is None: - stop_z = self.z.val() - if stop_cx is None: - stop_cx = self.cx.val() - if stop_cy is None: - stop_cy = self.cy.val() - - # List of scan parameters values, comma separated. The axes start values define the beginning - # of the exposure, that is when all the axes have a steady speed and when the shutter/detector - # are triggered. - # The axes stop values are for the end of detector exposure and define the position at the - # beginning of the deceleration. - # Inputs names: "start_angle", "scan_range", "exposure_time", "start_y", "start_z", "start_cx", - # "start_cy", "stop_y", "stop_z", "stop_cx", "stop_cy" - param_list = [ - start_angle, - scan_range, - exposure_time, - start_y, - start_z, - start_cx, - start_cy, - stop_y, - stop_z, - stop_cx, - stop_cy, - ] - return self.exporter.cmd(command, param_list) - - def raster_scan( - self, - omega_range=0, # double: omega relative move angle (deg) before closing the shutter. - line_range=0.1, # double: horizontal range of the grid (mm). - total_uturn_range=0.1, # double: vertical range of the grid (mm). - start_omega=None, # double: angle (deg) at which the shutter opens and omega speed is stable. - start_y=None, # double: PhiY axis position at the beginning of the exposure. - start_z=None, # double: PhiZ axis position at the beginning of the exposure. - start_cx=None, # double: CentringX axis position at the beginning of the exposure. - start_cy=None, # double: CentringY axis position at the beginning of the exposure. - number_of_lines=5, # int: number of frames on the vertical range. - frames_per_line=5, # int: number of frames on the horizontal range. - exposure_time=1.2, # double: exposure time (sec) to control shutter command. +1, based on the exaples given - invert_direction=True, # boolean: true to enable passes in the reverse direction. - use_centring_table=True, # boolean: true to use the centring table to do the pitch movements. - use_fast_mesh_scans=True, # boolean: true to use the fast raster scan if available (power PMAC). - ): - - command = "startRasterScanEx" - if start_omega is None: - start_omega = self.omega.val() - if start_y is None: - start_y = self.y.val() - if start_z is None: - start_z = self.z.val() - if start_cx is None: - start_cx = self.cx.val() - if start_cy is None: - start_cy = self.cy.val() - # List of scan parameters values, "/t" separated. The axes start values define the beginning - # of the exposure, that is when all the axes have a steady speed and when the shutter/detector - # are triggered. - # The axes stop values are for the end of detector exposure and define the position at the - # beginning of the deceleration. - # Inputs names: "omega_range", "line_range", "total_uturn_range", "start_omega", "start_y", - # "start_z", "start_cx", "start_cy", "number_of_lines", "frames_per_lines", "exposure_time", - # "invert_direction", "use_centring_table", "use_fast_mesh_scans" - param_list = [ - omega_range, - line_range, - total_uturn_range, - start_omega, - start_y, - start_z, - start_cx, - start_cy, - number_of_lines, - frames_per_line, - exposure_time, - invert_direction, - use_centring_table, - use_fast_mesh_scans, - ] - return self.exporter.cmd(command, param_list) - - -class MD2ApertureDevice(Device): - # this device needs additional signals for "CurrentApertureDiameterIndex" and "ApertureDiameters" - current_index = Cpt( - EpicsSignal, "CurrentApertureDiameterIndex", name="current_index" - ) - diameters = Cpt(EpicsSignalRO, "ApertureDiameters", name="diameters") - - def get_diameter_list(self): - # must format list for GUI - # also, can't currently get from PV - return self.diameters.get() - - def set_diameter(self, diameter): - if diameter in self.get_diameter_list(): - self.current_index.put(self.get_diameter_list().index(diameter)) - - -class ShutterDevice(Device): - control = Cpt( - EpicsSignal, "{MD2}:FastShutterIsOpen", name="control" - ) # PV to send control signal - pos_opn = Cpt(EpicsSignalRO, "{Gon:1-Sht}Pos:Opn-I", name="pos_opn") - pos_cls = Cpt(EpicsSignalRO, "{Gon:1-Sht}Pos:Cls-I", name="pos_cls") - - def is_open(self): - return self.control.get() == 1 # self.pos_opn.get() - - def open_shutter(self): - self.control.set( - 1 - ) # self.pos_opn.get()) iocs are down, so just setting it to 1 - - def close_shutter(self): - self.control.set(0) # self.pos_cls.get()) - - -class CameraDevice(Device): - # MD2 camera has the following attributes: - # CoaxCamScaleX - # CoaxCamScaleY - # CoaxialCameraZoomValue - scale_x = Cpt(EpicsSignalRO, "CoaxCamScaleX", name="scale_x") - scale_y = Cpt(EpicsSignalRO, "CoaxCamScaleY", name="scale_y") - zoom = Cpt(EpicsSignal, "CoaxialCameraZoomValue", name="zoom") diff --git a/mxbluesky/devices/md2_flyers.py b/mxbluesky/devices/md2_flyers.py deleted file mode 100644 index 01021d65..00000000 --- a/mxbluesky/devices/md2_flyers.py +++ /dev/null @@ -1,284 +0,0 @@ -import logging -import os -from collections import deque -import getpass -import grp -from ophyd.sim import NullStatus -from ophyd.status import SubscriptionStatus -from ophyd.utils import WaitTimeoutError - -logger = logging.getLogger(__name__) - -DEFAULT_DATUM_DICT = {"data": None, "omega": None} - -INTERNAL_SERIES = 0 -INTERNAL_ENABLE = 1 -EXTERNAL_SERIES = 2 -EXTERNAL_ENABLE = 3 - -class MD2StandardFlyer(): - def __init__(self, md2, detector=None) -> None: - self.name = "MD2StandardFlyer" - self.detector = detector - self.md2 = md2 - self.collection_params = {} - - self._asset_docs_cache = deque() - self._resource_uids = [] - self._datum_counter = None - self._datum_ids = DEFAULT_DATUM_DICT - self._master_file = None - self._master_metadata = [] - - self._collection_dictionary = None - - def kickoff(self): - md2_msg = self.md2.standard_scan(num_images=self.collection_params["total_num_images"], - start_angle=self.collection_params["start_angle"], - scan_range=self.collection_params["scan_range"], - exposure_time=self.collection_params["exposure_time"]) - logger.info(f"md2 KICKOFF msg: {md2_msg}") - return NullStatus() - - def update_parameters(self, total_num_images, start_angle, scan_range, exposure_time): - self.collection_params = { - "total_num_images": total_num_images, - "start_angle": start_angle, - "scan_range": scan_range, - "exposure_time": exposure_time, - } - - def configure_detector(self, file_prefix, data_directory_name): - self.detector.file.external_name.put(file_prefix) - self.detector.file.write_path_template = data_directory_name - - def detector_arm(self, angle_start, img_width, total_num_images, exposure_per_image, - file_prefix, data_directory_name, file_number_start, x_beam, y_beam, - wavelength, det_distance_m): - self.detector.cam.save_files.put(1) - self.detector.cam.sequence_id.put(file_number_start) - self.detector.cam.det_distance.put(det_distance_m) - self.detector.cam.file_owner.put(getpass.getuser()) - self.detector.cam.file_owner_grp.put(grp.getgrgid(os.getgid())[0]) - self.detector.cam.file_perms.put(420) - file_prefix_minus_directory = str(file_prefix) - file_prefix_minus_directory = file_prefix_minus_directory.split("/")[-1] - self.detector.cam.acquire_time.put(exposure_per_image) - self.detector.cam.acquire_period.put(exposure_per_image) - self.detector.cam.num_triggers.put(1) - self.detector.cam.num_images.put(total_num_images) - self.detector.cam.trigger_mode.put( - EXTERNAL_SERIES - ) # must be external_enable to get the correct number of triggers and stop acquire - self.detector.cam.file_path.put(data_directory_name) - self.detector.cam.fw_name_pattern.put(f"{file_prefix_minus_directory}_$id") - self.detector.cam.beam_center_x.put(x_beam) - self.detector.cam.beam_center_y.put(y_beam) - self.detector.cam.omega_incr.put(img_width) - self.detector.cam.omega_start.put(angle_start) - self.detector.cam.wavelength.put(wavelength) - self.detector.file.file_write_images_per_file.put(500) - - #def armed_callback(value, old_value, **kwargs): - # if old_value == 0 and value == 1: - # return True - # return False - - #status = SubscriptionStatus(self.detector.cam.armed, armed_callback, run=False) - #self.detector.cam.acquire.put(1) - #yield status - - def complete(self): - # monitor md2 status, wait for ready or timeout and then return - #ready_status = self.md2.ready_status() - - #logger.info(f"TASK INFO[6]: {self.md2.task_info[6]}") - #logger.info(f"TASK OUTPUT: {self.md2.task_output}") - logger.debug(f"FLYER COMPLETE FUNCTION") - task_status = self.md2.task_status() - logger.debug(f"assigning task status") - timeout = (self.collection_params["exposure_time"] * 3) + 80 - logger.info(f"TASK TIMEOUT: {timeout}") - #ready_status.wait(timeout=timeout) - try: - task_status.wait(timeout=timeout) - except WaitTimeoutError: - logger.info("reached task timeout") - logger.info(f"TASK INFO: {self.md2.task_info}") - logger.info(f"TASK OUTPUT: {self.md2.task_output}") - return - return task_status - - def describe_collect(self): - return {"stream_name": {}} - #return {self.name: self._collection_dictionary} - - def collect(self): - logger.debug("raster_flyer.collect(): going to unstage now") - yield {"data": {}, "timestamps": {}, "time": 0, "seq_num": 0} - #return self._collection_dictionary - - def unstage(self): - logger.debug("flyer unstaging") - self.collection_params = {} - - def read_configuration(self): - return {} - - def describe_configuration(self): - return {} - - # def collect_asset_docs(self): - # for _ in (): - # yield _ - - def collect_asset_docs(self): - asset_docs_cache = [] - - # Get the Resource which was produced when the detector was staged. - ((name, resource),) = self.detector.file.collect_asset_docs() - - asset_docs_cache.append(("resource", resource)) - self._datum_ids = DEFAULT_DATUM_DICT - # Generate Datum documents from scratch here, because the detector was - # triggered externally by the DeltaTau, never by ophyd. - resource_uid = resource["uid"] - # num_points = int(math.ceil(self.detector.cam.num_images.get() / - # self.detector.cam.fw_num_images_per_file.get())) - - # We are currently generating only one datum document for all frames, that's why - # we use the 0th index below. - # - # Uncomment & update the line below if more datum documents are needed: - # for i in range(num_points): - - seq_id = self.detector.cam.sequence_id.get() - - self._master_file = f"{resource['root']}/{resource['resource_path']}_{seq_id}_master.h5" - if not os.path.isfile(self._master_file): - raise RuntimeError(f"File {self._master_file} does not exist") - - # The pseudocode below is from Tom Caswell explaining the relationship between resource, datum, and events. - # - # resource = { - # "resource_id": "RES", - # "resource_kwargs": {}, # this goes to __init__ - # "spec": "AD-EIGER-MX", - # ...: ..., - # } - # datum = { - # "datum_id": "a", - # "datum_kwargs": {"data_key": "data"}, # this goes to __call__ - # "resource": "RES", - # ...: ..., - # } - # datum = { - # "datum_id": "b", - # "datum_kwargs": {"data_key": "omega"}, - # "resource": "RES", - # ...: ..., - # } - - # event = {...: ..., "data": {"detector_img": "a", "omega": "b"}} - - for data_key in self._datum_ids.keys(): - datum_id = f"{resource_uid}/{data_key}" - self._datum_ids[data_key] = datum_id - datum = { - "resource": resource_uid, - "datum_id": datum_id, - "datum_kwargs": {"data_key": data_key}, - } - asset_docs_cache.append(("datum", datum)) - return tuple(asset_docs_cache) - - def _extract_metadata(self, field="omega"): - with h5py.File(self._master_file, "r") as hf: - return hf.get(f"entry/sample/goniometer/{field}")[()] - -class MD2VectorFlyer(MD2StandardFlyer): - def __init__(self, md2, detector=None) -> None: - super().__init__(md2, detector) - self.name = "MD2VectorFlyer" - - def kickoff(self): - # params used are start_angle, scan_range, exposure_time, start_y, start_z, stop_y, stop_z - md2_msg = self.md2.vector_scan(start_angle=self.collection_params["start_angle"], - scan_range=self.collection_params["scan_range"], - exposure_time=self.collection_params["exposure_time"], - start_cx=self.collection_params["start_cx"], - start_cy=self.collection_params["start_cy"], - start_y=self.collection_params["start_y"], - start_z=self.collection_params["start_z"], - stop_cx=self.collection_params["stop_cx"], - stop_cy=self.collection_params["stop_cy"], - stop_y=self.collection_params["stop_y"], - stop_z=self.collection_params["stop_z"],) - logger.info(f"md2 VEC KICKOFF msg: {md2_msg}") - return NullStatus() - - def update_parameters(self, start_angle, scan_range, exposure_time, start_y, start_z, stop_y, stop_z, start_cx, start_cy, stop_cx, stop_cy): - self.collection_params = { - "start_angle": start_angle, - "scan_range": scan_range, - "exposure_time": exposure_time, - "start_cx": start_cx, - "start_cy": start_cy, - "start_y": start_y, - "start_z": start_z, - "stop_cx": stop_cx, - "stop_cy": stop_cy, - "stop_y": stop_y, - "stop_z": stop_z, - } - -class MD2RasterFlyer(MD2StandardFlyer): - # List of scan parameters values, "/t" separated. The axes start values define the beginning - # of the exposure, that is when all the axes have a steady speed and when the shutter/detector - # are triggered. - # The axes stop values are for the end of detector exposure and define the position at the - # beginning of the deceleration. - # Inputs names: "omega_range", "line_range", "total_uturn_range", "start_omega", "start_y", - # "start_z", "start_cx", "start_cy", "number_of_lines", "frames_per_lines", "exposure_time", - # "invert_direction", "use_centring_table", "use_fast_mesh_scans" - - def __init__(self, md2, detector=None) -> None: - super().__init__(md2, detector) - self.name = "MD2RasterFlyer" - - def kickoff(self): - # params used are start_angle, scan_range, exposure_time, start_y, start_z, stop_y, stop_z - md2_msg = self.md2.raster_scan(omega_range=self.collection_params["omega_range"], - line_range=self.collection_params["line_range"], - total_uturn_range=self.collection_params["total_uturn_range"], - start_omega=self.collection_params["start_omega"], - start_y=self.collection_params["start_y"], - start_z=self.collection_params["start_z"], - start_cx=self.collection_params["start_cx"], - start_cy=self.collection_params["start_cy"], - number_of_lines=self.collection_params["number_of_lines"], - frames_per_line=self.collection_params["frames_per_line"], - exposure_time=self.collection_params["exposure_time"], - invert_direction=self.collection_params["invert_direction"], - use_centring_table=self.collection_params["use_centring_table"], - use_fast_mesh_scans=self.collection_params["use_fast_mesh_scans"]) - logger.info(f"md2 RASTER KICKOFF msg: {md2_msg}") - return NullStatus() - - def update_parameters(self, omega_range, line_range, total_uturn_range, start_omega, start_y, start_z, start_cx, start_cy, number_of_lines, frames_per_line, exposure_time, invert_direction, use_centring_table, use_fast_mesh_scans): - self.collection_params = { - "omega_range": omega_range, - "line_range": line_range, - "total_uturn_range": total_uturn_range, - "start_omega": start_omega, - "start_y": start_y, - "start_z": start_z, - "start_cx": start_cx, - "start_cy": start_cy, - "number_of_lines": number_of_lines, - "frames_per_line": frames_per_line, - "exposure_time": exposure_time, - "invert_direction": invert_direction, - "use_centring_table": use_centring_table, - "use_fast_mesh_scans": use_fast_mesh_scans, - } diff --git a/start_bs.py b/start_bs.py index 75b2991b..80864f99 100755 --- a/start_bs.py +++ b/start_bs.py @@ -17,27 +17,9 @@ # Provide an endstation prefix, if needed, with a trailing "-" new_md = RedisJSONDict(redis.Redis(uri),prefix="lsdc-") -#12/19 - author unknown. DAMA can help -""" -# Subscribe metadatastore to documents. -# If this is removed, data is not saved to metadatastore. -import metadatastore.commands -from bluesky.global_state import gs -gs.RE.subscribe_lossless('all', metadatastore.commands.insert) -from bluesky.callbacks.broker import post_run -# At the end of every run, verify that files were saved and -# print a confirmation message. -from bluesky.callbacks.broker import verify_files_saved -gs.RE.subscribe('stop', post_run(verify_files_saved)) -""" -# Import matplotlib and put it in interactive mode. import matplotlib.pyplot as plt plt.ion() -# Register bluesky IPython magics. -#from bluesky.magics import BlueskyMagics -#get_ipython().register_magics(BlueskyMagics) - import bluesky.plans as bp from bluesky.run_engine import RunEngine @@ -53,34 +35,12 @@ from bluesky.log import config_bluesky_logging config_bluesky_logging() -#from bluesky.utils import ts_msg_hook -#RE.msg_hook = ts_msg_hook -# from bluesky.callbacks.best_effort import BestEffortCallback -# bec = BestEffortCallback() -# RE.subscribe(bec) -# convenience imports -# from ophyd.commands import * from bluesky.callbacks import * -# from bluesky.spec_api import * -# from bluesky.global_state import gs, abort, stop, resume -# from databroker import (DataBroker as db, get_events, get_images, -# get_table, get_fields, restream, process) - -# RE = gs.RE # convenience alias -#rest is hugo abort = RE.abort resume = RE.resume stop = RE.stop -# the following lines should not be needed as these should be persisted -#RE.md['group'] = beamline -#RE.md['beamline_id'] = beamline.upper() - -# loop = asyncio.get_event_loop() -# loop.set_debug(False) - - from ophyd import (SingleTrigger, ProsilicaDetector, ImagePlugin, StatsPlugin, ROIPlugin) @@ -208,47 +168,6 @@ class SampleXYZ(Device): home_pins = home_pins_plan(gov_mon_signal, gonio_mon_signal, pyz_homer, gonio) robot_arm = RobotArm("XF:17IDC-ES:FMX", name="robot_arm") cs700 = CryoStream("XF:17ID2:CS700:", name="cs700", atol=0.1) - -elif beamline=="nyx": - from mxbluesky.devices.md2 import LightDevice, BeamstopDevice, MD2SimpleHVDevice, MD2Device, ShutterDevice - two_click_low = mount_pos = loop_detector = top_aligner_fast = top_aligner_slow = work_pos = None - mercury = ABBIXMercury('XF:17IDC-ES:FMX{Det:Mer}', name='mercury') - mercury.read_attrs = ['mca.spectrum', 'mca.preset_live_time', 'mca.rois.roi0.count', - 'mca.rois.roi1.count', 'mca.rois.roi2.count', 'mca.rois.roi3.count'] - vdcm = VerticalDCM('XF:17IDA-OP:FMX{Mono:DCM', name='vdcm') - md2 = MD2Device("XF:19IDC-ES{MD2}:", name="md2") - gonio = md2 - shutter = ShutterDevice('XF:19IDC-ES{MD2}:', name='shutter') - beamstop = BeamstopDevice('XF:19IDC-ES{MD2}:', name='beamstop') - front_light = LightDevice('XF:19IDC-ES{MD2}:Front', name='front_light') - back_light = LightDevice('XF:19IDC-ES{MD2}:Back', name='back_light') - aperature = MD2SimpleHVDevice('XF:19IDC-ES{MD2}:Aperature', name='aperature') - scintillator = MD2SimpleHVDevice('XF:19IDC-ES{MD2}:Scintillator', name='scintillator') - capillary = MD2SimpleHVDevice('XF:19IDC-ES{MD2}:Capillary', name='capillary') - zebra = Zebra('XF:19IDC-ES{Zeb:1}:', name='zebra') - from nyxtools.vector import VectorProgram - vector = VectorProgram("XF:19IDC-ES{Gon:1-Vec}", name="vector") - from mxtools.eiger import EigerSingleTriggerV26 - detector = EigerSingleTriggerV26("XF:19ID-ES:NYX{Det:Eig9M}", name="detector", beamline=beamline) - #from nyxtools.flyer_eiger2 import NYXEiger2Flyer - from mxbluesky.md2_flyers import MD2StandardFlyer, MD2VectorFlyer, MD2RasterFlyer - flyer = MD2StandardFlyer(md2, detector) - vector_flyer = MD2VectorFlyer(md2, detector) - raster_flyer = MD2RasterFlyer(md2, detector) - - from nyxtools.isara_robot import IsaraRobotDevice - from denso_robot import OphydRobot - ophyd_robot = IsaraRobotDevice("XF19IDC-ES{Rbt:1}", name="robot") - robot = OphydRobot(ophyd_robot) # OphydRobot is the robot_lib API-compatible object - govs = _make_governors("XF:19IDC-ES", name="govs") - gov_robot = govs.gov.Robot - - det_move_done = EpicsSignalRO("XF:19IDC-ES{Det:1-Ax:Z}Mtr.DMOV", name="det_move_done") - #back_light = EpicsSignal(read_pv="XF:19IDD-CT{DIODE-Box_D1:4}InCh00:Data-RB",write_pv="XF:19IDD-CT{DIODE-Box_D1:4}OutCh00:Data-SP",name="back_light") - back_light_low_limit = EpicsSignalRO("XF:19IDD-CT{DIODE-Box_D1:4}CfgCh00:LowLimit-RB",name="back_light_low_limit") - back_light_high_limit = EpicsSignalRO("XF:19IDD-CT{DIODE-Box_D1:4}CfgCh00:HighLimit-RB",name="back_light_high_limit") - back_light_range = (back_light_low_limit.get(), back_light_high_limit.get()) - samplexyz = SampleXYZ("XF:19IDC-ES{Gon:1-Ax", name="samplexyz") else: raise Exception(f"Invalid beamline name provided: {beamline}") From ad9d8a9d69b59578f1eda30e7e6a0f45991d0baa Mon Sep 17 00:00:00 2001 From: Shekar V Date: Wed, 14 Jan 2026 08:40:22 -0500 Subject: [PATCH 2/4] Fixed syntax errors suggested by copilot Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- daq_lib.py | 2 +- gui/control_main.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/daq_lib.py b/daq_lib.py index 12e62ec6..f7723e3e 100644 --- a/daq_lib.py +++ b/daq_lib.py @@ -758,7 +758,7 @@ def collect_detector_seq_hw(sweep_start,range_degrees,image_width,exposure_perio logger.info("collect %f degrees for %f seconds %d images exposure_period = %f exposure_time = %f" % (range_degrees,range_seconds,number_of_images,exposure_period,exposure_time)) - if (protocol in (CollectionProtocols.STANDARD, CollectionProtocols.BURN): + if (protocol in (CollectionProtocols.STANDARD, CollectionProtocols.BURN)): logger.info("vectorSync " + str(time.time())) daq_macros.vectorSync() logger.info("zebraDaq " + str(time.time())) diff --git a/gui/control_main.py b/gui/control_main.py index 7a9f8cf5..6f5aa8d2 100644 --- a/gui/control_main.py +++ b/gui/control_main.py @@ -595,7 +595,7 @@ def createSampleTab(self): colBeamHLabel.setAlignment(QtCore.Qt.AlignCenter) self.beamHeight_ledit = QtWidgets.QLineEdit() self.beamHeight_ledit.setFixedWidth(60) - hBoxColParams4.addWidget(self.colBeamWLabel) + hBoxColParams4.addWidget(colBeamWLabel) hBoxColParams4.addWidget(self.beamWidth_ledit) hBoxColParams4.addWidget(colBeamHLabel) hBoxColParams4.addWidget(self.beamHeight_ledit) @@ -4977,7 +4977,7 @@ def pauseButtonStateCB(self, value=None, char_value=None, **kw): self.pauseButtonStateSignal.emit(pauseButtonStateVar) def initOphyd(self): - if daq_utils.beamline = "amx": + if daq_utils.beamline == "amx": ophyd_prefix = "XF:17IDB-ES:AMX" else: ophyd_prefix = "XF:17IDC-ES:FMX" From 13030ce2c45b2003c3789c57170e4186f061d274 Mon Sep 17 00:00:00 2001 From: vshekar1 Date: Wed, 14 Jan 2026 08:47:06 -0500 Subject: [PATCH 3/4] Changed local variables to instance variables in control_main --- gui/control_main.py | 78 ++++++++++++++++++++++----------------------- 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/gui/control_main.py b/gui/control_main.py index 6f5aa8d2..59dc3db2 100644 --- a/gui/control_main.py +++ b/gui/control_main.py @@ -435,9 +435,9 @@ def createSampleTab(self): colParamsGB = QtWidgets.QGroupBox() colParamsGB.setTitle("Acquisition") vBoxColParams1 = QtWidgets.QVBoxLayout() - colStartLabel = QtWidgets.QLabel("Oscillation Start:") - colStartLabel.setFixedWidth(140) - colStartLabel.setAlignment(QtCore.Qt.AlignCenter) + self.colStartLabel = QtWidgets.QLabel("Oscillation Start:") + self.colStartLabel.setFixedWidth(140) + self.colStartLabel.setAlignment(QtCore.Qt.AlignCenter) self.osc_start_ledit = QtWidgets.QLineEdit() self.setGuiValues({"osc_start": "0.0"}) self.osc_start_ledit.setFixedWidth(60) @@ -454,9 +454,9 @@ def createSampleTab(self): ) if daq_utils.beamline == "fmx": self.osc_end_ledit.textChanged.connect(self.calcLifetimeCB) - colRangeLabel = QtWidgets.QLabel("Oscillation Width:") - colRangeLabel.setFixedWidth(140) - colRangeLabel.setAlignment(QtCore.Qt.AlignCenter) + self.colRangeLabel = QtWidgets.QLabel("Oscillation Width:") + self.colRangeLabel.setFixedWidth(140) + self.colRangeLabel.setAlignment(QtCore.Qt.AlignCenter) self.osc_range_ledit = QtWidgets.QLineEdit() self.osc_range_ledit.setFixedWidth(60) self.osc_range_ledit.setValidator(QtGui.QDoubleValidator(0.001, 3600, 3)) @@ -469,13 +469,13 @@ def createSampleTab(self): else: self.stillModeCheckBox.setChecked(False) self.osc_range_ledit.setEnabled(True) - colExptimeLabel = QtWidgets.QLabel("ExposureTime:") + self.colExptimeLabel = QtWidgets.QLabel("ExposureTime:") self.stillModeCheckBox.clicked.connect(self.stillModeUserPushCB) self.osc_range_ledit.textChanged[str].connect( functools.partial(self.totalExpChanged, "oscRange") ) - colExptimeLabel.setFixedWidth(140) - colExptimeLabel.setAlignment(QtCore.Qt.AlignCenter) + self.colExptimeLabel.setFixedWidth(140) + self.colExptimeLabel.setAlignment(QtCore.Qt.AlignCenter) self.exp_time_ledit = QtWidgets.QLineEdit() self.exp_time_ledit.setFixedWidth(60) self.exp_time_ledit.textChanged[str].connect(self.totalExpChanged) @@ -487,9 +487,9 @@ def createSampleTab(self): ) ) self.exp_time_ledit.textChanged.connect(self.checkEntryState) - totalExptimeLabel = QtWidgets.QLabel("Total Exposure Time (s):") - totalExptimeLabel.setFixedWidth(155) - totalExptimeLabel.setAlignment(QtCore.Qt.AlignCenter) + self.totalExptimeLabel = QtWidgets.QLabel("Total Exposure Time (s):") + self.totalExptimeLabel.setFixedWidth(155) + self.totalExptimeLabel.setAlignment(QtCore.Qt.AlignCenter) self.totalExptime_ledit = QtWidgets.QLineEdit() self.totalExptime_ledit.setReadOnly(True) self.totalExptime_ledit.setFrame(False) @@ -503,7 +503,7 @@ def createSampleTab(self): ) self.totalExptime_ledit.textChanged.connect(self.checkEntryState) - sampleLifetimeLabel = QtWidgets.QLabel("Estimated Sample Lifetime (s): ") + self.sampleLifetimeLabel = QtWidgets.QLabel("Estimated Sample Lifetime (s): ") if daq_utils.beamline == "amx": self.sampleLifetimeReadback = QtEpicsPVLabel( daq_utils.pvLookupDict["sampleLifetime"], self, 70, 2 @@ -522,7 +522,7 @@ def createSampleTab(self): self.transmissionSetPoint = QtEpicsPVEntry( daq_utils.pvLookupDict["RI_Atten_SP"], self, 60, 3 ) - colTransmissionLabel = QtWidgets.QLabel("Transmission (RI) (0.0-1.0):") + self.colTransmissionLabel = QtWidgets.QLabel("Transmission (RI) (0.0-1.0):") else: self.transmissionReadback = QtEpicsPVLabel( daq_utils.pvLookupDict["transmissionRBV"], self, 60, 3 @@ -530,7 +530,7 @@ def createSampleTab(self): self.transmissionSetPoint = QtEpicsPVEntry( daq_utils.pvLookupDict["transmissionSet"], self, 60, 3 ) - colTransmissionLabel = QtWidgets.QLabel("Transmission (BCU) (0.0-1.0):") + self.colTransmissionLabel = QtWidgets.QLabel("Transmission (BCU) (0.0-1.0):") else: self.transmissionReadback = QtEpicsPVLabel( daq_utils.pvLookupDict["transmissionRBV"], self, 60, 3 @@ -538,13 +538,13 @@ def createSampleTab(self): self.transmissionSetPoint = QtEpicsPVEntry( daq_utils.pvLookupDict["transmissionSet"], self, 60, 3 ) - colTransmissionLabel = QtWidgets.QLabel("Transmission (0.0-1.0):") + self.colTransmissionLabel = QtWidgets.QLabel("Transmission (0.0-1.0):") self.transmissionReadback_ledit = self.transmissionReadback.getEntry() - colTransmissionLabel.setAlignment(QtCore.Qt.AlignCenter) - colTransmissionLabel.setFixedWidth(190) + self.colTransmissionLabel.setAlignment(QtCore.Qt.AlignCenter) + self.colTransmissionLabel.setFixedWidth(190) - transmisionSPLabel = QtWidgets.QLabel("SetPoint:") + self.transmisionSPLabel = QtWidgets.QLabel("SetPoint:") self.transmission_ledit = self.transmissionSetPoint.getEntry() self.transmission_ledit.setValidator( @@ -569,50 +569,50 @@ def createSampleTab(self): self.beamsizeComboBox.activated[str].connect(self.beamsizeComboActivatedCB) if daq_utils.beamline == "amx" or self.energy_pv.get() < 9000: self.beamsizeComboBox.setEnabled(False) - colEnergyLabel = QtWidgets.QLabel("Energy (eV):") - colEnergyLabel.setAlignment(QtCore.Qt.AlignCenter) + self.colEnergyLabel = QtWidgets.QLabel("Energy (eV):") + self.colEnergyLabel.setAlignment(QtCore.Qt.AlignCenter) self.energyMotorEntry = QtEpicsPVLabel( daq_utils.motor_dict["energy"] + ".RBV", self, 70, 2 ) self.energyReadback = self.energyMotorEntry.getEntry() - energySPLabel = QtWidgets.QLabel("SetPoint:") + self.energySPLabel = QtWidgets.QLabel("SetPoint:") self.energyMoveLedit = QtEpicsPVEntry( daq_utils.motor_dict["energy"] + ".VAL", self, 75, 2 ) self.energy_ledit = self.energyMoveLedit.getEntry() self.energy_ledit.setValidator(QtGui.QDoubleValidator()) self.energy_ledit.returnPressed.connect(self.moveEnergyMaxDeltaCB) - moveEnergyButton = QtWidgets.QPushButton("Move Energy") - moveEnergyButton.clicked.connect(self.moveEnergyCB) + self.moveEnergyButton = QtWidgets.QPushButton("Move Energy") + self.moveEnergyButton.clicked.connect(self.moveEnergyCB) hBoxColParams4 = QtWidgets.QHBoxLayout() - colBeamWLabel = QtWidgets.QLabel("Beam Width:") - colBeamWLabel.setFixedWidth(140) - colBeamWLabel.setAlignment(QtCore.Qt.AlignCenter) + self.colBeamWLabel = QtWidgets.QLabel("Beam Width:") + self.colBeamWLabel.setFixedWidth(140) + self.colBeamWLabel.setAlignment(QtCore.Qt.AlignCenter) self.beamWidth_ledit = QtWidgets.QLineEdit() self.beamWidth_ledit.setFixedWidth(60) - colBeamHLabel = QtWidgets.QLabel("Beam Height:") - colBeamHLabel.setFixedWidth(140) - colBeamHLabel.setAlignment(QtCore.Qt.AlignCenter) + self.colBeamHLabel = QtWidgets.QLabel("Beam Height:") + self.colBeamHLabel.setFixedWidth(140) + self.colBeamHLabel.setAlignment(QtCore.Qt.AlignCenter) self.beamHeight_ledit = QtWidgets.QLineEdit() self.beamHeight_ledit.setFixedWidth(60) - hBoxColParams4.addWidget(colBeamWLabel) + hBoxColParams4.addWidget(self.colBeamWLabel) hBoxColParams4.addWidget(self.beamWidth_ledit) - hBoxColParams4.addWidget(colBeamHLabel) + hBoxColParams4.addWidget(self.colBeamHLabel) hBoxColParams4.addWidget(self.beamHeight_ledit) - colResoLabel = QtWidgets.QLabel("Edge Resolution:") - colResoLabel.setAlignment(QtCore.Qt.AlignCenter) + self.colResoLabel = QtWidgets.QLabel("Edge Resolution:") + self.colResoLabel.setAlignment(QtCore.Qt.AlignCenter) self.resolution_ledit = QtWidgets.QLineEdit() self.resolution_ledit.setFixedWidth(60) self.resolution_ledit.setValidator(QtGui.QDoubleValidator()) self.resolution_ledit.textEdited[str].connect(self.resoTextChanged) self.detDistLabel = QtWidgets.QLabel("Detector Dist.") #self.detDistLabel.setAlignment(QtCore.Qt.AlignCenter) - detDistRBLabel = QtWidgets.QLabel("Readback:") + self.detDistRBLabel = QtWidgets.QLabel("Readback:") self.detDistRBVLabel = QtEpicsPVLabel( daq_utils.motor_dict["detectorDist"] + ".RBV", self, 70 ) self.detDistTextChanged(self.detDistRBVLabel.getEntry().text()) - detDistSPLabel = QtWidgets.QLabel("SetPoint:") + self.detDistSPLabel = QtWidgets.QLabel("SetPoint:") self.detDistMotorEntry = QtEpicsPVEntry( daq_utils.motor_dict["detectorDist"] + ".VAL", self, 70, 2 ) @@ -634,8 +634,8 @@ def createSampleTab(self): hBoxColParams6.setAlignment(QtCore.Qt.AlignLeft) hBoxColParams7 = QtWidgets.QHBoxLayout() hBoxColParams7.setAlignment(QtCore.Qt.AlignLeft) - centeringLabel = QtWidgets.QLabel("Sample Centering:") - centeringLabel.setFixedWidth(140) + self.centeringLabel = QtWidgets.QLabel("Sample Centering:") + self.centeringLabel.setFixedWidth(140) centeringOptionList = ["Interactive", "AutoLoop", "AutoRaster", "Testing"] self.centeringComboBox = QtWidgets.QComboBox(self) self.centeringComboBox.addItems(centeringOptionList) @@ -684,7 +684,7 @@ def createSampleTab(self): hBoxColParams6.addWidget(self.protoRasterRadio) hBoxColParams6.addWidget(self.protoVectorRadio) hBoxColParams6.addWidget(self.protoComboBox) - hBoxColParams7.addWidget(centeringLabel) + hBoxColParams7.addWidget(self.centeringLabel) hBoxColParams7.addWidget(self.centeringComboBox) self.processingOptionsFrame = QFrame() self.hBoxProcessingLayout1 = QtWidgets.QHBoxLayout() From 7bfa0c0b5f33b37c3ccaa1fce5096963d1d205ed Mon Sep 17 00:00:00 2001 From: vshekar1 Date: Wed, 14 Jan 2026 09:23:58 -0500 Subject: [PATCH 4/4] Removed commented out code --- gui/control_main.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/gui/control_main.py b/gui/control_main.py index 59dc3db2..0e828d58 100644 --- a/gui/control_main.py +++ b/gui/control_main.py @@ -1516,8 +1516,6 @@ def amx_fmx_parameter_layout(self): hBoxColParams25.addWidget(self.stillModeCheckBox) hBoxColParams25.addWidget(self.totalExptimeLabel) hBoxColParams25.addWidget(self.totalExptime_ledit) - # if (daq_utils.beamline == "fmx"): - # hBoxColParams25.addWidget(calcLifetimeButton) hBoxColParams25.addWidget(self.sampleLifetimeLabel) hBoxColParams25.addWidget(self.sampleLifetimeReadback_ledit) hBoxColParams22 = QtWidgets.QHBoxLayout()