def Gas_Plan(gas_in='He', liveplot_key=None, totExpTime=5, num_exp=1, delay=1): """ Example ------- Set the gasses. They can be in any other, nothing to do with the order they are used in the plan. But, should match the connections on switch. >>> gas.gas_list = ['He', 'N2', 'CO2'] >>> RGA mass is set to different value, base shows 1^-13 with He 5 cc flow shows max 2^-8 >>> RGA mass setup in mID mode: 4,18,28,31,44,79,94,32,81 Parameters ---------- gas_in : string e.g., 'He', default is 'He' These gas must be in `gas.gas_list` but they may be in any order. liveplot_key : str, optional e. g., liveplot_key = rga_mass1 data key for LivePlot. default is None, which means no LivePlot totExpTime : float total exposure time per frame in seconds. Dafault value is 5 sec num_exp : int number of images/exposure, default is 1 delay: float delay time between exposures in sec Execute it ---------- >> %run -i /home/xf28id1/Documents/Sanjit/Scripts/GasXrun_Plan.py >> change all the parameters inside Gas_Plan as required >>> gas_plan = Gas_Plan(gas_in = 'He', liveplot_key= 'rga_mass1', totExpTime = 5, num_exp = 3, delay = 1) >> to run the xrun, save metadata & save_tiff run the following >>> run_and_save(sample_num = 0) """ ## switch gas yield from abs_set(gas, gas_in) ## configure the exposure time first _configure_area_det(totExpTime) # 5 secs exposuretime ## ScanPlan you need plan = bp.count([pe1c, gas.current_gas, rga], num=num_exp, delay=delay) #plan = bp.subs_wrapper(plan, LiveTable([xpd_configuration['area_det'], rga])) # give you LiveTable plan = bp.subs_wrapper( plan, LiveTable([xpd_configuration['area_det'], gas.current_gas, rga])) if liveplot_key and isinstance(liveplot_key, str): plan = bp.subs_wrapper(plan, LivePlot(liveplot_key)) yield from plan
def cam_scan(detectors, camera, motor, start, stop, num, md=None, idle_time=1): def per_step(dets, motor, step): yield from one_1d_step(dets, motor, step) yield from bp.abs_set(camera, 1, wait=True) yield from bp.abs_set(camera, 0, wait=True) yield from bp.sleep(idle_time) if md is None: md = {} md = ChainMap( md, {'plan_args': {'detectors': list(map(repr, detectors)), 'num': num, 'motor': repr(motor), 'start': start, 'stop': stop, 'per_step': repr(per_step), 'idle_time': float(idle_time)}, 'plan_name': 'cam_scan', }) return (yield from bp.subs_wrapper( bp.scan(detectors, motor, start, stop, num, per_step=per_step, md=md), LiveTable(detectors + [motor])) )
def take_dark(): """a plan for taking a single dark frame""" print('INFO: closing shutter...') # 60 means open at XPD, Oct.4, 2016 yield from bp.abs_set(glbl.shutter, 0, wait=True) #if glbl.shutter_control: # yield from bp.sleep(2) print('INFO: taking dark frame....') # upto this stage, glbl.pe1c has been configured to so exposure time is # correct acq_time = glbl.area_det.cam.acquire_time.get() num_frame = glbl.area_det.images_per_set.get() computed_exposure = acq_time * num_frame # update md _md = { 'sp_time_per_frame': acq_time, 'sp_num_frames': num_frame, 'sp_computed_exposure': computed_exposure, 'sp_type': 'ct', # 'sp_uid': str(uuid.uuid4()), # dark plan doesn't need uid 'sp_plan_name': 'dark_{}'.format(computed_exposure), 'dark_frame': True } c = bp.count([glbl.area_det], md=_md) yield from bp.subs_wrapper(c, {'stop': [_update_dark_dict_list]}) print('opening shutter...')
def take_dark(): """a plan for taking a single dark frame""" print('INFO: closing shutter...') yield from bp.abs_set(glbl.shutter, 0) if glbl.shutter_control: yield from bp.sleep(2) print('INFO: taking dark frame....') # upto this stage, glbl.pe1c has been configured to so exposure time is # correct acq_time = glbl.area_det.cam.acquire_time.get() num_frame = glbl.area_det.images_per_set.get() computed_exposure = acq_time * num_frame # update md _md = {'sp_time_per_frame': acq_time, 'sp_num_frames': num_frame, 'sp_computed_exposure': computed_exposure, 'sp_type': 'ct', # 'sp_uid': str(uuid.uuid4()), # dark plan doesn't need uid 'sp_plan_name': 'dark_{}'.format(computed_exposure), 'dark_frame': True} c = bp.count([glbl.area_det], md=_md) yield from bp.subs_wrapper(c, {'stop': [_update_dark_dict_list]}) print('opening shutter...') yield from bp.abs_set(glbl.shutter, 1) if glbl.shutter_control: yield from bp.sleep(2)
def Tramp(dets, exposure, Tstart, Tstop, Tstep, *, md=None): """ Scan over temeprature controller in steps. temeprature steps are defined by starting point, stoping point and step size Parameters ---------- detectors : list list of 'readable' objects exposure : float exposure time at each temeprature step in seconds Tstart : float starting point of temperature sequence Tstop : float stoping point of temperature sequence Tstep : float step size between Tstart and Tstop of this sequence md : dict, optional extra metadata Note ---- temperature controller that is driven will always be the one configured in global state. Please refer to http://xpdacq.github.io for more information """ pe1c, = dets if md is None: md = {} # setting up area_detector (num_frame, acq_time, computed_exposure) = _configure_pe1c(exposure) # compute Nsteps (Nsteps, computed_step_size) = _nstep(Tstart, Tstop, Tstep) # update md _md = ChainMap(md, {'sp_time_per_frame': acq_time, 'sp_num_frames': num_frame, 'sp_requested_exposure': exposure, 'sp_computed_exposure': computed_exposure, 'sp_type': 'Tramp', 'sp_startingT': Tstart, 'sp_endingT': Tstop, 'sp_requested_Tstep': Tstep, 'sp_computed_Tstep': computed_step_size, 'sp_Nsteps': Nsteps, # need a name that shows all parameters values # 'sp_name': 'Tramp_<exposure_time>', 'sp_uid': str(uuid.uuid4()), 'sp_plan_name': 'Tramp'}) plan = bp.scan([glbl.area_det], glbl.temp_controller, Tstart, Tstop, Nsteps, md=_md) plan = bp.subs_wrapper(plan, LiveTable([glbl.area_det, glbl.temp_controller])) yield from plan
def tseries(dets, exposure, delay, num, *, md=None): """ time series scan with area detector. Parameters ---------- detectors : list list of 'readable' objects exposure : float exposure time at each reading from area detector in seconds delay : float delay between two adjustant reading from area detector in seconds num : int total number of readings md : dict, optional metadata Note ---- area detector that is triggered will always be the one configured in global state. Please refer to http://xpdacq.github.io for more information """ pe1c, = dets if md is None: md = {} # setting up area_detector (num_frame, acq_time, computed_exposure) = _configure_pe1c(exposure) real_delay = max(0, delay - computed_exposure) period = max(computed_exposure, real_delay + computed_exposure) print('INFO: requested delay = {}s -> computed delay = {}s'.format( delay, real_delay)) print('INFO: nominal period (neglecting readout overheads) of {} s'.format( period)) # update md _md = ChainMap( md, { 'sp_time_per_frame': acq_time, 'sp_num_frames': num_frame, 'sp_requested_exposure': exposure, 'sp_computed_exposure': computed_exposure, 'sp_type': 'tseries', # need a name that shows all parameters values # 'sp_name': 'tseries_<exposure_time>', 'sp_uid': str(uuid.uuid4()), 'sp_plan_name': 'tseries' }) plan = bp.count([glbl.area_det], num, delay, md=_md) plan = bp.subs_wrapper(plan, LiveTable([glbl.area_det])) yield from plan
def tseries(dets, exposure, delay, num, *, md=None): """ time series scan with area detector. Parameters ---------- detectors : list list of 'readable' objects exposure : float exposure time at each reading from area detector in seconds delay : float delay between two adjustant reading from area detector in seconds num : int total number of readings md : dict, optional metadata Note ---- area detector that is triggered will always be the one configured in global state. Please refer to http://xpdacq.github.io for more information """ pe1c, = dets if md is None: md = {} # setting up area_detector (num_frame, acq_time, computed_exposure) = _configure_pe1c(exposure) real_delay = max(0, delay - computed_exposure) period = max(computed_exposure, real_delay + computed_exposure) print('INFO: requested delay = {}s -> computed delay = {}s' .format(delay, real_delay)) print('INFO: nominal period (neglecting readout overheads) of {} s' .format(period)) # update md _md = ChainMap(md, {'sp_time_per_frame': acq_time, 'sp_num_frames': num_frame, 'sp_requested_exposure': exposure, 'sp_computed_exposure': computed_exposure, 'sp_requested_delay': delay, 'sp_requested_num': num, 'sp_type': 'tseries', # need a name that shows all parameters values # 'sp_name': 'tseries_<exposure_time>', 'sp_uid': str(uuid.uuid4()), 'sp_plan_name': 'tseries'}) plan = bp.count([glbl.area_det], num, delay, md=_md) plan = bp.subs_wrapper(plan, LiveTable([glbl.area_det])) yield from plan
def Tlist(dets, exposure, T_list): """defines a flexible scan with user-specified temperatures A frame is exposed for the given exposure time at each of the user-specified temperatures Parameters ---------- dets : list list of objects that represent instrument devices. In xpdAcq, it is defaulted to area detector. exposure : float total time of exposure in seconds for area detector T_list : list a list of temperature where a scan will be run Note ---- area detector and temperature controller will always be the one configured in global state. To find out which these are, please using following commands: >>> glbl.area_det >>> glbl.temp_controller To interrogate which devices are currently in use. """ pe1c, = dets # setting up area_detector and temp_controller (num_frame, acq_time, computed_exposure) = _configure_pe1c(exposure) T_controller = glbl.temp_controller xpdacq_md = {'sp_time_per_frame': acq_time, 'sp_num_frames': num_frame, 'sp_requested_exposure': exposure, 'sp_computed_exposure': computed_exposure, 'sp_T_list': T_list, 'sp_type': 'Tlist', 'sp_uid': str(uuid.uuid4()), 'sp_plan_name': 'Tlist' } # pass xpdacq_md to as additional md to bluesky plan plan = bp.list_scan([glbl.area_det], T_controller, T_list, md=xpdacq_md) plan = bp.subs_wrapper(plan, LiveTable([glbl.area_det, T_controller])) yield from plan
def test_intreupted_with_callbacks(fresh_RE, int_meth, stop_num, msg_num): RE = fresh_RE docs = defaultdict(list) def collector_cb(name, doc): nonlocal docs docs[name].append(doc) RE.msg_hook = MsgCollector() RE(subs_wrapper(run_wrapper(pause()), {'all': collector_cb})) getattr(RE, int_meth)() assert len(docs['start']) == 1 assert len(docs['event']) == 0 assert len(docs['descriptor']) == 0 assert len(docs['stop']) == stop_num assert len(RE.msg_hook.msgs) == msg_num
def test_subs(): def cb(name, doc): pass def plan(*args, **kwargs): # check that args to plan are passed through yield from [Msg("null", None, *args, **kwargs)] processed_plan = list(subs_wrapper(plan("test_arg", test_kwarg="val"), {"all": cb})) expected = [ Msg("subscribe", None, "all", cb), Msg("null", None, "test_arg", test_kwarg="val"), Msg("unsubscribe", token=None), ] assert processed_plan == expected processed_plan = list(subs_decorator({"all": cb})(plan)("test_arg", test_kwarg="val")) assert processed_plan == expected
def ct(dets, exposure, *, md=None): """ Take one reading from area detectors with given exposure time Parameters ---------- detectors : list list of 'readable' objects exposure : float total time of exposrue in seconds md : dict, optional extra metadata Note ---- area detector that is triggered will always be the one configured in global state. Please refer to http://xpdacq.github.io for more information """ pe1c, = dets if md is None: md = {} # setting up area_detector (num_frame, acq_time, computed_exposure) = _configure_pe1c(exposure) # update md _md = ChainMap( md, { 'sp_time_per_frame': acq_time, 'sp_num_frames': num_frame, 'sp_requested_exposure': exposure, 'sp_computed_exposure': computed_exposure, 'sp_type': 'ct', # need a name that shows all parameters values # 'sp_name': 'ct_<exposure_time>', 'sp_uid': str(uuid.uuid4()), 'sp_plan_name': 'ct' }) plan = bp.count([glbl.area_det], md=_md) plan = bp.subs_wrapper(plan, LiveTable([glbl.area_det])) yield from plan
def test_subs(): def cb(name, doc): pass def plan(*args, **kwargs): # check that args to plan are passed through yield from [Msg('null', None, *args, **kwargs)] processed_plan = list(subs_wrapper(plan('test_arg', test_kwarg='val'), {'all': cb})) expected = [Msg('subscribe', None, 'all', cb), Msg('null', None, 'test_arg', test_kwarg='val'), Msg('unsubscribe', token=None)] assert processed_plan == expected processed_plan = list(subs_decorator({'all': cb})(plan)('test_arg', test_kwarg='val')) assert processed_plan == expected
def ct(dets, exposure, *, md=None): """ Take one reading from area detectors with given exposure time Parameters ---------- detectors : list list of 'readable' objects exposure : float total time of exposrue in seconds md : dict, optional extra metadata Note ---- area detector that is triggered will always be the one configured in global state. Please refer to http://xpdacq.github.io for more information """ pe1c, = dets if md is None: md = {} # setting up area_detector (num_frame, acq_time, computed_exposure) = _configure_pe1c(exposure) # update md _md = ChainMap(md, {'sp_time_per_frame': acq_time, 'sp_num_frames': num_frame, 'sp_requested_exposure': exposure, 'sp_computed_exposure': computed_exposure, 'sp_type': 'ct', # need a name that shows all parameters values # 'sp_name': 'ct_<exposure_time>', 'sp_uid': str(uuid.uuid4()), 'sp_plan_name': 'ct'}) plan = bp.count([glbl.area_det], md=_md) plan = bp.subs_wrapper(plan, LiveTable([glbl.area_det])) yield from plan
def custom_subs(plan): yield from bp.subs_wrapper(plan, my_sub)
def hf2dwire(*, xstart, xnumstep, xstepsize, zstart, znumstep, zstepsize, acqtime, numrois=1, i0map_show=True, itmap_show=False, energy=None, u_detune=None): ''' input: xstart, xnumstep, xstepsize (float) zstart, znumstep, zstepsize (float) acqtime (float): acqusition time to be set for both xspress3 and F460 numrois (integer): number of ROIs set to display in the live raster scans. This is for display ONLY. The actualy number of ROIs saved depend on how many are enabled and set in the read_attr However noramlly one cares only the raw XRF spectra which are all saved and will be used for fitting. i0map_show (boolean): When set to True, map of the i0 will be displayed in live raster, default is True itmap_show (boolean): When set to True, map of the trasnmission diode will be displayed in the live raster, default is True energy (float): set energy, use with caution, hdcm might become misaligned u_detune (float): amount of undulator to detune in the unit of keV ''' #record relevant meta data in the Start document, defined in 90-usersetup.py md = get_stock_md() #setup the detector # TODO do this with configure current_preamp.exp_time.put(acqtime - 0.09) xs.settings.acquire_time.put(acqtime) xs.total_points.put((xnumstep + 1) * (znumstep + 1)) # det = [current_preamp, xs] det = [xs] #setup the live callbacks livecallbacks = [] livetableitem = [ hf_stage.x, hf_stage.z, 'current_preamp_ch0', 'current_preamp_ch2', 'xs_channel1_rois_roi01_value' ] xstop = xstart + xnumstep * xstepsize zstop = zstart + znumstep * zstepsize print('xstop = ' + str(xstop)) print('zstop = ' + str(zstop)) for roi_idx in range(numrois): roi_name = 'roi{:02}'.format(roi_idx + 1) roi_key = getattr(xs.channel1.rois, roi_name).value.name livetableitem.append(roi_key) # livetableitem.append('saturn_mca_rois_roi'+str(roi_idx)+'_net_count') # livetableitem.append('saturn_mca_rois_roi'+str(roi_idx)+'_count') # #roimap = LiveRaster((xnumstep, znumstep), 'saturn_mca_rois_roi'+str(roi_idx)+'_net_count', clim=None, cmap='viridis', xlabel='x', ylabel='y', extent=None) colormap = 'inferno' #previous set = 'viridis' # roimap = LiveRaster((znumstep, xnumstep), 'saturn_mca_rois_roi'+str(roi_idx)+'_count', clim=None, cmap='inferno', # xlabel='x (mm)', ylabel='y (mm)', extent=[xstart, xstop, zstop, zstart]) # roimap = myLiveRaster((znumstep+1, xnumstep+1), roi_key, clim=None, cmap='inferno', aspect='equal', # xlabel='x (mm)', ylabel='y (mm)', extent=[xstart, xstop, zstop, zstart]) roimap = LiveRaster((znumstep + 1, xnumstep + 1), roi_key, clim=None, cmap='inferno', aspect=0.01, xlabel='x (mm)', ylabel='y (mm)', extent=[xstart, xstop, zstop, zstart]) # liveplotfig = plt.figure('through focus') # roiplot = LivePlot(roi_key,x=hf_stage.x.name, fig=liveplotfig) livecallbacks.append(roimap) # livecallbacks.append(roiplot) # if i0map_show is True: # i0map = myLiveRaster((znumstep+1, xnumstep+1), 'current_preamp_ch2', clim=None, cmap='inferno', # xlabel='x (mm)', ylabel='y (mm)', extent=[xstart, xstop, zstop, zstart]) # livecallbacks.append(i0map) # if itmap_show is True: # itmap = myLiveRaster((znumstep+1, xnumstep+1), 'current_preamp_ch0', clim=None, cmap='inferno', # xlabel='x (mm)', ylabel='y (mm)', extent=[xstart, xstop, zstop, zstart]) # livecallbacks.append(itmap) # commented out liveTable in 2D scan for now until the prolonged time issue is resolved livecallbacks.append(LiveTable(livetableitem)) #setup the plan if energy is not None: if u_detune is not None: # TODO maybe do this with set energy.detune.put(u_detune) # TODO fix name shadowing yield from bp.abs_set(energy, energy, wait=True) # shut_b.open_cmd.put(1) # while (shut_b.close_status.get() == 1): # epics.poll(.5) # shut_b.open_cmd.put(1) hf2dwire_scanplan = bp.grid_scan(det, hf_stage.z, zstart, zstop, znumstep + 1, hf_stage.x, xstart, xstop, xnumstep + 1, True, md=md) hf2dwire_scanplan = bp.subs_wrapper(hf2dwire_scanplan, livecallbacks) scaninfo = yield from hf2dwire_scanplan # shut_b.close_cmd.put(1) # while (shut_b.close_status.get() == 0): # epics.poll(.5) # shut_b.close_cmd.put(1) #write to scan log logscan('2dwire') return scaninfo
def Tramp(dets, exposure, Tstart, Tstop, Tstep, *, md=None): """ Scan over temeprature controller in steps. temeprature steps are defined by starting point, stoping point and step size Parameters ---------- detectors : list list of 'readable' objects exposure : float exposure time at each temeprature step in seconds Tstart : float starting point of temperature sequence Tstop : float stoping point of temperature sequence Tstep : float step size between Tstart and Tstop of this sequence md : dict, optional extra metadata Note ---- temperature controller that is driven will always be the one configured in global state. Please refer to http://xpdacq.github.io for more information """ pe1c, = dets if md is None: md = {} # setting up area_detector (num_frame, acq_time, computed_exposure) = _configure_pe1c(exposure) # compute Nsteps (Nsteps, computed_step_size) = _nstep(Tstart, Tstop, Tstep) # update md _md = ChainMap( md, { 'sp_time_per_frame': acq_time, 'sp_num_frames': num_frame, 'sp_requested_exposure': exposure, 'sp_computed_exposure': computed_exposure, 'sp_type': 'Tramp', 'sp_startingT': Tstart, 'sp_endingT': Tstop, 'sp_requested_Tstep': Tstep, 'sp_computed_Tstep': computed_step_size, 'sp_Nsteps': Nsteps, # need a name that shows all parameters values # 'sp_name': 'Tramp_<exposure_time>', 'sp_uid': str(uuid.uuid4()), 'sp_plan_name': 'Tramp' }) plan = bp.scan([glbl.area_det], glbl.temp_controller, Tstart, Tstop, Nsteps, md=_md) plan = bp.subs_wrapper(plan, LiveTable([glbl.area_det, glbl.temp_controller])) yield from plan
def statTramp( dets, exposure, Tstart, Tstop, Tstep, sample_mapping, *, bt=None ): """ Parameters: ----------- sample_mapping : dict {'sample_ind': croysta_motor_pos} """ pe1c, = dets # setting up area_detector (num_frame, acq_time, computed_exposure) = yield from _configure_area_det( exposure ) area_det = xpd_configuration["area_det"] temp_controller = xpd_configuration["temp_controller"] stat_motor = xpd_configuration["stat_motor"] ring_current = xpd_configuration["ring_current"] # compute Nsteps (Nsteps, computed_step_size) = _nstep(Tstart, Tstop, Tstep) # stat_list _sorted_mapping = sorted(sample_mapping.items(), key=lambda x: x[1]) sp_uid = str(uuid.uuid4()) xpdacq_md = { "sp_time_per_frame": acq_time, "sp_num_frames": num_frame, "sp_requested_exposure": exposure, "sp_computed_exposure": computed_exposure, "sp_type": "statTramp", "sp_startingT": Tstart, "sp_endingT": Tstop, "sp_requested_Tstep": Tstep, "sp_computed_Tstep": computed_step_size, "sp_Nsteps": Nsteps, "sp_uid": sp_uid, "sp_plan_name": "statTramp", } # plan uids = {k: [] for k in sample_mapping.keys()} yield from bp.mv(temp_controller, Tstart) for t in np.linspace(Tstart, Tstop, Nsteps): yield from bp.mv(temp_controller, t) for s, pos in _sorted_mapping: # sample ind yield from bp.mv(stat_motor, pos) # update md md = list(bt.samples.values())[int(s)] _md = ChainMap(md, xpdacq_md) plan = bp.count( [temp_controller, stat_motor, ring_current] + dets, md=_md ) plan = bp.subs_wrapper( plan, LiveTable( [area_det, temp_controller, stat_motor, ring_current] ), ) # plan = bp.baseline_wrapper(plan, [temp_controller, # stat_motor, # ring_current]) uid = yield from plan if uid is not None: from xpdan.data_reduction import save_last_tiff save_last_tiff() uids[s].append(uid) for s, uid_list in uids.items(): from databroker import db import pandas as pd hdrs = db[uid_list] dfs = [db.get_table(h, stream_name="primary") for h in hdrs] df = pd.concat(dfs) fn_md = list(bt.samples.keys())[int(s)] fn_md = "_".join([fn_md, sp_uid]) + ".csv" fn = os.path.join(glbl["tiff_base"], fn_md) df.to_csv(fn) return uids