Esempio n. 1
0
def fly(global_PVs, params):
    angular_range =  params.sample_rotation_end -  params.sample_rotation_start
    flyscan_time_estimate = angular_range / params.slew_speed
    log.warning('  *** Fly Scan Time Estimate: %4.2f minutes' % (flyscan_time_estimate/60.))
    #Trigger fly motion to start.  Don't wait for it, since it takes time.
    start_time = time.time()
    driver.motor.move(motor_end, wait=False)
    time.sleep(1)
    old_image_counter = 0
    expected_framerate = driver.motor.slew_speed / delta_egu
    #Monitor the motion to make sure we aren't stuck.
    i = 0
    while time.time() - start_time < 1.5 * flyscan_time_estimate:
        i += 1
        if i % 10 == 0:
            log.info('  *** *** Sample rotation at angle {:f}'.format(driver.motor.readback))
        time.sleep(1)
        if not driver.motor.moving:
            log.info('  *** *** Sample rotation stopped moving.')
            if abs(driver.motor.drive - motor_end) > 1e-2:
                log.error('  *** *** Sample rotation ended but not at right position!')
                raise ValueError
            else:
                log.info('  *** *** Stopped at correct position.')
                break
        #Make sure we're actually getting frames.
        current_image_counter = global_PVs['Cam1_NumImagesCounter'].get()
        if current_image_counter - old_image_counter < 0.2 * expected_framerate:
            log.error('  *** *** Not collecting frames!')
            raise ValueError 
        else:
            old_image_counter = current_image_counter
    else:
        log.warning('  *** *** Fly motion timed out!')
        raise ValueError
Esempio n. 2
0
def take_image(global_PVs, params):

    log.info('  *** taking a single image')

    nRow = global_PVs['Cam1_SizeY_RBV'].get()
    nCol = global_PVs['Cam1_SizeX_RBV'].get()

    image_size = nRow * nCol

    global_PVs['Cam1_ImageMode'].put('Single', wait=True)
    global_PVs['Cam1_NumImages'].put(1, wait=True)

    global_PVs['Cam1_TriggerMode'].put('Internal', wait=True)
    wait_time_sec = int(params.exposure_time) + 5

    global_PVs['Cam1_Acquire'].put(DetectorAcquire, wait=True, timeout=1000.0)
    time.sleep(0.1)
    if aps7bm.wait_pv(global_PVs['Cam1_Acquire'], DetectorIdle,
                      wait_time_sec) == False:  # adjust wait time
        global_PVs['Cam1_Acquire'].put(DetectorIdle)
        log.warning(
            'The camera failed to finish acquisition.  Set to done manually.')

    # Get the image loaded in memory
    img_vect = global_PVs['Cam1_Image'].get(count=image_size)
    if global_PVs['Cam1_Image_Dtype'].get(as_string=True) == 'UInt16':
        img_vect = img_vect.astype(np.uint16)
    img = np.reshape(img_vect, [nRow, nCol])

    return img
Esempio n. 3
0
def set(global_PVs, params):
    '''Sets up detector and arms it for PSO pulses.
    '''
    fname = params.file_name
    # Set detectors
    if params.camera_ioc_prefix in params.valid_camera_prefixes:
        log.info(' ')
        log.info('  *** setup Point Grey')

        # Make sure that we aren't acquiring now
        global_PVs['Cam1_Acquire'].put(DetectorIdle)
        aps7bm.wait_pv(global_PVs['Cam1_Acquire'], DetectorIdle)
        #Set up the XML files to determine HDF file layout
        attrib_file = Path.joinpath(
            Path(__file__).parent, 'mctDetectorAttributes1.xml')
        global_PVs['Cam1_AttributeFile'].put(str(attrib_file), wait=True)
        layout_file = Path.joinpath(Path(__file__).parent, 'mct3.xml')
        global_PVs['HDF1_XMLFileName'].put(str(layout_file), wait=True)

        global_PVs['Cam1_ArrayCallbacks'].put('Enable', wait=True)
        global_PVs['Cam1_AcquirePeriod'].put(float(params.exposure_time),
                                             wait=True)
        global_PVs['Cam1_AcquireTime'].put(float(params.exposure_time),
                                           wait=True)

        log.info('  *** setup Point Grey: Done!')
    else:
        log.error('Detector %s is not defined' % params.camera_ioc_prefix)
        return
    if params.file_name is None:
        log.warning('  *** hdf_writer will not be configured')
    else:
        _setup_hdf_writer(global_PVs, params, fname)
