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 adjust(params): global_PVs = aps2bm.init_general_PVs(params) params.file_name = None # so we don't run the flir._setup_hdf_writer 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)) flir.init(global_PVs, params) flir.set(global_PVs, params) dark_field, white_field = flir.take_dark_and_white( global_PVs, params) if (params.resolution == True): find_resolution(params, dark_field, white_field, angle_shift=-0.7) if (params.image_resolution == None): log.error( ' *** Detector resolution is not determined. Please run tomo adjust --resolution first!' ) exit() else: if (params.focus == True): adjust_focus(params) if (params.center == True): adjust_center(params, dark_field, white_field) if (params.roll == True): adjust_roll(params, dark_field, white_field, angle_shift=-0.7) if (params.pitch == True): adjust_pitch(params, dark_field, white_field, angle_shift=-0.7) if (params.roll == True or params.pitch == True): # align center again for higher accuracy adjust_center(params, dark_field, white_field) config.update_sphere(params) except KeyError: log.error(' *** Some PV assignment failed!') pass
def dummy_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)) except KeyError: log.error(' *** Some PV assignment failed!') pass
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 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 move_center(params, cmass_0, x, y): global_PVs = aps2bm.init_general_PVs(params) log.info(' *** moving sample top X to the rotation center ***') global_PVs["Motor_Sample_Top_0"].put( global_PVs["Motor_Sample_Top_0"].get() + x * params.image_resolution / 1000, wait=True, timeout=5.0) log.info(' *** moving sample top Z to the rotation center ***') global_PVs["Motor_Sample_Top_90"].put( global_PVs["Motor_Sample_Top_90"].get() + y * params.image_resolution / 1000, wait=True, timeout=5.0) log.info(' *** moving rotation center to the detector center ***') global_PVs["Motor_SampleX"].put( global_PVs["Motor_SampleX"].get() - (cmass_0[1] - x - global_PVs['Cam1_SizeX'].get() / 2) * params.image_resolution / 1000, wait=True, timeout=600.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
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_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 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]))
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)