Пример #1
0
def open_shutters(global_PVs, params):

    log.info(' ')
    log.info('  *** open_shutters')
    if TESTING:
        # Logger(variableDict['LogFileName']).info('\x1b[2;30;43m' + '  *** WARNING: testing mode - shutters are deactivated during the scans !!!!' + '\x1b[0m')
        log.warning(
            '  *** testing mode - shutters are deactivated during the scans !!!!'
        )
    else:
        if params.station == '2-BM-A':
            # Use Shutter A
            if ShutterAisFast:
                global_PVs['ShutterAOpen'].put(1, wait=True)
                wait_pv(global_PVs['ShutterAMoveStatus'], ShutterAOpen_Value)
                time.sleep(3)
                global_PVs['FastShutter'].put(1, wait=True)
                time.sleep(1)
                log.info('  *** open_shutter fast: Done!')
            else:
                global_PVs['ShutterAOpen'].put(1, wait=True)
                wait_pv(global_PVs['ShutterAMoveStatus'], ShutterAOpen_Value)
                time.sleep(3)
                log.info('  *** open_shutter A: Done!')
        elif params.station == '2-BM-B':
            global_PVs['ShutterBOpen'].put(1, wait=True)
            wait_pv(global_PVs['ShutterB_Move_Status'], ShutterBOpen_Value)
            log.info('  *** open_shutter B: Done!')