Esempio n. 4
0
def acquire(global_PVs, params):
    # Make sure that we aren't acquiring now
    global_PVs['Cam1_Acquire'].put(DetectorIdle)
    aps7bm.wait_pv(global_PVs['Cam1_Acquire'], DetectorIdle)

    global_PVs['Cam1_FrameType'].put(FrameTypeData, wait=True)
    global_PVs['Cam1_ImageMode'].put('Multiple', wait=True)

    num_images = int(params.num_projections) * params.recursive_filter_n_images
    global_PVs['Cam1_NumImages'].put(num_images, wait=True)

    # Set trigger mode
    global_PVs['Cam1_TriggerMode'].put('Overlapped', wait=True)

    # start acquiring
    global_PVs['Cam1_Acquire'].put(DetectorAcquire)
    aps7bm.wait_pv(global_PVs['Cam1_Acquire'], DetectorAcquire)

    log.info(' ')
    log.info('  *** Fly Scan: Start!')
    pso.fly(global_PVs, params)

    # if the fly scan wait times out we should call done on the detector
    if aps7bm.wait_pv(global_PVs['Cam1_Acquire'], DetectorIdle, 5) == False:
        log.warning('  *** *** Camera did not finish acquisition')
        global_PVs['Cam1_Acquire'].put(DetectorIdle)
    log.info('  *** Fly Scan: Done!')
    # Set trigger mode to internal for post dark and white
    global_PVs['Cam1_TriggerMode'].put('Internal')
    return pso.proj_positions
Esempio n. 5
0
def log_info():
    log.warning('  *** *** Positions for fly scan.')
    log.info('  *** *** *** Motor start = {0:f}'.format(req_start))
    log.info('  *** *** *** Motor end = {0:f}'.format(actual_end))
    log.info('  *** *** *** # Points = {0:4d}'.format(num_proj))
    log.info('  *** *** *** Degrees per image = {0:f}'.format(delta_egu))
    log.info('  *** *** *** Degrees per projection = {0:f}'.format(delta_egu / num_images_per_proj))
    log.info('  *** *** *** Encoder counts per image = {0:d}'.format(delta_encoder_counts))
Esempio n. 6
0
def close_shutters(global_PVs, params):
    log.info(' ')
    log.info('  *** close_shutters')
    if TESTING:
        log.warning(
            '  *** testing mode - shutters are deactivated during the scans !!!!'
        )
    else:
        global_PVs['ShutterA_Close'].put(1, wait=True)
        wait_pv(global_PVs['ShutterA_Move_Status'], ShutterA_Close_Value)
        log.info('  *** close_shutter A: Done!')
Esempio n. 7
0
def fly_scan(params):
    '''Perform potentially repeated fly scan.
    '''
    tic = time.time()
    global_PVs = aps7bm.init_general_PVs(params)
    try:
        if not check_camera_IOC(global_PVs, params):
            return False
        # Set the slew speed, possibly based on blur and acquisition parameters
        set_slew_speed(global_PVs, params)
        # init camera
        flir.init(global_PVs, params)

        log.info(' ')
        log.info("  *** Running %d sleep scans" % params.sleep_steps)
        for i in np.arange(params.sleep_steps):
            tic_01 = time.time()
            # set sample file name
            params.file_path = global_PVs['HDF1_FilePath'].get(as_string=True)
            params.file_name = str('{:03}'.format(
                global_PVs['HDF1_FileNumber'].get(
                ))) + '_' + global_PVs['Sample_Name'].get(as_string=True)
            log.info(' ')
            log.info('  *** Start scan {:d} of {:d}'.format(
                int(i + 1), int(params.sleep_steps)))
            tomo_fly_scan(global_PVs, params)
            if ((i + 1) != params.sleep_steps):
                log.warning('  *** Wait (s): %s ' % str(params.sleep_time))
                time.sleep(params.sleep_time)

            log.info(' ')
            log.info('  *** Data file: %s' %
                     global_PVs['HDF1_FullFileName_RBV'].get(as_string=True))
            log.info('  *** Total scan time: %s minutes' % str(
                (time.time() - tic_01) / 60.))
            log.info('  *** Scan Done!')

            #dm.scp(global_PVs, params)

        log.info('  *** Total loop scan time: %s minutes' % str(
            (time.time() - tic) / 60.))
        global_PVs['Cam1_ImageMode'].put('Continuous')
        log.info('  *** Done!')
    except KeyError:
        log.error('  *** Some PV assignment failed!')
    except Exception as ee:
        stop_scan(global_PVs, params)
        log.info('  Exception recorded: ' + str(ee))
