コード例 #1
0
def measuring(element, edge=None):
    BMMuser.element = element
    rkvs.set('BMM:pds:element', element)
    if edge is not None:
        BMMuser.edge = edge
        rkvs.set('BMM:pds:edge', edge)
    if use_4element:
        xs.reset_rois()
    if use_1element:
        xs1.reset_rois()
    show_edges()
コード例 #2
0
 def from_json(self, filename):
     if os.path.isfile(filename):
         with open(filename, 'r') as jsonfile:
             config = json.load(jsonfile)
         for k in config.keys():
             if k in ('cycle', ):
                 continue
             setattr(self, k, config[k])
         #rois.trigger = True
     from BMM.workspace import rkvs
     try:
         #rkvs.set('BMM:pds:edge',        str(config['edge']))
         #rkvs.set('BMM:pds:element',     str(config['element']))
         rkvs.set('BMM:pds:edge_energy',
                  edge_energy(config['element'], config['edge']))
         BMMuser.element = rkvs.get('BMM:pds:element').decode('utf-8')
         BMMuser.edge = rkvs.get('BMM:pds:edge').decode('utf-8')
     except:
         pass
コード例 #3
0
def set_instrument(instrument=None):
    if instrument.lower() == 'glancing angle':
        print(bold_msg('Setting instrument as glancing angle stage'))
        BMMuser.instrument = 'glancing angle stage'
    elif instrument.lower() == 'double wheel':
        print(bold_msg('Setting instrument as double sample wheel'))
        BMMuser.instrument = 'double wheel'
    elif instrument.lower() == 'linkam':
        print(bold_msg('Setting instrument as Linkam stage'))
        BMMuser.instrument = 'Linkam stage'
    elif instrument.lower() == 'lakeshore':
        print(bold_msg('Setting instrument as LakeShore 331'))
        BMMuser.instrument = 'LakeShore'
    elif instrument.lower() == 'grid':
        print(bold_msg('Setting instrument as sample grid'))
        BMMuser.instrument = 'motor grid'
    else:
        print(bold_msg('Default instrument choice: sample wheel'))
        BMMuser.instrument = 'sample wheel'
    rkvs.set('BMM:automation:type', instrument)
コード例 #4
0
    def main_plan(start, stop, nsteps, move, slp, force):
        (ok, text) = BMM_clear_to_start()
        if force is False and ok is False:
            print(error_msg(text))
            yield from null()
            return

        user_ns['RE'].msg_hook = None
        BMMuser.motor = dm3_bct
        func = lambda doc: (doc['data'][motor.name], doc['data']['I0'])
        plot = DerivedPlot(func, xlabel=motor.name, ylabel='I0', title='I0 signal vs. slit height')
        line1 = '%s, %s, %.3f, %.3f, %d -- starting at %.3f\n' % \
                (motor.name, 'i0', start, stop, nsteps, motor.user_readback.get())
        rkvs.set('BMM:scan:type',      'line')
        rkvs.set('BMM:scan:starttime', str(datetime.datetime.timestamp(datetime.datetime.now())))
        rkvs.set('BMM:scan:estimated', 0)

        @subs_decorator(plot)
        #@subs_decorator(src.callback)
        def scan_slit(slp):

            #if slit_height < 0.5:
            #    yield from mv(slits3.vsize, 0.5)
            
            yield from mv(quadem1.averaging_time, 0.1)
            yield from mv(motor.velocity, 0.4)
            yield from mv(motor.kill_cmd, 1)

            uid = yield from rel_scan([quadem1], motor, start, stop, nsteps, md={'plan_name' : f'rel_scan linescan {motor.name} I0'})

            user_ns['RE'].msg_hook = BMM_msg_hook
            BMM_log_info('slit height scan: %s\tuid = %s, scan_id = %d' %
                         (line1, uid, user_ns['db'][-1].start['scan_id']))
            if move:
                t  = user_ns['db'][-1].table()
                signal = t['I0']
                #if get_mode() in ('A', 'B', 'C'):
                #    position = com(signal)
                #else:
                position = peak(signal)
                top = t[motor.name][position]
                
                yield from sleep(slp)
                yield from mv(motor.kill_cmd, 1)
                yield from sleep(slp)
                yield from mv(motor, top)

            else:
                action = input('\n' + bold_msg('Pluck motor position from the plot? [Y/n then Enter] '))
                if action.lower() == 'n' or action.lower() == 'q':
                    return(yield from null())
                yield from sleep(slp)
                yield from mv(motor.kill_cmd, 1)
                #yield from mv(motor.inpos, 1)
                yield from sleep(slp)
                yield from move_after_scan(motor)
            yield from mv(quadem1.averaging_time, 0.5)
        yield from scan_slit(slp)