Пример #2
0
def fly_scan(params):

    tic =  time.time()
    global_PVs = aps2bm.init_general_PVs(params)
    aps2bm.user_info_params_update_from_pv(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' 
            rot_speed = calc_blur_pixel(global_PVs, params)
            params.slew_speed = rot_speed

            # init camera
            flir.init(global_PVs, params)

            log.info(' ')
            log.info("  *** Running %d sleep scans" % params.sleep_steps)
            for i in np.arange(0, params.sleep_steps, 1):
                tic_01 =  time.time()
                # set sample file name
                #fname = str('{:03}'.format(global_PVs['HDF1_FileNumber'].get())) + '_' + global_PVs['Sample_Name'].get(as_string=True)
                params.scan_counter = global_PVs['HDF1_FileNumber'].get()
                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/%d' % (i, (params.sleep_steps -1)))
                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.))
 
            log.info('  *** Moving rotary stage to start position')
            global_PVs["Motor_SampleRot"].put(params.sample_rotation_start, 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
Пример #3
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!')
Пример #4
0
def acquire(global_PVs, params):
    theta = []

    # Estimate the time needed for the flyscan
    angular_range =  params.rotation_end -  params.rotation_start
    flyscan_time_estimate = angular_range / params.slew_speed

    # log.info(' ')
    log.warning('  *** Fly Scan Time Estimate: %4.2f minutes' % (flyscan_time_estimate/60.))

    global_PVs['Cam1FrameType'].put(FrameTypeData, wait=True)
    time.sleep(2)    

    # global_PVs['Cam1AcquireTime'].put(float(params.exposure_time) )

    if (params.recursive_filter == False):
        params.recursive_filter_n_images = 1

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


    # Set detectors
    if (params.camera_ioc_prefix == '2bmbPG3:'):   
        global_PVs['Cam1TriggerMode'].put('Overlapped', wait=True)
    elif (params.camera_ioc_prefix == '2bmbSP1:'):
        global_PVs['Cam1TriggerMode'].put('On', wait=True)

    # start acquiring
    global_PVs['Cam1Acquire'].put(DetectorAcquire)
    pv.wait_pv(global_PVs['Cam1Acquire'], 1)

    log.info(' ')
    log.info('  *** Fly Scan: Start!')
    global_PVs['FlyRun'].put(1, wait=True)
    # wait for acquire to finish 
    pv.wait_pv(global_PVs['FlyRun'], 0)

    # if the fly scan wait times out we should call done on the detector
#    if pv.wait_pv(global_PVs['Cam1Acquire'], DetectorIdle, flyscan_time_estimate) == False:
    if pv.wait_pv(global_PVs['Cam1Acquire'], DetectorIdle, 5) == False:
        global_PVs['Cam1Acquire'].put(DetectorIdle)
        #  got error here once when missing 100s of frames: pv.wait_pv( 2bmbSP1:cam1:Acquire 0 5 ) reached max timeout. Return False
    
    log.info('  *** Fly Scan: Done!')
    # Set trigger mode to internal for post dark and white
    if (params.camera_ioc_prefix == '2bmbPG3:'):   
        global_PVs['Cam1TriggerMode'].put('Internal')
    elif (params.camera_ioc_prefix == '2bmbSP1:'):
        global_PVs['Cam1TriggerMode'].put('Off', wait=True)


    theta = global_PVs['OmegaArray'].get(count=int(params.num_angles))
    if (params.recursive_filter_n_images > 1):
        theta = np.mean(theta.reshape(-1, params.recursive_filter_n_images), axis=1)
    
    return theta
Пример #5
0
def yes_or_no(question):
    answer = str(input(question + " (Y/N): ")).lower().strip()
    while not (answer == "y" or answer == "yes" or answer == "n"
               or answer == "no"):
        log.warning("Input yes or no")
        answer = str(input(question + "(Y/N): ")).lower().strip()
    if answer[0] == "y":
        return True
    else:
        return False
Пример #6
0
def write_hdf(args=None, sections=None):
    """
    Write in the hdf raw data file the content of *config_file* with values from *args* 
    if they are specified, otherwise use the defaults. If *sections* are specified, 
    write values from *args* only to those sections, use the defaults on the remaining ones.
    """
    if (args == None):
        log.warning("  *** Not saving log data to the HDF file.")

    else:
        hdf_fname = args.file_path + os.sep + args.file_name + '.h5'

        with h5py.File(hdf_fname, 'r+') as hdf_file:
            #If the group we will write to already exists, remove it
            if hdf_file.get('/process/acquisition/tomo-scan-2bm-' +
                            __version__):
                del (hdf_file['/process/acquisition/tomo-scan-2bm-' +
                              __version__])
            #dt = h5py.string_dtype(encoding='ascii')
            log.info(
                "  *** tomopy.conf parameter written to /process/acquisition/tomo-scan-2bm-%s in file %s "
                % (__version__, args.file_name))
            config = configparser.ConfigParser()
            for section in SECTIONS:
                config.add_section(section)
                for name, opts in SECTIONS[section].items():
                    if args and sections and section in sections and hasattr(
                            args, name.replace('-', '_')):
                        value = getattr(args, name.replace('-', '_'))
                        if isinstance(value, list):
                            # print(type(value), value)
                            value = ', '.join(value)
                    else:
                        value = opts['default'] if opts[
                            'default'] is not None else ''

                    prefix = '# ' if value is '' else ''

                    if name != 'config':
                        dataset = '/process' + '/acquisition/tomo-scan-2bm-' + __version__ + '/' + section + '/' + name
                        dset_length = len(str(value)) * 2 if len(
                            str(value)) > 5 else 10
                        dt = 'S{0:d}'.format(dset_length)
                        hdf_file.require_dataset(dataset,
                                                 shape=(1, ),
                                                 dtype=dt)
                        log.info(name + ': ' + str(value))
                        try:
                            hdf_file[dataset][0] = np.string_(str(value))
                        except TypeError:
                            print(value)
                            raise TypeError
Пример #7
0
def check_remote_directory(remote_server, remote_dir):
    try:
        rcmd = 'ls ' + remote_dir
        # rcmd is the command used to check if the remote directory exists
        subprocess.check_call(['ssh', remote_server, rcmd], stderr=open(os.devnull, 'wb'), stdout=open(os.devnull, 'wb'))
        log.warning('      *** remote directory %s exists' % (remote_dir))
        return 0

    except subprocess.CalledProcessError as e: 
        # log.info('      *** return code = %d' % (e.returncode))
        log.warning('      *** remote directory %s does not exist' % (remote_dir))
        if e.returncode == 2:
            return e.returncode
        else:
            log.error('  *** Unknown error code returned: %d' % (e.returncode))
            return -1
Пример #8
0
def check_center(params, white_field, dark_field):

    global_PVs = aps2bm.init_general_PVs(params)

    log.warning('  *** CHECK center of mass for the centered sphere')

    log.info('  *** moving rotary stage to %f deg position ***' % float(0))
    global_PVs["Motor_SampleRot"].put(float(0), wait=True, timeout=600.0)
    log.info('  *** acquire sphere at %f deg position ***' % float(0))

    sphere_0 = util.normalize(flir.take_image(global_PVs, params), white_field,
                              dark_field)
    cmass_0 = util.center_of_mass(sphere_0)
    log.warning(
        '  *** center of mass for the centered sphere at 0 deg: [%f,%f] ***' %
        (cmass_0[1], cmass_0[0]))
Пример #9
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_fname = args.file_path + os.sep + 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))
    if (args.dx_update):
        write_hdf(args, sections)
