def PlotXPAbs(starData, clusterName='NGC-0752', ionList=kAllIonList, fileTag='', labelPlot=True, labelPoints=False, showTrendLine=False, modelAtms=None, pradks=None, referenceCorrect=False): # Make XP vs. Ab for the passed star # One element per plot. starName = starData[0] starParmTuple = tuple(starData[1:]) isGiant = RC.isGiantStar(starParmTuple) if isGiant: modelPath = k.GiantModelPath else: modelPath = k.DwarfModelPath if modelAtms == None or pradks == None: modelFiles = mk.findDataFiles(modelPath) modelAtms, pradks = mk.LoadModels(modelFiles) abdict, uncorrLines, unusedMin, unusedMax = \ AB.CalcAbsAndLines(clusterName+' '+starName, tuple(starData[1:6]), ionList=ionList, modelAtms=modelAtms, pradks=pradks) # uncorrLines: # # {elem.ion:[[Wavelength, Ex.Pot., logGf, eqw, logRW, abund],...]} if referenceCorrect: if isGiant: # Obligatory comment on bad Giant corrections, and using # Solar instead. correctDict, referenceLines, lineWeights = \ RC.GetSolarCorrections(ionList=ionList, modelAtms=modelAtms, pradks=pradks) else: correctDict, referenceLines, lineWeights = \ RC.GetDwarfCorrections(ionList=ionList, modelAtms=modelAtms, pradks=pradks) correctionsAvailable = False if len(correctDict) > 0 and len(referenceLines) > 0: correctionsAvailable = True for ion in ionList: if ion not in uncorrLines.keys(): continue # Does this element have NLTE corrections available? Note: we do # this BEFORE Solar corrections, which assumes that the same # NLTE corrections are already applied to any Solar corrections # we use. if ion in NLTEIons: LTELines = AB.CorrectNLTEAbs(ion, uncorrLines[ion], tuple(starData[1:6])) else: if ion in uncorrLines.keys(): LTELines = uncorrLines[ion] else: # Either synthesized lines, or none available LTELines = np.array([]) # Do we want the "reference corrected" abundances? if referenceCorrect and correctionsAvailable: tempAdj,tempAll = \ RC.SortAndFilterLines(LTELines, ion, tuple(starData[1:6]), solarCorrect=referenceCorrect, solarLines=referenceLines[ion], solarCorrs=correctDict[ion], lineWeights=lineWeights[ion]) # correctedLines: # [[ab, line STR score, wl, "quality"], ...] # allLines: # [[ab, line STR score, wl],...] # We want to use np.arrays, so... allLines = np.array(tempAll) correctedLines = np.array(tempAdj) if len(allLines) == 0 or len(correctedLines) == 0: correctionsAvailable = False elif len(allLines) == 1 or len(correctedLines) == 1: print('Single Line determination:{0}'.format(starData[0])) print(allLines, correctedLines) # One plot per ion. if labelPlot: plotLabel = 'XP vs Ab for [{2}/H] in {0} {1}.'.\ format(clusterName, starName, el.getIonName(ion)) else: plotLabel = '' if referenceCorrect and correctionsAvailable: tempPoints = [] for line in uncorrLines[ion]: correctedAbs = [l[0] for l in correctedLines if \ u.in_range(l[2],line[0]-0.05, line[0]+0.05)] if len(correctedAbs) > 0: tempPoints.append( [line[1], np.mean(correctedAbs), line[3], line[0]]) else: tempPoints.append([line[1], line[5], line[3], line[0]]) XPAbPoints = np.array(tempPoints) else: XPAbPoints = np.array([[line[1],line[5],line[3],line[0]]\ for line in uncorrLines[ion]]) if labelPoints: # Label the points with the wavelength pointLabels = ['{0:2.3f}'.format(point[3]) \ for point in XPAbPoints] else: pointLabels = None ps.XPAbPlot(XPAbPoints, starName, ion, fileTag=fileTag + 'XPAb', plotTitle=plotLabel, pointLabels=pointLabels, showTrendLine=showTrendLine)
def GetAbTable(clusterName='NGC-0752', starDataList=None, ions=kAllIonList, filterBlends=False, referenceCorrect=False, useDAOSpec=False, gModelAtms=None, gPradks=None, dModelAtms=None, dPradks=None): # Returns a dictionary with each star name (key) has a list of elements # (secondary key), with a list containing [Abundance in [X/H], variance in the # line measurements, count of lines measured, average quality score]: # returnDict={starName:{ion:[[X/H],stdev, count, avg.quality],...},...} if starDataList == None: starDataList = GetAllStarParms(clusterName=clusterName) # Since we're doing a bunch of lines (uh...), we'll need both giant and # dwarf references. Giant references are prefixed by a 'g', dwarfs by 'd'. if gModelAtms == None or gPradks == None: gModelFiles = mk.findDataFiles(k.GiantModelPath) gModelAtms, gPradks = mk.LoadModels(gModelFiles) if dModelAtms == None or dPradks == None: dModelFiles = mk.findDataFiles(k.DwarfModelPath) dModelAtms, dPradks = mk.LoadModels(dModelFiles) # We need iron to do relative abundances: if 26.0 not in ions: ions.append(26.0) # Turns out our giant corrections are not good # gCorrectDict, gReferenceLines, gLineWeights = \ # GetGiantCorrections(ionList=ions, # modelAtms=gModelAtms, # pradks=gPradks) # So, use the Solar corrections for now gCorrectDict, gReferenceLines, gLineWeights = \ RC.GetSolarCorrections(ionList=ions, modelAtms=dModelAtms, pradks=dPradks) dCorrectDict, dReferenceLines, dLineWeights = \ RC.GetDwarfCorrections(ionList=ions, modelAtms=dModelAtms, pradks=dPradks) tableDict = {} for starData in starDataList: starName = starData[0] starParms = tuple(starData[1:6]) if RC.isGiantStar(starParms): modelAtms = gModelAtms pradks = gPradks referenceLines = gReferenceLines referenceDict = gCorrectDict lineWeights = gLineWeights else: modelAtms = dModelAtms pradks = dPradks referenceLines = dReferenceLines referenceDict = dCorrectDict lineWeights = dLineWeights tableDict[starName] = GetAbsForStar(starData, ions=ions,\ filterBlends=filterBlends, refCorrect=referenceCorrect,\ refDict=referenceDict, refLines=referenceLines, \ lineWeights=lineWeights, useDAOSpec=useDAOSpec, \ modelAtms=modelAtms, pradks=pradks) return tableDict
def MakeVPlots(clusterName='NGC-0752', starDataList=None, fileTag='', filterBlends=False, referenceCorrect=False, useDAOSpec=False, ions=[20.0]): # Function plots V_turb vs. sigma [Ca/H] (sigma is the line-to-line # standard deviation of the measured Ca lines), for a range of V_turb values. # Intended to provide a spectroscopic confirmation/adjustment # for photometrically-determined parameters. if starDataList is None: starDataList = STP.GetAllStarParms(clusterName=clusterName) dModelFiles = mk.findDataFiles(k.DwarfModelPath) dModelAtms, dPradks = mk.LoadModels(dModelFiles) dCorrectDict, dReferenceLines, dLineWeights = \ RC.GetDwarfCorrections(ionList=ions, modelAtms=dModelAtms, pradks=dPradks) gModelFiles = mk.findDataFiles(k.GiantModelPath) gModelAtms, gPradks = mk.LoadModels(gModelFiles) # Note: We're using dwarf corrections for giant stars... # because they're better than giant corrections for the # giant stars. This needs to be fixed. :( gCorrectDict, gReferenceLines, gLineWeights = \ RC.GetSolarCorrections(ionList=ions, modelAtms=dModelAtms, pradks=dPradks) # For now, CaI appears to work best for all stars. # VI, Ti I/II, Fe I/II, Cr I/II also work, but not as well - (See Reddy, et al. 2012). # ions = [20.0] abDict = {} colorArray=['r','orange','gold','darkgreen','navy',\ 'm','saddlebrown','skyblue','hotpink'] for starParms in starDataList: if RC.isGiantStar(starParms[1:]): modelAtms = gModelAtms pradks = gPradks refLines = gReferenceLines refDict = gCorrectDict lineWeights = gLineWeights else: modelAtms = dModelAtms pradks = dPradks refLines = dReferenceLines refDict = dCorrectDict lineWeights = dLineWeights starPoints = {} for v in np.linspace(0.5, 3.0, 26): parmTuple = (starParms[0], starParms[1], starParms[2], v, \ starParms[4], starParms[5], starParms[6]) abDict[v] = STP.GetAbsForStar(parmTuple, ions=ions,\ filterBlends=filterBlends, refCorrect=referenceCorrect,\ refDict=refDict, refLines=refLines, lineWeights=lineWeights,\ useDAOSpec=useDAOSpec, modelAtms=modelAtms, pradks=pradks) for ion in abDict[v].keys(): if ion not in starPoints.keys(): starPoints[ion] = {} if abDict[v][ion][0] == 0.: continue starPoints[ion][v] = abDict[v][ion][1] colorIdx = 0 ymaxes = [] for ion in starPoints.keys(): Xs = sorted(np.array(list(starPoints[ion].keys()))) if len(Xs) == 0 or ion in STP.SynthAbsDict.keys(): continue Ys = np.array([starPoints[ion][x] for x in Xs]) if len(Xs) < 2 or len(Ys) < 2: continue Ys = Ys / min(Ys) ymaxes.append(max(Ys)) try: minV = Xs[np.where(Ys == min(Ys))[0][0]] except IndexError: continue pyplot.plot(Xs, Ys, label=r'$({1}) V_{{turb}}={0:3.1f}km/sec$'.format( minV, el.getIonName(ion)), color=colorArray[colorIdx]) pyplot.scatter(Xs, Ys, color=colorArray[colorIdx]) pyplot.axvline(minV, linestyle=':', color=colorArray[colorIdx]) colorIdx += 1 if colorIdx == len(colorArray): colorIdx = 0 ax = pyplot.gca() ax.set_xlabel(r'$V_{{turb}} km/s$') ax.set_ylabel('Normalized [X/H] variance') ax.set_ylim((0., min(5.0, max(ymaxes)))) pyplot.legend(fontsize=8) pyplot.savefig(k.ParmPlotDir + 'Vturb/' + starParms[0] + fileTag + '.png') pyplot.close()
def PlotAbs(clusterName, starData, ions, fileTag='', plotTitle='', filterBlends=False, referenceCorrect=False, labelPoints=False, useDAOSpec=False, modelAtms=None, pradks=None): pointLabels = None # Lookup the abundance(s) for the passed star, and plot them # (into a .png file). One element per plot. starName = starData[0] starParmTuple = tuple(starData[1:6]) isGiant = RC.isGiantStar(starParmTuple) if isGiant: modelPath = k.GiantModelPath else: modelPath = k.DwarfModelPath if modelAtms == None or pradks == None: modelFiles = mk.findDataFiles(modelPath) modelAtms, pradks = mk.LoadModels(modelFiles) # uncorrLines format: # {elem.ion:[[Wavelength, Ex.Pot., logGf, eqw, logRW, abund],...]} # abDict format: # {elem.ion:[abundance mean, ab. std.dev., # lines]} abdict, uncorrLines, unusedMin, unusedMax = \ AB.CalcAbsAndLines(clusterName+' '+starName, starParmTuple, ionList=ions, modelAtms=modelAtms, pradks=pradks, useDAOlines=useDAOSpec) if isGiant: # Obtain the reference corrections for a giant star - Note: this is # badly broken! So, we're just going to use the Solar corrections for # now: correctDict, referenceLines, lineWeights = \ RC.GetDwarfCorrections(ionList=ions, modelAtms=modelAtms, pradks=pradks, useDAOSpec=useDAOSpec) # correctDict, referenceLines, lineWeights = \ # GetGiantCorrections(ionList=ions, # modelAtms=modelAtms, # pradks=pradks) else: # ...or for a dwarf star. correctDict, referenceLines, lineWeights = \ RC.GetDwarfCorrections(ionList=ions, modelAtms=modelAtms, pradks=pradks, useDAOSpec=useDAOSpec) for ion in ions: # We'll make one plot per ion. pointLabels = [] redData = greenData = blueData = [] if ion not in uncorrLines.keys(): print('No {0:2.1f} lines for {1}.'.format(ion, starName)) continue if (referenceCorrect or filterBlends) and \ ion in referenceLines.keys() and ion in correctDict.keys() and \ ion in lineWeights.keys(): adjustedLines, dataPoints = \ RC.SortAndFilterLines(uncorrLines[ion], ion, starParmTuple, filterBlends=filterBlends, solarCorrect=referenceCorrect, solarLines=referenceLines[ion], solarCorrs=correctDict[ion], lineWeights=lineWeights[ion]) tempData = [] for line in uncorrLines[ion]: corrLine = u.find(lambda l: l[0] == line[0], dataPoints) if corrLine is not None: tempData.append(corrLine) else: tempData.append([line[5], el.STR(line[2], line[1], \ starParmTuple[0]),line[0]]) redData = np.array(tempData) else: dataPoints = np.array([[line[5], el.STR(line[2], line[1], starParmTuple[0]), line[0]] \ for line in uncorrLines[ion]]) if labelPoints: pointLabels = ['{0:4.3f}'.format(line[2]) for line in dataPoints] pointLabels.extend(['{0:4.3f}'.\ format(line[2]) for line in redData]) pointLabels.extend(['{0:4.3f}'.\ format(line[2]) for line in greenData]) pointLabels.extend(['{0:4.3f}'.\ format(line[2]) for line in blueData]) loSlope, loIntercept, rv, pv, err = \ ps.GetDetectionLimit(starParmTuple, ion, modelAtms=modelAtms, pradks=pradks) hiSlope, hiIntercept, rv, pv, err = \ ps.GetCoGLimit(starParmTuple, ion, modelAtms=modelAtms, pradks=pradks) ps.AbSTRPlot(starName, ion, dataPoints, redSet=redData, greenSet=greenData, blueSet=blueData, lowLimit=(loSlope, loIntercept), hiLimit=(hiSlope, hiIntercept), fileTag=fileTag, plotTitle=plotTitle, labelPoints=pointLabels)
def MakeTeffPlots(clusterName='NGC-0752', starDataList=None, fileTag='', referenceCorrect=False): # Function plots Teff vs. slope of (XP vs. [Fe/H]) for a range of temperatures. # Intended to provide a spectroscopic confirmation/adjustment # for photometrically-determined parameters. We assume that at the "correct" # temperature, the slope of XP vs. [Fe/H] would be zero. if starDataList is None: starDataList = STP.GetAllStarParms(clusterName=clusterName) dModelFiles = mk.findDataFiles(k.DwarfModelPath) dModelAtms, dPradks = mk.LoadModels(dModelFiles) gModelFiles = mk.findDataFiles(k.GiantModelPath) gModelAtms, gPradks = mk.LoadModels(gModelFiles) # Map Fe I Ab vs. Ex pot. ions = [26.0] abDict = {} dTeffRange = np.linspace(5000, 7000, 81) gTeffRange = np.linspace(4000, 6000, 81) for star in starDataList: starName = star[0] isGiant = RC.isGiantStar(star[1:]) if isGiant: modelAtms = gModelAtms pradks = gPradks tRange = gTeffRange if referenceCorrect: correctDict, referenceLines, lineWeights = \ RC.GetGiantCorrections(ionList=ions, modelAtms=modelAtms, pradks=pradks) else: modelAtms = dModelAtms pradks = dPradks tRange = dTeffRange if referenceCorrect: correctDict, referenceLines, lineWeights = \ RC.GetDwarfCorrections(ionList=ions, modelAtms=modelAtms, pradks=pradks) logG = star[2] vTurb = star[3] met = star[4] slopes = [] for Teff in tRange: unusedDict, uncorrLines, unusedMin, unusedMax = \ AB.CalcAbsAndLines(clusterName+' '+starName, tuple([Teff, star[2], star[3], star[4], star[5]]),\ ionList=ions, modelAtms=modelAtms, pradks=pradks) XPs = [] Abs = [] if referenceCorrect: adjLines, allLines = RC.SortAndFilterLines( uncorrLines[26.0], 26.0, tuple([Teff, star[2], star[3], star[4], star[5]]), solarCorrect=True, solarLines=referenceLines[26.0], solarCorrs=correctDict[26.0], lineWeights=lineWeights[26.0]) if len(adjLines) > 10: # Assume 10 Fe I lines needed for nice plots for line in adjLines: # XP isn't returned, so have to do a lookup into the # original list. XPs.append( u.find(lambda l: l[0] == line[2], uncorrLines[26.0])[1]) Abs.append(line[0]) if len(XPs) == 0 or len(Abs) == 0: # Either no corrections, or corrections failed XPs = [line[1] for line in uncorrLines[26.0]] Abs = [line[5] for line in uncorrLines[26.0]] slope, intercept, rVal, pVal, err = sp.stats.linregress(XPs, Abs) slopes.append(slope) # We have to flip because interp expects the xvalues to be # monotomically increasing interpTs = np.interp([-0.02, 0., 0.02], slopes[::-1], tRange[::-1]) if interpTs[0] > interpTs[1]: minusR = interpTs[1] - interpTs[2] plusR = interpTs[0] - interpTs[1] else: minusR = interpTs[1] - interpTs[0] plusR = interpTs[2] - interpTs[1] fig = pyplot.figure() TeffLabel = r'$T_{{eff}} = {0:4.0f}^{{+{1:4.0f}}}_{{-{2:4.0f}}}$)'.\ format(interpTs[1],minusR,plusR) pyplot.scatter(tRange, slopes, label=TeffLabel) pyplot.axhline(0.0, linestyle=':') pyplot.legend() pyplot.savefig(k.ParmPlotDir + 'Teff/' + star[0] + fileTag + '_FeSlope.png') pyplot.close()