コード例 #5
0
def change_edge(el,
                focus=False,
                edge='K',
                energy=None,
                slits=True,
                target=300.,
                xrd=False,
                bender=True):
    '''Change edge energy by:
    1. Moving the DCM above the edge energy
    2. Moving the photon delivery system to the correct mode
    3. Running a rocking curve scan
    4. Running a slits_height scan

    Parameters
    ----------
    el : str
        one- or two-letter symbol
    focus : bool, optional
        T=focused or F=unfocused beam [False, unfocused]
    edge : str, optional
        edge symbol ['K']
    energy : float, optional
        e0 value [None, determined from el/edge]
    slits : bool, optional
        perform slit_height() scan [False]
    target : float, optional
        energy where rocking curve is measured [300]
    xrd : boolean, optional
        force photon delivery system to XRD [False]

    Examples
    --------
    Normal use, unfocused beam:
       
    >>> RE(change_edge('Fe'))

    Normal use, focused beam:
       
    >>> RE(change_edge('Fe', focus=True))

    L2 or L1 edge:
       
    >>> RE(change_edge('Re', edge='L2'))

    Measure rocking curve at edge energy:
      
    >>> RE(change_edge('Fe', target=0))

    XRD, new energy:
       
    >>> RE(change_edge('Fe', xrd=True, energy=8600))
        
    note that you must specify an element, but it doesn't matter which
    one the energy will be moved to the specified energy xrd=True
    implies focus=True and target=0

    '''
    # try:
    #     xs = user_ns['xs']
    # except:
    #     pass
    #BMMuser.prompt = True
    el = el.capitalize()

    ######################################################################
    # this is a tool for verifying a macro.  this replaces an xafsmod scan  #
    # with a sleep, allowing the user to easily map out motor motions in #
    # a macro                                                            #
    if BMMuser.macro_dryrun:
        print(
            info_msg(
                '\nBMMuser.macro_dryrun is True.  Sleeping for %.1f seconds rather than changing to the %s edge.\n'
                % (BMMuser.macro_sleep, el)))
        countdown(BMMuser.macro_sleep)
        return (yield from null())
    ######################################################################

    if pds_motors_ready() is False:
        print(
            error_msg(
                '\nOne or more motors are showing amplifier faults.\nToggle the correct kill switch, then re-enable the faulted motor.'
            ))
        return (yield from null())

    (ok, text) = BMM_clear_to_start()
    if ok is False:
        print(
            error_msg('\n' + text) +
            bold_msg('Quitting change_edge() macro....\n'))
        return (yield from null())

    if energy is None:
        energy = edge_energy(el, edge)

    if energy is None:
        print(
            error_msg('\nEither %s or %s is not a valid symbol\n' %
                      (el, edge)))
        return (yield from null())
    if energy > 23500:
        edge = 'L3'
        energy = edge_energy(el, 'L3')

    if energy < 4000:
        print(warning_msg('The %s edge energy is below 4950 eV' % el))
        print(warning_msg('You have to change energy by hand.'))
        return (yield from null())

    if energy > 23500:
        print(
            warning_msg(
                'The %s edge energy is outside the range of this beamline!' %
                el))
        return (yield from null())

    BMM_suspenders()

    if energy > 8000:
        mode = 'A' if focus else 'D'
    elif energy < 6000:
        #mode = 'B' if focus else 'F'   ## mode B currently is inaccessible :(
        mode = 'C' if focus else 'F'
    else:
        mode = 'C' if focus else 'E'
    if xrd:
        mode = 'XRD'
        focus = True
        target = 0.0
    current_mode = get_mode()
    if mode in ('D', 'E', 'F') and current_mode in ('D', 'E', 'F'):
        with_m2 = False
    elif mode in ('A', 'B',
                  'C') and current_mode in ('A', 'B',
                                            'C'):  # no need to move M2
        with_m2 = False
    else:
        with_m2 = True
    if all_connected(with_m2) is False:
        print(warning_msg('Ophyd connection failure' % el))
        return (yield from null())

    ################################
    # confirm configuration change #
    ################################
    print(bold_msg('\nEnergy change:'))
    print('   %s: %s %s' %
          (list_msg('edge'), el.capitalize(), edge.capitalize()))
    print('   %s: %.1f' % (list_msg('edge energy'), energy))
    print('   %s: %.1f' % (list_msg('target energy'), energy + target))
    print('   %s: %s' % (list_msg('focus'), str(focus)))
    print('   %s: %s' % (list_msg('photon delivery mode'), mode))
    print('   %s: %s' % (list_msg('optimizing slits height'), str(slits)))
    if BMMuser.prompt:
        action = input("\nBegin energy change? [Y/n then Enter] ")
        if action.lower() == 'q' or action.lower() == 'n':
            return (yield from null())
        if mode == 'C' and energy < 6000:
            print(
                warning_msg(
                    '\nMoving to mode C for focused beam and an edge energy below 6 keV.'
                ))
            action = input(
                "You will not get optimal harmonic rejection.  Continue anyway?  [Y/n then Enter] "
            )
            if action.lower() == 'q' or action.lower() == 'n':
                return (yield from null())

    BMMuser.edge = edge
    BMMuser.element = el
    BMMuser.edge_energy = energy
    rkvs.set('BMM:pds:edge', edge)
    rkvs.set('BMM:pds:element', el)
    rkvs.set('BMM:pds:edge_energy', energy)

    start = time.time()
    if mode == 'XRD':
        report('Configuring beamline for XRD', level='bold', slack=True)
    else:
        report(
            f'Configuring beamline for {el.capitalize()} {edge.capitalize()} edge',
            level='bold',
            slack=True)
    yield from dcm.kill_plan()

    ################################################
    # change to the correct photon delivery mode   #
    #      + move mono to correct energy           #
    #      + move reference holder to correct slot #
    ################################################
    # if not calibrating and mode != current_mode:
    #     print('Moving to photon delivery mode %s...' % mode)
    yield from mv(dcm_bragg.acceleration, BMMuser.acc_slow)
    yield from change_mode(mode=mode,
                           prompt=False,
                           edge=energy + target,
                           reference=el,
                           bender=bender)
    yield from mv(dcm_bragg.acceleration, BMMuser.acc_fast)
    if arrived_in_mode(mode=mode) is False:
        print(error_msg(f'\nFailed to arrive in Mode {mode}'))
        print(
            'Fixing this is often as simple as re-running the change_mode() command.'
        )
        print(
            'Or try dm3_bct.kill_cmd() then dm3_bct.enable_cmd() then re-run the change_mode() command.'
        )
        print('If that doesn\'t work, call for help')
        return (yield from null())

    yield from kill_mirror_jacks()
    yield from sleep(1)
    if BMMuser.motor_fault is not None:
        print(
            error_msg('\nSome motors are reporting amplifier faults: %s' %
                      BMMuser.motor_fault))
        print(
            'Clear the faults and try running the same change_edge() command again.'
        )
        print('Troubleshooting: ' + url_msg(
            'https://nsls-ii-bmm.github.io/BeamlineManual/trouble.html#amplifier-fault'
        ))
        BMMuser.motor_fault = None
        return (yield from null())
    BMMuser.motor_fault = None

    ############################
    # run a rocking curve scan #
    ############################
    print('Optimizing rocking curve...')
    yield from mv(dcm_pitch.kill_cmd, 1)
    yield from mv(dcm_pitch, approximate_pitch(energy + target))
    yield from sleep(1)
    yield from mv(dcm_pitch.kill_cmd, 1)
    yield from sleep(1)
    yield from rocking_curve()
    close_last_plot()

    ##########################
    # run a slit height scan #
    ##########################
    if slits:
        print('Optimizing slits height...')
        yield from slit_height(move=True)
        close_last_plot()
        ## redo rocking curve?

    ##################################
    # set reference and roi channels #
    ##################################
    if not xrd:
        ## reference channel
        print('Moving reference foil...')
        yield from rois.select_plan(el)
        ## Xspress3
        if with_xspress3:
            BMMuser.verify_roi(xs, el, edge)
        ## feedback
        show_edges()

    if mode == 'XRD':
        report('Finished configuring for XRD', level='bold', slack=True)
    else:
        report(
            f'Finished configuring for {el.capitalize()} {edge.capitalize()} edge',
            level='bold',
            slack=True)
    if slits is False:
        print(
            '  * You may need to verify the slit position:  RE(slit_height())')
    #xBMMuser.to_json(os.path.join(BMMuser.folder, '.BMMuser'))
    BMM_clear_suspenders()
    yield from dcm.kill_plan()
    yield from mv(m2_bender.kill_cmd, 1)
    end = time.time()
    print('\n\nThat took %.1f min' % ((end - start) / 60))
    return ()