Пример #10
0
def set_pso(global_PVs, params):

    acclTime = 1.0 * params.slew_speed / params.accl_rot
    scanDelta = abs(((float(params.sample_rotation_end) -
                      float(params.sample_rotation_start))) /
                    ((float(params.num_projections)) *
                     float(params.recursive_filter_n_images)))

    log.info('  *** *** start_pos %f' % float(params.sample_rotation_start))
    log.info('  *** *** end pos %f' % float(params.sample_rotation_end))

    global_PVs['Fly_StartPos'].put(float(params.sample_rotation_start),
                                   wait=True)
    global_PVs['Fly_EndPos'].put(float(params.sample_rotation_end), wait=True)
    global_PVs['Fly_SlewSpeed'].put(params.slew_speed, wait=True)
    global_PVs['Fly_ScanDelta'].put(scanDelta, wait=True)
    time.sleep(3.0)

    calc_num_proj = global_PVs['Fly_Calc_Projections'].get()

    if calc_num_proj == None:
        log.error(
            '  *** *** Error getting fly calculated number of projections!')
        calc_num_proj = global_PVs['Fly_Calc_Projections'].get()
        log.error('  *** *** Using %s instead of %s' %
                  (calc_num_proj, params.num_projections))
    if calc_num_proj != int(params.num_projections):
        log.warning(
            '  *** *** Changing number of projections from: %s to: %s' %
            (params.num_projections, int(calc_num_proj)))
        params.num_projections = int(calc_num_proj)
    log.info('  *** *** Number of projections: %d' %
             int(params.num_projections))
    log.info('  *** *** Fly calc triggers: %d' % int(calc_num_proj))
    global_PVs['Fly_ScanControl'].put('Standard')

    log.info(' ')
    log.info('  *** Taxi before starting capture')
    global_PVs['Fly_Taxi'].put(1, wait=True)
    wait_pv(global_PVs['Fly_Taxi'], 0)
    log.info('  *** Taxi before starting capture: Done!')
Пример #11
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')
Пример #12
0
def find_resolution(params, dark_field, white_field, angle_shift):

    global_PVs = aps2bm.init_general_PVs(params)

    log.warning(' *** Find resolution ***')
    log.info('  *** moving rotary stage to %f deg position ***' %
             float(0 + angle_shift))
    global_PVs["Motor_SampleRot"].put(float(0 + angle_shift),
                                      wait=True,
                                      timeout=600.0)
    log.info('  *** First image at X: %f mm' % (params.sample_in_position))
    log.info('  *** acquire first image')

    sphere_0 = util.normalize(flir.take_image(global_PVs, params), white_field,
                              dark_field)

    second_image_x_position = params.sample_in_position + params.off_axis_position
    log.info('  *** Second image at X: %f mm' % (second_image_x_position))
    global_PVs["Motor_SampleX"].put(second_image_x_position,
                                    wait=True,
                                    timeout=600.0)
    log.info('  *** acquire second image')
    sphere_1 = util.normalize(flir.take_image(global_PVs, params), white_field,
                              dark_field)

    log.info('  *** moving X stage back to %f mm position' %
             (params.sample_in_position))
    aps2bm.move_sample_in(global_PVs, params)

    shift = register_translation(sphere_0, sphere_1, 100)
    log.info('  *** shift X: %f, Y: %f' % (shift[0][1], shift[0][0]))
    image_resolution = abs(params.off_axis_position) / np.linalg.norm(
        shift[0]) * 1000.0

    log.warning('  *** found resolution %f um/pixel' % (image_resolution))
    params.image_resolution = image_resolution

    aps2bm.image_resolution_pv_update(global_PVs, params)
