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!')
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
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!')
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
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
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
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
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]))
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)
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!')
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')
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)
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
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]))
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)
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)
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
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]))