Esempio n. 1
0
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
Esempio n. 2
0
 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='.'))
Esempio n. 3
0
    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='.'))
Esempio n. 4
0
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)
Esempio n. 5
0
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')
Esempio n. 8
0
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)
Esempio n. 9
0
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()
Esempio n. 11
0
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
Esempio n. 13
0
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
Esempio n. 14
0
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()
Esempio n. 15
0
    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()
Esempio n. 16
0
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
Esempio n. 17
0
		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)
		
Esempio n. 18
0
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())
Esempio n. 19
0
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
Esempio n. 20
0
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}))
Esempio n. 21
0
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())
Esempio n. 22
0
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())
Esempio n. 23
0
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?
Esempio n. 25
0
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)
Esempio n. 26
0
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'))
Esempio n. 27
0
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
Esempio n. 28
0
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.
Esempio n. 29
0
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] )

Esempio n. 30
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])