Пример #13
0
def adjust_focus(params):

    global_PVs = aps2bm.init_general_PVs(params)

    step = 1

    direction = 1
    max_std = 0
    three_std = np.ones(3) * 2**16
    cnt = 0
    decrease_step = False
    while (step > 0.01):
        initpos = global_PVs['Motor_Focus'].get()
        curpos = initpos + step * direction
        global_PVs['Motor_Focus'].put(curpos, wait=True, timeout=600.0)
        img = flir.take_image(global_PVs, params)
        cur_std = np.std(img)
        log.info('  ***   *** Positon: %f Standard deviation: %f ' %
                 (curpos, cur_std))
        if (cur_std > max_std):  # store max std
            max_std = cur_std
        three_std[np.mod(cnt,
                         3)] = cur_std  # store std for 3 last measurements
        if (np.sum(three_std < max_std) == 3):  # pass a peak
            direction = -direction
            if (decrease_step):  # decrease focusing motor step
                step /= 2
            else:  #do not decrease step for the first direction change
                decrease_step = True
            three_std = np.ones(3) * 2**16
            max_std = 0
            log.warning('  *** change direction and step to %f' % (step))
        cnt += 1

    log.warning('  *** Focusing done')

    return
Пример #14
0
def adjust_pitch(params, dark_field, white_field, angle_shift):

    global_PVs = aps2bm.init_general_PVs(params)

    log.warning(' *** Adjusting pitch ***')
    log.info(
        '  *** acquire sphere after moving it along the beam axis by 1mm ***')
    global_PVs["Motor_Sample_Top_90"].put(
        global_PVs["Motor_Sample_Top_90"].get() - 1.0,
        wait=True,
        timeout=600.0)

    log.info('  *** moving rotary stage to %f deg position ***' %
             float(0 + angle_shift))
    global_PVs["Motor_SampleRot"].put(float(0 + angle_shift),
                                      wait=True,
                                      timeout=600.0)
    log.info('  *** acquire sphere at %f deg position ***' %
             float(0 + angle_shift))
    sphere_0 = util.normalize(flir.take_image(global_PVs, params), white_field,
                              dark_field)

    log.info('  *** moving rotary stage to %f deg position ***' %
             float(0 + angle_shift))
    global_PVs["Motor_SampleRot"].put(float(180 + angle_shift),
                                      wait=True,
                                      timeout=600.0)
    log.info('  *** acquire sphere at %f deg position ***' %
             float(180 + angle_shift))
    sphere_180 = util.normalize(flir.take_image(global_PVs, params),
                                white_field, dark_field)

    cmass_0 = util.center_of_mass(sphere_0)
    cmass_180 = util.center_of_mass(sphere_180)
    log.info('  *** center of mass for the initial sphere (%f,%f) ***' %
             (cmass_0[1], cmass_0[0]))
    log.info('  *** center of mass for the shifted sphere (%f,%f) ***' %
             (cmass_180[1], cmass_180[0]))
    pitch = np.rad2deg(
        np.arctan((cmass_180[0] - cmass_0[0]) * params.image_resolution /
                  1000 / 2.0))
    log.warning('  *** found pitch error: %f' % pitch)
    log.info('  *** acquire sphere back along the beam axis by -1mm ***')
    global_PVs["Motor_Sample_Top_90"].put(
        global_PVs["Motor_Sample_Top_90"].get() + 1.0,
        wait=True,
        timeout=600.0)
    log.warning('  *** change pitch to %f ***' %
                float(global_PVs["Motor_Pitch"].get() - pitch))
    global_PVs["Motor_Pitch"].put(global_PVs["Motor_Pitch"].get() - pitch,
                                  wait=True,
                                  timeout=600.0)
    global_PVs["Motor_SampleRot"].put(float(0 + angle_shift),
                                      wait=True,
                                      timeout=600.0)

    log.info('  *** TEST: acquire sphere at %f deg position ***' %
             float(0 + angle_shift))
    sphere_0 = util.normalize(flir.take_image(global_PVs, params), white_field,
                              dark_field)
    cmass_0 = util.center_of_mass(sphere_0)
    log.info('  *** TEST: center of mass for the sphere at 0 deg (%f,%f) ***' %
             (cmass_0[1], cmass_0[0]))