コード例 #6
0
    def main_plan(detector, slow, startslow, stopslow, nslow, fast, startfast,
                  stopfast, nfast, pluck, force, dwell, md):
        (ok, text) = BMM_clear_to_start()
        if force is False and ok is False:
            print(error_msg(text))
            BMMuser.final_log_entry = False
            yield from null()
            return

        user_ns['RE'].msg_hook = None

        ## sanity checks on slow axis
        if type(slow) is str: slow = slow.lower()
        if slow not in motor_nicknames.keys() and 'EpicsMotor' not in str(
                type(slow)) and 'PseudoSingle' not in str(type(slow)):
            print(
                error_msg('\n*** %s is not an areascan motor (%s)\n' %
                          (slow, str.join(', ', motor_nicknames.keys()))))
            BMMuser.final_log_entry = False
            yield from null()
            return
        if slow in motor_nicknames.keys():
            slow = motor_nicknames[slow]

        ## sanity checks on fast axis
        if type(fast) is str: fast = fast.lower()
        if fast not in motor_nicknames.keys() and 'EpicsMotor' not in str(
                type(fast)) and 'PseudoSingle' not in str(type(fast)):
            print(
                error_msg('\n*** %s is not an areascan motor (%s)\n' %
                          (fast, str.join(', ', motor_nicknames.keys()))))
            BMMuser.final_log_entry = False
            yield from null()
            return
        if fast in motor_nicknames.keys():
            fast = motor_nicknames[fast]

        detector = detector.capitalize()
        yield from mv(_locked_dwell_time, dwell)
        dets = [
            quadem1,
        ]

        if with_xspress3 and detector == 'If':
            detector = 'Xs'

        if detector == 'If':
            dets.append(vor)
            detector = 'ROI1'
        if detector.lower() == 'xs':
            dets.append(xs)
            detector = BMMuser.xs1
            yield from mv(xs.total_points, nslow * nfast)

        if 'PseudoSingle' in str(type(slow)):
            valueslow = slow.readback.get()
        else:
            valueslow = slow.user_readback.get()
        line1 = 'slow motor: %s, %.3f, %.3f, %d -- starting at %.3f\n' % \
            (slow.name, startslow, stopslow, nslow, valueslow)

        if 'PseudoSingle' in str(type(fast)):
            valuefast = fast.readback.get()
        else:
            valuefast = fast.user_readback.get()
        line2 = 'fast motor: %s, %.3f, %.3f, %d -- starting at %.3f\n' % \
            (fast.name, startfast, stopfast, nfast, valuefast)

        npoints = nfast * nslow
        estimate = int(npoints * (dwell + 0.7))

        # extent = (
        #     valuefast + startfast,
        #     valueslow + startslow,
        #     valuefast + stopfast,
        #     valueslow + stopslow,
        # )
        # extent = (
        #     0,
        #     nfast-1,
        #     0,
        #     nslow-1
        # )
        # print(extent)
        # return(yield from null())

        # areaplot = LiveScatter(fast.name, slow.name, detector,
        #                        xlim=(startfast, stopfast), ylim=(startslow, stopslow))

        close_all_plots()

        areaplot = LiveGrid(
            (nslow, nfast),
            detector,  #aspect='equal', #aspect=float(nslow/nfast), extent=extent,
            xlabel='fast motor: %s' % fast.name,
            ylabel='slow motor: %s' % slow.name)
        #BMMuser.ax     = areaplot.ax
        #BMMuser.fig    = areaplot.ax.figure
        BMMuser.motor = fast
        BMMuser.motor2 = slow
        #BMMuser.fig.canvas.mpl_connect('close_event', handle_close)

        thismd = dict()
        thismd['XDI'] = dict()
        thismd['XDI']['Facility'] = dict()
        thismd['XDI']['Facility']['GUP'] = BMMuser.gup
        thismd['XDI']['Facility']['SAF'] = BMMuser.saf
        thismd['slow_motor'] = slow.name
        thismd['fast_motor'] = fast.name

        report(
            f'Starting areascan at x,y = {fast.position:.3f}, {slow.position:.3f}',
            level='bold',
            slack=True)

        ## engage suspenders right before starting scan sequence
        if force is False: BMM_suspenders()

        @subs_decorator(areaplot)
        #@subs_decorator(src.callback)
        def make_areascan(dets,
                          slow,
                          startslow,
                          stopslow,
                          nslow,
                          fast,
                          startfast,
                          stopfast,
                          nfast,
                          snake=False):
            BMMuser.final_log_entry = False
            uid = yield from grid_scan(
                dets,
                slow,
                startslow,
                stopslow,
                nslow,
                fast,
                startfast,
                stopfast,
                nfast,
                snake,
                md={
                    'plan_name':
                    f'grid_scan measurement {slow.name} {fast.name} {detector}'
                })
            BMMuser.final_log_entry = True
            return uid

        rkvs.set('BMM:scan:type', 'area')
        rkvs.set('BMM:scan:starttime',
                 str(datetime.datetime.timestamp(datetime.datetime.now())))
        rkvs.set('BMM:scan:estimated', estimate)

        BMM_log_info('begin areascan observing: %s\n%s%s' %
                     (detector, line1, line2))
        uid = yield from make_areascan(dets,
                                       slow,
                                       valueslow + startslow,
                                       valueslow + stopslow,
                                       nslow,
                                       fast,
                                       valuefast + startfast,
                                       valuefast + stopfast,
                                       nfast,
                                       snake=False)

        if pluck is True:

            close_all_plots()
            thismap = user_ns['db'].v2[uid]
            x = numpy.array(thismap.primary.read()[fast.name])
            y = numpy.array(thismap.primary.read()[slow.name])
            z=numpy.array(thismap.primary.read()[BMMuser.xs1]) +\
                numpy.array(thismap.primary.read()[BMMuser.xs2]) +\
                numpy.array(thismap.primary.read()[BMMuser.xs3]) +\
                numpy.array(thismap.primary.read()[BMMuser.xs4])
            z = z.reshape(nfast, nslow)

            # grabbing the first nfast elements of x and every
            # nslow-th element of y is more reliable than
            # numpy.unique due to float &/or motor precision issues

            #plt.title(f'Energy = {energies["below"]}')
            plt.xlabel(f'fast axis ({fast.name}) position (mm)')
            plt.ylabel(f'slow axis ({slow.name}) position (mm)')
            plt.gca().invert_yaxis()  # plot an xafs_x/xafs_y plot upright
            plt.contourf(x[:nfast], y[::nslow], z, cmap=plt.cm.viridis)
            plt.colorbar()
            plt.show()
            fname = os.path.join(BMMuser.folder, 'map-' + now() + '.png')
            plt.savefig(fname)
            try:
                img_to_slack(fname)
            except:
                post_to_slack('failed to post image: {fname}')
                pass

            BMMuser.x = None
            figs = list(map(plt.figure, plt.get_fignums()))
            canvas = figs[0].canvas
            action = input('\n' + bold_msg(
                'Pluck motor position from the plot? [Y/n then Enter] '))
            if action.lower() == 'n' or action.lower() == 'q':
                return (yield from null())
            print(
                'Single click the left mouse button on the plot to pluck a point...'
            )
            cid = canvas.mpl_connect(
                'button_press_event',
                interpret_click)  # see 65-derivedplot.py and
            while BMMuser.x is None:  #  https://matplotlib.org/users/event_handling.html
                yield from sleep(0.5)

            # print('Converting plot coordinates to real coordinates...')
            # begin = valuefast + startfast
            # stepsize = (stopfast - startfast) / (nfast - 1)
            # pointfast = begin + stepsize * BMMuser.x
            # #print(BMMuser.x, pointfast)

            # begin = valueslow + startslow
            # stepsize = (stopslow - startslow) / (nslow - 1)
            # pointslow = begin + stepsize * BMMuser.y
            # #print(BMMuser.y, pointslow)

            # print('That translates to x=%.3f, y=%.3f' % (pointfast, pointslow))
            yield from mv(fast, BMMuser.x, slow, BMMuser.y)
            report(
                f'Moved to position x,y = {fast.position:.3f}, {slow.position:.3f}',
                level='bold',
                slack=True)
