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 GetAbsForStar(starData, clusterName='NGC-0752', ions=kAllIonList, \ filterBlends=False, refCorrect=False,\ refLines=None, refDict=None, lineWeights=None, useDAOSpec=False, modelAtms=None, pradks=None): # Get all the elemental abundances for the single passed star (params): # starData: (starName, Teff, LogG, VTurb, Met, Mass) # # Returns a dictionary of {ion:(Ab, std, #lines, avg Quality)...} starName = starData[0] starParms = tuple(starData[1:6]) abdict, uncorrLines, unusedMins, unusedMaxes = \ AB.CalcAbsAndLines(clusterName+' '+starName, starParms, ionList=ions, modelAtms=modelAtms, pradks=pradks, useDAOlines=useDAOSpec) # uncorrLines: # # {elem.ion:[[Wavelength, Ex.Pot., logGf, eqw, logRW, abund],...]} starAbDict = {} ionLUT = sorted(list(abdict.keys())) ionLUT = sorted(set(ionLUT + [ion for ion in SynthAbsDict.keys()\ if starName in SynthAbsDict[ion].keys()])) if refCorrect and (refLines is None or refDict is None): refCorrect = False for ion in ionLUT: # We'll make one line per ion. Note, synth elements won't # necessarily have lines in the table/dict. if ion not in list(uncorrLines.keys()) + list(SynthAbsDict.keys()): continue if refCorrect and ion not in refLines.keys(): correctionsAvail = False else: correctionsAvail = True # 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], starParms) else: if ion in uncorrLines.keys(): LTELines = uncorrLines[ion] else: # Either synthesized lines, or none available LTELines = np.array([]) # Now apply "Solar" or "Astrophysical Log gf" corrections, if requested if correctionsAvail and (refCorrect or filterBlends) and ion in uncorrLines.keys(): tempAdj,tempAll = \ RC.SortAndFilterLines(LTELines, ion, starParms, filterBlends=filterBlends, solarCorrect=refCorrect, solarLines=refLines[ion], solarCorrs=refDict[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) else: if len(LTELines) > 0: allLines = np.array(\ [[l[5], el.STR(l[2], l[1], starParms[0]), l[0]] \ for l in LTELines]) correctedLines = np.array(\ [[l[0], l[1], l[2], k.AbWeights[-1]] \ for l in allLines]) else: allLines = correctedLines = np.array([]) if ion in SynthAbsDict.keys() and \ starName in SynthAbsDict[ion].keys(): # We have a C I or N I synthesis: if ion == 6.0: nonSynthLines = np.array([l for l in correctedLines\ if l[2]<7110 or l[2]>7120]) elif ion == 7.0: # N I synthesis uses both the 7115 region (giants) # and the 7442 region (all). Only the 7442 region # has a potentially measured line, tho. nonSynthLines = np.array([l for l in correctedLines \ if np.floor(l[2]) != 7442]) else: nonSynthLines = [] synthArray = GetSynthLines(starName, ion,\ clusterName=clusterName) # Returned tuple: (synthMean, synthStd, synthCount) # Include our synthesis as the number of lines measured if len(nonSynthLines) == 0: starAbDict[ion] = [synthArray[0], synthArray[1],\ synthArray[2],k.NoAbWeight] else: mean = np.mean(nonSynthLines[:, 0]) std = np.std(nonSynthLines[:, 0]) ct = len(nonSynthLines) totalCt = ct + synthArray[2] totalMean = ((mean*ct)+(synthArray[0]*synthArray[2]))/\ (totalCt) totalStd = np.sqrt(\ (ct*(totalMean-mean)**2+ synthArray[2]*(synthArray[0]-mean)**2)/\ (totalCt-1)) starAbDict[ion] = [totalMean, totalStd, totalCt, k.NoAbWeight] # We have already created the abundance dictionary for this ion, # so skip out on the next part. continue else: # No synthesized lines need to be added. pass if refCorrect and len(correctedLines) > 0: linesToCount = correctedLines avgQ = np.mean(correctedLines[:, 3]) else: linesToCount = allLines avgQ = k.NoAbWeight if len(linesToCount) > 0: starAbDict[ion] = [ np.mean(linesToCount[:, 0]), np.std(linesToCount[:, 0]), len(linesToCount), avgQ ] else: # No lines to count. Make sure we don't have an entry: if ion in starAbDict.keys(): del starAbDict[ion] return starAbDict