コード例 #1
0
    def to_xdi(self, filename=None):
        '''Write an XDI-style file with bin energy in the first column and the
        waveform of each of the 4 channels in the other columns.

        '''
        dcm, BMMuser, ring = user_ns['dcm'], user_ns['BMMuser'], user_ns[
            'ring']

        column_list = ['MCA1', 'MCA2', 'MCA3', 'MCA4']
        column_list = [
            f'MCA{channel_number}' for channel_number in self.channel_numbers
        ]
        m2state, m3state = mirror_state()

        handle = open(filename, 'w')
        handle.write('# XDI/1.0 BlueSky/%s\n' % bluesky_version)
        #handle.write('# Scan.uid: %s\n'          % dataframe['start']['uid'])
        #handle.write('# Scan.transient_id: %d\n' % dataframe['start']['scan_id'])
        handle.write(
            '# Beamline.name: BMM (06BM) -- Beamline for Materials Measurement'
        )
        handle.write('# Beamline.xray_source: NSLS-II three-pole wiggler\n')
        handle.write(
            '# Beamline.collimation: paraboloid mirror, 5 nm Rh on 30 nm Pt\n')
        handle.write('# Beamline.focusing: %s\n' % m2state)
        handle.write('# Beamline.harmonic_rejection: %s\n' % m3state)
        handle.write('# Beamline.energy: %.3f\n' % dcm.energy.position)
        handle.write(
            '# Detector.fluorescence: SII Vortex ME4 (4-element silicon drift)\n'
        )
        handle.write('# Scan.end_time: %s\n' % now())
        handle.write('# Scan.dwell_time: %.2f\n' % self.cam.acquire_time.value)
        handle.write('# Facility.name: NSLS-II\n')
        handle.write('# Facility.current: %.1f mA\n' % ring.current.value)
        handle.write('# Facility.mode: %s\n' % ring.mode.value)
        handle.write('# Facility.cycle: %s\n' % BMMuser.cycle)
        handle.write('# Facility.GUP: %d\n' % BMMuser.gup)
        handle.write('# Facility.SAF: %d\n' % BMMuser.saf)
        handle.write('# Column.1: energy (eV)\n')
        for c, mca_number in enumerate(column_list):
            handle.write(f'# Column.{c+2}: MCA{mca_number} (counts)\n')
        handle.write(
            '# ==========================================================\n')
        handle.write('# energy ')

        ## data table
        e = numpy.arange(0, len(
            self.channels.channel01.mca.array_data.get())) * 10
        mca_data_array_list = [
            channel.mca.array_data.get()
            for channel in self.iterate_channels()
        ]
        a = numpy.vstack(mca_data_array_list)
        b = pandas.DataFrame(a.transpose(), index=e, columns=column_list)
        handle.write(b.to_csv(sep=' '))

        handle.flush()
        handle.close()
        print(bold_msg('wrote XRF spectra to %s' % filename))