コード例 #7
0
    def main_plan(detector, axis, start, stop, nsteps, pluck, force, md):
        (ok, text) = BMM_clear_to_start()
        if force is False and ok is False:
            print(error_msg(text))
            yield from null()
            return

        detector, axis = ls_backwards_compatibility(detector, axis)
        # print('detector is: ' + str(detector))
        # print('axis is: ' + str(axis))
        # return(yield from null())

        user_ns['RE'].msg_hook = None
        ## sanitize input and set thismotor to an actual motor
        if type(axis) is str: axis = axis.lower()
        detector = detector.capitalize()

        ## sanity checks on axis
        if axis not in motor_nicknames.keys() and 'EpicsMotor' not in str(type(axis)) \
           and 'PseudoSingle' not in str(type(axis)) and 'WheelMotor' not in str(type(axis)):
            print(error_msg('\n*** %s is not a linescan motor (%s)\n' %
                          (axis, str.join(', ', motor_nicknames.keys()))))
            yield from null()
            return

        if 'EpicsMotor' in str(type(axis)):
            thismotor = axis
        elif 'PseudoSingle' in str(type(axis)):
            thismotor = axis
        elif 'WheelMotor' in str(type(axis)):
            thismotor = axis
        else:                       # presume it's an xafs_XXXX motor
            thismotor = motor_nicknames[axis]

        current = thismotor.position
        if current+start < thismotor.limits[0]:
            print(error_msg(f'These scan parameters will take {thismotor.name} outside it\'s lower limit of {thismotor.limits[0]}'))
            print(whisper(f'(starting position = {thismotor.position})'))
            return(yield from null())
        if current+stop > thismotor.limits[1]:
            print(error_msg(f'These scan parameters will take {thismotor.name} outside it\'s upper limit of {thismotor.limits[1]}'))
            print(whisper(f'(starting position = {thismotor.position})'))
            return(yield from null())

        BMMuser.motor = thismotor

        # sanity checks on detector
        if detector not in ('It', 'If', 'I0', 'Iy', 'Ir', 'Both', 'Bicron', 'Ia', 'Ib', 'Dualio', 'Xs', 'Xs1'):
            print(error_msg('\n*** %s is not a linescan measurement (%s)\n' %
                            (detector, 'it, if, i0, iy, ir, both, bicron, dualio, xs, xs1')))
            yield from null()
            return

        yield from mv(_locked_dwell_time, inttime)
        if detector == 'Xs':
            yield from mv(xs.cam.acquire_time, inttime)
            yield from mv(xs.total_points, nsteps)
        dets  = [quadem1, ]
        denominator = ''
        detname = ''

        # If should be xs when using Xspress3
        if with_xspress3 and detector == 'If':
            detector = 'Xs'
        
        # func is an anonymous function, built on the fly, for feeding to DerivedPlot
        if detector == 'It':
            denominator = ' / I0'
            detname = 'transmission'
            func = lambda doc: (doc['data'][thismotor.name], doc['data']['It']/doc['data']['I0'])
        elif detector == 'Ia' and dualio is not None:
            dets.append(dualio)
            detname = 'Ia'
            func = lambda doc: (doc['data'][thismotor.name], doc['data']['Ia'])
        elif detector == 'Ib' and dualio is not None:
            dets.append(dualio)
            detname = 'Ib'
            func = lambda doc: (doc['data'][thismotor.name], doc['data']['Ib'])
        elif detector == 'Ir':
            #denominator = ' / It'
            detname = 'reference'
            #func = lambda doc: (doc['data'][thismotor.name], doc['data']['Ir']/doc['data']['It'])
            func = lambda doc: (doc['data'][thismotor.name], doc['data']['Ir'])
        elif detector == 'I0':
            detname = 'I0'
            func = lambda doc: (doc['data'][thismotor.name], doc['data']['I0'])
        elif detector == 'Bicron':
            dets.append(vor)
            detname = 'Bicron'
            func = lambda doc: (doc['data'][thismotor.name], doc['data']['Bicron'])
        elif detector == 'Iy':
            denominator = ' / I0'
            detname = 'electron yield'
            func = lambda doc: (doc['data'][thismotor.name], doc['data']['Iy']/doc['data']['I0'])
        elif detector == 'If':
            dets.append(vor)
            denominator = ' / I0'
            detname = 'fluorescence'
            func = lambda doc: (doc['data'][thismotor.name],
                                (doc['data'][BMMuser.dtc1] +
                                 doc['data'][BMMuser.dtc2] +
                                 doc['data'][BMMuser.dtc3] +
                                 doc['data'][BMMuser.dtc4]   ) / doc['data']['I0'])
        elif detector == 'Xs':
            dets.append(xs)
            denominator = ' / I0'
            detname = 'fluorescence'
            func = lambda doc: (doc['data'][thismotor.name],
                                (doc['data'][BMMuser.xs1] +
                                 doc['data'][BMMuser.xs2] +
                                 doc['data'][BMMuser.xs3] +
                                 doc['data'][BMMuser.xs4] ) / doc['data']['I0'])
            yield from mv(xs.total_points, nsteps) # Xspress3 demands that this be set up front

        elif detector == 'Xs1':
            dets.append(xs1)
            denominator = ' / I0'
            detname = 'fluorescence'
            func = lambda doc: (doc['data'][thismotor.name],
                                doc['data'][BMMuser.xs8] / doc['data']['I0'])
            yield from mv(xs1.total_points, nsteps) # Xspress3 demands that this be set up front

        elif detector == 'Dualio':
            dets.append(dualio)
            funcia = lambda doc: (doc['data'][thismotor.name], doc['data']['Ia'])
            funcib = lambda doc: (doc['data'][thismotor.name], doc['data']['Ib'])

        ## need a "Both" for trans + xs !!!!!!!!!!
        elif detector == 'Both':
            dets.append(vor)
            functr = lambda doc: (doc['data'][thismotor.name], doc['data']['It']/doc['data']['I0'])
            funcfl = lambda doc: (doc['data'][thismotor.name],
                                  (doc['data'][BMMuser.dtc1] +
                                   doc['data'][BMMuser.dtc2] +
                                   doc['data'][BMMuser.dtc3] +
                                   doc['data'][BMMuser.dtc4]   ) / doc['data']['I0'])
        ## and this is the appropriate way to plot this linescan

        #mv(_locked_dwell_time, 0.5)
        if detector == 'Both':
            plot = [DerivedPlot(funcfl, xlabel=thismotor.name, ylabel='If/I0', title='fluorescence vs. %s' % thismotor.name),
                    DerivedPlot(functr, xlabel=thismotor.name, ylabel='It/I0', title='transmission vs. %s' % thismotor.name)]
        elif detector == 'Dualio':
            plot = [DerivedPlot(funcia, xlabel=thismotor.name, ylabel='Ia/I0', title='Ia vs. %s' % thismotor.name),
                    DerivedPlot(funcib, xlabel=thismotor.name, ylabel='Ib/I0', title='Ib vs. %s' % thismotor.name)]
        else:
            plot = DerivedPlot(func,
                               xlabel=thismotor.name,
                               ylabel=detector+denominator,
                               title='%s vs. %s' % (detname, thismotor.name))
        if 'PseudoSingle' in str(type(axis)):
            value = thismotor.readback.get()
        else:
            value = thismotor.user_readback.get()
        line1 = '%s, %s, %.3f, %.3f, %d -- starting at %.3f\n' % \
                (thismotor.name, detector, start, stop, nsteps, value)
        ##BMM_suspenders()            # engage suspenders

        thismd = dict()
        thismd['XDI'] = dict()
        thismd['XDI']['Facility'] = dict()
        thismd['XDI']['Facility']['GUP'] = BMMuser.gup
        thismd['XDI']['Facility']['SAF'] = BMMuser.saf
        #if 'purpose' not in md:
        #    md['purpose'] = 'alignment'
        
        rkvs.set('BMM:scan:type',      'line')
        rkvs.set('BMM:scan:starttime', str(datetime.datetime.timestamp(datetime.datetime.now())))
        rkvs.set('BMM:scan:estimated', 0)

        @subs_decorator(plot)
        #@subs_decorator(src.callback)
        def scan_xafs_motor(dets, motor, start, stop, nsteps):
            uid = yield from rel_scan(dets, motor, start, stop, nsteps, md={**thismd, **md, 'plan_name' : f'rel_scan linescan {motor.name} {detector}'})
            return uid

        uid = yield from scan_xafs_motor(dets, thismotor, start, stop, nsteps)
        #global mytable
        #run = src.retrieve()
        #mytable = run.primary.read().to_dataframe()
        BMM_log_info('linescan: %s\tuid = %s, scan_id = %d' %
                     (line1, uid, user_ns['db'][-1].start['scan_id']))
        if pluck is True:
            action = input('\n' + bold_msg('Pluck motor position from the plot? [Y/n then Enter] '))
            if action.lower() == 'n' or action.lower() == 'q':
                return(yield from null())
            yield from move_after_scan(thismotor)