Пример #15
0
def set(global_PVs, params):

    fname = params.file_name
    # Set detectors
    if (params.camera_ioc_prefix == '2bmbPG3:'):   
        log.info(' ')
        log.info('  *** setup Point Grey')

        # mona runf always in B with PG camera
        global_PVs['Cam1AttributeFile'].put('monaDetectorAttributes.xml', wait=True) 
        global_PVs['HDFXMLFileName'].put('monaLayout.xml', wait=True) 

        global_PVs['Cam1ImageMode'].put('Multiple')
        global_PVs['Cam1ArrayCallbacks'].put('Enable')
        #global_PVs['Image1_Callbacks'].put('Enable')
        global_PVs['Cam1AcquirePeriod'].put(float(params.exposure_time))
        global_PVs['Cam1AcquireTime'].put(float(params.exposure_time))
        # if we are using external shutter then set the exposure time
        global_PVs['Cam1FrameRateOnOff'].put(0)

        wait_time_sec = int(params.exposure_time) + 5
        global_PVs['Cam1TriggerMode'].put('Overlapped', wait=True) #Ext. Standard
        global_PVs['Cam1NumImages'].put(1, wait=True)
        global_PVs['Cam1Acquire'].put(DetectorAcquire)
        pv.wait_pv(global_PVs['Cam1Acquire'], DetectorAcquire, 2)
        global_PVs['Cam1SoftwareTrigger'].put(1)
        pv.wait_pv(global_PVs['Cam1Acquire'], DetectorIdle, wait_time_sec)
        global_PVs['Cam1Acquire'].put(DetectorAcquire)
        pv.wait_pv(global_PVs['Cam1Acquire'], DetectorAcquire, 2)
        global_PVs['Cam1SoftwareTrigger'].put(1)
        pv.wait_pv(global_PVs['Cam1Acquire'], DetectorIdle, wait_time_sec)
        log.info('  *** setup Point Grey: Done!')

    elif (params.camera_ioc_prefix == '2bmbSP1:'):
        log.info(' ')
        log.info('  *** setup FLIR camera')

        if params.station == '2-BM-A':
            global_PVs['Cam1AttributeFile'].put('flir2bmaDetectorAttributes.xml')
            global_PVs['HDFXMLFileName'].put('flir2bmaLayout.xml')           
        else: # Mona (B-station)
            global_PVs['Cam1AttributeFile'].put('flir2bmbDetectorAttributes.xml', wait=True) 
            global_PVs['HDFXMLFileName'].put('flir2bmbLayout.xml', wait=True) 

        global_PVs['Cam1Acquire'].put(DetectorIdle)
        pv.wait_pv(global_PVs['Cam1Acquire'], DetectorIdle, 2)

        global_PVs['Cam1TriggerMode'].put('Off', wait=True)
        global_PVs['Cam1TriggerSource'].put('Line2', wait=True)
        global_PVs['Cam1TriggerOverlap'].put('ReadOut', wait=True)
        global_PVs['Cam1ExposureMode'].put('Timed', wait=True)
        global_PVs['Cam1TriggerSelector'].put('FrameStart', wait=True)
        global_PVs['Cam1TriggerActivation'].put('RisingEdge', wait=True)

        global_PVs['Cam1ImageMode'].put('Multiple')
        global_PVs['Cam1ArrayCallbacks'].put('Enable')
        #global_PVs['Image1_Callbacks'].put('Enable')
        #global_PVs['Cam1AcquirePeriod'].put(float(params.exposure_time))
        global_PVs['Cam1FrameRateOnOff'].put(0)
        global_PVs['Cam1AcquireTimeAuto'].put('Off')

        global_PVs['Cam1AcquireTime'].put(float(params.exposure_time))
        # if we are using external shutter then set the exposure time

        wait_time_sec = int(params.exposure_time) + 5

        global_PVs['Cam1TriggerMode'].put('On', wait=True)
        log.info('  *** setup FLIR camera: Done!')
    
    else:
        log.error('Detector %s is not defined' % params.camera_ioc_prefix)
        return
    if fname is None:
        log.warning('  *** hdf_writer will not be configured')
    else:
        _setup_hdf_writer(global_PVs, params, fname)