コード例 #2
0
    def to_xdi(self, filename=None):
        '''Write an XDI-style file with bin energy in the first column and the
        waveform of the measurement channel in the second column.

        '''

        dcm, BMMuser, ring = user_ns['dcm'], user_ns['BMMuser'], user_ns[
            'ring']

        column_list = ['MCA8']
        #template = "  %.3f  %.6f  %.6f  %.6f  %.6f\n"
        m2state, m3state = mirror_state()

        handle = open(filename, 'w')
        handle.write('# XDI/1.0 BlueSky/%s\n' % bluesky_version)
        #handle.write('# Scan.uid: %s\n'          % dataframe['start']['uid'])
        #handle.write('# Scan.transient_id: %d\n' % dataframe['start']['scan_id'])
        handle.write(
            '# Beamline.name: BMM (06BM) -- Beamline for Materials Measurement'
        )
        handle.write('# Beamline.xray_source: NSLS-II three-pole wiggler\n')
        handle.write(
            '# Beamline.collimation: paraboloid mirror, 5 nm Rh on 30 nm Pt\n')
        handle.write('# Beamline.focusing: %s\n' % m2state)
        handle.write('# Beamline.harmonic_rejection: %s\n' % m3state)
        handle.write('# Beamline.energy: %.3f\n' % dcm.energy.position)
        handle.write(
            '# Detector.fluorescence: SII Vortex ME4 (4-element silicon drift)\n'
        )
        handle.write('# Scan.end_time: %s\n' % now())
        handle.write('# Scan.dwell_time: %.2f\n' %
                     self.settings.acquire_time.value)
        handle.write('# Facility.name: NSLS-II\n')
        handle.write('# Facility.current: %.1f mA\n' % ring.current.value)
        handle.write('# Facility.mode: %s\n' % ring.mode.value)
        handle.write('# Facility.cycle: %s\n' % BMMuser.cycle)
        handle.write('# Facility.GUP: %d\n' % BMMuser.gup)
        handle.write('# Facility.SAF: %d\n' % BMMuser.saf)
        handle.write('# Column.1: energy (eV)\n')
        handle.write('# Column.2: MCA1 (counts)\n')
        handle.write(
            '# ==========================================================\n')
        handle.write('# energy ')

        ## data table
        e = numpy.arange(0, len(self.mca1.value)) * 10
        a = numpy.vstack([
            self.mca1.value, self.mca2.value, self.mca3.value, self.mca4.value
        ])
        b = pd.DataFrame(a.transpose(), index=e, columns=column_list)
        handle.write(b.to_csv(sep=' '))

        handle.flush()
        handle.close()
        print(bold_msg('wrote XRF spectra to %s' % filename))
コード例 #3
0
def xrd_webcam(filename=None, **kwargs):
    XRDURL = 'http://xf06bm-cam6/axis-cgi/jpg/image.cgi'
    CAM_PROXIES = {
        "http": None,
        "https": None,
    }
    if filename is None:
        filename = os.environ['HOME'] + '/XRD_camera_' + now() + '.jpg'
    r = requests.get(XRDURL, proxies=CAM_PROXIES)
    Image.open(BytesIO(r.content)).save(filename, 'JPEG')
    if 'annotation' in kwargs:
        annotate_image(filename, kwargs['annotation'])
    report('XRD webcam image written to %s' % filename)
コード例 #4
0
def analog_camera(filename=None,
                  sample=None,
                  folder=os.environ['HOME'],
                  device='/dev/video0',
                  camera=0,
                  skip=30,
                  frames=5,
                  brightness=30,
                  x=320,
                  y=240,
                  linecolor='white',
                  nocrosshair=True,
                  quiet=False,
                  reset=False,
                  usbid='534d:0021',
                  title='NIST BMM (NSLS-II 06BM)',
                  timestamp='%Y-%m-%d %H:%M:%S'):
    """A function for interacting with fswebcam in a way that meets the
    needs of 06BM.

    Parameters
    ----------
    folder : str
        location to drop jpg image [$HOME]
    device : str
        char device of camera [/dev/video0] should be set to something in /dev/v4l/by-id/
    camera : int
        camera number[0]
    skip : int
        number of frames to skip waiting for camera to wake up  [30]
    frames : int
        number of frames to accumulate in image [5]
    brightness : int
        brightness setting of camera as a percentage [30]
    x : int
        middle of image, in pixels,  X-location of cross hair [320]
    y : int
        middle of image, in pixels,  Y-location of cross hair [240]
    linecolor : str
        color of cross hair lines [white]
    nocrosshair : bool
        flag to suppress cross hair [True]
    quiet : bool
        flag to suppress screen messages [False]
    usbid : str
        vendor and product ID of camera of AV to USB device at 06BM [534d:0021]
    title : str
        title string for fswebcam banner [NIST BMM (NSLS-II 06BM)]
    filename : str
        output file name                   

    """

    USBDEVFS_RESET = 21780

    if reset is True:
        if not quiet: print("resetting video device")
        try:
            lsusb_out = Popen("lsusb | grep -i %s" % usbid,
                              shell=True,
                              bufsize=64,
                              stdin=PIPE,
                              stdout=PIPE,
                              close_fds=True).stdout.read().strip().split()
            bus = lsusb_out[1].decode('UTF-8')
            device = lsusb_out[3][:-1].decode('UTF-8')
            print("/dev/bus/usb/%s/%s" % (bus, device))
            f = open("/dev/bus/usb/%s/%s" % (bus, device), 'w', os.O_WRONLY)
            fcntl.ioctl(f, USBDEVFS_RESET, 0)
            sleep(1)
        except Exception as msg:
            print("failed to reset device:", msg)

    quiet = ''
    if quiet: quiet = '-q '
    if filename is None:
        filename = folder + '/analog_camera_' + now() + '.jpg'

    if sample is not None and sample != '':
        title = title + ' - ' + sample
    if user_ns['BMMuser'].host == 'xf06bm-ws1':
        command = [
            'fswebcam', quiet, '-i', f'{camera}', '-d', device, '-r',
            f'{x}x{y}', '--title', title, '--timestamp', timestamp, '-S',
            f'{skip}', '-F', f'{frames}', '--set', f'brightness={brightness}%',
            filename
        ]
    else:
        command = [
            'ssh', 'xf06bm@xf06bm-ws1',
            f"fswebcam {quiet}-i {camera} -d {device} -r {x}x{y} --title '{title}' --timestamp '{timestamp}' -S {skip} -F {frames} --set brightness={brightness}% '{filename}'"
        ]
    run(command)

    #command = f"fswebcam {quiet}-i {camera} -d {device} -r {x}x{y} --title '{title}' --timestamp '{timestamp}' -S {skip} -F {frames} --set brightness={brightness}% '{filename}'"
    #system(command)
    #command = f"fswebcam {quiet}-i {camera} -d {device} -r {x}x{y} --title '{title}' --timestamp '{timestamp}' -S {skip} -F {frames} --set brightness={brightness}% '{filename}'"
    #system(f'ssh xf06bm@xf06bm-ws1 "{command}"')

    report('Analog camera image written to %s' % filename)
