コード例 #1
0
def params_from_experiment(can_params_file, params_cfg):
    '''
    Generates a simulation-compatible configuration given a Cantilever Parameters file
    (typically acquired in the experiment) and a Params.cfg file saved with FFtrEFM data

    can_params : string
        Path to cantilever parameters file (from Force Calibration tab)

    params_cfg : string
        Path to parameters.cfg file (from FFtrEFM experiment, in the data folder)
    '''

    can = cantilever_params(can_params_file)
    _, par = configuration(params_cfg)

    if isinstance(params_cfg, dict):
        par = params_cfg

    can_params = {}
    can_params['amp_invols'] = can['Initial']['AMPINVOLS']
    can_params['def_invols'] = can['Initial']['DEFINVOLS']
    can_params['soft_amp'] = 0.3
    can_params['drive_freq'] = par['drive_freq']
    can_params['res_freq'] = par['drive_freq']
    can_params['k'] = can['Initial']['SpringConstant']
    can_params['q_factor'] = can['Initial']['Q']

    force_params = {}
    force_params['es_force'] = can['Differential']['ElectroForce']
    force_params['ac_force'] = can['Initial']['DrivingForce']
    force_params['dc_force'] = 0  # only for GKPFM
    force_params['delta_freq'] = can['Differential']['ResFrequency']
    force_params['tau'] = 1e-5
    force_params['dFdz'] = can['Differential']['dFdZ']
    force_params['lift_height'] = can['Initial']['LiftHeight']

    sim_params = {}
    sim_params['trigger'] = par['trigger']
    sim_params['total_time'] = par['total_time']
    sim_params['sampling_rate'] = par['sampling_rate']

    return can_params, force_params, sim_params, can, par
コード例 #2
0
    def generate_tf(self, can_params_dict={}, plot=False):
        """
        Uses the cantilever simulation to generate a tune as the transfer function
        
        :param can_params_dict: use ffta.pixel_utils.load.cantilever_params()
        :type can_params_dict: Dict
            
        :param plot: Plots the time-dependent tune
        :type plot: bool

        """
        if isinstance(can_params_dict, str):
            can_params_dict = cantilever_params(can_params_dict)
            can_params_dict = can_params_dict['Initial']

        can_params = {
            'amp_invols': 7.5e-08,
            'def_invols': 6.88e-08,
            'soft_amp': 0.3,
            'drive_freq': 309412.0,
            'res_freq': 309412.0,
            'k': 43.1,
            'q_factor': 340.0
        }

        force_params = {
            'es_force': 1e-10,
            'ac_force': 6e-07,
            'dc_force': 3e-09,
            'delta_freq': -170.0,
            'tau': 0.001,
            'v_dc': 3.0,
            'v_ac': 2.0,
            'v_cpd': 1.0,
            'dCdz': 1e-10,
            'v_step': 1.0
        }
        sim_params = {'trigger': 0.02, 'total_time': 0.05}

        for k, v in can_params_dict.items():
            can_params.update(k=v)

        # Update from GKPixel class
        sim_params['trigger'] = self.trigger
        sim_params['sampling_rate'] = self.sampling_rate
        sim_params['total_time'] = self.total_time
        sim_params['sampling_rate'] = self.sampling_rate
        can_params['drive_freq'] = self.drive_freq
        can_params['res_freq'] = self.drive_freq

        force_keys = ['es_force']
        can_keys = {
            'amp_invols': ['amp_invols', 'AMPINVOLS'],
            'q': ['q_factor', 'Q'],
            'k': ['SpringConstant', 'k']
        }

        for f in force_keys:
            if 'Force' in can_params_dict:
                force_params.update(es_force=can_params_dict['Force'])
            elif 'es_force' in can_params_dict:
                force_params.update(es_force=can_params_dict['es_force'])

        for c in ['amp_invols', 'q', 'k']:
            for l in can_keys[c]:
                if l in can_params_dict:
                    can_params.update(l=can_params_dict[l])

        if can_params['k'] < 1e-3:
            can_params['k'] *= 1e9  # old code had this off by 1e9

        cant = Cantilever(can_params, force_params, sim_params)
        cant.trigger = cant.total_time  # don't want a trigger
        Z, _ = cant.simulate()
        Z = Z.flatten()
        if plot:
            plt.figure()
            plt.plot(Z)
            plt.title('Tip response)')

        TF = np.fft.fftshift(np.fft.fft(Z))

        Q = can_params['q_factor']
        mid = int(len(self.f_ax) / 2)
        drive_bin = np.searchsorted(self.f_ax[mid:], self.drive_freq) + mid
        TFmax = np.abs(TF[drive_bin])

        TF_norm = Q * (TF - np.min(np.abs(TF))) / (TFmax - np.min(np.abs(TF)))

        self.tf = Z
        self.TF = TF
        self.TF_norm = TF_norm

        self.tf_f_ax = np.linspace(-self.sampling_rate / 2,
                                   self.sampling_rate / 2,
                                   num=self.tf.shape[0])

        self.tf_exc = gen_chirp(sampling_rate=self.sampling_rate,
                                length=self.tf.shape / self.sampling_rate)
        self.TF_EXC = np.fft.fftshift(np.fft.fft(self.tf_exc))

        return