Exemplo n.º 1
0
def GetDwarfAbs(parmList, abDict):
    # Note: could use an XOR, and a isGiant flag to combine the Dwarf and Giant
    # versions of this function
    accumulator = {}
    dwarfList = [s[0] for s in parmList if not RC.isGiantStar(s[1:])]
    for dName in dwarfList:
        if dName in abDict.keys():
            for ion in abDict[dName].keys():
                if ion in accumulator.keys():
                    accumulator[ion].append(abDict[dName][ion][0])
                else:
                    accumulator[ion] = [abDict[dName][ion][0]]
    retDict = {}
    for ion in accumulator.keys():
        retDict[ion] = np.mean([ab for ab in accumulator[ion]])

    return retDict
Exemplo n.º 2
0
def MakeLineListTable(ions=[], wls=[], outFile=d.TableDir + 'Table2.dat'):
    lines, refs = LL.getLines(elements=ions, wavelengthRange=wls,\
        dataFormat=None)
    unused1, unused2, weights = RC.GetSolarCorrections()

    fp = open(outFile, 'w')
    fmt, db = BuildFormatString(table2Format,
                                DataLabels=table2Labels,
                                DataUnits=table2Units,
                                DataExp=table2Desc,
                                MakeBbBDesc=True)
    fp.write(db)
    allIons = sorted(set(np.array(lines)[:, 1]))
    lineData = []
    for i in allIons:
        ion = np.round(i, decimals=1)
        (elem, state, unused) = el.getIonState(el.getIonName(ion))
        ionLines = np.array(
            sorted([l for l in lines if np.round(l[1], decimals=1) == ion],
                   key=lambda l: l[0]))
        for line in ionLines:
            wl = np.round(line[0], decimals=3)
            xp = line[2]
            gf = line[3]
            if gf < 0:
                gfs = '-'
            else:
                gfs = ''
            gf = abs(gf)
            try:
                qu = int(weights[ion][wl])
            except KeyError:
                qu = 0
            rf = line[5]
            lineData.append([elem, state, wl, xp, gfs, gf, qu, rf])
    for line in lineData:
        fp.write(fmt.format(*line) + '\n')
    fp.close()
Exemplo n.º 3
0
def selectLinesForElement(lines, ion, modelAtms, pradks, starParms, varLimit = np.finfo(np.float64).max, enforceMin=False, refLines=None, refCorrs=None, lineWeights=None):
    # From the passed list, select all the lines of the passed ion
    # (in XX.x form), with abundances within +/-varLimit of the mean.
    # An additional selection criteria is that the line eqw falls on
    # the linear portion of the curve of growth.
    # If enforceMin = True, the selection will be limited to the lesser
    # of the total number of lines for this element, or the constant
    # MinNumStatLines.
    # To save time in looped, or multiple calls, solar (or giant) corrections
    # can be passed in refLines and refCorrs. This is basically the output
    # of RC.getGiantCorrections or RC.getSolarCorrections for the passed ion.

    corrLines, allLines = RC.SortAndFilterLines(lines[ion], ion, starParms, filterBlends=True, refCorrect=True, modelAtms=modelAtms , pradks=pradks, refLines=refLines, refCorrs=refCorrs, lineWeights=lineWeights)
    
    # If we did not receive enough (any) corrected lines, so return a subset of
    # all the lines.
    if (corrLines==None or len(corrLines) < k.MinNumStatLines):
        if len(allLines) <= k.MinNumStatLines:
            # Well, we can't make more lines, so just return what we have
            return sorted(allLines, key=lambda line: line[0])
        else:
            meanAb = np.mean(np.array(allLines)[:,5])
            allSorted = sorted(allLines, key=lambda line: abs(line[5]-meanAb))[:k.MinNumStatLines]
            return sorted(allSorted, key=lambda line: line[0])
    elif enforceMin:
        # We have enough lines to consider filtering for the variance limit.
        meanAb = np.mean(np.array(corrLines)[:,5])
        limitedLines = [line for line in corrLines if abs(line[5]-meanAb)<=varLimit]
        if len(limitedLines) < k.MinNumStatLines:
        # Variance filtering was a bit much, return the best we can
            return sorted(sorted(corrLines, key=lambda line: abs(line[5]-meanAb))[:k.MinNumStatLines], key=lambda l: l[0])
        else:
            return sorted(limitedLines, key=lambda line: line[0])
    else:
        # enforceMin not set, so filter away!
        meanAb = np.mean(np.array(corrLines)[:,5])
        rtnLines = [x for x in corrLines if abs(x[5]-meanAb) < abs(varLimit)]
        return sorted(rtnLines, key=lambda line: line[0])
