コード例 #1
0
ファイル: scan.py プロジェクト: MarkRivers/13bm-tomo
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
コード例 #2
0
ファイル: sphere.py プロジェクト: MarkRivers/13bm-tomo
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
コード例 #3
0
ファイル: scan.py プロジェクト: MarkRivers/13bm-tomo
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
コード例 #4
0
ファイル: sphere.py プロジェクト: MarkRivers/13bm-tomo
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]))
コード例 #5
0
ファイル: sphere.py プロジェクト: MarkRivers/13bm-tomo
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)
コード例 #6
0
ファイル: sphere.py プロジェクト: MarkRivers/13bm-tomo
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)
コード例 #7
0
ファイル: sphere.py プロジェクト: MarkRivers/13bm-tomo
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
コード例 #8
0
ファイル: scan.py プロジェクト: MarkRivers/13bm-tomo
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
コード例 #9
0
ファイル: sphere.py プロジェクト: MarkRivers/13bm-tomo
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]))
コード例 #10
0
ファイル: sphere.py プロジェクト: MarkRivers/13bm-tomo
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]))
コード例 #11
0
ファイル: sphere.py プロジェクト: MarkRivers/13bm-tomo
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)