def error_one(Star_in, SolvePars, Ref=object): s = Star() s.__dict__ = Star_in.__dict__.copy() try: Ref.get_model_atmosphere(SolvePars.grid) logger.info('Relative abundances') except: logger.info('Absolute abundances') dteff = 20 dvt = 0.02 dlogg = 0.02 s.teff = s.teff + dteff s.get_model_atmosphere(SolvePars.grid) specpars.iron_stats(s, Ref=Ref) fx1 = s.iron_stats['slope_ep'] efx1 = s.iron_stats['err_slope_ep'] gx1 = s.iron_stats['slope_rew'] egx1 = s.iron_stats['err_slope_rew'] hx1 = s.iron_stats['afe1'] - s.iron_stats['afe2'] ehx1 = np.sqrt(s.iron_stats['err_afe1']**2+ s.iron_stats['err_afe2']**2)/\ np.sqrt(s.iron_stats['nfe1']+s.iron_stats['nfe2']) s.teff = s.teff - 2*dteff s.get_model_atmosphere(SolvePars.grid) specpars.iron_stats(s, Ref=Ref) fx2 = s.iron_stats['slope_ep'] efx2 = s.iron_stats['err_slope_ep'] gx2 = s.iron_stats['slope_rew'] egx2 = s.iron_stats['err_slope_rew'] hx2 = s.iron_stats['afe1'] - s.iron_stats['afe2'] ehx2 = np.sqrt(s.iron_stats['err_afe1']**2+ s.iron_stats['err_afe2']**2)/\ np.sqrt(s.iron_stats['nfe1']+s.iron_stats['nfe2']) s.teff = s.teff + dteff dfx = 1e0*(fx2-fx1)/(2*dteff) efx = 1e0*(efx1+efx2)/2 dgx = 1e0*(gx2-gx1)/(2*dteff) egx = 1e0*(egx1+egx2)/2 dhx = 1e0*(hx2-hx1)/(2*dteff) ehx = 1e0*(ehx1+ehx2)/2 dfdt, dgdt, dhdt = dfx, dgx, dhx eft, egt, eht = efx, egx, ehx s.vt = s.vt + dvt s.get_model_atmosphere(SolvePars.grid) specpars.iron_stats(s, Ref=Ref) fx1 = s.iron_stats['slope_ep'] efx1 = s.iron_stats['err_slope_ep'] gx1 = s.iron_stats['slope_rew'] egx1 = s.iron_stats['err_slope_rew'] hx1 = s.iron_stats['afe1'] - s.iron_stats['afe2'] ehx1 = np.sqrt(s.iron_stats['err_afe1']**2+ s.iron_stats['err_afe2']**2)/\ np.sqrt(s.iron_stats['nfe1']+s.iron_stats['nfe2']) s.vt = s.vt - 2*dvt s.get_model_atmosphere(SolvePars.grid) specpars.iron_stats(s, Ref=Ref) fx2 = s.iron_stats['slope_ep'] efx2 = s.iron_stats['err_slope_ep'] gx2 = s.iron_stats['slope_rew'] egx2 = s.iron_stats['err_slope_rew'] hx2 = s.iron_stats['afe1'] - s.iron_stats['afe2'] ehx2 = np.sqrt(s.iron_stats['err_afe1']**2+ s.iron_stats['err_afe2']**2)/\ np.sqrt(s.iron_stats['nfe1']+s.iron_stats['nfe2']) s.vt = s.vt + dvt dfx = 1e0*(fx2-fx1)/(2*dvt) efx = 1e0*(efx1+efx2)/2 dgx = 1e0*(gx2-gx1)/(2*dvt) egx = 1e0*(egx1+egx2)/2 dhx = 1e0*(hx2-hx1)/(2*dvt) ehx = 1e0*(ehx1+ehx2)/2 dfdv, dgdv, dhdv = dfx, dgx, dhx efv, egv, ehv = efx, egx, ehx s.logg = s.logg + dlogg s.get_model_atmosphere(SolvePars.grid) specpars.iron_stats(s, Ref=Ref) fx1 = s.iron_stats['slope_ep'] efx1 = s.iron_stats['err_slope_ep'] gx1 = s.iron_stats['slope_rew'] egx1 = s.iron_stats['err_slope_rew'] hx1 = s.iron_stats['afe1'] - s.iron_stats['afe2'] ehx1 = np.sqrt(s.iron_stats['err_afe1']**2+ s.iron_stats['err_afe2']**2)/\ np.sqrt(s.iron_stats['nfe1']+s.iron_stats['nfe2']) s.logg = s.logg - 2*dlogg s.get_model_atmosphere(SolvePars.grid) specpars.iron_stats(s, Ref=Ref) fx2 = s.iron_stats['slope_ep'] efx2 = s.iron_stats['err_slope_ep'] gx2 = s.iron_stats['slope_rew'] egx2 = s.iron_stats['err_slope_rew'] hx2 = s.iron_stats['afe1'] - s.iron_stats['afe2'] ehx2 = np.sqrt(s.iron_stats['err_afe1']**2+ s.iron_stats['err_afe2']**2)/\ np.sqrt(s.iron_stats['nfe1']+s.iron_stats['nfe2']) s.logg = s.logg + dlogg dfx = 1e0*(fx2-fx1)/(2*dlogg) efx = 1e0*(efx1+efx2)/2 dgx = 1e0*(gx2-gx1)/(2*dlogg) egx = 1e0*(egx1+egx2)/2 dhx = 1e0*(hx2-hx1)/(2*dlogg) ehx = 1e0*(ehx1+ehx2)/2 dfdg, dgdg, dhdg = dfx, dgx, dhx efg, egg, ehg = efx, egx, ehx d = matrix( [ [dfdt, dfdv, dfdg], [dgdt, dgdv, dgdg], [dhdt, dhdv, dhdg] ] ) di = d.I s0 = np.mean([eft,efv,efg]) s1 = np.mean([egt,egv,egg]) s2 = np.mean([eht,ehv,ehg]) eteff = np.sqrt ( (s0*di[0, 0])**2 + (s1*di[0, 1])**2 + (s2*di[0, 2])**2 ) evt = np.sqrt ( (s0*di[1, 0])**2 + (s1*di[1, 1])**2 + (s2*di[1, 2])**2 ) elogg = np.sqrt ( (s0*di[2, 0])**2 + (s1*di[2, 1])**2 + (s2*di[2, 2])**2 ) s.teff = s.teff + eteff s.get_model_atmosphere(SolvePars.grid) specpars.iron_stats(s, Ref=Ref) ap = s.iron_stats['afe'] s.teff = s.teff - 2*eteff s.get_model_atmosphere(SolvePars.grid) specpars.iron_stats(s, Ref=Ref) am = s.iron_stats['afe'] s.teff = s.teff + eteff eat = (ap-am)/2 s.logg = s.logg + elogg s.get_model_atmosphere(SolvePars.grid) specpars.iron_stats(s, Ref=Ref) ap = s.iron_stats['afe'] s.logg = s.logg - 2*elogg s.get_model_atmosphere(SolvePars.grid) specpars.iron_stats(s, Ref=Ref) am = s.iron_stats['afe'] s.logg = s.logg + elogg eag = (ap-am)/2 s.vt = s.vt + evt s.get_model_atmosphere(SolvePars.grid) specpars.iron_stats(s, Ref=Ref) ap = s.iron_stats['afe'] s.vt = s.vt - 2*evt s.get_model_atmosphere(SolvePars.grid) specpars.iron_stats(s, Ref=Ref) am = s.iron_stats['afe'] s.vt = s.vt + evt eav = (ap-am)/2 ea = np.sqrt(eat**2+eag**2+eav**2+s2**2) Star_in.sp_err = {'teff': int(eteff), 'logg': elogg, 'afe': ea, 'vt': evt}
def solve_one(Star, SolveParsInit, Ref=object, PlotPars=object): sp = SolvePars() sp.__dict__ = SolveParsInit.__dict__.copy() if not hasattr(Star, 'model_atmosphere_grid'): logger.info('Star has no model yet. Calculating.') Star.get_model_atmosphere(sp.grid) if Star.model_atmosphere_grid != sp.grid: logger.info('Inconsistent model atmosphere grids '+ '(Star and SolvePars). '+ 'Fixing problem now.') Star.get_model_atmosphere(sp.grid) if hasattr(Ref, 'name'): if not hasattr(Ref, 'model_atmosphere_grid'): logger.info('Ref star has no model yet. Calculating.') Ref.get_model_atmosphere(sp.grid) if Ref.model_atmosphere_grid != sp.grid: logger.info('Inconsistent model atmosphere grids '+ '(Ref star and SolvePars). '+ 'Fixing problem now.') Ref.get_model_atmosphere(sp.grid) dtv, dgv, dvv, stop_iter = [], [], [], False if hasattr(Star, 'converged'): if not Star.converged: Star.converged = False else: Star.converged = False Star.stop_iter = sp.niter if sp.niter == 0: Star.converged = True print 'it Teff logg [Fe/H] vt [Fe/H]' print '-- ---- ---- ------ ---- --------------' for i in range(sp.niter+1): if sp.step_teff <= 1 and sp.step_logg <= 0.01 \ and sp.step_vt <= 0.01: if not stop_iter: Star.converged = False if SolveParsInit.niter > 0: print '-- Begin final loop' stop_iter = True if i > 0: if Star.iron_stats['slope_ep'] > 0: Star.teff += sp.step_teff else: Star.teff -= sp.step_teff if Star.teff > 7000: Star.teff = 7000 if Star.iron_stats['slope_rew'] > 0: Star.vt += sp.step_vt else: Star.vt -= sp.step_vt if Star.vt < 0: Star.vt = 0 dfe = Star.iron_stats['afe1'] - Star.iron_stats['afe2'] if dfe > 0: Star.logg += sp.step_logg else: Star.logg -= sp.step_logg if Star.logg > 5.0: Star.logg = 5.0 if hasattr(Ref, 'name'): Star.feh = Ref.feh + Star.iron_stats['afe'] else: Star.feh = Star.iron_stats['afe'] - sp.solar_afe if Star.feh > 1.0: Star.feh = 1.0 if Star.feh > 0.5 and sp.grid != 'over': Star.feh = 0.5 Star.get_model_atmosphere(sp.grid) if i+1 == sp.niter or sp.niter == 0: plot = Star.name if hasattr(Ref, 'name'): plot = Star.name+'-'+Ref.name if Star.name == Ref.name: plot = None Star.converged = '' else: plot = None is_done = iron_stats(Star, Ref=Ref, plot=plot, PlotPars=PlotPars) print "{0:2d} {1:4d} {2:4.2f} {3:6.3f} {4:4.2f}"\ " ---> {5:6.3f}+/-{6:5.3f}".\ format(i, Star.teff, Star.logg, Star.feh, Star.vt, Star.iron_stats['afe'], Star.iron_stats['err_afe']) dtv.append(Star.teff) dgv.append(Star.logg) dvv.append(Star.vt) if i >= 4: if np.std(dtv[-5:]) <= 0.8*sp.step_teff and \ np.std(dgv[-5:]) <= 0.8*sp.step_logg and \ np.std(dvv[-5:]) <= 0.8*sp.step_vt: print '-- Converged at iteration '+str(i)+ \ ' of '+str(sp.niter) if stop_iter: plot = Star.name if hasattr(Ref, 'name'): plot = Star.name+'-'+Ref.name iron_stats(Star, Ref=Ref, plot=plot, PlotPars=PlotPars) Star.converged = True Star.stop_iter = i break sp.step_teff = sp.step_teff/2 sp.step_logg = sp.step_logg/2 sp.step_vt = sp.step_vt/2 if sp.step_teff < 1 and sp.step_teff > 0: sp.step_teff = 1 if sp.step_logg < 0.01 and sp.step_logg > 0: sp.step_logg = 0.01 if sp.step_vt < 0.01 and sp.step_vt > 0: sp.step_vt = 0.01 if not Star.converged: if hasattr(Ref, 'name'): if Star.name == Ref.name or SolveParsInit.niter == 0: print '--' else: print '-- Did not achieve final convergence.' else: print '-- Did not achieve final convergence.' print '------------------------------------------------------' if hasattr(Ref, 'name'): print ' D[Fe/H] || D[Fe/H] Fe I | D[Fe/H] Fe II' else: print ' A(Fe) || A(Fe I) | A(Fe II) ' print "{0:6.3f} {1:6.3f} || {2:6.3f} {3:6.3f} {4:3d} "\ "| {5:6.3f} {6:6.3f} {7:3d}".\ format(Star.iron_stats['afe'], Star.iron_stats['err_afe'], Star.iron_stats['afe1'], Star.iron_stats['err_afe1'], Star.iron_stats['nfe1'], Star.iron_stats['afe2'], Star.iron_stats['err_afe2'], Star.iron_stats['nfe2']) print '------------------------------------------------------' Star.sp_err = {'teff': 0, 'logg': 0, 'afe': 0, 'vt': 0} if ((Star.converged and sp.errors == True) or \ (sp.niter == 0 and sp.errors == True and Star.converged != '')): errors.error_one(Star, sp, Ref) Star.err_teff = int(Star.sp_err['teff']) Star.err_logg = Star.sp_err['logg'] Star.err_feh = Star.sp_err['afe'] Star.err_vt = Star.sp_err['vt'] print "Solution with formal errors:" print "Teff = {0:6d} +/- {1:5d}".\ format(int(Star.teff), int(Star.sp_err['teff'])) print "log g = {0:6.3f} +/- {1:5.3f}".\ format(Star.logg, Star.sp_err['logg']) if hasattr(Ref, 'name'): print "D[Fe/H] = {0:6.3f} +/- {1:5.3f}".\ format(Star.iron_stats['afe'], Star.sp_err['afe']) else: print "A(Fe) = {0:6.3f} +/- {1:5.3f}".\ format(Star.iron_stats['afe'], Star.sp_err['afe']) print "vt = {0:6.2f} +/- {1:5.2f}".\ format(Star.vt, Star.sp_err['vt']) print '------------------------------------------------------'