コード例 #5
0
    def _capture(self, status, i):
        "This runs on a background thread."
        try:
            if not self._acquiring_lock.acquire(timeout=0):
                raise RuntimeError("Cannot trigger, currently trigggering!")
            filename = os.path.join(self._root, self._rel_path_template % i)
            # Kick off requests, or subprocess, or whatever with the result
            # that a file is saved at `filename`.

            if self._SPEC == "BMM_XAS_WEBCAM" or self._SPEC == "BMM_XRD_WEBCAM":
                CAM_PROXIES = {
                    "http": None,
                    "https": None,
                }
                r = requests.get(self._url, proxies=CAM_PROXIES)
                im = Image.open(BytesIO(r.content))
                im.save(filename, 'JPEG')
                #print(f'w: {im.width}    h: {im.height}')
                self.image.shape = (im.height, im.width, 3)

                annotation = 'NIST BMM (NSLS-II 06BM)      ' + self._annotation_string + '      ' + now(
                )
                annotate_image(filename, annotation)
            else:
                analog_camera(device=self.device,
                              x=self.x,
                              y=self.y,
                              brightness=self.brightness,
                              filename=filename,
                              sample=self._annotation_string,
                              folder=self._root,
                              quiet=True)
                self.image.shape = (self.y, self.x, 3)
            self._annotation_string = ''

            datum = self._datum_factory({"index": i})
            self._asset_docs_cache.append(('datum', datum))
            self.image.set(datum["datum_id"]).wait()
        except Exception as exc:
            status.set_exception(exc)
        else:
            status.set_finished()
        finally:
            self._acquiring_lock.release()