Esempio n. 8
0
def update_config(args):
       # update tomo2bm.conf
        sections = SCAN_PARAMS
        write(args.config, args=args, sections=sections)

        # copy tomo2bm.conf to the raw data directory with a unique name (sample_name.conf)
        log.info(args.file_path)
        log.info(args.file_name)
        log_fname = str(Path.joinpath(Path(args.file_path), args.file_name + '.conf'))
        try:
            shutil.copyfile(args.config, log_fname)
            log.info('  *** copied %s to %s ' % (args.config, log_fname))
        except:
            log.error('  *** attempt to copy %s to %s failed' % (args.config, log_fname))
            pass
        log.warning(' *** command to repeat the scan: tomo scan --config {:s}'.format(log_fname))
Esempio n. 9
0
def log_values(args):
    """Log all values set in the args namespace.

    Arguments are grouped according to their section and logged alphabetically
    using the DEBUG log level thus --verbose is required.
    """
    args = args.__dict__

    log.warning('tomo scan status start')
    for section, name in zip(SECTIONS, NICE_NAMES):
        entries = sorted((k for k in args.keys() if k.replace('_', '-') in SECTIONS[section]))

        # print('log_values', section, name, entries)
        if entries:
            log.info(name)

            for entry in entries:
                value = args[entry] if args[entry] is not None else "-"
                log.info("  {:<16} {}".format(entry, value))

    log.warning('tomo scan status end')
Esempio n. 10
0
def compute_positions():
    '''Computes several parameters describing the fly scan motion.
    These calculations are for tomography scans, where for N images we need N pulses.
    Moreover, we base these on the number of images, not the delta between.
    '''
    global actual_end, delta_egu, delta_encoder_counts, motor_start, motor_end, PSO_positions
    global proj_positions
    _compute_senses()
    #Get the distance needed for acceleration = 1/2 a t^2 = 1/2 * v * t
    motor_accl_time = driver.motor.acceleration    #Acceleration time in s
    accel_dist = motor_accl_time * speed / 2.0  

    #Compute the actual delta to keep things at an integral number of encoder counts
    raw_delta_encoder_counts = (abs(req_end - req_start) 
                                    / ((num_proj - 1) * num_images_per_proj) * driver.encoder_multiply)
    delta_encoder_counts = round(raw_delta_encoder_counts)
    if abs(raw_delta_encoder_counts - delta_encoder_counts) > 1e-4:
        log.warning('  *** *** *** Requested scan would have used a non-integer number of encoder pulses.')
        log.warning('  *** *** *** Calculated # of encoder pulses per step = {0:9.4f}'.format(raw_delta_encoder_counts))
        log.warning('  *** *** *** Instead, using {0:d}'.format(delta_encoder_counts))
    delta_egu = delta_encoder_counts / driver.encoder_multiply
                
    #Make taxi distance an integral number of measurement deltas >= accel distance
    #Add 1/2 of a delta to ensure that we are really up to speed.
    taxi_dist = (math.ceil(accel_dist / delta_egu) + 0.5) * delta_egu
    motor_start = req_start - taxi_dist * user_direction
    motor_end = req_end + taxi_dist * user_direction
    
    #Where will the last point actually be?
    actual_end = req_start + (num_proj * num_images_per_proj- 1) * delta_egu * user_direction
    end_proj = req_start + (num_proj - 1) * delta_egu * user_direction * num_images_per_proj
    PSO_positions = np.linspace(req_start, actual_end, num_proj * num_images_per_proj)
    proj_positions = np.linspace(req_start, end_proj, num_proj) 
    log_info()
