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()
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
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)
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)
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 ()
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)
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)
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)
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()
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)
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)
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)