コード例 #6
0
def energystep(filename = None,
               start    = None,
               end      = None,
               nsteps   = None,
               delay    = 5,
               dosteps  = True):
    '''A simple energy scan, just step forward in energy and don't measure
    anything.  This is a quick hack for use with a crude resonant
    reflectivity experiment with IBM folks.

      filename: name of file, will be appended to DATA for the full path (required)
      start:    starting energy value (required)
      end:      ending energy value (required)
      nsteps:   number of energy steps (required)
      delay:    pause between energy steps, in seconds [5]
      dosteps:  False to see energy values printed to screen without moving mono [True]

    Writes a data file with columns of energy readback, energy
    requested, time of epoch, and ISO 8601 timestamp

    Example:
       energystep(filename='blahblah', start=18936, end=19036, nsteps=101)
    '''

    BMMuser, dcm = user_ns['BMMuser'], user_ns['dcm']
    BMM_log_info("energystep(filename=%s, start=%.1f, end=%.1f, nsteps=%d, delay=%.1f, dosteps=%s)" % (filename, start, end, nsteps, delay, str(dosteps)))
    datafile = BMMuser.DATA + filename
    handle = open(datafile, 'w')
    handle.write('# energy steps from %.1f to %.1f in %d steps\n' % (start, end, nsteps))
    handle.write('#----------------------------------------------------\n')
    handle.write('# energy        requested          epoch        iso8601\n')
    handle.flush()
    
    if dosteps:
        yield from mv(dcm.energy, start)
    print('  %.1f       %.1f     %.6f    %s' % (dcm.energy.readback.get(), start, time.time(), now()))
    handle.write('  %.1f       %.1f     %.6f    %s\n' % (dcm.energy.readback.get(), start, time.time(), now()))
    handle.flush()
    yield from sleep(delay)

    energy = start
    estep = (end-start) / nsteps
    while energy <= end:
        if dosteps:
            yield from mvr(dcm.energy, estep)
        print('  %.1f       %.1f     %.6f    %s' % (dcm.energy.readback.get(), energy, time.time(), now()))
        handle.write('  %.1f       %.1f     %.6f    %s\n' % (dcm.energy.readback.get(), energy, time.time(), now()))
        handle.flush()
        energy = energy + estep
        yield from sleep(delay)
        

    handle.flush()
    handle.close()
コード例 #7
0
def analog_camera(filename=None,
                  sample=None,
                  folder=os.environ['HOME'],
                  device='/dev/video0',
                  camera=0,
                  skip=30,
                  frames=5,
                  brightness=20,
                  x=320,
                  y=240,
                  linecolor='white',
                  nocrosshair=True,
                  quiet=False,
                  reset=False,
                  usbid='534d:0021',
                  title='NIST BMM (NSLS-II 06BM)',
                  timestamp='%Y-%m-%d %H:%M:%S'):
    """A function for interacting with fswebcam in a way that meets the
    needs of 06BM.

    Parameters:
        folder:      location to drop jpg image         [$HOME]
        device:      char device of camera              [/dev/video0]
        camera:      camera number                      [0]
        skip:        number of frames to skip waiting for camera to wake up [30]
        frames:      number of frames to accumulate in image [5]
        brightness:  brightness setting of camera as a percentage [20]
        x:           X-location of cross hair           [320] (middle of image)
        y:           Y-location of cross hair           [240] (middle of image)
        linecolor:   color of cross hair lines          [white]
        nocrosshair: flag to suppress cross hair        [True]
        quiet:       flag to suppress screen messages   [False]
        usbid:       vendor and product ID of camera    [534d:0021] (AV to USB device at 06BM)
        title:       title string for fswebcam banner   [NIST BMM (NSLS-II 06BM)]
        filename:    output file name                   [ISO 8601 timestamp in folder]

    """

    USBDEVFS_RESET = 21780

    if reset is True:
        if not quiet: print("resetting video device")
        try:
            lsusb_out = Popen("lsusb | grep -i %s" % usbid,
                              shell=True,
                              bufsize=64,
                              stdin=PIPE,
                              stdout=PIPE,
                              close_fds=True).stdout.read().strip().split()
            bus = lsusb_out[1].decode('UTF-8')
            device = lsusb_out[3][:-1].decode('UTF-8')
            print("/dev/bus/usb/%s/%s" % (bus, device))
            f = open("/dev/bus/usb/%s/%s" % (bus, device), 'w', os.O_WRONLY)
            fcntl.ioctl(f, USBDEVFS_RESET, 0)
            sleep(1)
        except Exception as msg:
            print("failed to reset device:", msg)

    quiet = ''
    if quiet: quiet = '-q '
    if filename is None:
        filename = folder + '/analog_camera_' + now() + '.jpg'

    if sample is not None:
        title = title + ' - ' + sample
    command = "fswebcam %s-i %s -d %s -r 640x480 --title \"%s\" --timestamp \"%s\" -S %d -F %d --set brightness=%s%% \"%s\"" %\
              (quiet, camera, device, title, timestamp, skip, frames, brightness, filename)
    system(command)

    report('Analog camera image written to %s' % filename)
コード例 #8
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)