コード例 #8
0
        def doscan():
            line1 = '%s, %s, %.3f, %.3f, %d -- starting at %.3f\n' % \
                    (motor.name, sgnl, start, stop, nsteps, motor.user_readback.get())

            uid = yield from rel_scan(dets, motor, start, stop, nsteps, md={'plan_name' : f'rel_scan linescan {motor.name} I0'})
            t  = user_ns['db'][-1].table()
            if detector.lower() == 'if':
                signal   = numpy.array((t[BMMuser.xs1]+t[BMMuser.xs2]+t[BMMuser.xs3]+t[BMMuser.xs4])/t['I0'])
            elif detector.lower() == 'it':
                signal   = numpy.array(t['It']/t['I0'])
            elif detector.lower() == 'ir':
                signal   = numpy.array(t['Ir']/t['It'])

            signal = signal - signal[0]
            if negate is True:
                signal = -1 * signal
            pos      = numpy.array(t[motor.name])
            mod      = RectangleModel(form='erf')
            pars     = mod.guess(signal, x=pos)
            out      = mod.fit(signal, pars, x=pos)
            print(whisper(out.fit_report(min_correl=0)))
            out.plot()
            if filename is not None:
                plt.savefig(filename)
            #middle   = out.params['center1'].value + (out.params['center2'].value - out.params['center1'].value)/2
            yield from mv(motor, out.params['midpoint'].value)
            print(bold_msg(f'Found center at {motor.name} = {motor.position}'))
            rkvs.set('BMM:lmfit:center1',   out.params['center1'].value)
            rkvs.set('BMM:lmfit:center2',   out.params['center2'].value)
            rkvs.set('BMM:lmfit:sigma1',    out.params['sigma1'].value)
            rkvs.set('BMM:lmfit:sigma2',    out.params['sigma2'].value)
            rkvs.set('BMM:lmfit:amplitude', out.params['amplitude'].value)
            rkvs.set('BMM:lmfit:midpoint',  out.params['midpoint'].value)