Exemplo n.º 4
0
def MakeSolarCompTable(outFilename=k.TempAbOutFilename,
                       headerLeft='',
                       headerRight=''):
    # Function creates a LaTeX table with elemental abundances as calculated from
    # our Solar reference spectrum, based on a "quality" measurement of each line.
    # Each column of the table represents a measurement using lines of a particular
    # quality or better. The final column is represents all of the measured lines.
    corrections, lines, weights = RC.GetSolarCorrections()

    # We're going to create one column for each "quality" setting from the
    # returned weights list. Basically, each weight is a quality level.
    # The columnDict contains:
    # {weight:{ion:[ab,std,#lines],...},...}
    columnDict = {}
    for wt in k.AbWeights:
        columnDict[wt] = {}

    allIonList = sorted(lines.keys())
    for ion in allIonList:
        ionLines = lines[ion]
        # A single line will not show up as a list of one item. Rather, the
        # entire list will be that one line's parameters...grrr.
        if not u.is_list(ionLines[0]):
            ionLines = [ionLines]
        for wt in k.AbWeights:
            wtLines = np.array([line for line in ionLines \
                        if line[0] in weights[ion] and weights[ion][line[0]] >= wt])
            if len(wtLines) > 0:
                asplundCorr = PA.ptoe[int(ion) - 1][PA.abIdx]
                columnDict[wt][ion] = [
                    np.mean(wtLines[:, 5]) + asplundCorr,
                    np.std(wtLines[:, 5]),
                    len(wtLines)
                ]

    # Create a nice column title for each quality type:
    nameList = [
        r'$\Delta\leq{0:1.2f}$'.format(r[1]) for r in k.AbWeightRanges[:-1]
    ]
    nameList.append('All lines')

    outfile = open(outFilename, 'w')

    latexHeader = STP.kLaTexHeader1 + '\\rhead{\\textbf{' + headerRight\
                  + '}}\n\\lhead{\\textbf{' + headerLeft\
                  + '}}\n\\begin{document}\n'
    outfile.write(latexHeader)

    outfile.write('\\begin{landscape}\n'\
                  + '\\hspace*{-5cm}\n'\
                  + '\\begin{tabular}{|l|l|l|l|l|l|l|l|l|l|')
    outfile.write(
        '}\n\\multicolumn{1}{l}{Ion} & \\multicolumn{1}{l}{Asplund (2009)}')

    for name in nameList:
        outfile.write(' & \\multicolumn{{1}}{{l}}{{{0}}}'.format(name))
    outfile.write('\\\\\n\\hline\n')

    for ion in allIonList:
        outfile.write('{0} & {1:1.2f}$\pm${2:1.2f}'.format(el.getIonName(ion),\
                                          PA.ptoe[int(ion)-1][PA.abIdx],\
                                          PA.ptoe[int(ion)-1][PA.solarErrIdx]))

        for wt in k.AbWeights:
            if ion in columnDict[wt].keys() and columnDict[wt][ion][2] > 0:
                outfile.write(' & {0:1.2f}$\pm${1:1.2f} ({2:d})'.\
                  format(columnDict[wt][ion][0]-PA.ptoe[int(ion)-1][PA.abIdx],
                         columnDict[wt][ion][1],
                         columnDict[wt][ion][2]))
            else:
                outfile.write(' & \\multicolumn{1}{c|}{---} ')

        outfile.write('\\\\\n\\hline\n')

    outfile.write('\\label{{tab:SolarAbs}}\n' +
                  '\\end{tabular}\n\\end{landscape}\n' + '\\clearpage\n')

    outfile.write('\\end{document}\n')
    outfile.close()