Пример #16
0
def adjust_center(params, dark_field, white_field):

    global_PVs = aps2bm.init_general_PVs(params)

    log.warning(' *** Adjusting center ***')
    for ang in [params.adjust_center_angle_1, params.adjust_center_angle_2]:
        log.warning('  *** take 3 spheres angular %f deg ***' % float(ang))

        #sphere 0
        log.info('  *** sphere 0')
        log.info('  ***  *** moving rotary stage to %f deg position ***' %
                 float(0))
        global_PVs["Motor_SampleRot"].put(float(0), wait=True, timeout=600.0)
        log.error('  ***  *** acquire sphere at %f deg position ***' %
                  float(0))
        sphere_0 = util.normalize(flir.take_image(global_PVs, params),
                                  white_field, dark_field)

        #sphere 1
        log.info('  *** sphere 1')
        log.info('  ***  *** moving rotary stage to %f deg position ***' %
                 float(ang))
        global_PVs["Motor_SampleRot"].put(float(ang), wait=True, timeout=600.0)
        log.error('  ***  *** acquire sphere at %f deg position ***' %
                  float(ang))
        sphere_1 = util.normalize(flir.take_image(global_PVs, params),
                                  white_field, dark_field)

        #sphere 2
        log.info('  *** sphere 2')
        log.info('  ***  *** moving rotary stage to %f deg position ***' %
                 float(2 * ang))
        global_PVs["Motor_SampleRot"].put(float(2 * ang),
                                          wait=True,
                                          timeout=600.0)
        log.error('  ***  *** acquire sphere at %f deg position ***' %
                  float(2 * ang))
        sphere_2 = util.normalize(flir.take_image(global_PVs, params),
                                  white_field, dark_field)

        # find shifts
        shift0 = register_translation(sphere_1, sphere_0, 100)[0][1]
        shift1 = register_translation(sphere_2, sphere_1, 100)[0][1]
        a = ang * np.pi / 180
        # x=-(1/4) (d1+d2-2 d1 Cos[a]) Csc[a/2]^2,
        x = -(1 / 4) * (shift0 + shift1 - 2 * shift0 * np.cos(a)) * 1 / np.sin(
            a / 2)**2
        # r = 1/2 Csc[a/2]^2 Csc[a] Sqrt[(d1^2+d2^2-2 d1 d2 Cos[a]) Sin[a/2]^2]
        r = 1 / 2 * 1 / np.sin(a / 2)**2 * 1 / np.sin(a) * np.sqrt(
            np.abs((shift0**2 + shift1**2 - 2 * shift0 * shift1 * np.cos(a)) *
                   np.sin(a / 2)**2))
        # g = ArcCos[((-d1-d2+2 d1 Cos[a]) Sin[a])/(2 Sqrt[(d1^2+d2^2-2 d1 d2 Cos[a]) Sin[a/2]^2])]
        g = np.arccos(
            ((-shift0 - shift1 + 2 * shift0 * np.cos(a)) * np.sin(a)) /
            (2 * np.sqrt(
                np.abs(
                    (shift0**2 + shift1**2 - 2 * shift0 * shift1 * np.cos(a)) *
                    np.sin(a / 2)**2))))
        y = r * np.sin(g) * np.sign(shift0)

        # find center of mass
        cmass_0 = util.center_of_mass(sphere_0)

        log.info('  ')
        log.info(
            '  *** position of the initial sphere wrt to the rotation center (%f,%f) ***'
            % (x, y))
        log.info('  *** center of mass for the initial sphere (%f,%f) ***' %
                 (cmass_0[1], cmass_0[0]))
        log.info(
            '  *** moving sphere to the position of the rotation center ***')

        if (params.ask):
            if util.yes_or_no('   *** Yes or No'):
                move_center(params, cmass_0, x, y)
                check_center(params, white_field, dark_field)
            else:
                log.warning(' No motion ')
                exit()

        else:
            move_center(params, cmass_0, x, y)
            check_center(params, white_field, dark_field)