コード例 #9
0
    def main_plan(motor, start, stop, nsteps, detector, negate):
        (ok, text) = BMM_clear_to_start()
        if ok is False:
            print(error_msg(text))
            yield from null()
            return

        user_ns['RE'].msg_hook = None
        BMMuser.motor = motor

        dets = [user_ns['quadem1'],]

        sgnl = 'fluorescence (Xspress3)'

        if detector.lower() == 'if':
            dets.append(user_ns['xs'])
            denominator = ' / I0'
            sgnl = 'fluorescence (Xspress3)'
            func = lambda doc: (doc['data'][motor.name],
                                (doc['data'][BMMuser.xs1] +
                                 doc['data'][BMMuser.xs2] +
                                 doc['data'][BMMuser.xs3] +
                                 doc['data'][BMMuser.xs4] ) / doc['data']['I0'])
            yield from mv(xs.total_points, nsteps)
        elif detector.lower() == 'it':
            sgnl = 'transmission'
            func = lambda doc: (doc['data'][motor.name], doc['data']['It']/ doc['data']['I0'])
        elif detector.lower() == 'ir':
            sgnl = 'reference'
            func = lambda doc: (doc['data'][motor.name], doc['data']['Ir']/ doc['data']['It'])

        titl = f'{sgnl} vs. {motor.name}'
        plot = DerivedPlot(func, xlabel=motor.name, ylabel=sgnl, title=titl)

        rkvs.set('BMM:scan:type',      'line')
        rkvs.set('BMM:scan:starttime', str(datetime.datetime.timestamp(datetime.datetime.now())))
        rkvs.set('BMM:scan:estimated', 0)
        
        @subs_decorator(plot)
        #@subs_decorator(src.callback)
        def doscan():
            line1 = '%s, %s, %.3f, %.3f, %d -- starting at %.3f\n' % \
                    (motor.name, sgnl, start, stop, nsteps, motor.user_readback.get())

            uid = yield from rel_scan(dets, motor, start, stop, nsteps, md={'plan_name' : f'rel_scan linescan {motor.name} I0'})
            t  = user_ns['db'][-1].table()
            if detector.lower() == 'if':
                signal   = numpy.array((t[BMMuser.xs1]+t[BMMuser.xs2]+t[BMMuser.xs3]+t[BMMuser.xs4])/t['I0'])
            elif detector.lower() == 'it':
                signal   = numpy.array(t['It']/t['I0'])
            elif detector.lower() == 'ir':
                signal   = numpy.array(t['Ir']/t['It'])

            signal = signal - signal[0]
            if negate is True:
                signal = -1 * signal
            pos      = numpy.array(t[motor.name])
            mod      = RectangleModel(form='erf')
            pars     = mod.guess(signal, x=pos)
            out      = mod.fit(signal, pars, x=pos)
            print(whisper(out.fit_report(min_correl=0)))
            out.plot()
            if filename is not None:
                plt.savefig(filename)
            #middle   = out.params['center1'].value + (out.params['center2'].value - out.params['center1'].value)/2
            yield from mv(motor, out.params['midpoint'].value)
            print(bold_msg(f'Found center at {motor.name} = {motor.position}'))
            rkvs.set('BMM:lmfit:center1',   out.params['center1'].value)
            rkvs.set('BMM:lmfit:center2',   out.params['center2'].value)
            rkvs.set('BMM:lmfit:sigma1',    out.params['sigma1'].value)
            rkvs.set('BMM:lmfit:sigma2',    out.params['sigma2'].value)
            rkvs.set('BMM:lmfit:amplitude', out.params['amplitude'].value)
            rkvs.set('BMM:lmfit:midpoint',  out.params['midpoint'].value)

        yield from doscan()