Exemplo n.º 5
0
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)
Exemplo n.º 6
0
def MakeAbTable(clusterName='NGC-0752',
                starDataList=None,
                ions=kAllIonList,
                outFilename=k.TempAbOutFilename,
                filterBlends=False,
                referenceCorrect=False,
                useDAOSpec=False,
                headerLeft='',
                headerRight=''):

    if starDataList == None:
        starDataList = GetAllStarParms(clusterName=clusterName)

    # Lookup the abundance(s) for the passed star(s), and create a LaTeX chart

    tableDict = GetAbTable(clusterName, starDataList, ions, filterBlends,
                           referenceCorrect, useDAOSpec)

    giantNames = np.array([s[0] for s in starDataList \
        if RC.isGiantStar(s[1:5])])
    #    dwarfNames = np.array([s[0] for s in starDataList
    #        if not RC.isGiantStar(s[1],s[2])])

    # Iron abundance is listed as [Fe/H], all others will be [X/Fe].

    # Compile a cluster/dwarfs/giants average table entry.
    # Entries are of the form:
    # {Ion:[[star ab, star line quality], ...], ...}
    clusterDict = {}
    dwarfDict = {}
    giantDict = {}
    for star in tableDict.keys():
        # Place this stars measures into the proper category dictionary
        if star in giantNames:
            catDict = giantDict
        else:
            catDict = dwarfDict

        starFe = GetStarFeH(tableDict[star])

        for ion in tableDict[star].keys():
            solarIonH = PA.ptoe[int(ion) - 1][PA.abIdx]
            if tableDict[star][ion][0] == 0.:
                continue

            if ion not in [26.0, 26.1]:
                # Adjust values for [X/Fe]
                tableDict[star][ion][0] = tableDict[star][ion][0]\
                                          - solarIonH\
                                          - starFe

            if ion in clusterDict.keys():
                clusterDict[ion].append([tableDict[star][ion][0],\
                                         tableDict[star][ion][3]])
            else:
                clusterDict[ion] = [[tableDict[star][ion][0],\
                                     tableDict[star][ion][3]]]

            if ion in catDict.keys():
                catDict[ion].append([tableDict[star][ion][0],\
                                     tableDict[star][ion][3]])
            else:
                catDict[ion] = [[tableDict[star][ion][0],\
                                 tableDict[star][ion][3]]]

    idxName = clusterName + ' (all)'
    tableDict[idxName] = {}
    for ion in clusterDict.keys():
        # If each star's ab measurement for are "independent measures" of the
        # cluster abundance, we should divide the stdev by sqrt(num_measures)...
        # Calcs broken into separate lines for readability.
        cMean = np.mean([l[0] for l in clusterDict[ion]])
        cStd = np.std([l[0] for l in clusterDict[ion]])
        cScoreMean = np.mean([l[1] for l in clusterDict[ion]])
        tableDict[idxName][ion] = \
                        [cMean, cStd, len(clusterDict[ion]), cScoreMean]

    idxName = clusterName + ' (dwarfs)'
    tableDict[idxName] = {}
    for ion in dwarfDict.keys():
        dMean = np.mean([l[0] for l in dwarfDict[ion]])
        dStd = np.std([l[0] for l in dwarfDict[ion]])
        dScoreMean = np.mean([l[1] for l in dwarfDict[ion]])
        tableDict[idxName][ion] = \
                    [dMean, dStd, len(dwarfDict[ion]), dScoreMean]

    idxName = clusterName + ' (giants)'
    tableDict[idxName] = {}
    for ion in giantDict.keys():
        gMean = np.mean([l[0] for l in giantDict[ion]])
        gStd = np.std([l[0] for l in giantDict[ion]])
        gScoreMean = np.mean([l[1] for l in giantDict[ion]])
        tableDict[idxName][ion] = \
                    [gMean, gStd, len(giantDict[ion]), gScoreMean]

    ions = sorted(list(set(ions)))
    # The cluster name starts with "N", so it will be first in the list
    nameList = sorted(tableDict.keys())

    outfile = open(outFilename, 'w')

    latexHeader = kLaTexHeader1 + '\\rhead{\\textbf{' + headerRight\
                  + '}}\n\\lhead{\\textbf{' + headerLeft\
                  + '}}\n\\begin{document}\n'
    outfile.write(latexHeader)
    # New page/table:
    for tableCount in range(int(len(nameList) / 6) + 1):
        outfile.write('\\begin{landscape}\n'\
                      + '\\hspace*{-5cm}\n'\
                      + '\\begin{tabular}{|l|l|l|l|l|l|l|')
        outfile.write('}\n\\multicolumn{1}{l}{Ion}')
        for name in nameList[tableCount * 6:(tableCount + 1) * 6]:
            outfile.write(' & \\multicolumn{{1}}{{l}}{{{0}}}'.format(name))
        outfile.write('\\\\\n\\hline\n')

        # A little bit of stupidity to put FeI and FeII at the top of the table:
        printIons = sorted(ions)
        printIons.remove(26.)
        printIons.remove(26.1)
        printIons = [26.0, 26.1] + printIons

        for ion in printIons:
            if int(ion) == 26:
                outfile.write('[{0}/H]'.format(el.getIonName(ion)))
            else:
                outfile.write('[{0}/Fe]'.format(el.getIonName(ion)))

            for star in nameList[tableCount * 6:(tableCount + 1) * 6]:
                if ion in tableDict[star].keys(
                ) and tableDict[star][ion][2] > 0:
                    outfile.write(' & {0:3.2f}$\pm${1:3.2f} ({2:d}, {3:1.1f})'.\
                                  format(tableDict[star][ion][0],
                                         tableDict[star][ion][1],
                                         tableDict[star][ion][2],
                                         tableDict[star][ion][3]))
                else:
                    outfile.write(' & \multicolumn{1}{c|}{---}')

            outfile.write('\\\\\n\\hline\n')
            # Place a double line after the Fe/H measures
            if ion == 26.1:
                outfile.write('\\hline\n')

        outfile.write('\\label{{tab:752Abs-{0}}}\n'.format(tableCount + 1) +
                      '\\end{tabular}\n\\end{landscape}\n' + '\\clearpage\n')

    outfile.write('\\end{document}\n')
    outfile.close()
