def return_spectrum_all(self, frequency): """here you will get all spectra back""" if self.connect_temp: self.temp2 = self.temp1 my_dict = self.create_dictionary() #return spectra.get_spectra(frequency,self.element,self.bfield,self.temp1,self.length,self.rb85frac,self.temp2,self.inputpol,self.detpol,self.frequency_shift,self.frequency_broadening,self.connect_temp,self.line,self.frequency_delta,self.k40frac,self.k41frac) return spectra.get_spectra(frequency*1000.,my_dict,outputs='All')
def test_MLfit(): """ Test simple Marquart-Levenburg fit for S1 spectrum. Generate a data set and add random noise, then run an ML fit to the noisy data set, with randomised initial parameters that are the correct ones plus some small change """ p_dict = { 'Elem': 'Rb', 'Dline': 'D2', 'T': 80., 'lcell': 2e-3, 'Bfield': 600., 'Btheta': 0., 'Bphi': 0., 'GammaBuf': 0., 'shift': 0. } p_dict_guess = p_dict # only need to specify parameters that are varied p_dict_bools = {'T': True, 'Bfield': True} E_in = np.sqrt(1. / 2) * np.array([1., 1., 0]) # need to express E_in as Ex, Ey and phase difference for fitting E_in_angle = [E_in[0].real, [abs(E_in[1]), np.angle(E_in[1])]] # Generate spectrum and add some random noise x = np.linspace(-10000, 10000, 300) [y] = get_spectra(x, E_in, p_dict, outputs=['S1']) + np.random.randn(len(x)) * 0.01 # randomise the starting parameters a little p_dict_guess = p_dict p_dict_guess['T'] += np.random.randn() * 1 p_dict_guess['Bfield'] += np.random.randn() * 10 data = [x, y.real] best_params, RMS, result = EM.fit_data(data, p_dict_guess, p_dict_bools, E_in=E_in_angle, data_type='S1', fit_algorithm='ML') report = result.fit_report() fit = result.best_fit print(report) plt.plot(x, y, 'k.', label='Data') plt.plot(x, fit, 'r-', lw=2, label='Fit') plt.legend(loc=0) plt.show()
def _create_sphere(self): sphere = self.scene.mlab.points3d(0, 0, 0, scale_mode='none', scale_factor=2, color=(0.67, 0.77, 0.93), resolution=50, opacity=0.2, name='poin') sphere.actor.property.specular = 0.45 sphere.actor.property.specular_power = 5 sphere.actor.property.backface_culling = True theta = np.linspace(0, 2 * np.pi, 100) for angle in np.linspace(-np.pi, np.pi, 9): xlat = np.cos(theta) * np.cos(angle) ylat = np.sin(theta) * np.cos(angle) zlat = np.ones_like(theta) * np.sin(angle) xlon = np.sin(angle) * np.sin(theta) ylon = np.cos(angle) * np.sin(theta) zlon = np.cos(theta) self.scene.mlab.plot3d( xlat, ylat, zlat, color=(0.67, 0.77, 1), opacity=self.frame_alpha, tube_radius=self.frame_radius) self.scene.mlab.plot3d( xlon, ylon, zlon, color=(0.67, 0.77, 1), opacity=self.frame_alpha, tube_radius=self.frame_radius) axis = np.linspace(-1.2, 1.2, 10) other = np.zeros_like(axis) self.scene.mlab.plot3d( axis, other, other, color=(1, 0.77, 1), tube_radius=self.axes_radius, opacity=self.axes_alpha) self.scene.mlab.plot3d( other, axis, other, color=(1, 0.77, 1), tube_radius=self.axes_radius, opacity=self.axes_alpha) self.scene.mlab.plot3d( other, other, axis, color=(1, 0.77, 1), tube_radius=self.axes_radius, opacity=self.axes_alpha) mesh = np.arange(self.frequency_begin, self.frequency_end, self.frequency_delta/1000.) #ss=spectra.all_spec(mesh,self.element,self.bfield,self.temp1,self.length,self.rb85frac,self.temp2,self.inputpol,self.detpol,self.frequency_shift,self.frequency_broadening,True,self.line,self.frequency_delta,self.k40frac,self.k41frac) my_dict=self.create_dictionary() ss=spectra.get_spectra(mesh*1000.,my_dict,outputs='All') t, x, z, y = ss[0:4]#self.S0_spec,self.S1_spec,self.S2_spec,self.S3_spec self.plotsphere = self.scene.mlab.plot3d(x, y, z, t,tube_radius=0.01)
def test_fit(): p_dict = { 'Elem': 'Rb', 'Dline': 'D2', 'T': 80., 'lcell': 2e-3, 'Bfield': 600., 'Btheta': 0., 'Bphi': 0., 'GammaBuf': 0., 'shift': 0. } # only need to specify parameters that are varied p_dict_bools = {'T': True, 'Bfield': True, 'E_x': True} p_dict_bounds = {'T': 10, 'Bfield': 100, 'E_x': 0.01} E_in = np.array([0.7, 0.7, 0]) E_in_angle = [E_in[0].real, [abs(E_in[1]), np.angle(E_in[1])]] print(E_in_angle) x = np.linspace(-10000, 10000, 100) [y] = get_spectra(x, E_in, p_dict, outputs=['S1']) + np.random.randn(len(x)) * 0.015 data = [x, y.real] best_params, result = RR_fit(data, E_in_angle, p_dict, p_dict_bools, p_dict_bounds, no_evals=8, data_type='S1') report = result.fit_report() fit = result.best_fit print(report) plt.plot(x, y, 'ko') plt.plot(x, fit, 'r-', lw=2) plt.show()
def test_MLfit(): """ Test simple Marquart-Levenburg fit for S1 spectrum. Generate a data set and add random noise, then run an ML fit to the noisy data set, with randomised initial parameters that are the correct ones plus some small change """ p_dict = {'Elem':'Rb','Dline':'D2','T':80.,'lcell':2e-3,'Bfield':600.,'Btheta':0., 'Bphi':0.,'GammaBuf':0.,'shift':0.} p_dict_guess = p_dict # only need to specify parameters that are varied p_dict_bools = {'T':True,'Bfield':True} E_in = np.sqrt(1./2) * np.array([1.,1.,0]) # need to express E_in as Ex, Ey and phase difference for fitting E_in_angle = [E_in[0].real,[abs(E_in[1]),np.angle(E_in[1])]] # Generate spectrum and add some random noise x = np.linspace(-10000,10000,300) [y] = get_spectra(x,E_in,p_dict,outputs=['S1']) + np.random.randn(len(x))*0.01 # randomise the starting parameters a little p_dict_guess = p_dict p_dict_guess['T'] += np.random.randn()*1 p_dict_guess['Bfield'] += np.random.randn()*10 data = [x,y.real] best_params, RMS, result = EM.fit_data(data, p_dict_guess, p_dict_bools, E_in=E_in_angle, data_type='S1',fit_algorithm='ML') report = result.fit_report() fit = result.best_fit print(report) plt.plot(x,y,'k.',label='Data') plt.plot(x,fit,'r-',lw=2,label='Fit') plt.legend(loc=0) plt.show()
def compare_fit_methods(): """ Compare ML and RR, SA and differential_evolution (DE) fitting for a more complicated case where there is a chi-squared local minimum in parameter space. In this case, the simple ML fit doesn't work, since it gets stuck in a very bad local minimum. The RR, SA and DE methods all converge to a good solution, but in different times. The RR fit takes somewhere in the region of 50x longer than ML, but produces a much better fit. The SA fit takes somewhere in the region of 100x longer than ML, but produces a much better fit. The DE fit takes somewhere in the region of 20x longer than ML, but produces a much better fit. From this test (and others which are broadly similar but for different data sets), we see that for global minimisation, we recommend using DE """ p_dict = {'Elem':'Rb','Dline':'D2','T':100.,'lcell':5e-3,'Bfield':7000.,'Btheta':0., 'Bphi':0.,'GammaBuf':50,'shift':0.} # only need to specify parameters that are varied p_dict_bools = {'T':True,'Bfield':True,'GammaBuf':True}#,'E_x':True,'E_y':True,'E_phase':True} E_in = np.array([0.7,0.7,0]) # need to express E_in as Ex, Ey and phase difference for fitting E_in_angle = [E_in[0].real,[abs(E_in[1]),np.angle(E_in[1])]] x = np.linspace(-21000,-13000,300) y = get_spectra(x,E_in,p_dict,outputs=['S0'])[0] + np.random.randn(len(x))*0.01 # <<< RMS error should be around 0.01 for the best case fit data = [x,y.real] # start at not the optimal parameters (near a local minimum in chi-squared) p_dict['T'] = 90 p_dict['Bfield'] = 6100 p_dict['GammaBuf'] = 150 p_dict_bounds = {} # time it... st_ML = time.clock() best_paramsML, RMS_ML, resultML = EM.fit_data(data, p_dict, p_dict_bools, E_in=E_in_angle, data_type='S0') et_ML = time.clock() -st_ML print('ML complete') # RR and SA need range over which to search p_dict_bounds['T'] = [30] p_dict_bounds['Bfield'] = [3000] p_dict_bounds['GammaBuf'] = [150] st_RR = time.clock() best_paramsRR, RMS_RR, resultRR = EM.fit_data(data, p_dict, p_dict_bools, E_in=E_in_angle, p_dict_bounds=p_dict_bounds, data_type='S0', fit_algorithm='RR') et_RR = time.clock() - st_RR print('RR complete') st_SA = time.clock() best_paramsSA, RMS_SA, resultSA = EM.fit_data(data, p_dict, p_dict_bools, E_in=E_in_angle, p_dict_bounds=p_dict_bounds, data_type='S0', fit_algorithm='SA') et_SA = time.clock() - st_SA print('SA complete') # differential evolution needs upper and lower bounds on fit parameters p_dict_bounds['T'] = [70,130] p_dict_bounds['Bfield'] = [4000,8000] p_dict_bounds['GammaBuf'] = [0, 100] st_DE = time.clock() best_paramsDE, RMS_DE, resultDE = EM.fit_data(data, p_dict, p_dict_bools, E_in=E_in_angle, p_dict_bounds=p_dict_bounds, data_type='S0', fit_algorithm='differential_evolution') et_DE = time.clock() - st_DE print('DE complete') print(('ML found best params in ', et_ML, 'seconds. RMS error, ', RMS_ML)) print(('RR found best params in ', et_RR, 'seconds. RMS error, ', RMS_RR)) print(('SA found best params in ', et_SA, 'seconds. RMS error, ', RMS_SA)) print(('DE found best params in ', et_DE, 'seconds. RMS error, ', RMS_DE)) reportML = resultML.fit_report() fitML = resultML.best_fit reportRR = resultRR.fit_report() fitRR = resultRR.best_fit reportSA = resultSA.fit_report() fitSA = resultSA.best_fit reportDE = resultDE.fit_report() fitDE = resultDE.best_fit #print '\n ML fit report:' #print reportML #print '\n DE fit report:' #print reportDE plt.plot(x,y,'k.',label='Data') plt.plot(x,fitML,'-',lw=2,label='ML fit') plt.plot(x,fitDE,'-',lw=2,label='RR fit') plt.plot(x,fitDE,'--',lw=2,label='SA fit') plt.plot(x,fitDE,':',lw=2,label='DE fit') plt.legend(loc=0) plt.show()
def fit_function(x, E_x, E_y, E_phase, T, lcell, Bfield, Btheta, Bphi, GammaBuf, shift, DoppTemp=20, rb85frac=72.17, K40frac=0.01, K41frac=6.73, Elem='Rb', Dline='D2', Constrain=True, output='S0', verbose=False): """ Fit function that is used by lmfit. Essentially just a wrapper for the get_spectra method, but the arguments are specified explicitly rather than being inside a parameter dictionary. Also allows for the polarisation components to be fitted For explanation of parameters, see the documentation for get_spectra (in spectra.py) """ if verbose: print(('Parameters: ', Bfield, T, lcell, E_x, E_y, E_phase, Btheta, Bphi, GammaBuf, shift, DoppTemp, rb85frac)) # Ex / Ey separated to allow for fitting polarisation E_in = np.array([E_x, E_y * np.exp(1.j * E_phase), 0.]) #print E_in #reconstruct parameter dictionary from arguments p_dict = { 'Elem': Elem, 'Dline': Dline, 'T': T, 'lcell': lcell, 'Bfield': Bfield, 'Btheta': Btheta, 'Bphi': Bphi, 'GammaBuf': GammaBuf, 'shift': shift, 'DoppTemp': DoppTemp, 'Constrain': Constrain, 'rb85frac': rb85frac, 'K40frac': K40frac, 'K41frac': K41frac } #for key in p_dict.keys(): # print key, p_dict[key] outputs = [output] y_out = get_spectra(x, E_in, p_dict, outputs)[0].real return y_out