def test_ui_source_methods_with_full_model(clean_ui, setup_ui_full): ui.load_data('full', setup_ui_full.ascii) ui.set_full_model('full', 'powlaw1d.p1') # Test Case 1 with pytest.raises(IdentifierErr) as exc: ui.get_source('full') emsg = "Convolved model\n'powlaw1d.p1'\n is set for dataset full. You should use get_model instead." assert str(exc.value) == emsg with pytest.raises(IdentifierErr) as exc: ui.plot_source('full') emsg = "Convolved model\n'powlaw1d.p1'\n is set for dataset full. You should use plot_model instead." assert str(exc.value) == emsg with pytest.raises(IdentifierErr) as exc: ui.get_source_plot('full') emsg = "Convolved model\n'powlaw1d.p1'\n is set for dataset full. You should use get_model_plot instead." assert str(exc.value) == emsg # Test Case 2 ui.set_source('full', 'powlaw1d.p2') ui.get_source('full') # Test Case 3 ui.load_data('not_full', setup_ui_full.ascii) with pytest.raises(IdentifierErr) as exc: ui.get_source('not_full') emsg = 'source not_full has not been set, consider using set_source() or set_model()' assert emsg == str(exc.value)
def test_source_methods_with_full_model(self): from sherpa.utils.err import IdentifierErr ui.load_data('full', self.ascii) ui.set_full_model('full', 'powlaw1d.p1') # Test Case 1 try: ui.get_source('full') except IdentifierErr as e: self.assertRegex( str(e), "Convolved model\n.*\n is set for dataset full. You should use get_model instead.", str(e)) try: ui.plot_source('full') except IdentifierErr as e: self.assertRegex( str(e), "Convolved model\n.*\n is set for dataset full. You should use plot_model instead.", str(e)) # Test Case 2 ui.set_source('full', 'powlaw1d.p2') ui.get_source('full') # Test Case 3 ui.load_data('not_full', self.ascii) try: ui.get_source('not_full') except IdentifierErr as e: self.assertEqual( 'source not_full has not been set, consider using set_source() or set_model()', str(e))
def test_source_methods_with_full_model(self): from sherpa.utils.err import IdentifierErr ui.load_data('full', self.ascii) ui.set_full_model('full', 'powlaw1d.p1') # Test Case 1 try: ui.get_source('full') except IdentifierErr as e: self.assertRegexpMatches(str(e), "Convolved model\n.*\n is set for dataset full. You should use get_model instead.", str(e)) try: ui.plot_source('full') except IdentifierErr as e: self.assertEquals("Convolved model\n'p1'\n is set for dataset full. You should use plot_model instead.", str(e)) # Test Case 2 ui.set_source('full', 'powlaw1d.p2') ui.get_source('full') # Test Case 3 ui.load_data('not_full', self.ascii) try: ui.get_source('not_full') except IdentifierErr as e: self.assertEquals('source not_full has not been set, consider using set_source() or set_model()', str(e))
def test_ui_set_full_model_checks_dimensions_match(clean_ui, setup_ui_2d): ui.load_psf('psf1', 'gauss2d.g1') with pytest.raises(ArgumentErr) as err: ui.set_full_model('psf1(gauss1d.g2)+const2d.c1') assert str( err.value ) == "invalid model expression: Models do not match: 2D (gauss2d.g1) and 1D (gauss1d.g2)"
def test_ui_set_full_model_2d_mismatch_1d(clean_ui, setup_ui_2d): ui.load_psf('psf1', 'gauss1d.g1') ui.set_full_model('psf1(gauss1d.g2 ) +const1d.c1') # Ideally this would fail but it currently does not ui.get_model()
def test_ui_set_full_model_2d(clean_ui, setup_ui_2d): ui.load_psf('psf1', 'gauss2d.g1') ui.set_full_model('psf1(gauss2d.g2 ) +const2d.c1') ui.get_model()
def test_set_full_model(self): ui.load_psf("psf1", "gauss2d.g1") ui.set_full_model("psf1(gauss2d.g2)+const2d.c1") ui.get_model() ui.get_source()
def test_set_full_model(self): ui.load_psf('psf1', 'gauss2d.g1') ui.set_full_model('psf1(gauss2d.g2)+const2d.c1') ui.get_model()
def fitne(ne_data, nemodeltype, tspec_data=None): ''' Fits gas number density profile according to selected profile model. The fit is performed using python sherpa with the Levenberg-Marquardt method of minimizing chi-squared . Args: ----- ne_data (astropy table): observed gas density profile in the form established by set_prof_data() tspec_data (astropy table): observed temperature profile in the form established by set_prof_data() Returns: -------- nemodel (dictionary): stores relevant information about the model gas density profile nemodel['type']: ne model type; one of the following: ['single_beta','cusped_beta','double_beta_tied','double_beta'] nemodel['parnames']: names of the stored ne model parameters nemodel['parvals']: parameter values of fitted gas density model nemodel['parmins']: lower error bound on parvals nemodel['parmaxes']: upper error bound on parvals nemodel['chisq']: chi-squared of fit nemodel['dof']: degrees of freedom nemodel['rchisq']: reduced chi-squared of fit nemodel['nefit']: ne model values at radial values matching tspec_data (the observed temperature profile) References: ----------- python sherpa: https://github.com/sherpa/ ''' # remove any existing models and data ui.clean() # load data ui.load_arrays(1, np.array(ne_data['radius']), np.array(ne_data['ne']), np.array(ne_data['ne_err'])) # set guess and boundaries on params given selected model if nemodeltype == 'single_beta': # param estimate betaguess = 0.6 rcguess = 20. # units????? ne0guess = max(ne_data['ne']) # beta model ui.load_user_model(betamodel, "beta1d") ui.add_user_pars("beta1d", ["ne0", "rc", "beta"]) ui.set_source(beta1d) # creates model ui.set_full_model(beta1d) # set parameter values ui.set_par(beta1d.ne0, ne0guess, min=0, max=10. * max(ne_data['ne'])) ui.set_par(beta1d.rc, rcguess, min=0.1, max=max(ne_data['radius'])) ui.set_par(beta1d.beta, betaguess, min=0.1, max=1.) if nemodeltype == 'cusped_beta': # param estimate betaguess = 0.7 rcguess = 5. # [kpc] ne0guess = max(ne_data['ne']) alphaguess = 10. # ???? # beta model ui.load_user_model(cuspedbetamodel, "cuspedbeta1d") ui.add_user_pars("cuspedbeta1d", ["ne0", "rc", "beta", "alpha"]) ui.set_source(cuspedbeta1d) # creates model ui.set_full_model(cuspedbeta1d) # set parameter values ui.set_par(cuspedbeta1d.ne0, ne0guess, min=0.001 * max(ne_data['ne']), max=10. * max(ne_data['ne'])) ui.set_par(cuspedbeta1d.rc, rcguess, min=0.1, max=max(ne_data['radius'])) ui.set_par(cuspedbeta1d.beta, betaguess, min=0.1, max=1.) ui.set_par(cuspedbeta1d.alpha, alphaguess, min=0., max=100.) if nemodeltype == 'double_beta': # param estimate ne0guess1 = max(ne_data['ne']) # [cm^-3] rcguess1 = 10. # [kpc] betaguess1 = 0.6 ne0guess2 = 0.01 * max(ne_data['ne']) # [cm^-3] rcguess2 = 100. # [kpc] betaguess2 = 0.6 # double beta model ui.load_user_model(doublebetamodel, "doublebeta1d") ui.add_user_pars("doublebeta1d", ["ne01", "rc1", "beta1", "ne02", "rc2", "beta2"]) ui.set_source(doublebeta1d) # creates model ui.set_full_model(doublebeta1d) # set parameter values ui.set_par(doublebeta1d.ne01, ne0guess1, min=0.0001 * max(ne_data['ne']), max=100. * max(ne_data['ne'])) ui.set_par(doublebeta1d.rc1, rcguess1, min=0.1, max=max(ne_data['radius'])) ui.set_par(doublebeta1d.beta1, betaguess1, min=0.1, max=1.) ui.set_par(doublebeta1d.ne02, ne0guess2, min=0.0001 * max(ne_data['ne']), max=100. * max(ne_data['ne'])) ui.set_par(doublebeta1d.rc2, rcguess2, min=10., max=max(ne_data['radius'])) ui.set_par(doublebeta1d.beta2, betaguess2, min=0.1, max=1.) if nemodeltype == 'double_beta_tied': # param estimate ne0guess1 = max(ne_data['ne']) rcguess1 = 10. betaguess1 = 0.6 ne0guess2 = 0.01 * max(ne_data['ne']) rcguess2 = 100. # double beta model ui.load_user_model(doublebetamodel_tied, "doublebeta1d_tied") ui.add_user_pars("doublebeta1d_tied", ["ne01", "rc1", "beta1", "ne02", "rc2"]) ui.set_source(doublebeta1d_tied) # creates model ui.set_full_model(doublebeta1d_tied) # set parameter values ui.set_par(doublebeta1d_tied.ne01, ne0guess1, min=0.00001 * max(ne_data['ne']), max=100. * max(ne_data['ne'])) ui.set_par(doublebeta1d_tied.rc1, rcguess1, min=0.1, max=max(ne_data['radius'])) ui.set_par(doublebeta1d_tied.beta1, betaguess1, min=0.1, max=1.) ui.set_par(doublebeta1d_tied.ne02, ne0guess2, min=0.00001 * max(ne_data['ne']), max=100. * max(ne_data['ne'])) ui.set_par(doublebeta1d_tied.rc2, rcguess2, min=10., max=max(ne_data['radius'])) # fit model ui.fit() # fit statistics chisq = ui.get_fit_results().statval dof = ui.get_fit_results().dof rchisq = ui.get_fit_results().rstat # error analysis ui.set_conf_opt("max_rstat", 1e9) ui.conf() parvals = np.array(ui.get_conf_results().parvals) parmins = np.array(ui.get_conf_results().parmins) parmaxes = np.array(ui.get_conf_results().parmaxes) parnames = [ str(x).split('.')[1] for x in list(ui.get_conf_results().parnames) ] # where errors are stuck on a hard limit, change error to Inf if None in list(parmins): ind = np.where(parmins == np.array(None))[0] parmins[ind] = float('Inf') if None in list(parmaxes): ind = np.where(parmaxes == np.array(None))[0] parmaxes[ind] = float('Inf') # set up a dictionary to contain useful results of fit nemodel = {} nemodel['type'] = nemodeltype nemodel['parnames'] = parnames nemodel['parvals'] = parvals nemodel['parmins'] = parmins nemodel['parmaxes'] = parmaxes nemodel['chisq'] = chisq nemodel['dof'] = dof nemodel['rchisq'] = rchisq # if tspec_data included, calculate value of ne model at the same radius # positions as temperature profile if tspec_data is not None: if nemodeltype == 'double_beta': nefit_arr = doublebetamodel(nemodel['parvals'], np.array(tspec_data['radius'])) # [cm-3] if nemodeltype == 'single_beta': nefit_arr = betamodel(nemodel['parvals'], np.array(tspec_data['radius'])) # [cm-3] if nemodeltype == 'cusped_beta': nefit_arr = cuspedbetamodel(nemodel['parvals'], np.array(tspec_data['radius'])) # [cm-3] if nemodeltype == 'double_beta_tied': nefit_arr = doublebetamodel_tied(nemodel['parvals'], np.array(tspec_data['radius'])) # [cm-3] nemodel['nefit'] = nefit_arr return nemodel