def calc_fc_response(self, temp, num_points, max_time, is_emission, is_HT,
                      stdout):
     kbT = const.kb_in_Ha * temp
     if is_emission:
         self.fc_response = franck_condon_response.compute_full_response_func(
             self.freqs_gs_emission, self.freqs_ex_emission,
             self.J_emission, self.K_emission, self.E_adiabatic,
             self.dipole_mom, self.dipole_deriv, kbT, num_points, max_time,
             is_emission, is_HT, stdout)
     else:
         self.fc_response = franck_condon_response.compute_full_response_func(
             self.freqs_gs, self.freqs_ex, self.J, self.K, self.E_adiabatic,
             self.dipole_mom, self.dipole_deriv, kbT, num_points, max_time,
             is_emission, is_HT, stdout)
    def calc_full_FTFC_response(self, temp, num_points, max_time, is_emission,
                                is_HT, stdout):
        kbT = temp * const.kb_in_Ha
        counter = 0
        while counter < self.num_gboms:
            stdout.write('PROCESSING BATCH  ' + str(counter))
            ftfc_resp = franck_condon_response.compute_full_response_func(
                self[counter].freqs_gs, self[counter].freqs_ex,
                self[counter].J, self[counter].K, self[counter].E_adiabatic,
                self.dipole_mom, self.dipole_deriv, kbT, num_points, max_time,
                is_emission, is_HT, stdout)
            if counter == 0:
                self.full_FTFC_response = ftfc_resp
            else:
                self.full_FTFC_response[:,
                                        1] = self.full_FTFC_response[:,
                                                                     1] + ftfc_rsponse[:,
                                                                                       1]

            counter = counter + 1
        self.full_FTFC_response[:, 1] = self.full_FTFC_response[:, 1] / (
            1.0 * self.num_gboms)
    def calc_avZTFC_response(self, num_points, max_time, is_emission, is_HT,
                             stdout):
        low_temp_kbT = 10.0 * const.kb_in_Ha
        counter = 0
        while counter < self.num_gboms:
            ztfc_resp = franck_condon_response.compute_full_response_func(
                self[counter].freqs_gs, self[counter].freqs_ex,
                self[counter].J, self[counter].K, 0.0, self.dipole_mom,
                self.dipole_deriv, low_temp_kbT, num_points, max_time,
                is_emission, stdout)
            if counter == 0:
                self.avZTFC_response = ztfc_resp
            else:
                self.avZTFC_response[:,
                                     1] = self.avZTFC_response[:,
                                                               1] + ztfc_rsponse[:,
                                                                                 1]

            counter = counter + 1
        self.avZTFC_response[:,
                             1] = self.avZTFC_response[:, 1] / (1.0 *
                                                                self.num_gboms)
    def calc_eztfc_response(self, temp, num_points, max_time, is_qm,
                            is_emission, is_HT, stdout):
        low_temp_kbT = 10.0 * const.kb_in_Ha  # needed for computing low temperature FC limit. Set T to 10 K
        if is_emission:
            ztfc_resp = franck_condon_response.compute_full_response_func(
                self.freqs_gs_emission, self.freqs_ex_emission,
                self.J_emission, self.K_emission, self.E_adiabatic,
                low_temp_kbT, self.dipole_mom, self.dipole_deriv, num_points,
                max_time, is_emission, is_HT, stdout)
        else:
            ztfc_resp = franck_condon_response.compute_full_response_func(
                self.freqs_gs, self.freqs_ex, self.J, self.K, self.E_adiabatic,
                self.dipole_mom, self.dipole_deriv, low_temp_kbT, num_points,
                max_time, is_emission, is_HT, stdout)
        kbT = temp * const.kb_in_Ha
        # implement this so it works either with quantum wigner or classical distribution of nuclei
        if is_emission:
            omega_e_sq = get_omega_sq(self.freqs_ex_emission)
            omega_g_sq = get_omega_sq(self.freqs_gs_emission)
            if is_qm:
                # compute 'zero temperature' ensemble spectrum
                ensemble_resp_zero_t = gbom_ensemble_response.compute_ensemble_response(
                    self.freqs_gs_emission, self.freqs_ex_emission,
                    self.J_emission, self.K_emission, self.E_adiabatic,
                    self.lambda_0, self.gamma, self.Omega_sq, omega_e_sq,
                    omega_g_sq, low_temp_kbT, num_points, max_time, True,
                    is_emission, stdout)
                ensemble_resp = gbom_ensemble_response.compute_ensemble_response(
                    self.freqs_gs_emission, self.freqs_ex_emission,
                    self.J_emission, self.K_emission, self.E_adiabatic,
                    self.lambda_0, self.gamma, self.Omega_sq, omega_e_sq,
                    omega_g_sq, kbT, num_points, max_time, True, is_emission,
                    stdout)
            else:
                ensemble_resp = gbom_ensemble_response.compute_ensemble_response(
                    self.freqs_gs_emission, self.freqs_ex_emission,
                    self.J_emission, self.K_emission, self.E_adiabatic,
                    self.lambda_0, self.gamma, self.Omega_sq, omega_e_sq,
                    omega_g_sq, kbT, num_points, max_time, False, is_emission,
                    stdout)
        else:
            omega_e_sq = get_omega_sq(self.freqs_ex)
            omega_g_sq = get_omega_sq(self.freqs_gs)
            if is_qm:
                # compute 'zero temperature' ensemble spectrum
                ensemble_resp_zero_t = gbom_ensemble_response.compute_ensemble_response(
                    self.freqs_gs, self.freqs_ex, self.J, self.K,
                    self.E_adiabatic, self.lambda_0, self.gamma, self.Omega_sq,
                    omega_e_sq, omega_g_sq, low_temp_kbT, num_points, max_time,
                    True, is_emission, stdout)
                ensemble_resp = gbom_ensemble_response.compute_ensemble_response(
                    self.freqs_gs, self.freqs_ex, self.J, self.K,
                    self.E_adiabatic, self.lambda_0, self.gamma, self.Omega_sq,
                    omega_e_sq, omega_g_sq, kbT, num_points, max_time, True,
                    is_emission, stdout)
            else:
                ensemble_resp = gbom_ensemble_response.compute_ensemble_response(
                    self.freqs_gs, self.freqs_ex, self.J, self.K,
                    self.E_adiabatic, self.lambda_0, self.gamma, self.Omega_sq,
                    omega_e_sq, omega_g_sq, kbT, num_points, max_time, False,
                    is_emission, stdout)

        total_response = np.zeros((ztfc_resp.shape[0], 2), dtype=complex)
        counter = 0
        # now combine both the ZTFC and the Ensemble lineshapes. Add the magnitude and the phase
        # individually. We also need to add a term to the phase factor to ensure that the Ensemble
        # spectrum is centered around 0. Also, if this is a calculation using a QM wigner distribution
        # for computing the ensemlbe spectrum, make sure that we add the appropriate correction factor (the zero temperature
        # limit of the QM ensemble spectrum).
        while counter < ztfc_resp.shape[0]:
            total_response[counter, 0] = ztfc_resp[counter, 0]
            if is_qm:
                total_response[counter,
                               1] = ztfc_resp[counter, 1] * ensemble_resp[
                                   counter, 1] / ensemble_resp_zero_t[counter,
                                                                      1]
            else:
                total_response[counter, 1] = ztfc_resp[
                    counter, 1] * ensemble_resp[counter, 1] * cmath.exp(
                        1j * (self.E_adiabatic) * ztfc_resp[counter, 0])
            counter = counter + 1

        self.eztfc_response = total_response