def escan(start, stop, num, md=None): """ Scan the mono_energy while reading the scaler. Parameters ---------- start : number stop : number num : integer number of data points (i.e. number of strides + 1) md : dictionary, optional """ dets = [sclr] motor = mono.energy cols = ['I0', 'fbratio', 'It', 'If_tot'] x = 'mono_energy' fig, axes = plt.subplots(2, sharex=True) plan = bp.scan(dets, motor, start, stop, num, md=md) plan2 = bpp.subs_wrapper(plan, [ LiveTable(cols), LivePlot('If_tot', x, ax=axes[0]), LivePlot('I0', x, ax=axes[1]) ]) yield from plan2
def describe_plots(self): from bluesky.callbacks import LivePlot cur_name = self.NAMES['current'] off_name = self.NAMES['offset'] self.PLOTS.append(LivePlot(cur_name, x=off_name, ax=self.AXIS[0], marker='.')) self.PLOTS.append(LivePlot(cur_name, x=off_name, ax=self.AXIS[1], marker='.'))
def describe_plots(self): from bluesky.callbacks import LivePlot off_name = self.NAMES['inj_kicker'] cur1_name = self.NAMES['booster_current1'] cur2_name = self.NAMES['booster_current2'] self.PLOTS.append(LivePlot(cur1_name, x=off_name, ax=self.AXIS[0], marker='.')) self.PLOTS.append(LivePlot(cur2_name, x=off_name, ax=self.AXIS[1], marker='.'))
def setup_plot(*, motors, gs): """Setup a LivePlot by inspecting motors and gs. If motors is empty, use sequence number. """ y_key = gs.PLOT_Y if motors: x_key = first_key_heuristic(list(motors)[0]) fig_name = _figure_name('BlueSky: {} v {}'.format(y_key, x_key)) ax = plt.figure(fig_name).gca() return LivePlot(y_key, x_key, ax=ax) else: fig_name = _figure_name('BlueSky: {} v sequence number'.format(y_key)) ax = plt.figure(fig_name).gca() return LivePlot(y_key, ax=ax)
def test_live_plotter(): if skip_mpl: raise nose.SkipTest("matplotlib is not available") my_plotter = LivePlot('det', 'motor') assert_equal(RE.state, 'idle') RE(stepscan(det, motor), subs={'all': my_plotter}) assert_equal(RE.state, 'idle')
def find_peak_inner(detector, motor, start, stop, num, ax): if detector.name == "bpm3": det_name = detector.name + '_sum_all' else: det_name = detector.name mot_name = motor.name + '_setpoint' if motor is ivu_gap else motor.name + '_user_setpoint' # Prevent going below the lower limit or above the high limit if motor is ivu_gap: step_size = (stop - start) / (num - 1) while ivu_gap.gap.user_setpoint.get( ) + start < ivu_gap.gap.low_limit: start += 5 * step_size stop += 5 * step_size while ivu_gap.gap.user_setpoint.get( ) + stop > ivu_gap.gap.high_limit: start -= 5 * step_size stop -= 5 * step_size @bpp.subs_decorator(LivePlot(det_name, mot_name, ax=ax)) def inner(): peak_x, peak_y = yield from find_peak(detector, motor, start, stop, num) ax.plot([peak_x], [peak_y], 'or') return peak_x, peak_y return inner()
def calibrate_energy(self): # update the data self._calibration_data = pd.DataFrame(columns=['energy_nom', 'energy_act', 'resolution', 'uid']) e_min = float(self.edit_E_calib_min.text()) e_max = float(self.edit_E_calib_max.text()) e_step = float(self.edit_E_calib_step.text()) if e_min>e_max: message_box('Incorrect energy range','Calibration energy min should be less than max') return if (e_max - e_min) < e_step: message_box('Incorrect energy range','energy step size bigger than range') return energies = np.arange(e_min, e_max + e_step, e_step) each_scan_range = self.doubleSpinBox_range_energy.value() each_scan_step = self.doubleSpinBox_step_energy.value() plan = self.service_plan_funcs['johann_calibration_scan_plan'](energies, DE=each_scan_range, dE=each_scan_step) channel = self.comboBox_pilatus_channels.currentText() motor = self.motor_dictionary['hhm_energy']['object'] uids = self.RE(plan, LivePlot(channel, motor.name, ax=self.parent.figure_scan.ax)) energy_converter, energies_act, resolutions, I_fit_raws = analyze_many_elastic_scans(self.db, uids, energies, short_output=False) self.motor_emission.append_energy_converter(energy_converter) for each_energy_nom, each_energy_act, each_resolution, each_uid in zip(energies, energies_act, resolutions, uids): data_dict = {'energy_nom' : each_energy_nom, 'energy_act' : each_energy_act, 'resolution' : each_resolution, 'uid' : each_uid} self._calibration_data = self._calibration_data.append(data_dict, ignore_index=True) self.parent.update_proc_figure('calibration')
def test_live_fit_plot(fresh_RE): RE = fresh_RE try: import lmfit except ImportError: raise pytest.skip('requires lmfit') def gaussian(x, A, sigma, x0): return A * np.exp(-(x - x0)**2 / (2 * sigma**2)) model = lmfit.Model(gaussian) init_guess = { 'A': 2, 'sigma': lmfit.Parameter('sigma', 3, min=0), 'x0': -0.2 } livefit = LiveFit(model, 'det', {'x': 'motor'}, init_guess, update_every=50) lfplot = LiveFitPlot(livefit, color='r') lplot = LivePlot('det', 'motor', ax=plt.gca(), marker='o', ls='none') RE(scan([det], motor, -1, 1, 50), [lplot, lfplot]) expected = {'A': 1, 'sigma': 1, 'x0': 0} for k, v in expected.items(): assert np.allclose(livefit.result.values[k], v, atol=1e-6)
def plotLPList(y_list, header, samePlot=False): from bluesky.callbacks import LivePlot ax = None for y in y_list: ax_p = plotHeader(LivePlot(y, ax=ax), header) if samePlot: ax = ax_p
def find_peak_inner(detector, motor, start, stop, num, ax): det_name = detector.name + '_sum_all' mot_name = motor.name + '_user_setpoint' @bpp.subs_decorator(LivePlot(det_name, mot_name, ax=ax)) def inner(): peak_x, peak_y = yield from find_peak(detector, motor, start, stop, num) ax.plot([peak_x], [peak_y], 'or') return peak_x, peak_y return inner()
def factory(name, doc): # Runs may be subscribed to different sets of callbacks. Metadata from start # document may be used to identify, which run is currently being started. # In this example, the run key is explicitely added to the start document # and used to identify runs, but other data can be similarly used. cb_list = [] if doc["run_key"] == "run_1": cb_list.append(LiveTable([hw.motor1, hw.det1])) cb_list.append(LivePlot('det1', x='motor1')) elif doc["run_key"] == "run_2": cb_list.append(LiveTable([hw.motor1, hw.motor2, hw.det2])) return cb_list, []
def Gas_Plan(gas_in='He', liveplot_key=None, totExpTime=5, num_exp=1, delay=1): """ Execute it ---------- >> %run -i /home/xf28id2/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) 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 """ ## 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 = bpp.subs_wrapper(plan, LiveTable([xpd_configuration['area_det'], rga])) # give you LiveTable plan = bpp.subs_wrapper( plan, LiveTable([xpd_configuration['area_det'], gas.current_gas, rga])) if liveplot_key and isinstance(liveplot_key, str): plan = bpp.subs_wrapper(plan, LivePlot(liveplot_key)) yield from plan
def escan(): """ Scan the mono_energy while reading the scaler. Parameters ---------- start : number stop : number num : integer number of data points (i.e. number of strides + 1) md : dictionary, optional """ """ dets = [xs] motor = mono.energy cols = ['I0', 'fbratio', 'It', 'If_tot'] x = 'mono_energy' fig, axes = plt.subplots(2, sharex=True) plan = bp.scan(dets, motor, start, stop, num, md=md) plan2 = bpp.subs_wrapper(plan, [LiveTable(cols), LivePlot('If_tot', x, ax=axes[0]), LivePlot('I0', x, ax=axes[1])]) yield from plan2 """ ept = numpy.array([]) det = [sclr, xs] last_time_pt = time.time() ringbuf = collections.deque(maxlen=10) # c2pitch_kill=EpicsSignal("XF:05IDA-OP:1{Mono:HDCM-Ax:P2}Cmd:Kill-Cmd") xs.external_trig.put(False) # @bpp.stage_decorator([xs]) yield from abs_set(xs.settings.acquire_time, 0.1) yield from abs_set(xs.total_points, 100) roi_name = "roi{:02}".format(roinum[0]) roi_key = [] roi_key.append(getattr(xs.channel1.rois, roi_name).value.name) livetableitem.append(roi_key[0]) livecallbacks.append(LiveTable(livetableitem)) liveploty = roi_key[0] liveplotx = energy.energy.name liveplotfig = plt.figure("raw xanes") livecallbacks.append(LivePlot(liveploty, x=liveplotx, fig=liveplotfig)) myscan = count
def grid_in_grid(samples): """ Scan a grid around the neighborhood of each sample. Parameters ---------- sample : dict mapping each sample's name to its (x, y) position """ # In this example we hard-code the hardware and other parameters. For more # flexibility, they could instead be parameters to the function. detector = det4 x = motor1 y = motor2 x_range = y_range = 0.2 x_num = y_num = 5 @subs_decorator( [LiveTable([detector, x, y]), LivePlot('motor2', 'motor1')]) def plan(): for name, position in samples.items(): # Prepare metadata. md = {'sample': name} # Move to the cetner of the sample position. x_pos, y_pos = position yield from abs_set(x, x_pos) yield from abs_set(y, y_pos) yield from wait() # Scan a grid around that position. yield from relative_outer_product_scan([detector], x, -x_range, x_range, x_num, y, -y_range, y_range, y_num, True, md=md) yield from plan()
def plan(self): from bluesky.plans import subs_decorator, scan from bluesky.callbacks import LiveTable, LivePlot from bluesky.utils import first_key_heuristic lp = LivePlot(first_key_heuristic(self.dets[0]), first_key_heuristic(self.motor), fig=self.fig) @subs_decorator([LiveTable([self.motor] + self.dets), lp]) def scan_gui_plan(): yield from scan(self.dets, self.motor, self.start.value(), self.stop.value(), self.steps.value(), md={'created_by': 'GUI'}) return scan_gui_plan()
def test_live_plotter(RE, hw): RE.ignore_callback_exceptions = False try: import matplotlib.pyplot as plt del plt except ImportError as ie: pytest.skip( "Skipping live plot test because matplotlib is not installed." "Error was: {}".format(ie)) my_plotter = LivePlot('det', 'motor') assert RE.state == 'idle' RE(stepscan(hw.det, hw.motor), {'all': my_plotter}) assert RE.state == 'idle' xlen = len(my_plotter.x_data) assert xlen > 0 ylen = len(my_plotter.y_data) assert xlen == ylen RE.ignore_callback_exceptions = True
d4offset = EpicsSignalRO('29idd:userCalcOut2.VAL', name = 'd4offset') det4offset = d4offset.get() if not SimAlign: motor2.move(det4offset+10.0) motor.move(alignRange[0]) if plotter is None: figTh, thAx = plt.subplots() else: thAx = plotter cur_color = fit_colors[iteration % len(fit_colors)] coarsePlot = LivePlot(detector_name,x=motor_name, linestyle = 'none', marker = '^', markerfacecolor = 'none', markeredgecolor = cur_color, ax = thAx, label = '{} - coarse'.format(iteration)) coarsePeak = PeakStats(motor_name,detector_name) lt = LiveTable([detector, motor]) if verbose: coarse_cbs = [coarsePlot,coarsePeak, lt] else: coarse_cbs = [coarsePlot,coarsePeak] @subs_decorator(coarse_cbs) def coarseScan(detector, motor, cRange, pts = 10): #Coarse scan to find region of peak yield from scan([detector], motor, cRange[0], cRange[1], num = pts)
from bluesky.plans import rel_scan from bluesky.callbacks import LiveTable, LivePlot subs = [ LiveTable(['ivu_gap', 'xray_eye3_stats1_total', 'xray_eye3_stats1_total']), LivePlot('xray_eye3_stats1_total', 'ivu_gap') ] print(ivu_gap.read()) RE(rel_scan([xray_eye3], ivu_gap, -.1, .1, 3), subs) print(ivu_gap.read())
def Ecal_dips(detectors, motor, wguess, max_step, D='Si', detector_name='sc_chan1', theta_offset=-35.26, guessed_sigma=.002, nsigmas=10, output_file="result.csv"): ''' This is the new Ecal scan for dips. We should treat peaks separately to simplify matters (leaves for easier tweaking) This algorithm will search for a peak within a certain theta range The theta range is determined from the wavelength guess Parameters ---------- detectors : list list of detectors motor : motor the motor to scan on (th_cal) wguess : the guessed wavelength max_step : the max_step to scan on. This is the step size we use for the coarse initial scan D : string the reference sample to use for the calculation of the d spacings detector_name : str, optional the name of the detector theta_offset : the offset of theta zero estimated from the sample guessed_sigma : the guessed sigma of the sample nsigmas: int the number of sigmas to scan for the fine scan Example ------- RE(Ecal_dips([sc], motor1, wguess=.1878, max_step=.004, D='Si', detector_name=sc.name, theta_offset=-35.26, guessed_sigma=.002, nsigmas=15)) ''' global myresult # the sample to use (use from the string supplied) if isinstance(D, str): D = D_SPACINGS[D] cen_guesses = np.degrees(np.arcsin(wguess / (2 * D))) # only use the first center as a guess cen_guess = cen_guesses[0] theta_guess1, theta_guess2 = theta_offset + cen_guess, theta_offset - cen_guess print("Trying {} + {} = {}".format(theta_offset, cen_guess, theta_offset + cen_guess)) print("Trying {} - {} = {}".format(theta_offset, cen_guess, theta_offset - cen_guess)) # set up the live Plotting fig = plt.figure(detector_name) fig.clf() ax = plt.gca() #detector_name = detectors[0].name # set up a live plotter global lp lp = LivePlot(detector_name, x=motor.name, marker='o', ax=ax) xdata_total = list() ydata_total = list() cnt = 0 for theta_guess in [theta_guess1, theta_guess2]: cnt += 1 # scan the first peak # the number of points for each side npoints = 30 start, stop = theta_guess - max_step * npoints, theta_guess + max_step * npoints # reverse to go negative start, stop = stop, start print("Trying to a guess. Moving {} from {} to {} in {} steps".format( motor.name, start, stop, npoints)) yield from bpp.subs_wrapper( bp.scan(detectors, motor, start, stop, npoints), lp) # TODO : check if a peak was found here # find the position c1 in terms of theta c1 = lp.x_data[np.argmin(lp.y_data)] res_one = fit_Ecal_onedip(lp.x_data, lp.y_data, c1, guessed_sigma=guessed_sigma) plt.figure('fitting coarse {}'.format(cnt)) plt.clf() plt.plot(lp.x_data, lp.y_data, linewidth=0, marker='o', color='b', label="data") plt.plot(lp.x_data, res_one.best_fit, color='r', label="fit") c1_fit = res_one.best_values['c1'] theta_guess = c1_fit print("Found center at {}, running finer scan".format(c1_fit)) npoints = 120 start, stop = theta_guess - guessed_sigma * nsigmas, theta_guess + guessed_sigma * nsigmas # reverse to go negative start, stop = stop, start print("Trying to a guess. Moving {} from {} to {} in {} steps".format( motor.name, start, stop, npoints)) yield from bpp.subs_wrapper( bp.scan(detectors, motor, start, stop, npoints), lp) # add to total xdata_total.extend(lp.x_data) ydata_total.extend(lp.y_data) plt.figure('fine scan {}'.format(cnt)) plt.clf() plt.plot(lp.x_data, lp.y_data, linewidth=0, marker='o', color='b', label="data") myresult.result = fit_Ecal_dips_symmetric(xdata_total, ydata_total, wguess=wguess, D=D) myresult.xdata = xdata_total myresult.ydata = ydata_total
def exafs_plan(erange=[], estep=[], E0=0., krange=[], kstep=[], harmonic=1, correct_c2_x=True, correct_c1_r=False, detune=None, acqtime=1., roinum=1, delaytime=0.00, struck=True, fluor=True, samplename='', filename='', shutter=True, align=False, align_at=None, per_step=None, ax1=None, ax2=None, ax3=None): ''' SRX EXAFS scan This will first scan over the edge using energy points before switching to k-space. erange (list of floats): energy ranges for XANES in eV, e.g. erange = [7112-50, 7112-20, 7112+50, 7112+120] estep (list of floats): energy step size for each energy range in eV, e.g. estep = [2, 1, 5] E0 <float> Energy to normalize to in eV krange <list of floats> k-space range for EXAFS, e.g. krange = [2, 5, 10] kstep <list of floats> k-space step size for each k-space range e.g. kstep = [0.10, 0.05] harmonic (odd integer): when set to 1, use the highest harmonic achievable automatically. when set to an odd integer, force the XANES scan to use that harmonic correct_c2_x (boolean or float): when True, automatically correct the c2x when False, c2x will not be moved during the XANES scan correct_c1_r (False or float): when False, c1r will not be moved during a XANES scan when set to a float, c1r will be set to that value before a XANES scan but will remain the same during the whole scan detune: add this value to the gap of the undulator to reduce flux [mm] acqtime (float): acqusition time to be set for both xspress3 and preamplifier roinum: select the roi to be used to calculate the XANES spectrum delaytime: reduce acquisition time of F460 by this value [sec] struck: Use the SRS and Struck scaler for the ion chamber and diode. Set to False to use the F460. fluorescence: indicate the presence of fluorescence data [bool] samplename (string): sample name to be saved in the scan metadata filename (string): filename to be added to the scan id as the text output filename shutter: instruct the scan to control the B shutter [bool] align: control the tuning of the DCM pointing before each XANES scan [bool] align_at: energy at which to align, default is the first energy point ''' ept = numpy.array([]) det = [] filename = filename last_time_pt = time.time() # ringbuf = collections.deque(maxlen=10) # c2pitch_kill=EpicsSignal("XF:05IDA-OP:1{Mono:HDCM-Ax:P2}Cmd:Kill-Cmd") # xs.external_trig.put(False) # make sure user provided correct input if erange is []: raise AttributeError( "An energy range must be provided in a list by means of the 'erange' keyword." ) if estep is []: raise AttributeError( "A list of energy steps must be provided by means of the 'esteps' keyword." ) if (not isinstance(erange, list)) or (not isinstance(estep, list)): raise TypeError("The keywords 'estep' and 'erange' must be lists.") if len(erange) - len(estep) is not 1: raise ValueError("The 'erange' and 'estep' lists are inconsistent;" \ + 'c.f., erange = [7000, 7100, 7150, 7500], estep = [2, 0.5, 5] ') if type(roinum) is not list: roinum = [roinum] if detune is not None: yield from abs_set(energy.detune, detune) # record relevant meta data in the Start document, defined in 90-usersetup.py # metadata_record() # add user meta data RE.md['sample'] = {'name': samplename} RE.md['scaninfo'] = { 'type': 'XANES', 'ROI': roinum, 'raster': False, 'dwell': acqtime } RE.md['scan_input'] = str(np.around(erange, 2)) + ', ' + str( np.around(estep, 2)) # convert erange and estep to numpy array erange = numpy.array(erange) estep = numpy.array(estep) # calculation for the energy points for i in range(len(estep)): ept = numpy.append(ept, numpy.arange(erange[i], erange[i + 1], estep[i])) ept = numpy.append(ept, numpy.array(erange[-1])) if krange != []: # Calculate k-space points and convert to energy kpt = np.array([], dtype=np.float) krange = np.array(krange, dtype=np.float) if (krange[0] == -1): krange[0] = Etok(ept[-1], E0) kstep = np.array(kstep, dtype=np.float) for i in range(len(kstep)): kpt = np.append(kpt, np.arange(krange[i], krange[i + 1], kstep[i])) kpt = np.append(kpt, np.array(krange[-1])) kptE = ktoE(kpt, E0) ept = np.append(ept, kptE) ept = np.unique(ept) ept.sort() # Debugging # Convert energy to bragg angle egap = np.array(()) ebragg = np.array(()) exgap = np.array(()) for i in ept: # Convert from eV to keV # if (i > 4500): # i = i / 1000 # Convert keV to bragg angle # b, _, _ = energy.energy_to_positions(i, 5, 0) eg, eb, ex = energy.forward(i) egap = np.append(egap, eg) ebragg = np.append(ebragg, eb) exgap = np.append(exgap, ex) # print(ebragg) # register the detectors # det = [ring_current] # if struck == True: # det.append(sclr1) # else: # det.append(current_preamp) # if fluor == True: # det.append(xs) # setup xspress3 # yield from abs_set(xs.settings.acquire_time,acqtime) # yield from abs_set(xs.total_points,len(ept)) det.append(sclr1) det.append(xs) #Taken from exafs plan # Setup the detectors # det = [ring_current, sclr1, xs] # yield from abs_set(xs.settings.acquire_time, acqtime) # yield from abs_set(xs.total_points, len(ept)) # yield from abs_set(xs.external_trig, False) # yield from abs_set(sclr1.preset_time, acqtime) # Make sure correction function on undulator is disabled #yield from abs_set(energy.u_gap.corrfunc_dis, 1) # energy.u_gap.corrfunc_dis.put(1) # Open b shutter # if (shutter is True): # yield from mv(shut_b, 'Open') # setup the preamp # if struck == True: # yield from abs_set(sclr1.preset_time,acqtime) # else: # yield from abs_set(current_preamp.exp_time,acqtime-delaytime) # setup dcm/energy options # if correct_c2_x is False: # yield from abs_set(energy.move_c2_x,False) # if correct_c1_r is not False: # yield from abs_set(dcm.c1_roll,correct_c1_r) if harmonic != 1: yield from abs_set(energy.harmonic, harmonic) # prepare to peak up DCM at first scan point # if align_at is not None: # align = True # if align is True: # if align_at == None: # yield from abs_set(energy, ept[0], wait = True) # else: # print("aligning at ",align_at) # yield from abs_set(energy, float(align_at), wait = True) # energy.u_gap.corrfunc_dis.put(1) # open b shutter # if shutter is True: # shut_b.open() # yield from mv(shut_b, 'Open') # yield from abs_set(shut_b,1,wait=True) # peak up DCM at first scan point # if align is True: # ps = PeakStats(dcm.c2_pitch.name,'sclr_i0') # e_value = energy.energy.get()[1] # if e_value < 10.: # yield from abs_set(sclr1.preset_time,0.1, wait = True) # peakup = scan([sclr1], dcm.c2_pitch, -19.335, -19.305, 31) # else: # yield from abs_set(sclr1.preset_time,1., wait = True) # peakup = scan([sclr1], dcm.c2_pitch, -19.355, -19.320, 36) # if e_value < 14.: # sclr1.preset_time.put(0.1) # else: # sclr1.preset_time.put(1.) # peakup = scan([sclr1], dcm.c2_pitch, -19.320, -19.360, 41) # peakup = subs_wrapper(peakup,ps) # yield from peakup # yield from abs_set(dcm.c2_pitch, ps.cen, wait = True) # ttime.sleep(10) # yield from abs_set(c2pitch_kill, 1) # setup the live callbacks myscan = list_scan(det, energy, list(ept), per_step=per_step) livecallbacks = [] livetableitem = ['en.energy'] if struck == True: livetableitem = livetableitem + ['sclr_i0', 'sclr_it'] # else: # livetableitem = livetableitem + ['current_preamp_ch0', 'current_preamp_ch2'] if fluor == True: # roi_name = 'roi{:02}'.format(roinum[0]) # roi_key = [] # roi_key.append(getattr(xs.channel1.rois, roi_name).value.name) # roi_key.append(getattr(xs.channel2.rois, roi_name).value.name) # roi_key.append(getattr(xs.channel3.rois, roi_name).value.name) # livetableitem.append(roi_key[0]) #livecallbacks.append(LiveTable(['xs_intensity'])) # liveploty = [xs] liveploty = xs.name liveplotx = en.energy.name #liveplotfig = plt.figure('raw xanes') # elif struck == True: # liveploty = 'sclr_it' # liveplotx = energy.energy.name # liveplotfig = plt.figure('raw xanes') # livecallbacks.append(LiveTable([sclr1, xs, energy])) ########Tom said to edit it here!!!!!!!!! # livecallbacks.append(LivePlot(y =liveploty, x=liveplotx, fig=liveplotfig)) #livecallbacks.append(LivePlot(y='xs_intensity', x=liveplotx, fig=liveplotfig)) # livecallbacks.append(LivePlot(y =liveploty, x=liveplotx, ax=plt.gca(title='raw xanes'))) if struck == True: liveploty = 'sclr_i0' i0 = 'sclr_i0' # else: # liveploty = 'current_preamp_ch2' # i0 = 'current_preamp_ch2' #liveplotfig2 = plt.figure(i0) #livecallbacks.append(LivePlot(liveploty, x=liveplotx, fig=liveplotfig2)) # livecallbacks.append(LivePlot(liveploty, x=liveplotx, ax=plt.gca(title='incident intensity'))) #livenormfig = plt.figure('normalized xanes') # if fluor == True: # livecallbacks.append(NormalizeLivePlot([xs], x=liveplotx, norm_key = i0, fig=livenormfig)) # livecallbacks.append(NormalizeLivePlot(roi_key[0], x=liveplotx, norm_key = i0, ax=plt.gca(title='normalized xanes'))) # else: # livecallbacks.append(NormalizeLivePlot('sclr_it', x=liveplotx, norm_key = i0, fig=livenormfig)) # livecallbacks.append(NormalizeLivePlot(roi_key[0], x=liveplotx, norm_key = i0, ax=plt.gca(title='normalized xanes'))) # def after_scan(name, doc): # if name != 'stop': # print("You must export this scan data manually: xanes_afterscan_plan(doc[-1], <filename>, <roinum>)") # return # xanes_afterscan_plan(doc['run_start'], filename, roinum) # logscan_detailed('xanes') # def at_scan(name, doc): # scanrecord.current_scan.put(doc['uid'][:6]) # scanrecord.current_scan_id.put(str(doc['scan_id'])) # scanrecord.current_type.put(RE.md['scaninfo']['type']) # scanrecord.scanning.put(True) # def finalize_scan(): # yield from abs_set(energy.u_gap.corrfunc_en,1) # disabled to test if # undulator gets stuck -AMK # yield from abs_set(energy.move_c2_x, True) # yield from abs_set(energy.harmonic, 1) # scanrecord.scanning.put(False) # if shutter == True: # yield from mv(shut_b,'Close') # if detune is not None: # energy.detune.put(0) # del RE.md['sample']['name'] # del RE.md['scaninfo'] # det = noisy_det myscan = list_scan(det, en.energy, list(ept)) # myscan = list_scan([sclr1], en.energy, list(ept)) # myscan = list_scan(det, energy, list(ept), per_step=per_step(detectors, motor, step)) # myscan = list_scan(det, energy.bragg, list(ebragg), energy.u_gap, list(egap), energy.c2_x, list(exgap)) # myscan = scan_nd(det, energy.bragg, list(ebragg), energy.u_gap, list(egap), energy.c2_x, list(exgap)) # myscan = finalize_wrapper(myscan,finalize_scan) livecallbacks = [] #livecallbacks.append(LiveTable([xs, en.energy])) #liveplotfig = plt.figure('raw xanes') ax = ax1 livecallbacks.append(LivePlot(y='xs_intensity', x='en_energy', ax=ax)) # livecallbacks.append(LiveTable([xs, en.energy])) #liveplotfig2 = plt.figure('io') ax = ax2 livecallbacks.append(LivePlot(y='sclr1', x='en_energy', ax=ax)) # livecallbacks.append(LivePlot(y='sclr_io', x='en_energy', fig='io')) #RE.subscribe(livecallbacks) return (yield from subs_wrapper(myscan, {'all': livecallbacks}))
from bluesky.plans import rel_scan from bluesky.callbacks import LiveTable, LivePlot subs = [ LiveTable(['dcm_b', 'xray_eye3_stats1_total', 'xray_eye3_stats2_total']), LivePlot('xray_eye3_stats1_total', 'dcm_b') ] print(dcm.b.read()) RE(rel_scan([xray_eye3], dcm.b, -.1, .1, 3), subs) print(dcm.b.read())
from bluesky.plans import rel_scan from bluesky.callbacks import LiveTable, LivePlot subs = [ LiveTable(['gsl_xc', 'xray_eye3_stats4_total', 'xray_eye3_stats4_total']), LivePlot('xray_eye3_stats4_total', 'gsl_xc') ] print(gsl.xc.read()) RE(rel_scan([xray_eye3], gsl.xc, -.1, .1, 3), subs) print(gsl.xc.read())
from bluesky.plans import rel_scan from bluesky.callbacks import LiveTable, LivePlot subs = [ LiveTable([ 'gsl_xc_readback', 'xray_eye3_stats1_total', 'xray_eye3_stats2_total' ]), LivePlot('xray_eye3_stats1_total', 'gsl_xc_readback') ] print(gsl.xc.read()) RE(rel_scan([xray_eye3], gsl.xc, -.1, .1, 10), subs) print(gsl.xc.read()) print('here')
from bluesky.plans import rel_scan from bluesky.callbacks import LiveTable, LivePlot subs = [ LiveTable([ 'diff_xh', 'eiger1m_single_stats1_total', 'eiger1m_single_stats2_total' ]), LivePlot('eiger1m_single_stats1_total', 'diff_xh') ] print( 'The fast shutter will open/close three times, motor is diff.xh, camera is eiger1m_single' ) RE(rel_scan([eiger1m_single], diff.xh, -.1, .1, 3), subs) img = get_images(db[-1], 'eiger1m_single_image') print('show the first image') plt.imshow(img[0][0]) #can we change only one mater file for the same dscan?
def plan_simultaneously(x_centroid, y_centroid, x, y, atol, x_target=None, y_target=None): """ This BlueSky plan aligns the laser's centroid with the x-ray's centroid. This plan implements 'walk_to_pixel' from the pswalker (a beam alignment module). The plan uses an iterative procedure to align any beam to a position on a screen, when two motors move the beam along the two axes. Liveplots are updated and show the paths taken to achieve alignment. Parameters ---------- x_centroid, y_centroid : These represent the x_centroid and y_centroid x, y: These respresnt the x_motor and y_motor x_target, y_target : int Target value on the x-axis and y-axis """ #Create a figure fig = plt.figure(figsize=(15, 10)) fig.subplots_adjust(hspace=0.3, wspace=0.4) #The first subplot, which plots the y_centroid vs x_centroid ax1 = fig.add_subplot(2, 2, 1) ax1.invert_yaxis() x_centroid_y_centroid = LivePlot(y_centroid.name, x_centroid.name, ax=ax1, marker='x', markersize=7, color='orange') #The second subplot, which plots the y_centroid and x_centroid with same x-axis (y_motor) ax2 = fig.add_subplot(2, 2, 3) ax2.set_ylabel(y_centroid.name, color='red') ax3 = ax2.twinx() # ax2.invert_yaxis() # ax3.invert_yaxis() ax3.set_ylabel(x_centroid.name, color='blue') y_plot_y_centroid = LivePlot(y_centroid.name, y.name, ax=ax2, marker='x', markersize=6, color='red') y_plot_x_centroid = LivePlot(x_centroid.name, y.name, ax=ax3, marker='o', markersize=6, color='blue') #The third subplot, which plots the y_centroid and x_centroid with same x-axis (x_motor) ax4 = fig.add_subplot(2, 2, 4) ax4.set_ylabel(y_centroid.name, color='green') ax5 = ax4.twinx() ax5.set_ylabel(x_centroid.name, color='purple') x_plot_y_centroid = LivePlot(y_centroid.name, x.name, ax=ax4, marker='x', markersize=6, color='green') x_plot_x_centroid = LivePlot(x_centroid.name, x.name, ax=ax5, marker='o', markersize=6, color='purple') #Subscribe the plots token_x_centroid_y_centroid = yield from subscribe('all', x_centroid_y_centroid) token_y_plot_x_centroid = yield from subscribe('all', y_plot_x_centroid) token_y_plot_y_centroid = yield from subscribe('all', y_plot_y_centroid) token_x_plot_x_centroid = yield from subscribe('all', x_plot_x_centroid) token_x_plot_y_centroid = yield from subscribe('all', x_plot_y_centroid) #Start a new run yield from open_run( md={ 'detectors': [(x_centroid.name), (y_centroid.name)], 'motors': [(x.name), (y.name)], 'hints': { 'dimensions': [(x.hints['fields'], 'primary'), (y.hints['fields'], 'primary')] } }) #Ask for the target values if x_target is None: x_target = int(input('Enter the x value: ')) if y_target is None: y_target = int(input('Enter the y value: ')) #Iteratively move until x_target and x-centroid are within a certain threshold of each other while True: if not np.isclose(x_target, x_centroid.get(), atol): yield from walk_to_pixel(x_centroid, x, x_target, first_step=0.1, target_fields=[x_centroid.name, x.name], tolerance=atol, average=5, system=[y, y_centroid]) elif not np.isclose(y_target, y_centroid.get(), atol): yield from walk_to_pixel(y_centroid, y, y_target, first_step=0.1, tolerance=atol, average=5, target_fields=[y_centroid.name, y.name], system=[x, x_centroid]) else: break # plt.show(block=True) #Close the run yield from close_run() #Unsubscribe the plots yield from unsubscribe(token_x_centroid_y_centroid) yield from unsubscribe(token_y_plot_x_centroid) yield from unsubscribe(token_y_plot_y_centroid) yield from unsubscribe(token_x_plot_x_centroid) yield from unsubscribe(token_x_plot_y_centroid)
from bluesky import RunEngine RE = RunEngine({}) from bluesky.plans import count, scan from bluesky.callbacks import LivePlot from ophyd.sim import noisy_det RE(count([noisy_det], num=200, delay = 0.1), LivePlot('noisy_det'))
def Ecal_old(detectors, motor, guessed_energy, mode, *, guessed_amplitude=0.5, guessed_sigma=0.004, min_step=0.001, D='LaB6', max_n=3, margin=0.5, md=None): """ Energy calibration scan Parameters ---------- detectors : detectors motor : the motor guessed_energy : number units of keV mode : {'peaks', 'dips'} guessed_amplitude : number, optional detector units, defaults to 1500 guessed_sigma : number, optional in units of degrees, defaults to 0.004 min_step : number, optional step size in degrees, defaults to 0.001 D : string or array, optional Either provide the spacings literally (as an array) or give the name of a known spacing ('LaB6' or 'Si') max_n : integer, optional how many peaks (on one side of 0), default is 3 margin : number, optional how far to scan in two theta beyond the guessed left and right peaks, default 0.5 Example ------- Execute an energy calibration scan with default steps. >>> RE(Ecal(68)) """ if mode == 'peaks': #motor = tth_cal factor = 2 offset = 0 sign = 1 if mode == 'dips': #motor = th_cal factor = 1 # theta_hardware = theta_theorhetical + offset offset = -35.26 # degrees sign = -1 if isinstance(D, str): D = D_SPACINGS[D] # Based on the guessed energy, compute where the peaks should be centered # in theta. This will be used as an initial guess for peak-fitting. guessed_wavelength = 12.398 / guessed_energy # angtroms theta = np.rad2deg(np.arcsin(guessed_wavelength / (2 * D))) guessed_centers = factor * theta # 'factor' puts us in two-theta units if applicable _range = max(guessed_centers) + (factor * margin) # Scan from positive to negative because that is the direction # that the th_cal and tth_cal motors move without backlash. start, stop = _range + offset, -_range + offset print('guessed_wavelength={} [Angstroms]'.format(guessed_wavelength)) print('guessed_centers={} [in {}-theta DEGREES]'.format( guessed_centers, factor)) print('will scan from {} to {} in hardware units'.format(start, stop)) if max_n > 3: raise NotImplementedError("I only work for n up to 3.") # todo : make a model and sum them def peaks(x, c0, wavelength, a1, a2, sigma): # x comes from hardware in [theta or two-theta] degrees x = np.deg2rad(x / factor - offset) # radians assert np.all(wavelength < 2 * D), \ "wavelength would result in illegal arg to arcsin" cs = np.arcsin(wavelength / (2 * D)) c1 = cs[0] c2 = cs[1] #c3 = cs[2] # first peak result = ( voigt(x=x, amplitude=sign * a1, center=c0 - c1, sigma=sigma) + voigt(x=x, amplitude=sign * a1, center=c0 + c1, sigma=sigma)) # second peak result += ( voigt(x=x, amplitude=sign * a2, center=c0 - c2, sigma=sigma) + voigt(x=x, amplitude=sign * a2, center=c0 + c2, sigma=sigma)) # third peak #result += (voigt(x=x, amplitude=sign*a3, center=c0 - c3, sigma=sigma) + #voigt(x=x, amplitude=sign*a3, center=c0 + c3, sigma=sigma)) return result model = Model(peaks) + LinearModel() # Fill out initial guess. init_guess = { 'intercept': Parameter('intercept', value=0, min=-100, max=100), 'slope': Parameter('slope', value=0, min=-100, max=100), 'sigma': Parameter('sigma', value=np.deg2rad(guessed_sigma)), 'c0': Parameter('c0', value=np.deg2rad(0), min=-0.2, max=0.2), 'wavelength': Parameter('wavelength', guessed_wavelength, min=0.8 * guessed_wavelength, max=1.2 * guessed_wavelength) } # min=0, max=np.min(2 * D))} kwargs = {'min': 0.5 * guessed_amplitude, 'max': 2 * guessed_amplitude} for i, center in enumerate(guessed_centers): init_guess.update({ 'a%d' % (1 + i): Parameter('a%d' % (1 + i), guessed_amplitude, **kwargs) }) print(init_guess) lf = LiveFit(model, detectors[0].name, {'x': motor.name}, init_guess, update_every=100) fig, ax = plt.subplots() # explitly create figure, axes to use below plot = LivePlot(detectors[0].name, motor.name, linestyle='none', marker='o', ax=ax) lfp = LiveFitPlot(lf, ax=ax, color='r') subs = [lfp, plot] #detectors = [det]#[sc] # Set up metadata -- based on the sourcecode of bluesky.plans.scan. _md = { 'detectors': [det.name for det in detectors], 'motors': [motor.name], 'hints': {}, } _md.update(md or {}) try: dimensions = [(motor.hints['fields'], 'primary')] except (AttributeError, KeyError): pass else: _md['hints'].setdefault('dimensions', dimensions) initial_steps = np.arange(start, stop, -min_step) assert len(initial_steps), "bad start, stop, min_step parameters" size = factor * 0.05 # region around each predicted peak location @bpp.stage_decorator(list(detectors) + [motor]) @bpp.run_decorator(md=_md) def inner_scan(): wavelength = guessed_wavelength for step in initial_steps: yield from bps.one_1d_step(detectors, motor, step) x_data = lf.independent_vars_data['x'] if x_data and lf.result is not None: # Have we yet scanned past the third peak? wavelength = lf.result.values['wavelength'] # Convert c's to hardware units here for comparison with x_data. c1, c2, c3 = factor * np.rad2deg( np.arcsin(wavelength / (2 * D))) + offset if np.min(x_data) < (c1 - 1): # Stop dense scanning. print('Preliminary result:\n', lf.result.values) print('Becoming adaptive to save time....') break # left of zero peaks c1, c2, c3 = -factor * np.rad2deg(np.arcsin(wavelength / (2 * D))) + offset neighborhoods = [ np.arange(c + size, c - size, -min_step) for c in (c1, c2, c3) ] for neighborhood in neighborhoods: for step in neighborhood: yield from bps.one_1d_step(detectors, motor, step) plan = inner_scan() plan = bpp.subs_wrapper(plan, subs) plan = bpp.reset_positions_wrapper(plan, [motor]) ret = (yield from plan) print(lf.result.values) print('WAVELENGTH: {} [Angstroms]'.format(lf.result.values['wavelength'])) return ret
from bluesky.callbacks import LivePlot from ophyd.sim import motor, det # Do this if running the example interactively; # skip it when building the documentation. import os if 'BUILDING_DOCS' not in os.environ: from bluesky.utils import install_qt_kicker # for notebooks, qt -> nb install_qt_kicker() plt.ion() det.exposure_time = 0.5 # simulate slow exposures RE = RunEngine({}) RE( adaptive_scan([det], 'det', motor, start=-15, stop=10, min_step=0.01, max_step=5, target_delta=.05, backstep=True), LivePlot('det', 'motor', markersize=10, marker='o')) ############################################################################### # Observe how the scan lengthens its stride through the flat regions, oversteps # through the peak, moves back, samples it with smaller steps, and gradually # adopts a larger stride as the peak flattens out again.
from bluesky.plans import rel_scan from bluesky.callbacks import LiveTable, LivePlot subs = [LiveTable(['diff_xh', 'xray_eye3_stats1_total', 'xray_eye3_stats2_total']), LivePlot('xray_eye3_stats1_total', 'diff_xh')] print ( 'Motor is diff.xh, camera is xray_eye3 with saving images') RE(rel_scan([xray_eye3_writing], diff.xh, -.1, .1, 3), subs) img = get_images(db[-1], 'xray_eye3_image') print('show the first image') plt.imshow( img[0] )
def xScanAndCenter(iteration, detector, det_name, motor, motor_name, alignRange = [-1, 2], stepRange = [0.01, 0.10], targetDelta = def_xTargetDelta, plotter = [], SimAlign = False, fudge = def_fudge, verbose = False): """ align_x: -scan xMotor through range -monitors detector looking for transition of beam/no-beam Parameters ---------- iteration : overall iteration of full alignment loop, required for plot colors/legend detector : detector object detector_name : detector object's name motor : X motor object motor_name : X motor object's name alignRange : list of two floats, describing range of x-alignment Default value is [-1,2] mm, StepRange : list of two floats, minimum and maximum steps for adaptive scan. Default value is [0.015, 0.075] degrees Minimum thMotor step is 0.01 degrees targetDelta : float, maximum jump in detector value before scan step decreased, default is set to def_xTargetDelta value is 10 in detector units, plotter : axis object for x alignment data, Default value is None which later creates new object SimAlign : boolean flag for simulation/testing Default value is False, fudge : Fudge factor for x-scan data reduction to remove bump from post-scan fit (in mm). Defaults to def_fudge verbose : boolean for showing alignment process using LiveTable callbacks. Default value is False """ if plotter is None: figX, xAx = plt.subplots() else: xAx = plotter cur_color = fit_colors[iteration % len(fit_colors)] cur_linestyle = linestyles[iteration // len(fit_colors)] scanPlot = LivePlot(det_name,x=motor_name, markeredgecolor = cur_color, markerfacecolor = 'none', ax = xAx, linestyle = 'none', marker = '^', label = '{} - data'.format(iteration)) comp_model = lmfit.Model(erfx, prefix="erf_") + lmfit.Model(gaussian, prefix = "gau_") comp_guess = {'erf_low': 0, 'erf_high': 0.03, 'erf_wid': lmfit.Parameter('erf_wid', value = 0.4, min=0), 'erf_x0': -0.1, 'gau_A': 0.01, 'gau_sigma': lmfit.Parameter('gau_sigma', value = .1, min=0), 'gau_x0': 1.0} xLiveFit = LiveFit(comp_model, det_name, {'x': motor_name}, comp_guess, update_every=5) lt = LiveTable([detector, motor]) if verbose: cbs = [scanPlot, xLiveFit, lt] else: cbs = [scanPlot, xLiveFit] @subs_decorator(cbs) def preFitScan(detectors, motor, alignRange, stepRange, targetDelta): yield from adaptive_scan([detectors], det_name, motor, start = alignRange[0], stop = alignRange[1], min_step = stepRange[0], max_step = stepRange[1], target_delta = targetDelta, backstep = True) yield from preFitScan(detector, motor, alignRange, stepRange, targetDelta) x0_rough = xLiveFit.result.params['erf_x0'].value width = xLiveFit.result.params['erf_wid'].value new_x0 = fitAndPlotBumplessData(np.asarray(scanPlot.y_data), np.asarray(scanPlot.x_data), x0_rough, width, ax = xAx, color = cur_color, linestyle = cur_linestyle, fudge = fudge) other_data = [] leg_raw = {'label' : 'Data', 'shape' : '^', 'color' : 'k', 'size' : '10'} other_data = [leg_raw] cleanLegend(iteration, xAx, other_data) asd.x0.append(new_x0) if not SimAlign: if (asd.x0[-1] <= min(alignRange) or asd.x0[-1] >= max(alignRange)): print("Peak estimated to be outside of alignment range") else: motor.move(asd.x0[-1])