Exemplo n.º 7
0
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
Exemplo n.º 8
0
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
Exemplo n.º 9
0
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)
Exemplo n.º 10
0
def COGPlot(clusterName,
            starData,
            ions,
            fileTag='',
            labelPlot=True,
            labelPoints=False,
            modelAtms=None,
            pradks=None,
            makeQualityPlot=False):
    # Make Curve of Growth (COG) plots for the passed star
    # One element per plot.
    # If the makeQualityPlot flag is set, a second plot will be made, with the
    # points shaded relative to how well they correspond to the linear fit of
    # measurements with similar excitation potentials.
    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=ions,
                                   modelAtms=modelAtms, pradks=pradks)

    for ion in ions:
        # One plot per ion.

        if ion not in uncorrLines.keys():
            print('No {0:2.1f} lines for {1}.'.format(ion, starName))
            continue

        if labelPlot:
            plotLabel = 'Curve of Growth for [{2}/H] in {0} {1}.'.\
                        format(clusterName, starName, el.getIonName(ion))
        else:
            plotLabel = ''

        if labelPoints:
            # Label the points with the excitation potential
            pointLabels = ['{0:2.3f}'.format(point[1]) \
                           for point in np.array(uncorrLines[ion])]
        else:
            pointLabels = None

        ps.COGPlot(np.array(uncorrLines[ion]),
                   starName,
                   ion,
                   fileTag=fileTag,
                   plotTitle=plotLabel,
                   pointLabels=pointLabels)

        if makeQualityPlot:
            if labelPlot:
                plotLabel = 'Measurement quality for [{2}/H] in {0} {1}.'.\
                            format(clusterName, starName, el.getIonName(ion))
            else:
                plotLabel = ''
            ps.QualityPlot(np.array(uncorrLines[ion]),
                           starName,
                           ion,
                           fileTag=fileTag + 'QP',
                           plotTitle=plotLabel,
                           pointLabels=pointLabels)
