-
Notifications
You must be signed in to change notification settings - Fork 14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft PR for the NYX compliance changes #360
base: master
Are you sure you want to change the base?
Changes from all commits
4345590
3c1c0d1
743ee58
95a5f4e
d65e7c2
f4dffc0
1cc4afc
71091c7
f38f820
2972b53
46217fb
98122b3
cb948d9
de1c2e9
7553c0b
5644371
b4e90f4
2e9678b
4cea6f9
ce3b0dd
0774515
ef8ae08
5637df5
37beeef
c90f302
86caa96
541437d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,16 +27,21 @@ | |
from collections import OrderedDict | ||
from threading import Thread | ||
from config_params import * | ||
from ophyd.status import SubscriptionStatus | ||
from kafka_producer import send_kafka_message | ||
|
||
import gov_lib | ||
import urllib.request | ||
import io | ||
|
||
from scans import (zebra_daq_prep, setup_zebra_vector_scan, | ||
setup_zebra_vector_scan_for_raster, | ||
setup_vector_program) | ||
import bluesky.plan_stubs as bps | ||
import bluesky.plans as bp | ||
from bluesky.preprocessors import finalize_wrapper | ||
from bluesky.log import config_bluesky_logging | ||
config_bluesky_logging(level='INFO') | ||
from fmx_annealer import govStatusGet, govStateSet, fmxAnnealer, amxAnnealer # for using annealer specific to FMX and AMX | ||
|
||
try: | ||
|
@@ -224,7 +229,7 @@ def changeImageCenterHighMag(x,y,czoom): | |
def autoRasterLoop(currentRequest): | ||
global autoRasterFlag | ||
|
||
|
||
logger.info('entering autoRasterLoop') | ||
gov_status = gov_lib.setGovRobot(gov_robot, 'SA') | ||
if not gov_status.success: | ||
return 0 | ||
|
@@ -823,7 +828,7 @@ def runDozorThread(directory, | |
""" | ||
global rasterRowResultsList,processedRasterRowCount | ||
|
||
time.sleep(0.5) #allow for file writing | ||
time.sleep(1.0) #allow for file writing | ||
|
||
node = getNodeName("spot", rowIndex, 8) | ||
|
||
|
@@ -1834,9 +1839,12 @@ def snakeRasterBluesky(rasterReqID, grain=""): | |
if (daq_utils.beamline == "fmx"): | ||
setPvDesc("sampleProtect",0) | ||
setPvDesc("vectorGo", 0) #set to 0 to allow easier camonitoring vectorGo | ||
|
||
govStatus = gov_lib.setGovRobot(gov_robot, "DA") | ||
if govStatus.exception(): | ||
logger.error(f"Problem during start-of-raster governor move, aborting! exception: {govStatus.exception()}") | ||
return | ||
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, rows = params_from_raster_req_id(rasterReqID) | ||
rasterRowResultsList = [{} for i in range(0,rowCount)] | ||
rasterRowResultsList = [{} for i in range(0,rowCount)] | ||
processedRasterRowCount = 0 | ||
rasterEncoderMap = {} | ||
|
||
|
@@ -1853,41 +1861,39 @@ def snakeRasterBluesky(rasterReqID, grain=""): | |
parentRequest = db_lib.getRequestByID(parentReqID) | ||
parentReqObj = parentRequest["request_obj"] | ||
parentReqProtocol = parentReqObj["protocol"] | ||
detDist = parentReqObj["detDist"] | ||
detDist = parentReqObj["detDist"] | ||
|
||
rasterFilePrefix = dataFilePrefix + "_Raster" | ||
total_exposure_time = exptimePerCell*totalImages | ||
detDist /= 1000 # TODO find a way to standardize detector distance settings | ||
|
||
raster_flyer.configure_detector(file_prefix=rasterFilePrefix, data_directory_name=data_directory_name) | ||
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.') | ||
raster_flyer.detector.cam.acquire.put(0) | ||
logger.warning("Detector was in the armed state prior to this attempted collection.") | ||
return 0 | ||
start_time = time.time() | ||
arm_status = raster_flyer.detector_arm(angle_start=omega, img_width=img_width_per_cell, total_num_images=totalImages, exposure_period_per_image=exptimePerCell, file_prefix=rasterFilePrefix, | ||
raster_flyer.detector_arm(angle_start=omega, img_width=img_width_per_cell, total_num_images=totalImages, exposure_period_per_image=exptimePerCell, file_prefix=rasterFilePrefix, | ||
data_directory_name=data_directory_name, file_number_start=file_number_start, x_beam=xbeam, y_beam=ybeam, wavelength=wave, det_distance_m=detDist, | ||
num_images_per_file=numsteps) | ||
govStatus = gov_lib.setGovRobot(gov_robot, "DA") | ||
arm_status.wait() | ||
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-raster governor move, aborting! exception: {govStatus.exception()}") | ||
return | ||
raster_flyer.configure_detector(file_prefix=rasterFilePrefix, data_directory_name=data_directory_name) | ||
raster_flyer.detector.stage() | ||
num_images_per_file=numsteps) # rasterDef['numCells']) TODO: try to get all images in one file | ||
#raster_flyer.detector.stage() | ||
procFlag = int(getBlConfig("rasterProcessFlag")) | ||
spotFindThreadList = [] | ||
yield from bps.mv(samplexyz.omega, (omega-1)) # attempting to over-compensate omega movement | ||
for row_index, row in enumerate(rows): # since we have vectors in rastering, don't move between each row | ||
xMotAbsoluteMove, xEnd, yMotAbsoluteMove, yEnd, zMotAbsoluteMove, zEnd = raster_positions(row, stepsize, omegaRad, rasterStartX, rasterStartY, rasterStartZ, row_index) | ||
vector = {'x': (xMotAbsoluteMove, xEnd), 'y': (yMotAbsoluteMove, yEnd), 'z': (zMotAbsoluteMove, zEnd)} | ||
logger.info(f'starting new row: {row_index}') | ||
zMotAbsoluteMove, zEnd, yMotAbsoluteMove, yEnd, xMotAbsoluteMove, xEnd = raster_positions(row, stepsize, omegaRad+90, rasterStartZ*1000, rasterStartY*1000, rasterStartX*1000, row_index) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. these factors of 1000 cannot stay. can't you refine or make alternative PVs for sample centering-related PVs that would enable you to keep the current values and the same names of the objects to be moved? |
||
vector = {'x': (xMotAbsoluteMove/1000, xEnd/1000), 'y': (yMotAbsoluteMove/1000, yEnd/1000), 'z': (zMotAbsoluteMove/1000, zEnd/1000)} | ||
yield from bps.mv(samplexyz.x, xMotAbsoluteMove/1000, samplexyz.y, yMotAbsoluteMove/1000, samplexyz.z, zMotAbsoluteMove/1000, samplexyz.omega, omega-0.05) | ||
yield from zebraDaqRasterBluesky(raster_flyer, omega, numsteps, img_width_per_cell * numsteps, img_width_per_cell, exptimePerCell, rasterFilePrefix, | ||
data_directory_name, file_number_start, row_index, vector) | ||
raster_flyer.zebra.reset.put(1) # reset after every row to make sure it is clear for the next row | ||
time.sleep(0.2) # necessary for reliable row processing - see comment in commit 6793f4 | ||
#raster_flyer.zebra.reset.put(1) # reset after every row to make sure it is clear for the next row | ||
yield from bps.sleep(0.3) # necessary for reliable row processing - see comment in commit 6793f4 | ||
|
||
# processing | ||
if (procFlag): | ||
if (procFlag): | ||
if (daq_utils.detector_id == "EIGER-16"): | ||
seqNum = int(raster_flyer.detector.file.sequence_id.get()) | ||
else: | ||
|
@@ -1909,6 +1915,7 @@ def snakeRasterBluesky(rasterReqID, grain=""): | |
initiate transitions here allows for GUI sample/heat map image to update | ||
after moving to known position""" | ||
logger.debug(f'lastOnSample(): {lastOnSample()} autoRasterFlag: {autoRasterFlag}') | ||
yield from bps.sleep(3) #waiting for detector to not lose row | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this would be a major problem for the other beamlines, where this sleep isn't necessary |
||
if (lastOnSample() and not autoRasterFlag): | ||
govStatus = gov_lib.setGovRobot(gov_robot, 'SA', wait=False) | ||
if govStatus.exception(): | ||
|
@@ -1932,7 +1939,7 @@ def snakeRasterBluesky(rasterReqID, grain=""): | |
#data acquisition is finished, now processing and sample positioning | ||
if not procFlag: # no, no processing. just move to raster start | ||
#must go to known position to account for windup dist. | ||
logger.info("moving to raster start") | ||
logger.info(f" no processing! moving to raster start: {rasterStartX} {rasterStartY} {rasterStartZ} {omega}") | ||
yield from bps.mv(samplexyz.x, rasterStartX) | ||
yield from bps.mv(samplexyz.y, rasterStartY) | ||
yield from bps.mv(samplexyz.z, rasterStartZ) | ||
|
@@ -1941,25 +1948,37 @@ def snakeRasterBluesky(rasterReqID, grain=""): | |
|
||
else: # yes, do row processing | ||
if daq_lib.abort_flag != 1: | ||
print("processing rows") | ||
[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)) | ||
logger.info(str(processedRasterRowCount) + "/" + str(rowCount)) | ||
rasterResult = generateGridMap(rasterRequest) | ||
|
||
logger.info(f'protocol = {reqObj["protocol"]}') | ||
if (reqObj["protocol"] == "multiCol" or parentReqProtocol == "multiColQ"): | ||
if (parentReqProtocol == "multiColQ"): | ||
if (parentReqProtocol == "multiColQ"): | ||
multiColThreshold = parentReqObj["diffCutoff"] | ||
else: | ||
multiColThreshold = reqObj["diffCutoff"] | ||
gotoMaxRaster(rasterResult,multiColThreshold=multiColThreshold) | ||
multiColThreshold = reqObj["diffCutoff"] | ||
# gotoMaxRaster(rasterResult,multiColThreshold=multiColThreshold) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. calls to other code can't just be removed. make a config variable or something that enables you to make NYX work with your code while AMX/FMX use the gotoMaxRaster() function |
||
logger.info(f"moving to raster start: {rasterStartX} {rasterStartY} {rasterStartZ} {omega}") | ||
yield from bps.mv(samplexyz.x, rasterStartX) | ||
yield from bps.mv(samplexyz.y, rasterStartY) | ||
yield from bps.mv(samplexyz.z, rasterStartZ) | ||
yield from bps.mv(samplexyz.omega, omega) | ||
else: | ||
try: | ||
# go to start omega for faster heat map display | ||
gotoMaxRaster(rasterResult,omega=omega) | ||
# gotoMaxRaster(rasterResult,omega=omega) | ||
logger.info(f"moving to raster start: {rasterStartX} {rasterStartY} {rasterStartZ} {omega}") | ||
yield from bps.mv(samplexyz.x, rasterStartX) | ||
yield from bps.mv(samplexyz.y, rasterStartY) | ||
yield from bps.mv(samplexyz.z, rasterStartZ) | ||
yield from bps.mv(samplexyz.omega, omega) | ||
except ValueError: | ||
#must go to known position to account for windup dist. | ||
logger.info(f"moving to raster start: {rasterStartX} {rasterStartY} {rasterStartZ} {omega}") | ||
logger.info("moving to raster start") | ||
yield from bps.mv(samplexyz.x, rasterStartX) | ||
yield from bps.mv(samplexyz.y, rasterStartY) | ||
|
@@ -1984,7 +2003,7 @@ def snakeRasterBluesky(rasterReqID, grain=""): | |
rasterRequest["request_obj"]["rasterDef"]["status"] = ( | ||
RasterStatus.READY_FOR_SNAPSHOT.value | ||
) | ||
db_lib.updateRequest(rasterRequest) | ||
db_lib.updateRequest(rasterRequest) | ||
db_lib.updatePriority(rasterRequestID,-1) | ||
|
||
#ensure gov transitions have completed successfully | ||
|
@@ -2269,11 +2288,11 @@ def gotoMaxRaster(rasterResult,multiColThreshold=-1,**kwargs): | |
logger.info("goto " + str(x) + " " + str(y) + " " + str(z)) | ||
|
||
if 'omega' in kwargs: | ||
beamline_lib.mvaDescriptor("sampleX",x, | ||
"sampleY",y, | ||
"sampleZ",z, | ||
beamline_lib.mvaDescriptor("sampleX",x/1000, | ||
"sampleY",y/1000, | ||
"sampleZ",z/1000, | ||
"omega",kwargs['omega']) | ||
else: beamline_lib.mvaDescriptor("sampleX",x,"sampleY",y,"sampleZ",z) | ||
else: beamline_lib.mvaDescriptor("sampleX",x/1000,"sampleY",y/1000,"sampleZ",z/1000) | ||
|
||
if (autoVectorFlag): #if we found a hotspot, then look again at cellResults for coarse vector start and end | ||
xminColumn = [] #these are the "line rasters" of the ends of threshold points determined by the first pass on the raster results | ||
|
@@ -3210,12 +3229,20 @@ def clean_up_files(pic_prefix, output_file): | |
|
||
def loop_center_xrec(): | ||
global face_on | ||
print('entering daq_macros.loop_center_xrec') | ||
|
||
daq_lib.abort_flag = 0 | ||
pic_prefix = "findloop" | ||
output_file = 'xrec_result.txt' | ||
print('clean up files') | ||
clean_up_files(pic_prefix, output_file) | ||
zebraCamDaq(0,360,40,.4,pic_prefix,getBlConfig("visitDirectory"),0) | ||
#TODO: if daq_utils.beamline=='nyx': | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. make sure that the AMX/FMX code works for them |
||
print('post clean') | ||
xrec_no_zebra(0) | ||
print('post no zebra') | ||
#else: | ||
# zebraCamDaq(0,360,40,.4,pic_prefix,os.getcwd(),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: | ||
|
@@ -3268,7 +3295,37 @@ def loop_center_xrec(): | |
#now try to get the loopshape starting from here | ||
return 1 | ||
|
||
|
||
def xrec_no_zebra(angle_start): | ||
print(f'xrec_no_zebra{angle_start}') | ||
beamline_lib.mvaDescriptor("omega", angle_start) | ||
#yield from bps.mv(samplexyz.omega, angle_start) | ||
for omega_target in range (angle_start, angle_start+360, 40): | ||
#yield from bps.mv(samplexyz.omega, omega_target) | ||
beamline_lib.mvaDescriptor("omega", omega_target) | ||
logger.info(f'taking image at {omega_target}') | ||
timeout = 5 | ||
# change image mode to single(0) | ||
setPvDesc("lowMagImMode",0) | ||
# start camera | ||
setPvDesc("lowMagAcquire",1) | ||
try: | ||
with urllib.request.urlopen(daq_utils.lowMagCamURL, timeout=timeout) as response: | ||
logger.info("xnz: read") | ||
image_data = response.read() | ||
logger.info("xnz: read") | ||
with open(getBlConfig("visitDirectory")+"findloop_"+str(omega_target//40)+".jpg", "wb") as filename: | ||
logger.info("xnz: write file") | ||
filename.write(image_data) | ||
logger.info("xnz: write file") | ||
except urllib.error.URLError as e: | ||
print("Error:", e) | ||
logger.info("xnz: sleep") | ||
time.sleep(1) | ||
# change image mode to continuous(2) | ||
setPvDesc("lowMagImMode",2) | ||
# start camera | ||
setPvDesc("lowMagAcquire",1) | ||
|
||
|
||
def zebraCamDaq(angle_start,scanWidth,imgWidth,exposurePeriodPerImage,filePrefix,data_directory_name,file_number_start,scanEncoder=3): #scan encoder 0=x, 1=y,2=z,3=omega | ||
#careful - there's total exposure time, exposure period, exposure time | ||
|
@@ -3385,8 +3442,20 @@ def zebraDaqBluesky(flyer, angle_start, num_images, scanWidth, imgWidth, exposur | |
'change_state':changeState, 'transmission':vector_params["transmission"], | ||
'data_path':data_path} | ||
start_time = time.time() | ||
arm_status = flyer.detector_arm(**required_parameters) | ||
flyer.detector_arm(**required_parameters) | ||
|
||
def armed_callback(value, old_value, **kwargs): | ||
if old_value == 0 and value == 1: | ||
return True | ||
return False | ||
|
||
arm_status = SubscriptionStatus(flyer.detector.cam.armed, armed_callback, run=False) | ||
|
||
flyer.detector.cam.acquire.put(1) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. shouldn't this acquire be done after the detector is armed? |
||
|
||
govStatus = gov_lib.setGovRobot(gov_robot, "DA") | ||
time.sleep(0.5) | ||
govStatus.wait() | ||
arm_status.wait() | ||
logger.info(f"Governor move to DA and synchronous arming took {time.time()-start_time} seconds.") | ||
if govStatus.exception(): | ||
|
@@ -3441,7 +3510,7 @@ def zebraDaqRasterBluesky(flyer, angle_start, num_images, scanWidth, imgWidth, e | |
row_index=row_index, transmission=1, protocol="raster") | ||
yield from bp.fly([raster_flyer]) | ||
|
||
logger.info("vector Done") | ||
logger.info(f"vector Done, zebra arm status: {raster_flyer.zebra.pc.arm.output}") | ||
logger.info("zebraDaqRasterBluesky Done") | ||
|
||
def zebraDaq(vector_program,angle_start,scanWidth,imgWidth,exposurePeriodPerImage,filePrefix,data_directory_name,file_number_start,scanEncoder=3,changeState=True): #scan encoder 0=x, 1=y,2=z,3=omega | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -28,12 +28,9 @@ | |
logging.getLogger('ophyd').setLevel(logging.WARN) | ||
logging.getLogger('caproto').setLevel(logging.WARN) | ||
handler1 = handlers.RotatingFileHandler('lsdcServerLog.txt', maxBytes=5000000, backupCount=100) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. again, differences cannot be completely removed. |
||
handler2 = handlers.RotatingFileHandler('/var/log/dama/%slsdcServerLog.txt' % os.environ['BEAMLINE_ID'], maxBytes=5000000, backupCount=100) | ||
myformat = logging.Formatter('%(asctime)s %(name)-8s %(levelname)-8s %(message)s') | ||
handler1.setFormatter(myformat) | ||
handler2.setFormatter(myformat) | ||
logger.addHandler(handler1) | ||
logger.addHandler(handler2) | ||
|
||
perform_server_checks() | ||
setBlConfig("visitDirectory", os.getcwd()) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is there any reason why you couldn't use
DETECTOR_OBJECT_TYPE_OPHYD
?