コード例 #10
0
    def main_plan(start, stop, nsteps, detector):
        (ok, text) = BMM_clear_to_start()
        if ok is False:
            print(error_msg(text))
            yield from null()
            return

        user_ns['RE'].msg_hook = None
        BMMuser.motor = motor
    
        if detector.lower() == 'bicron':
            func = lambda doc: (doc['data'][motor.name], doc['data']['Bicron'])
            dets = [bicron,]
            sgnl = 'Bicron'
            titl = 'Bicron signal vs. DCM 2nd crystal pitch'
        else:
            func = lambda doc: (doc['data'][motor.name], doc['data']['I0'])
            dets = [quadem1,]
            sgnl = 'I0'
            titl = 'I0 signal vs. DCM 2nd crystal pitch'

        plot = DerivedPlot(func, xlabel=motor.name, ylabel=sgnl, title=titl)

        rkvs.set('BMM:scan:type',      'line')
        rkvs.set('BMM:scan:starttime', str(datetime.datetime.timestamp(datetime.datetime.now())))
        rkvs.set('BMM:scan:estimated', 0)

        @subs_decorator(plot)
        #@subs_decorator(src.callback)
        def scan_dcmpitch(sgnl):
            line1 = '%s, %s, %.3f, %.3f, %d -- starting at %.3f\n' % \
                    (motor.name, sgnl, start, stop, nsteps, motor.user_readback.get())

            yield from mv(_locked_dwell_time, 0.1)
            yield from dcm.kill_plan()

            yield from mv(slits3.vsize, 3)
            if sgnl == 'Bicron':
                yield from mv(slitsg.vsize, 5)
                
            uid = yield from rel_scan(dets, motor, start, stop, nsteps, md={'plan_name' : f'rel_scan linescan {motor.name} I0'})
            #yield from rel_adaptive_scan(dets, 'I0', motor,
            #                             start=start,
            #                             stop=stop,
            #                             min_step=0.002,
            #                             max_step=0.03,
            #                             target_delta=.15,
            #                             backstep=True)
            t  = user_ns['db'][-1].table()
            signal = t[sgnl]
            if choice.lower() == 'com':
                position = com(signal)
                top      = t[motor.name][position]
            elif choice.lower() == 'fit':
                pitch    = t['dcm_pitch']
                mod      = SkewedGaussianModel()
                pars     = mod.guess(signal, x=pitch)
                out      = mod.fit(signal, pars, x=pitch)
                print(whisper(out.fit_report(min_correl=0)))
                out.plot()
                top      = out.params['center'].value
            else:
                position = peak(signal)
                top      = t[motor.name][position]

            yield from mv(motor.kill_cmd, 1)
            yield from sleep(1.0)
            user_ns['RE'].msg_hook = BMM_msg_hook

            BMM_log_info('rocking curve scan: %s\tuid = %s, scan_id = %d' %
                         (line1, uid, user_ns['db'][-1].start['scan_id']))
            yield from mv(motor, top)
            if sgnl == 'Bicron':
                yield from mv(slitsg.vsize, gonio_slit_height)
        yield from scan_dcmpitch(sgnl)