Esempio n. 11
0
def fly_scan_vertical(params):

    tic = time.time()
    # aps7bm.update_variable_dict(params)
    global_PVsx = aps7bm.init_general_PVs(global_PVs, params)
    try:
        detector_sn = global_PVs['Cam1_SerialNumber'].get()
        if ((detector_sn == None) or (detector_sn == 'Unknown')):
            log.info(
                '*** The Point Grey Camera with EPICS IOC prefix %s is down' %
                params.camera_ioc_prefix)
            log.info('  *** Failed!')
        else:
            log.info('*** The Point Grey Camera with EPICS IOC prefix %s and serial number %s is on' \
                        % (params.camera_ioc_prefix, detector_sn))

            # calling global_PVs['Cam1_AcquireTime'] to replace the default 'ExposureTime' with the one set in the camera
            params.exposure_time = global_PVs['Cam1_AcquireTime'].get()
            # calling calc_blur_pixel() to replace the default 'SlewSpeed'
            blur_pixel, rot_speed, scan_time = calc_blur_pixel(
                global_PVs, params)
            params.slew_speed = rot_speed

            start_y = params.vertical_scan_start
            end_y = params.vertical_scan_end
            step_size_y = params.vertical_scan_step_size

            # init camera
            flir.init(global_PVs, params)

            log.info(' ')
            log.info("  *** Running %d scans" % params.sleep_steps)
            log.info(' ')
            log.info('  *** Vertical Positions (mm): %s' %
                     np.arange(start_y, end_y, step_size_y))

            for ii in np.arange(0, params.sleep_steps, 1):
                log.info(' ')
                log.info('  *** Start scan %d' % ii)
                for i in np.arange(start_y, end_y, step_size_y):
                    tic_01 = time.time()
                    # set sample file name
                    params.file_path = global_PVs['HDF1_FilePath'].get(
                        as_string=True)
                    params.file_name = str(
                        '{:03}'.format(global_PVs['HDF1_FileNumber'].get())
                    ) + '_' + global_PVs['Sample_Name'].get(as_string=True)

                    log.info(' ')
                    log.info('  *** The sample vertical position is at %s mm' %
                             (i))
                    global_PVs['Motor_SampleY'].put(i,
                                                    wait=True,
                                                    timeout=1000.0)
                    tomo_fly_scan(global_PVs, params)

                    log.info(' ')
                    log.info('  *** Data file: %s' %
                             global_PVs['HDF1_FullFileName_RBV'].get(
                                 as_string=True))
                    log.info('  *** Total scan time: %s minutes' % str(
                        (time.time() - tic_01) / 60.))
                    log.info('  *** Scan Done!')

                    dm.scp(global_PVs, params)

                log.info('  *** Moving vertical stage to start position')
                global_PVs['Motor_SampleY'].put(start_y,
                                                wait=True,
                                                timeout=1000.0)

                if ((ii + 1) != params.sleep_steps):
                    log.warning('  *** Wait (s): %s ' % str(params.sleep_time))
                    time.sleep(params.sleep_time)

            log.info('  *** Total loop scan time: %s minutes' % str(
                (time.time() - tic) / 60.))
            log.info('  *** Moving rotary stage to start position')
            global_PVs["Motor_SampleRot"].put(0, wait=True, timeout=600.0)
            log.info('  *** Moving rotary stage to start position: Done!')

            global_PVs['Cam1_ImageMode'].put('Continuous')

            log.info('  *** Done!')

    except KeyError:
        log.error('  *** Some PV assignment failed!')
        pass
