示例#1
0
def GetCoGLimit(starData, ion=26.0, modelAtms=None, pradks=None):
    # Returns the parameters for a line (using the same return parameters as
    # scipy.stats.linregress), representing the maximum limit for an EQW measurement
    # assuming that the non-linear portion of the Curve of Growth (CoG) begins
    # around a value of -4.60, as measured by Log(EQW/Wavelength).
    # The return parameters are (in order):
    #                               slope, intercept, r-value, p-value, stderr
    starName = k.MaxDetFakeStarName
    clustName = k.CalibClusterName
    abdict, lines, unusedMins, unusedMaxes = AB.CalcAbsAndLines(
        clustName + ' ' + starName,
        starData,
        ionList=[ion],
        modelAtms=modelAtms,
        pradks=pradks)
    if ion not in lines.keys():
        # Hack for N
        if ion == 7.0:
            return 0, 0, 0, 0, 0
        else:
            print(
                'Ion:{0:2.1f} will not use CoG limits (possibly HFS).'.format(
                    ion))
            return 0, 0, 0, 0, 0
    Xs = [line[5] for line in sorted(lines[ion], key=lambda l: l[0])]
    Ys = [
        el.STR(line[2], line[1], starData[0])
        for line in sorted(lines[ion], key=lambda l: l[0])
    ]

    return sp.stats.linregress(Xs, Ys)
def GetSolarCorrections(ionList=[], modelAtms=None,
                        pradks=None, useDAOSpec=False):
# Returns a dictionary of lines (for the passed ion list) with their
# abundance corrections, based on our line measurement of Solar spectra,
# and the accepted abundance (from Asplund 2009).
# If the passed ion list is empty, all corrected lines are returned.
#
# The three returned dictionaries:
# solarCorrs:{ion:{wl:correction,...},...}
# solarLines:{ion:[[wl, Ex.Pot., logGf, eqw, logRW, abund],...]}
# weights:   {ion:{wl:weight,...},...}
    solarCorrs = {}
    weights = {}

    # First, check to see if we already have calculated Solar abs
    allLines = LL.LookupSolarAbundances(ionList=ionList)
    if len(allLines.keys()) > 0:
        solarLines = allLines
    else:
        # Don't have them. So, calculate, and enter them. We have the line list
        # now.
        if modelAtms is None or pradks is None:
            modelPath = k.DwarfModelPath
            modelFiles = mk.findDataFiles(modelPath)
            modelAtms, pradks = mk.LoadModels(modelFiles) 

        allLines = LL.getSolarLines(ionList, [(4500.,8750.)],\
                                    useDAOSpec=useDAOSpec)
        # We need a slightly different form if we have to calculate the abs.
        compositeLines = sorted([[l[0], l[1], 'filler', 'filler', l[2]] \
                            for l in allLines], key = lambda l:(l[1], l[0]))

        unused1, solarLines, unused2, unused3 = AB.CalcAbsFromLines(\
                        compositeLines, k.SolarRefParms, star='SolarRef',\
                        ionList=ionList, modelAtms=modelAtms, pradks=pradks)
        # MOOG can fail, in which case, our dictionary will be empty:
        if len(solarLines.keys()) == 0:
            return {}, {}, {}
        # Now, put them into our DB, so we don't have to do this again.
        newLines = []
        for ion in sorted(solarLines.keys()):
            newLines.extend([[k.SolarRefStarName, ion, l[0], l[1], l[2], l[3], l[4], l[5]] for l in solarLines[ion]])
        LL.EnterCalibrationAbundances(newLines)
        
    if len(ionList) == 0:
        ionList = solarLines.keys()

    for ion in ionList:
        solarAb = PA.ptoe[int(ion)-1][PA.abIdx]
        solarCorrs[ion] = {}
        weights[ion] = {}
        if ion not in solarLines.keys():
            continue
        for line in solarLines[ion]:
            correction = solarAb-line[5]
            solarCorrs[ion][line[0]] = correction
            weights[ion][line[0]] = GetRefLineWeight(correction)

    return solarCorrs, solarLines, weights
示例#3
0
def GetDetectionLimit(starData, ion=26.0, modelAtms=None, pradks=None):
    # Returns the parameters for a line (using the same return parameters as
    # scipy.stats.linregress), representing the minimum detection limit for the
    # passed ion (default: FeI). Measurements below, and to the left of the line
    # are below the calculated detection limit of the spectra, and should be
    # ignored.
    # Since detection limit is affected by parameters, passing a stellar parameter
    # tuple of the form: (Teff, LogG, Vturb, [Fe/H], Giant mass (=0.0 for dwarfs))
    # is needed.
    # The return parameters are (in order):
    #                               slope, intercept, r-value, p-value, stderr

    starName = k.MinDetFakeStarName
    clustName = k.CalibClusterName
    abdict, lines, unusedMin, unusedMax = AB.CalcAbsAndLines(
        clustName + ' ' + starName,
        starData,
        ionList=[ion],
        modelAtms=modelAtms,
        pradks=pradks)

    if ion not in lines.keys():
        # Hack for N
        if ion == 7.0:
            return 0, 0, 0, 0, 0
        else:
            print('Ion:{0:2.1f} will not use detection limits (possibly HFS).'.
                  format(ion))
            return 0, 0, 0, 0, 0
    Xs = [line[5] for line in sorted(lines[ion], key=lambda l: l[0])]
    Ys = [
        el.STR(line[2], line[1], starData[0])
        for line in sorted(lines[ion], key=lambda l: l[0])
    ]

    return sp.stats.linregress(Xs, Ys)
示例#4
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)
示例#5
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
示例#6
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)
示例#7
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)
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()