def test_wrong_units(self): init_wl = np.linspace(300, 500, num=10) init_spec = np.ones(init_wl.shape) test_spec_base = Spectrum(init_wl, init_spec, 'nm', is_photon_flux=False) with self.assertRaises(ValueError): test_spec_base.get_spectrum(to_x_unit='s')
def test_6(self): init_wl = np.linspace(1, 5, num=10) init_spec = np.ones(init_wl.shape) test_spec_base = Spectrum(x_data=init_wl, y_data=init_spec, x_unit='eV', y_unit="") spectrum = test_spec_base.get_spectrum(to_x_unit='nm', to_y_area_unit="") assert np.all(np.isclose(spectrum[0, :], np.sort(_energy_to_length(init_wl,'eV','nm'))))
def test_mul_scalar(self): init_wl = np.linspace(300, 500, num=10) init_spec = np.ones(init_wl.shape) test_spec_base = Spectrum(init_wl, init_spec, 'nm', is_photon_flux=False) test_spec_base = test_spec_base * 0.5 spectrum = test_spec_base.get_spectrum('nm') self.assertEqual(spectrum[1, 5], 0.5)
def setUp(self): # set up cases for length wavelength conversions self.init_wl = np.linspace(300, 1000, num=5) self.init_spec = np.ones((self.init_wl.shape[0],)) self.spec_base = Spectrum(self.init_wl, self.init_spec, x_unit="nm", y_unit="m**-2") # set up cases self.init_wl2 = np.linspace(1, 5, num=1000) self.init_spec2 = np.linspace(1, 5, num=1000) self.spec_base2 = Spectrum(self.init_wl2, self.init_spec2, x_unit="eV", y_unit="m**-2", is_spec_density=True)
def test_photon_flux_conversion(self): """ This test converts energy flux to photons """ init_wl = np.linspace(300, 500, num=10) init_spec = np.ones(init_wl.shape) test_spec_base = Spectrum(init_wl, init_spec, 'nm', is_photon_flux=False) spectrum = test_spec_base.get_spectrum('nm', to_photon_flux=True) expect_spec = init_spec / (sc.h * sc.c / (init_wl*1e-9)) assert np.all(np.isclose(spectrum[1, :], expect_spec))
def test_hz_to_something_conv(self): init_wl = np.logspace(np.log10(2.4e14), np.log10(2.4e17), num=100) init_spec = np.ones(init_wl.shape) s1 = Spectrum(init_wl, init_spec, x_unit='s**-1', is_photon_flux=False,is_spec_density=True) x,y=s1.get_spectrum(to_x_unit='eV') # Compare the integration. For testing the conversion of spectral density int1=np.trapz(init_spec,init_wl) int2=np.trapz(y,x) self.assertTrue(np.isclose(int1,int2,rtol=1e-3))
def test_mul_spectrum(self): init_wl = np.linspace(300, 500, num=10) init_spec = np.ones(init_wl.shape) mulp_wl = np.linspace(200, 600, num=10) mulp_spec = np.ones(init_wl.shape) * 0.5 test_spec_base = Spectrum(init_wl, init_spec, 'nm', is_photon_flux=False) mulp_spec_base = Spectrum(mulp_wl, mulp_spec, 'nm', is_photon_flux=False) test_spec_base = test_spec_base * mulp_spec_base spec_arr = test_spec_base.get_spectrum('nm') self.assertEqual(spec_arr[1, 5], 0.5)
def test_4(self): init_wl2 = np.linspace(1, 5, num=1000) init_spec2 = np.linspace(1, 5, num=1000) spec_base2 = Spectrum(init_wl2, init_spec2, x_unit="eV", y_unit="", is_spec_density=True) spectrum = spec_base2.get_spectrum(to_x_unit='nm', to_y_area_unit='') self.assertTrue(np.all(np.isclose(spectrum[0, :], np.sort(_energy_to_length(init_wl2,'eV','nm'))))) area_before = np.trapz(init_spec2, init_wl2) area_after = np.trapz(spectrum[1, :], spectrum[0, :]) self.assertTrue(np.isclose(area_before, area_after), msg="area_before: %s, area_after: %s" % (area_before, area_after))
def gen_step_qe(bandEdge_in_eV, qe_in_ratio, qe_below_edge=1e-6, wl_bound=(0.0001, 5)): """ Generate a staircase QE array. Same as gen_square_qe_array() except that it generates a Spectrum class object. EQE(E)= qe if E >= Eg EQE(E)= z (z~0) if E<Eg :param bandEdge_in_eV: set Eg :type bandEdge_in_eV: float :param qe_in_ratio: set qe value (qe) above Eg :type qe_in_ratio: float :param qe_below_edge: set qe value (z) below Eg :param wl_bound: tuple: (minE, maxE), The minimum and maximum of photon energy of this array :type wl_bound: Tuple[float,float] :return: A Spectrum object :rtype: Spectrum """ qe_array = gen_step_qe_array(bandEdge_in_eV, qe_in_ratio, qe_below_edge=qe_below_edge, wl_bound=wl_bound) output_spec = Spectrum(x_data=qe_array[:, 0], y_data=qe_array[:, 1], x_unit="eV") return output_spec
def test_mul_wrong_spectrum(self): init_wl = np.linspace(300, 500, num=10) init_spec = np.ones(init_wl.shape) test_spec_base = Spectrum(init_wl, init_spec, 'nm', is_photon_flux=False) with self.assertRaises(TypeError): test_spec_base * 'r'
def spec_data_to_spec_class(data): x_data = data['WVLGTH'].values y_col = { 'ET_SPCTRUM': 'ext', 'BEAM_NORMAL': 'direct', 'BEAM_NORM+': 'direct_exp', 'GLOB_HORIZ': 'ghi', 'GLOBL_TILT': 'ghi_tilt' } output_data = {} for y_col_name in y_col.keys(): y_data = data[y_col_name].values spec = Spectrum(x_data, y_data, x_unit='nm', y_unit='m**-2', is_spec_density=True) output_data[y_col[y_col_name]] = spec return output_data
def test_energy_flux_conversion(self): """ This test converts photon flux to energy flux """ init_wl = np.linspace(300, 500, num=10) init_spec = np.ones(init_wl.shape) test_spec_base = Spectrum(init_wl, init_spec, x_unit='nm', is_photon_flux=True) spectrum = test_spec_base.get_spectrum(to_x_unit='nm') # Prepare an expected spectrum for comparsion expect_spec = init_spec * sc.h * sc.c / (init_wl*1e-9) # Since the values of the spectrum are very small, causing the errors in np.isclose() # ( both are in the order of ~1e-19) Need renormalise them for proper comparison. assert np.all(np.isclose(spectrum[1, :] * 1e19, expect_spec * 1e19))
def test_cm_1_conversion(self): init_wl = np.linspace(300, 500, num=100) init_spec = np.ones(init_wl.shape) s1 = Spectrum(init_wl, init_spec, 'nm', is_photon_flux=False,is_spec_density=True) x,y=s1.get_spectrum(to_x_unit='cm**-1') c_wl=np.sort(1/(init_wl*1e-7)) self.assertTrue(np.allclose(x,c_wl)) # Compare the integration. For testing the conversion of spectral density int1=np.trapz(init_spec,init_wl) int2=np.trapz(y,x) self.assertTrue(np.isclose(int1,int2,rtol=1e-3))
def test_interp_wrong_spectrum(self): init_wl = np.linspace(300, 500, num=10) init_spec = np.ones(init_wl.shape) test_spec_base = Spectrum(init_wl, init_spec, 'nm', is_photon_flux=False) test_spec_base.get_interp_spectrum(np.array([300, 500]), to_x_unit='nm') with self.assertRaises(ValueError): test_spec_base.get_interp_spectrum(np.array([299,501]),to_x_unit='nm') with self.assertRaises(ValueError): test_spec_base.get_interp_spectrum(np.array([300, 501]), to_x_unit='nm')
def test_gen_qe_from_abs(self): abs_array = np.array([[300, 1e7], [400, 1e8]]) layer_thickness = 500e-6 abs = Spectrum(abs_array[:, 0], abs_array[:, 1], x_unit='nm') qe = conv_abs_to_qe(abs, layer_thickness) qe_a = qe.get_spectrum(to_x_unit='nm') assert np.isclose(qe_a[1, 0], 1 - np.exp(-layer_thickness * abs_array[0, 1]))
def plot_calculate_bed(): qe_wl = np.array([1.1, 5]) qe_qe = np.array([1, 1]) unity_eqe = Spectrum(qe_wl, qe_qe, x_unit='eV') qe = gen_step_qe(1.1, 1, qe_below_edge=0) x1, y1 = calculate_bed(qe) x2, y2 = calculate_bed(unity_eqe) plt.semilogy(x1, y1, hold=True, label='gen_sq_qe') plt.semilogy(x2, y2, label="manual") plt.close()
def test_gen_qe_from_abs_2(self): abs_file = './si_alpha.csv' abs_array = np.loadtxt(abs_file, delimiter=',') abs = Spectrum(abs_array[:, 0], abs_array[:, 1], x_unit='m') qe_1 = conv_abs_to_qe(abs, 500e-6) qe_2 = conv_abs_to_qe(abs, 5e-6) qe_1_a = qe_1.get_spectrum(to_x_unit='nm') qe_2_b = qe_2.get_spectrum(to_x_unit='nm') plt.plot(qe_1_a[0, :], qe_1_a[1, :], hold=True) plt.plot(qe_2_b[0, :], qe_2_b[1, :]) plt.savefig("./test.png")
def test_lambert_abs(self): abs_file = './si_alpha.csv' abs_array = np.loadtxt(abs_file, delimiter=',') abs = Spectrum(abs_array[:, 0], np.ones(abs_array.shape[0]) * 0.1, x_unit='m') abs_set = [abs, abs * 2] t_set = [1, 2] T = lambert_abs(abs_set, t_set) for i in range(10): self.assertEqual(T[np.random.randint(abs_array.shape[0])], np.exp(-0.5))
def test_inv_op(self): init_wl = np.linspace(300, 500, num=10) init_spec = np.ones(init_wl.shape) s1 = Spectrum(init_wl, init_spec, 'nm', is_photon_flux=False) s3 = 1 - s1 * 0.2 s3_c = s1 * 0.8 s3_c2 = 1 + s1 * (-0.2) self.assertTrue(np.allclose(s3.core_y, s3_c.core_y)) self.assertTrue(np.allclose(s3.core_y, s3_c2.core_y)) s4 = 1 / (s1 * 2) s4_c = s1 * 0.5 self.assertTrue(np.allclose(s4.core_y, s4_c.core_y))
def gen_sub_qe_array(eg1, qe1, eg2, qe2, qe_below_edge=1e-6, wl_bound=(0.0001, 5), ouput_type="spectrum"): edge_step = 1e-4 lb = wl_bound[0] ub = wl_bound[1] qe = [[lb, qe_below_edge], [eg2 - edge_step, qe_below_edge], [eg2, qe2], [eg1 - edge_step, qe2], [eg1, qe1], [ub, qe1]] qe = np.array(qe) if ouput_type == "spectrum": qe = Spectrum(x_data=qe[:, 0], y_data=qe[:, 1], x_unit='eV') return qe
def conv_abs_to_qe(absorption, layer_thickness): """ Calculate the QE (absorptivity) from absorption coefficient and layer_thickness Note that the unit of the absorption should match the layer thickness. For example, if the unit of ``absorption`` is 1/meter, the layer_thickness should be meter. :param absorption: Spectrum class instance, the unit of absorption: 1/m :type absorption: Spectrum :param layer_thickness: layer thickness, unit: m :type layer_thickness: float :return: QE, a Spectrum class instance :rtype: Spectrum """ if isinstance(absorption, Spectrum) == False: raise TypeError("The parameter absorption should be a Spectrum class") wl, alpha = absorption.get_spectrum('m') abty = 1 - np.exp(-alpha * layer_thickness) qe = Spectrum(x_data=wl, y_data=abty, x_unit='m') return qe
def read_qe_sp(fname): x, y, _, _ = readeqe(fname) return Spectrum(x, y, x_unit='nm')
class SpectrumTestCases(unittest.TestCase): def setUp(self): # set up cases for length wavelength conversions self.init_wl = np.linspace(300, 1000, num=5) self.init_spec = np.ones((self.init_wl.shape[0],)) self.spec_base = Spectrum(self.init_wl, self.init_spec, x_unit="nm", y_unit="m**-2") # set up cases self.init_wl2 = np.linspace(1, 5, num=1000) self.init_spec2 = np.linspace(1, 5, num=1000) self.spec_base2 = Spectrum(self.init_wl2, self.init_spec2, x_unit="eV", y_unit="m**-2", is_spec_density=True) def test_convert_spectrum_unit(self): x_data = np.linspace(300, 1000, num=3) y_data = np.ones(x_data.shape) # test without area units spec = Spectrum(x_data=x_data, y_data=y_data, x_unit='nm', y_unit='', is_spec_density=False, is_photon_flux=False) new_x_data, new_y_data = spec.convert_spectrum_unit(x_data, y_data, from_x_unit='nm', to_x_unit='nm', from_y_area_unit='', to_y_area_unit='', is_spec_density=False) self.assertTrue(np.all(np.isclose(x_data, new_x_data))) assert np.all(np.isclose(y_data, new_y_data)) # test with area units new_x_data, new_y_data = spec.convert_spectrum_unit(x_data, y_data, from_x_unit='nm', to_x_unit='nm', from_y_area_unit='m**-2', to_y_area_unit='cm**-2', is_spec_density=False) self.assertTrue(np.all(np.isclose(x_data, new_x_data))) self.assertTrue(np.all(np.isclose(y_data, new_y_data * 10000))) new_x_data, new_y_data = spec.convert_spectrum_unit(x_data, y_data, from_x_unit='nm', to_x_unit='eV', from_y_area_unit='', to_y_area_unit='', is_spec_density=False) self.assertTrue(np.all(np.isclose(y_data, new_y_data))) self.assertTrue(np.all(np.isclose(x_data, _energy_to_length(new_x_data,'eV','nm')))) x_data = np.linspace(300, 1000, num=1000) # use trapz to check the result, therefore num has to be large y_data = np.ones(x_data.shape) print("Test converting nm to eV") new_x_data, new_y_data = spec.convert_spectrum_unit(x_data, y_data, from_x_unit='nm', to_x_unit='eV', from_y_area_unit='', to_y_area_unit='', is_spec_density=True) self.assertTrue(np.all(np.isclose(x_data, _energy_to_length(new_x_data,'eV','nm')))) area_after_conv = np.trapz(new_y_data[::-1], new_x_data[::-1]) area_before_conv = np.trapz(y_data, x_data) self.assertTrue(np.isclose(area_before_conv, area_after_conv, rtol=1e-3)) print("Test converting nm to eV with area:") new_x_data, new_y_data = spec.convert_spectrum_unit(x_data, y_data, from_x_unit='nm', to_x_unit='eV', from_y_area_unit='m**-2', to_y_area_unit='cm**-2', is_spec_density=True) self.assertTrue(np.all(np.isclose(x_data, _energy_to_length(new_x_data,'eV','nm')))) area_after_conv = np.trapz(new_y_data[::-1], new_x_data[::-1]) area_before_conv = np.trapz(y_data, x_data) self.assertTrue(np.isclose(area_before_conv, area_after_conv * 10000, rtol=1e-3)) new_x_data, new_y_data = spec.convert_spectrum_unit(x_data, y_data, from_x_unit='nm', to_x_unit='eV', from_y_area_unit='m**-2', to_y_area_unit='m**-2', is_spec_density=True) self.assertTrue(np.all(np.isclose(x_data, _energy_to_length(new_x_data,'eV','nm')))) area_after_conv = np.trapz(new_y_data[::-1], new_x_data[::-1]) area_before_conv = np.trapz(y_data, x_data) self.assertTrue(np.isclose(area_before_conv, area_after_conv, rtol=1e-3)) print("Test converting eV to nm") x_data = np.linspace(0.2, 5, num=1000) # use trapz to check the result, therefore num has to be large y_data = np.ones(x_data.shape) new_x_data, new_y_data = spec.convert_spectrum_unit(x_data, y_data, from_x_unit='eV', to_x_unit='nm', from_y_area_unit='', to_y_area_unit='', is_spec_density=True) self.assertTrue(np.all(np.isclose(x_data, _energy_to_length(new_x_data,'eV','nm')))) area_after_conv = np.trapz(new_y_data[::-1], new_x_data[::-1]) area_before_conv = np.trapz(y_data, x_data) self.assertTrue(np.isclose(area_before_conv, area_after_conv, rtol=1e-3)) x_data = np.linspace(0.2, 5, num=1000) # use trapz to check the result, therefore num has to be large y_data = np.ones(x_data.shape) print("Test converting eV to nm, per area:") new_x_data, new_y_data = spec.convert_spectrum_unit(x_data, y_data, from_x_unit='eV', to_x_unit='nm', from_y_area_unit='m**-2', to_y_area_unit='cm**-2', is_spec_density=True) area_after_conv = np.trapz(new_y_data[::-1], new_x_data[::-1]) area_before_conv = np.trapz(y_data, x_data) self.assertTrue(np.all(np.isclose(x_data, _energy_to_length(new_x_data,'eV','nm')))) self.assertTrue(np.isclose(area_before_conv, area_after_conv * 10000, rtol=1e-2)) def test_1(self): spectrum = self.spec_base.get_spectrum(to_x_unit="nm", to_y_area_unit='m**-2') assert np.all(np.isclose(spectrum[0, :], self.init_wl)) assert np.all(np.isclose(spectrum[1, :], self.init_spec)) spectrum = self.spec_base.get_spectrum('nm', 'cm**-2') assert np.all(np.isclose(spectrum[0, :], self.init_wl)) assert np.all(np.isclose(spectrum[1, :], self.init_spec / 1e4)) # This is not spectral density, therefore we don't have to convert nm->m in sefl.init_spec spectrum = self.spec_base.get_spectrum('m', 'cm**-2') assert np.all(np.isclose(spectrum[0, :], self.init_wl / 1e9)) assert np.all(np.isclose(spectrum[1, :], self.init_spec / 1e4)) def test_4(self): init_wl2 = np.linspace(1, 5, num=1000) init_spec2 = np.linspace(1, 5, num=1000) spec_base2 = Spectrum(init_wl2, init_spec2, x_unit="eV", y_unit="", is_spec_density=True) spectrum = spec_base2.get_spectrum(to_x_unit='nm', to_y_area_unit='') self.assertTrue(np.all(np.isclose(spectrum[0, :], np.sort(_energy_to_length(init_wl2,'eV','nm'))))) area_before = np.trapz(init_spec2, init_wl2) area_after = np.trapz(spectrum[1, :], spectrum[0, :]) self.assertTrue(np.isclose(area_before, area_after), msg="area_before: %s, area_after: %s" % (area_before, area_after)) def test_5(self): spectrum = self.spec_base2.get_spectrum(to_x_unit='J', to_y_area_unit="m**-2") assert np.all(np.isclose(spectrum[0, :], np.sort(self.init_wl2) * sc.e)) assert np.isclose(np.trapz(spectrum[1, :], spectrum[0, :]), np.trapz(self.init_spec2, self.init_wl2)) def test_6(self): init_wl = np.linspace(1, 5, num=10) init_spec = np.ones(init_wl.shape) test_spec_base = Spectrum(x_data=init_wl, y_data=init_spec, x_unit='eV', y_unit="") spectrum = test_spec_base.get_spectrum(to_x_unit='nm', to_y_area_unit="") assert np.all(np.isclose(spectrum[0, :], np.sort(_energy_to_length(init_wl,'eV','nm')))) def test_energy_flux_conversion(self): """ This test converts photon flux to energy flux """ init_wl = np.linspace(300, 500, num=10) init_spec = np.ones(init_wl.shape) test_spec_base = Spectrum(init_wl, init_spec, x_unit='nm', is_photon_flux=True) spectrum = test_spec_base.get_spectrum(to_x_unit='nm') # Prepare an expected spectrum for comparsion expect_spec = init_spec * sc.h * sc.c / (init_wl*1e-9) # Since the values of the spectrum are very small, causing the errors in np.isclose() # ( both are in the order of ~1e-19) Need renormalise them for proper comparison. assert np.all(np.isclose(spectrum[1, :] * 1e19, expect_spec * 1e19)) def test_photon_flux_conversion(self): """ This test converts energy flux to photons """ init_wl = np.linspace(300, 500, num=10) init_spec = np.ones(init_wl.shape) test_spec_base = Spectrum(init_wl, init_spec, 'nm', is_photon_flux=False) spectrum = test_spec_base.get_spectrum('nm', to_photon_flux=True) expect_spec = init_spec / (sc.h * sc.c / (init_wl*1e-9)) assert np.all(np.isclose(spectrum[1, :], expect_spec)) def test_wrong_units(self): init_wl = np.linspace(300, 500, num=10) init_spec = np.ones(init_wl.shape) test_spec_base = Spectrum(init_wl, init_spec, 'nm', is_photon_flux=False) with self.assertRaises(ValueError): test_spec_base.get_spectrum(to_x_unit='s') def test_9(self): """ This test sets up a spectrum, and filter it with GaAs substrate. Unfiltered part of the spectrum has 10% loss. This essentially cut the spectrum at 1.42 eV :return: """ sq_qe = gen_step_qe(1.42, 0.9) test_ill = Illumination() # test_qef = qe_filter(sq_qe) filtered_ill = test_ill * sq_qe assert isinstance(filtered_ill, Illumination) #plt.plot(filtered_ill.get_spectrum('eV')[0, :], filtered_ill.get_spectrum('eV')[1, :], label="filtered") #plt.plot(test_ill.get_spectrum('eV')[0, :], test_ill.get_spectrum('eV')[1, :], label="original") #plt.xlabel('wavelength (eV)') #plt.ylabel('spectrum (W/eV/m^2)') #plt.legend() #plt.show() def test_mul_scalar(self): init_wl = np.linspace(300, 500, num=10) init_spec = np.ones(init_wl.shape) test_spec_base = Spectrum(init_wl, init_spec, 'nm', is_photon_flux=False) test_spec_base = test_spec_base * 0.5 spectrum = test_spec_base.get_spectrum('nm') self.assertEqual(spectrum[1, 5], 0.5) def test_mul_spectrum(self): init_wl = np.linspace(300, 500, num=10) init_spec = np.ones(init_wl.shape) mulp_wl = np.linspace(200, 600, num=10) mulp_spec = np.ones(init_wl.shape) * 0.5 test_spec_base = Spectrum(init_wl, init_spec, 'nm', is_photon_flux=False) mulp_spec_base = Spectrum(mulp_wl, mulp_spec, 'nm', is_photon_flux=False) test_spec_base = test_spec_base * mulp_spec_base spec_arr = test_spec_base.get_spectrum('nm') self.assertEqual(spec_arr[1, 5], 0.5) def test_mul_wrong_spectrum(self): init_wl = np.linspace(300, 500, num=10) init_spec = np.ones(init_wl.shape) test_spec_base = Spectrum(init_wl, init_spec, 'nm', is_photon_flux=False) with self.assertRaises(TypeError): test_spec_base * 'r' def test_inv_op(self): init_wl = np.linspace(300, 500, num=10) init_spec = np.ones(init_wl.shape) s1 = Spectrum(init_wl, init_spec, 'nm', is_photon_flux=False) s3 = 1 - s1 * 0.2 s3_c = s1 * 0.8 s3_c2 = 1 + s1 * (-0.2) self.assertTrue(np.allclose(s3.core_y, s3_c.core_y)) self.assertTrue(np.allclose(s3.core_y, s3_c2.core_y)) s4 = 1 / (s1 * 2) s4_c = s1 * 0.5 self.assertTrue(np.allclose(s4.core_y, s4_c.core_y)) def test_evnm_conversion(self): val = _energy_to_length(1.42, 'eV', 'nm') print(val) def test_cm_1_conversion(self): init_wl = np.linspace(300, 500, num=100) init_spec = np.ones(init_wl.shape) s1 = Spectrum(init_wl, init_spec, 'nm', is_photon_flux=False,is_spec_density=True) x,y=s1.get_spectrum(to_x_unit='cm**-1') c_wl=np.sort(1/(init_wl*1e-7)) self.assertTrue(np.allclose(x,c_wl)) # Compare the integration. For testing the conversion of spectral density int1=np.trapz(init_spec,init_wl) int2=np.trapz(y,x) self.assertTrue(np.isclose(int1,int2,rtol=1e-3)) def test_eV_to_hz_conv(self): init_wl = np.logspace(np.log10(200), np.log10(30000), num=100) init_spec = np.ones(init_wl.shape) s1 = Spectrum(init_wl, init_spec, x_unit='cm**-1', is_photon_flux=False,is_spec_density=True) x,y=s1.get_spectrum(to_x_unit='s**-1') # Compare the integration. For testing the conversion of spectral density int1=np.trapz(init_spec,init_wl) int2=np.trapz(y,x) self.assertTrue(np.isclose(int1,int2,rtol=1e-3)) def test_hz_to_something_conv(self): init_wl = np.logspace(np.log10(2.4e14), np.log10(2.4e17), num=100) init_spec = np.ones(init_wl.shape) s1 = Spectrum(init_wl, init_spec, x_unit='s**-1', is_photon_flux=False,is_spec_density=True) x,y=s1.get_spectrum(to_x_unit='eV') # Compare the integration. For testing the conversion of spectral density int1=np.trapz(init_spec,init_wl) int2=np.trapz(y,x) self.assertTrue(np.isclose(int1,int2,rtol=1e-3)) def test_interp_wrong_spectrum(self): init_wl = np.linspace(300, 500, num=10) init_spec = np.ones(init_wl.shape) test_spec_base = Spectrum(init_wl, init_spec, 'nm', is_photon_flux=False) test_spec_base.get_interp_spectrum(np.array([300, 500]), to_x_unit='nm') with self.assertRaises(ValueError): test_spec_base.get_interp_spectrum(np.array([299,501]),to_x_unit='nm') with self.assertRaises(ValueError): test_spec_base.get_interp_spectrum(np.array([300, 501]), to_x_unit='nm') def test_cut_spectrum(self): ill=Illumination("AM1.5g") ill_a=ill.get_spectrum(to_x_unit='eV') ill_a=ill_a[:,ill_a[0,:]>1.1] ill_a=ill_a[:,ill_a[0,:]<1.42] ill_cut=ill.cut(1.1,1.42,unit='eV') ill_cut_a=ill_cut.get_spectrum(to_x_unit='eV') val1=np.trapz(ill_a[1,:],ill_a[0,:]) val2=np.trapz(ill_cut_a[1,:],ill_cut_a[0,:]) self.assertTrue(np.isclose(val1,val2,rtol=1e-2),msg="val 1=%s,val 2=%s"%(val1,val2))
def test_convert_spectrum_unit(self): x_data = np.linspace(300, 1000, num=3) y_data = np.ones(x_data.shape) # test without area units spec = Spectrum(x_data=x_data, y_data=y_data, x_unit='nm', y_unit='', is_spec_density=False, is_photon_flux=False) new_x_data, new_y_data = spec.convert_spectrum_unit(x_data, y_data, from_x_unit='nm', to_x_unit='nm', from_y_area_unit='', to_y_area_unit='', is_spec_density=False) self.assertTrue(np.all(np.isclose(x_data, new_x_data))) assert np.all(np.isclose(y_data, new_y_data)) # test with area units new_x_data, new_y_data = spec.convert_spectrum_unit(x_data, y_data, from_x_unit='nm', to_x_unit='nm', from_y_area_unit='m**-2', to_y_area_unit='cm**-2', is_spec_density=False) self.assertTrue(np.all(np.isclose(x_data, new_x_data))) self.assertTrue(np.all(np.isclose(y_data, new_y_data * 10000))) new_x_data, new_y_data = spec.convert_spectrum_unit(x_data, y_data, from_x_unit='nm', to_x_unit='eV', from_y_area_unit='', to_y_area_unit='', is_spec_density=False) self.assertTrue(np.all(np.isclose(y_data, new_y_data))) self.assertTrue(np.all(np.isclose(x_data, _energy_to_length(new_x_data,'eV','nm')))) x_data = np.linspace(300, 1000, num=1000) # use trapz to check the result, therefore num has to be large y_data = np.ones(x_data.shape) print("Test converting nm to eV") new_x_data, new_y_data = spec.convert_spectrum_unit(x_data, y_data, from_x_unit='nm', to_x_unit='eV', from_y_area_unit='', to_y_area_unit='', is_spec_density=True) self.assertTrue(np.all(np.isclose(x_data, _energy_to_length(new_x_data,'eV','nm')))) area_after_conv = np.trapz(new_y_data[::-1], new_x_data[::-1]) area_before_conv = np.trapz(y_data, x_data) self.assertTrue(np.isclose(area_before_conv, area_after_conv, rtol=1e-3)) print("Test converting nm to eV with area:") new_x_data, new_y_data = spec.convert_spectrum_unit(x_data, y_data, from_x_unit='nm', to_x_unit='eV', from_y_area_unit='m**-2', to_y_area_unit='cm**-2', is_spec_density=True) self.assertTrue(np.all(np.isclose(x_data, _energy_to_length(new_x_data,'eV','nm')))) area_after_conv = np.trapz(new_y_data[::-1], new_x_data[::-1]) area_before_conv = np.trapz(y_data, x_data) self.assertTrue(np.isclose(area_before_conv, area_after_conv * 10000, rtol=1e-3)) new_x_data, new_y_data = spec.convert_spectrum_unit(x_data, y_data, from_x_unit='nm', to_x_unit='eV', from_y_area_unit='m**-2', to_y_area_unit='m**-2', is_spec_density=True) self.assertTrue(np.all(np.isclose(x_data, _energy_to_length(new_x_data,'eV','nm')))) area_after_conv = np.trapz(new_y_data[::-1], new_x_data[::-1]) area_before_conv = np.trapz(y_data, x_data) self.assertTrue(np.isclose(area_before_conv, area_after_conv, rtol=1e-3)) print("Test converting eV to nm") x_data = np.linspace(0.2, 5, num=1000) # use trapz to check the result, therefore num has to be large y_data = np.ones(x_data.shape) new_x_data, new_y_data = spec.convert_spectrum_unit(x_data, y_data, from_x_unit='eV', to_x_unit='nm', from_y_area_unit='', to_y_area_unit='', is_spec_density=True) self.assertTrue(np.all(np.isclose(x_data, _energy_to_length(new_x_data,'eV','nm')))) area_after_conv = np.trapz(new_y_data[::-1], new_x_data[::-1]) area_before_conv = np.trapz(y_data, x_data) self.assertTrue(np.isclose(area_before_conv, area_after_conv, rtol=1e-3)) x_data = np.linspace(0.2, 5, num=1000) # use trapz to check the result, therefore num has to be large y_data = np.ones(x_data.shape) print("Test converting eV to nm, per area:") new_x_data, new_y_data = spec.convert_spectrum_unit(x_data, y_data, from_x_unit='eV', to_x_unit='nm', from_y_area_unit='m**-2', to_y_area_unit='cm**-2', is_spec_density=True) area_after_conv = np.trapz(new_y_data[::-1], new_x_data[::-1]) area_before_conv = np.trapz(y_data, x_data) self.assertTrue(np.all(np.isclose(x_data, _energy_to_length(new_x_data,'eV','nm')))) self.assertTrue(np.isclose(area_before_conv, area_after_conv * 10000, rtol=1e-2))
def test_jnp(self): w_n = 136.735 * 1e-9 # m w_p = 10.939 * 1e-9 # m x_n = 500 * 1e-9 # m x_p = 100 * 1e-9 # m d_n = 1.293e-3 # m^2/s d_p = 8.79e-5 # m^2/s l_n = 0.2e-6 # m l_p = 0.1e-6 # m s_n = 0 s_p = 0 n_d = 1e19 * 1e6 # /m^3 n_a = 1e17 * 1e6 # /m^3 abs_file = './gaas_nkalpha.csv' abs_array = np.loadtxt(abs_file, delimiter=',', skiprows=1) abs = Spectrum(abs_array[:, 0], abs_array[:, 2] * 100, x_unit='nm') abs_x, abs_y = abs.get_spectrum(to_x_unit='J') init_photon_flux = np.ones_like(abs_y) T = 297 Eg = 1.42 * sc.e m_e = 0.061 * sc.m_e m_h = 0.341 * sc.m_e ni = n_intrinsic(Eg, m_e, m_h, T) print(ni) vbi = builtin_volt(n_d, n_a, ni, T) print(vbi) Jgen, Jn, Jp, Jrec, bsInitial, energies, jgen, jn, jp = calc_jnp( V=0, Vbi=vbi, alphaBottom=abs_y, alphaI=abs_y, alphaTop=abs_y, bsInitial=init_photon_flux, bs_incident_on_top=init_photon_flux, d_bottom=d_n, d_top=d_p, energies=abs_x, T=T, l_bottom=l_n, l_top=l_p, ni=ni, pn_or_np='pn', s_bottom=s_n, s_top=s_p, w_bottom=w_n, w_top=w_p, x_bottom=x_n, x_top=x_p, xi=0) # print(Jgen/sc.e) # print(Jp/sc.e) print(jn[20:30] / sc.e) # print(energies/sc.e) import matplotlib.pyplot as plt plt.plot((jn + jp + jgen) / sc.e)