コード例 #11
0
def xlsx():
    '''Prompt for a macro building spreadsheet for any instrument. Use the
    content of cell B1 to direct this spreadsheet to the correct builder.

    if cell B1 is "Glancing angle" --> build a glancing angle macro

    if cell B1 is "Sample wheel" --> build a sample wheel macro

    if cell B1 is empty --> build a sample wheel macro

    Then prompt for the sheet, if there are more than 1 sheet in the
    spreadsheet file.
    
    '''
    spreadsheet = present_options('xlsx')
    if spreadsheet is None:
        print(error_msg('No spreadsheet specified!'))
        return None

    wb = load_workbook(os.path.join(BMMuser.folder, spreadsheet),
                       read_only=True)
    #ws = wb.active
    sheets = wb.sheetnames
    if len(sheets) == 1:
        sheet = sheets[0]
    elif len(sheets) == 2 and 'Version history' in sheets:
        sheet = sheets[0]
    else:
        print(f'Select a sheet from {spreadsheet}:\n')
        actual = []
        for i, x in enumerate(sheets):
            if x == 'Version history':
                continue
            print(f' {i+1:2}: {x}')
            actual.append(x)

        print('\n  r: return')
        choice = input("\nSelect a sheet > ")
        try:
            if int(choice) > 0 and int(choice) <= len(actual):
                sheet = actual[int(choice) - 1]
            else:
                print('No sheet specified')
                return
        except Exception as E:
            print(E)
            print('No sheet specified')
            return
    instrument = str(wb[sheet]['B1'].value).lower()

    if instrument.lower() == 'glancing angle':
        print(bold_msg('This is a glancing angle spreadsheet'))
        gawheel.spreadsheet(spreadsheet, sheet)
        BMMuser.instrument = 'glancing angle stage'
    elif instrument.lower() == 'double wheel':
        print(bold_msg('This is a double sample wheel spreadsheet'))
        wmb.spreadsheet(spreadsheet, sheet, double=True)
        BMMuser.instrument = 'double wheel'
    elif instrument.lower() == 'linkam':
        print(bold_msg('This is a Linkam spreadsheet'))
        lmb.spreadsheet(spreadsheet, sheet)
        BMMuser.instrument = 'Linkam stage'
    elif instrument.lower() == 'lakeshore':
        print(bold_msg('This is a LakeShore spreadsheet'))
        lsmb.spreadsheet(spreadsheet, sheet)
        BMMuser.instrument = 'LakeShore 331'
    elif instrument.lower() == 'grid':
        print(bold_msg('This is a motor grid spreadsheet'))
        gmb.spreadsheet(spreadsheet, sheet)
        BMMuser.instrument = 'motor grid'
    else:
        print(bold_msg('This is a sample wheel spreadsheet'))
        wmb.spreadsheet(spreadsheet, sheet, double=False)
        BMMuser.instrument = 'sample wheel'
    rkvs.set('BMM:automation:type', instrument)
コード例 #12
0
 def in_place(self):
     #user_ns['wmb'].outer_position = user_ns['xafs_x'].position
     #user_ns['wmb'].inner_position = user_ns['wmb'].outer_position + 26
     self.outer_position = user_ns['xafs_x'].position
     self.inner_position = self.outer_position + 26
     rkvs.set('BMM:wheel:outer', self.outer_position)