Exemplo n.º 11
0
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()
Exemplo n.º 12
0
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()
Exemplo n.º 13
0
def MakeTAbPlots(clusterName='NGC-0752',
                 starDataList=None,
                 ionList=STP.kAllIonList,
                 fileTag='',
                 useSubfigures=False,
                 referenceCorrect=False):
    # Create a bunch of .ps plots with the star's effective temperature vs. [X/Fe]
    # for all ions in the optional passed list. One ion per plot

    if starDataList == None:
        starDataList = STP.GetAllStarParms(clusterName=clusterName)

    abTable = STP.GetAbTable(clusterName=clusterName,
                             starDataList=starDataList,
                             ions=ionList,
                             referenceCorrect=referenceCorrect)

    solarFeH = PA.ptoe[25][PA.abIdx]

    clusterFeH = \
        0.75*np.mean([abTable[star][26.0][0] for star in abTable.keys()])+\
        0.25*np.mean([abTable[star][26.1][0] for star in abTable.keys() \
            if 26.1 in abTable[star].keys()])

    for ion in ionList:

        solarIonH = PA.ptoe[int(ion) - 1][PA.abIdx]

        fig = pyplot.figure()
        ax = pyplot.gca()

        redGPoints = []
        magGPoints = []
        bluDPoints = []
        cyaDPoints = []
        for star in starDataList:
            starName = star[0]
            if starName not in abTable.keys():
                continue
            starIons = sorted(abTable[starName].keys())
            if ion not in starIons:
                continue

            starParms = star[1:]

            # Get the Fe/H for this star. Note: We don't do Fe/Fe comps.
            if int(ion) != 26:
                # If both ions are measured, weight 75/25 for FeI/FeII
                if 26.0 in starIons and 26.1 in starIons:
                    starFe = 0.75*abTable[starName][26.0][0]\
                             + 0.25*abTable[starName][26.1][0]\
                             - solarFeH
                else:
                    starFe = abTable[starName][26.0][0] - solarFeH
            else:
                starFe = 0.

            if RC.isGiantStar(starParms):
                #                if starParms[5] < 50:
                #                    magGPoints.append([starParms[0],
                #                                   abTable[starName][ion][0]-solarIonH-starFe,
                #                                   abTable[starName][ion][1]])
                #                else:
                redGPoints.append([
                    starParms[0],
                    abTable[starName][ion][0] - solarIonH - starFe,
                    abTable[starName][ion][1]
                ])
            else:
                #                if starParms[5] < 25:
                #                    cyaDPoints.append([starParms[0],
                #                                   abTable[starName][ion][0]-solarIonH-starFe,
                #                                   abTable[starName][ion][1]])
                #                else:
                bluDPoints.append([
                    starParms[0],
                    abTable[starName][ion][0] - solarIonH - starFe,
                    abTable[starName][ion][1]
                ])

        dMean = np.mean([l[1] for l in cyaDPoints + bluDPoints])
        dStd = np.std([l[1] for l in cyaDPoints + bluDPoints])
        ax.axhline(y=dMean, ls='dashed', color='b',
                   label=r'Dwarf Avg. (${0:4.2f}\pm{1:4.2f}$)'.\
                   format(dMean,dStd))
        ax.axhline(y=dMean - dStd, ls='dotted', color='b')
        ax.axhline(y=dMean + dStd, ls='dotted', color='b')

        gMean = np.mean([l[1] for l in redGPoints + magGPoints])
        gStd = np.std([l[1] for l in redGPoints + magGPoints])
        ax.axhline(y=gMean, ls='dashed', color='r',
                   label=r'Giant Avg. (${0:4.2f}\pm{1:4.2f}$)'.\
                   format(gMean,gStd))
        ax.axhline(y=gMean - gStd, ls='dotted', color='r')
        ax.axhline(y=gMean + gStd, ls='dotted', color='r')

        ax.axhline(y=0., ls='dashed', color='g', linewidth=1.0,\
                   label='Solar (${0:4.2f}$)'.\
                   format(PA.ptoe[int(ion)-1][PA.abIdx]))

        pyplot.rcParams.update({'legend.fontsize': 10})
        ax.legend()

        if dMean > 0. and gMean > 0.:
            ax.set_ylim([
                min([dMean - 0.5, gMean - 0.5]),
                max([dMean + 0.5, gMean + 0.5])
            ])
        elif dMean > 0.:
            ax.set_ylim([dMean - 0.5, dMean + 0.5])
        elif gMean > 0:
            ax.set_ylim([gMean - 0.5, gMean + 0.5])

        Xs = [l[0] for l in bluDPoints]
        Ys = [l[1] for l in bluDPoints]
        Es = [l[2] for l in bluDPoints]
        eb = ax.errorbar(Xs, Ys, yerr=Es, fmt='o', color='b')
        if len(eb) > 0 and len(eb[-1]) > 0: eb[-1][0].set_linestyle('--')

        #        Xs = [l[0] for l in cyaDPoints]
        #        Ys = [l[1] for l in cyaDPoints]
        #        Es = [l[2] for l in cyaDPoints]
        #        eb=ax.errorbar(Xs, Ys, yerr=Es, fmt='s', color='c')
        #        if len(eb)>0 and len(eb[-1])>0: eb[-1][0].set_linestyle('--')

        Xs = [l[0] for l in redGPoints]
        Ys = [l[1] for l in redGPoints]
        Es = [l[2] for l in redGPoints]
        eb = ax.errorbar(Xs, Ys, yerr=Es, fmt='o', color='r')
        if len(eb) > 0 and len(eb[-1]) > 0: eb[-1][0].set_linestyle('--')

        #        Xs = [l[0] for l in magGPoints]
        #        Ys = [l[1] for l in magGPoints]
        #        Es = [l[2] for l in magGPoints]
        #        eb=ax.errorbar(Xs, Ys, yerr=Es, fmt='s', color='m')
        #        if len(eb)>0 and len(eb[-1])>0: eb[-1][0].set_linestyle('--')

        ionStr = el.getIonName(ion)

        if int(ion) != 26:
            ax.set_ylim((-0.5, 0.5))
        else:
            ax.set_ylim((-0.3, 0.3))

        ax.set_xlabel(r'$T_{eff}$ (K)')
        if int(ion) != 26:
            ax.set_ylabel(r'$[{0}/Fe]$'.format(ionStr))
        else:
            ax.set_ylabel(r'$[{0}]$'.format(ionStr))

        pyplot.savefig('{0}{1}{2}.png'.format(k.PlotDir + 'Elems/', ionStr,
                                              fileTag),
                       figure=fig)
        #        pyplot.show()
        pyplot.close(fig)