Esempio n. 12
0
def set_slew_speed(global_PVs, params):
    '''Determines the slew speed of the rotation stage.
    Make sure that we aren't moving so fast that the camera can't keep up.
    Based on user input, choices are:
    * Use value from config file.  Show how much blur this is and if camera
        can keep up.
    * Base on acquisition parameters (data throughput and exposure).
        Show how much blur this is.
    * Base on both blur and data throughput.
    '''
    log.info('  *** Calculate slew speed and blur')
    scan_range = abs(params.sample_rotation_start - params.sample_rotation_end)
    set_image_factor(global_PVs, params)
    delta_angle = scan_range / (params.num_projections -
                                1) / params.recursive_filter_n_images
    data_max_framerate = flir.calc_max_framerate(global_PVs, params)
    acq_max_framerate = 1.0 / (params.exposure_time + params.ccd_readout)
    #Compute the distance from the rotation axis to the farthest edge of the image
    #Assume SampleX motor is at zero when rotation axis is centered
    overall_res = float(global_PVs['PixelSizeMicrons'].get()) / float(
        global_PVs['Lens_Magnification'].get())
    rot_axis_offset = abs(global_PVs['Motor_SampleX'].drive * 1e3 /
                          overall_res)
    log.info(
        '  *** *** rotation axis offset {0:f} pixels'.format(rot_axis_offset))
    im_half_width = global_PVs['Cam1_SizeX'].get() / 2.0 + rot_axis_offset
    blur_max_framerate = 1e6

    if params.auto_slew_speed == 'manual':
        log.info('  *** *** Using manual slew speed')
        req_framerate = params.slew_speed / delta_angle
        log.info(
            '  *** *** Requested framerate is {:6.3} Hz'.format(req_framerate))
        if acq_max_framerate < req_framerate:
            log.warning(
                '  *** *** Requested framerate too fast for exposure time given.'
            )
            log.warning('  *** *** You will miss frames!')
        if data_max_framerate < req_framerate:
            log.warning(
                '  *** *** Requested framerate too fast for data transfer.')
            log.warning('  *** *** You will miss frames!')
        return finish_set_slew_speed(global_PVs, params)
    elif params.auto_slew_speed == 'acqusition':
        log.info(
            '  *** *** Calc slew speed from data throughput and exposure limits.'
        )
    elif params.recursive_filter_n_images > 1:
        log.warning(
            '  *** *** Blur calculation makes less sense with averaging in each projection.'
        )
    else:
        log.info(
            '  *** *** Calc slew speed based on blur and acquisition parameters.'
        )
        max_blur_angle = np.degrees(
            np.arcsin(params.permitted_blur / im_half_width))
        blur_max_framerate = max_blur_angle / (
            params.exposure_time) / delta_angle
    framerates = np.array(
        [data_max_framerate, acq_max_framerate, blur_max_framerate])
    params.slew_speed = np.min(framerates) * delta_angle
    log.info('  *** *** Max framerate for data transfer is {:6.3f} Hz'.format(
        data_max_framerate))
    log.info('  *** *** Max framerate for exposure time is {:6.3f} Hz'.format(
        acq_max_framerate))
    if blur_max_framerate == np.min(framerates):
        log.info('  *** *** Limited by blur to {:6.3f} Hz'.format(
            blur_max_framerate))
    elif data_max_framerate == np.min(framerates):
        log.info('  *** *** Limited by data throughput to {:6.3f} Hz'.format(
            data_max_framerate))
    else:
        log.info('  *** *** Limited by acquisition time to {:6.3f} Hz'.format(
            acq_max_framerate))
    blur = np.sin(np.radians(
        params.slew_speed * params.exposure_time)) * im_half_width
    if params.recursive_filter_n_images > 1:
        blur = np.sin(np.radians(delta_angle)) * im_half_width
    if blur > params.permitted_blur:
        log.warning(
            '  *** *** Motion blur on image edge = {:6.2f} px'.format(blur))
    else:
        log.info(
            '  *** *** Motion blur on image edge = {:6.2f} px'.format(blur))
    log.info('  *** *** Slew speed set to {:6.3f} deg/s'.format(
        params.slew_speed))
    global_PVs['Sample_Rotation_Speed'].put(params.slew_speed, wait=True)
    return params.slew_speed