Пример #17
0
def fly_scan_mosaic(params):

    tic =  time.time()
    global_PVs = aps2bm.init_general_PVs(params)
    aps2bm.user_info_params_update_from_pv(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' 
            rot_speed = 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


            start_x = params.horizontal_scan_start
            end_x = params.horizontal_scan_end
            step_size_x = params.horizontal_scan_step_size

            # set scan stop so also ends are included
            stop_x = end_x + step_size_x
            stop_y = end_y + step_size_y

            # init camera
            flir.init(global_PVs, params)

            log.info(' ')
            log.info("  *** Running %d sleep scans" % params.sleep_steps)
            for ii in np.arange(0, params.sleep_steps, 1):
                tic_01 =  time.time()

                log.info(' ')
                log.info("  *** Running %d mosaic scans" % (len(np.arange(start_x, stop_x, step_size_x)) * len(np.arange(start_y, stop_y, step_size_y))))
                log.info(' ')
                log.info('  *** Horizontal Positions (mm): %s' % np.arange(start_x, stop_x, step_size_x))
                log.info('  *** Vertical Positions (mm): %s' % np.arange(start_y, stop_y, step_size_y))

                h = 0
                v = 0
                
                for i in np.arange(start_y, stop_y, step_size_y):
                    log.info(' ')
                    log.error('  *** The sample vertical position is at %s mm' % (i))
                    global_PVs['Motor_SampleY'].put(i, wait=True)
                    for j in np.arange(start_x, stop_x, step_size_x):
                        log.error('  *** The sample horizontal position is at %s mm' % (j))
                        params.sample_in_position = j
                        params.scan_counter = global_PVs['HDF1_FileNumber'].get()
                        # 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) + '_y' + str(v) + '_x' + str(h)
                        tomo_fly_scan(global_PVs, params)
                        h = h + 1
                        dm.scp(global_PVs, params)
                    log.info(' ')
                    log.info('  *** Total scan time: %s minutes' % str((time.time() - tic)/60.))
                    log.info('  *** Data file: %s' % global_PVs['HDF1_FullFileName_RBV'].get(as_string=True))
                    v = v + 1
                    h = 0

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

                log.info('  *** Moving horizontal stage to start position')
                global_PVs['Motor_SampleX'].put(start_x, wait=True, timeout=1000.0)

                log.info('  *** Moving rotary stage to start position')
                global_PVs["Motor_SampleRot"].put(params.sample_rotation_start, wait=True, timeout=600.0)
                log.info('  *** Moving rotary stage to start position: Done!')

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

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

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

    except  KeyError:
        log.error('  *** Some PV assignment failed!')
        pass
Пример #18
0
def adjust_roll(params, dark_field, white_field, angle_shift):

    # angle_shift is the correction that is needed to apply to the rotation axis position
    # to align the Z stage on top of the rotary stage with the beam

    global_PVs = aps2bm.init_general_PVs(params)

    log.warning(' *** Adjusting roll ***')
    log.info('  *** moving rotary stage to %f deg position ***' %
             float(0 + angle_shift))
    global_PVs["Motor_SampleRot"].put(float(0 + angle_shift),
                                      wait=True,
                                      timeout=600.0)
    log.info('  *** moving sphere to the detector border ***')
    global_PVs["Motor_Sample_Top_0"].put(
        global_PVs["Motor_Sample_Top_0"].get() +
        global_PVs['Cam1_SizeX'].get() / 2 * params.image_resolution / 1000 -
        ((SPHERE_DIAMETER / 2) + GAP),
        wait=True,
        timeout=600.0)
    log.info('  *** acquire sphere at %f deg position ***' %
             float(0 + angle_shift))
    sphere_0 = util.normalize(flir.take_image(global_PVs, params), white_field,
                              dark_field)
    log.info('  *** moving rotary stage to %f deg position ***' %
             float(180 + angle_shift))
    global_PVs["Motor_SampleRot"].put(float(180 + angle_shift),
                                      wait=True,
                                      timeout=600.0)
    log.info('  *** acquire sphere at %f deg position ***' %
             float(180 + angle_shift))
    sphere_180 = util.normalize(flir.take_image(global_PVs, params),
                                white_field, dark_field)

    cmass_0 = util.center_of_mass(sphere_0)
    cmass_180 = util.center_of_mass(sphere_180)
    log.info('  *** center of mass for the sphere at 0 deg (%f,%f) ***' %
             (cmass_0[1], cmass_0[0]))
    log.info('  *** center of mass for the sphere at 180 deg (%f,%f) ***' %
             (cmass_180[1], cmass_180[0]))

    roll = np.rad2deg(
        np.arctan((cmass_180[0] - cmass_0[0]) / (cmass_180[1] - cmass_0[1])))
    log.warning('  *** found roll error: %f' % roll)

    log.info('  *** moving rotary stage to %f deg position ***' %
             float(0 + angle_shift))
    global_PVs["Motor_SampleRot"].put(float(0 + angle_shift),
                                      wait=True,
                                      timeout=600.0)
    log.info('  *** moving sphere back to the detector center ***')
    global_PVs["Motor_Sample_Top_0"].put(
        global_PVs["Motor_Sample_Top_0"].get() -
        (global_PVs['Cam1_SizeX'].get() / 2 * params.image_resolution / 1000 -
         ((SPHERE_DIAMETER / 2) + GAP)),
        wait=True,
        timeout=600.0)

    log.info('  *** find shifts resulting by the roll change ***')
    log.info('  *** acquire sphere at the current roll position ***')
    sphere_0 = util.normalize(flir.take_image(global_PVs, params), white_field,
                              dark_field)

    ang = roll / 2  # if roll is too big then ang should be decreased to keep the sphere in the field of view
    log.info('  *** acquire sphere after testing roll change %f ***' %
             float(global_PVs["Motor_Roll"].get() + ang))
    global_PVs["Motor_Roll"].put(global_PVs["Motor_Roll"].get() + ang,
                                 wait=True,
                                 timeout=600.0)
    sphere_1 = util.normalize(flir.take_image(global_PVs, params), white_field,
                              dark_field)

    shift0 = register_translation(sphere_1, sphere_0, 100)[0][1]
    shift1 = shift0 * np.sin(roll) * (np.cos(roll) * 1 / np.tan(ang) +
                                      np.sin(roll))
    log.info(
        '  *** the testing roll change corresponds to %f shift in x, calculated resulting roll change gives %f shift in x ***'
        % (shift0, shift1))
    log.warning('  *** change roll to %f ***' %
                float(global_PVs["Motor_Roll"].get() + roll - ang))
    global_PVs["Motor_Roll"].put(global_PVs["Motor_Roll"].get() + roll - ang,
                                 wait=True,
                                 timeout=600.0)
    log.info('  *** moving sphere to the detector center ***')
    global_PVs["Motor_SampleX"].put(global_PVs["Motor_SampleX"].get() -
                                    shift1 * params.image_resolution / 1000,
                                    wait=True,
                                    timeout=600.0)

    log.info('  *** TEST: acquire sphere at %f deg position ***' %
             float(0 + angle_shift))
    sphere_0 = util.normalize(flir.take_image(global_PVs, params), white_field,
                              dark_field)
    cmass_0 = util.center_of_mass(sphere_0)
    log.info('  *** TEST: center of mass for the sphere at 0 deg (%f,%f) ***' %
             (cmass_0[1], cmass_0[0]))