Exemplo n.º 1
0
def getGuesses(logFile, guessFilename):
    tGuess = k.SolarTeff
    gGuess = k.SolarLogG
    vGuess = k.SolarVturb

    if guessFilename is not None:
    # Assume the log file has the correct format of: NNNN_SSS_ssssss_II_OOO.fits
    # Where: 
    #           NNNN  = NGC catalog number of parent cluster 
    #                    (note: clusters not contained in the NGC catalog will be prefaced by a letter
    #                     representative of their catalog. ex: I = IC
    #           SSS    = Reference indexing system for this cluster. 
    #                    (ex: MJP = Montgomery, Janes, and Phelps)
    #           ssssss = Star index number from the aformetioned index.
    # ...which means that we can look up the guess by the star name.
        logFileWords = os.path.basename(logFile).split('_')
#        starName = '_'.join(logFileWords[0:3])
        starName = logFileWords[0]
        print('Looking for star: %s' % starName)
        try:
            guessFile = open(guessFilename, 'r')
            guessLines = guessFile.readlines()
        except:
            u.errorOut('Error in parameter determination:\nUnable to open file:%s' % guessFilename, True)

        try:
            guessStr = [guessLine for guessLine in guessLines if guessLine.find(starName)==0][0]
        except IndexError:
            return tGuess, gGuess, vGuess

        guesses = guessStr.split()
        if len(guesses) > 0 and u.is_number(guesses[1]):
            tGuess = float(guesses[1])
        if len(guesses) > 1 and  u.is_number(guesses[2]):
            gGuess = float(guesses[2])
        if len(guesses) > 2 and  u.is_number(guesses[3]):
            vGuess = float(guesses[3])
                    
    return tGuess, gGuess, vGuess
Exemplo n.º 2
0
def readDAORV(daoLogfile):
    # Reads the calculated RV from the first line of a log file.
    # We're expecting the first line to read:
    # "Radial velocity =    <RV value>  dispersion =..."
    rvStr = 'NaN'
    infile = open(daoLogfile, 'r')
    data = infile.readlines()
    infile.close()
    for line in data:
        words = line.split()
        if len(words) > 0:
            if words[0] == "Final":
                rvStr = words[3]
                break
    if u.is_number(rvStr):
        rv = float(rvStr)
    else:
        rv = -999.99
    return rv
Exemplo n.º 3
0
def ParseSimbadHTML(simbadBytes):
    fluxes = []
    simbadPage = simbadBytes.decode('UTF-8')
    if 'Fluxes' not in simbadPage:
        return fluxes

    # Get the table of fluxes
    fluxTable = simbadPage.split('Fluxes')[1].split('</TABLE>')[0]
    fluxStrs = fluxTable.split('<TR>')[1:]

    for fluxEntry in fluxStrs:
        # Each flux entry wants to have the form:
        # [filter, flux, [error], quality, flags, Ref]
        # First, some filters contain a space. Like "g (AB)" - so check
        # if the second field is a number, if not, assume it is a
        # continuation of a filter
        fe = fluxEntry.split('<TT>')[1].split('</TT>')[0].split()
        idx = 1
        if not u.is_number(fe[idx]):
            fil = ' '.join(fe[0:2])
            idx += 1
        else:
            fil = fe[0]

        mag = float(fe[idx])
        idx += 1
        try:
            err = float(fe[idx][1:-1])
        except ValueError:
            err = 0.

        idx += 1
        if fe[idx] == '<SPAN':
            grade = fe[idx + 4]
            idx += 5
        else:
            grade = '-'
        flags = ' '.join(fe[idx:])

        fluxes.append([fil, mag, err, grade, flags])
    return fluxes
Exemplo n.º 4
0
def ParseMOOGOut2File(out2Name):
    try:
        out2File = open(out2Name)
    except IOError:
        print('Unable to open {0} for line data read. Exiting.'.format(out2Name))
        sys.exit()
    
    fileData = out2File.read()
    out2File.close()

    lines = deque(str.split(fileData,'\n'))
    
    # MOOG can occasionally "bail" from an modeling run. Of course there's no easy
    # way to catch MOOG printing "...I QUIT!", so we manually read the second
    # line of the .out2 file: "Good" runs will have the first (comment) line
    # from the .log file. "Bad" runs will be the intermediate output product
    # starting with "element" - or nothing at all.
    waitForUser = False # For now, we're assuming automated operations:
    if len(lines)<3:
        print('MOOG unable to complete element:(unknown) for {0}.'.format(out2Name[:-4]))
        if k.isPython3:
            if waitForUser: input('Press enter to acknowledge and continue')
        else:
            if waitForUser: raw_input('Press enter to acknowledge and continue')
        return {}
        
    if lines[1].split()[0] == 'element':
        print('MOOG unable to complete element:{0} for {1}.'.format(lines[1].split()[1], out2Name[:-4]))
        if k.isPython3:
            if waitForUser: input('Press enter to acknowledge and continue')
        else:
            if waitForUser: raw_input('Press enter to acknowledge and continue')
        return {}

    # elementDict is a dictionary with the element symbol + 
    # ionization state (float) as key and an array of elements:
    # [Wavelength, Ex.Pot., logGf, eqw, logRW, abund]
    # for all the lines of that element as the value.
    # Example:   elementDict = {26.0:[[4347.23, 0.00, -5.503, 89.8, -4.68, 8.95]...]}
    elementDict = {}
    currentElement = 1.0 # HI is a flag for "No element"
    lineAbs = []
    
    while len(lines) > 1: 
        thisLine = lines.popleft().split();
        if len(thisLine) < 5:
            continue
        elif thisLine[0] == 'Abundance':
            # We have a new element. Put the last list (if any)
            # into the dictionary, and start clean
            if len(lineAbs) > 0:
                if currentElement in elementDict.keys():
                    elementDict[currentElement].extend(lineAbs)
                else:
                    elementDict[currentElement] = lineAbs

            currentElement = float(EL.symbolLU(thisLine[4])[0]) + (EL.ionLU(thisLine[5])-1.)/10.
            lineAbs = []
        elif u.is_number(thisLine[0]):
            # Note: MOOG2014 added the atom.ion ID as the second column in each line
            # So, now the input looks like:
            # [Wavelength, ID, Ex.Pot., logGf, eqw, logRW, abund, delta Avg.]
            #
            # If the abundance (or delta avg) field is 999.990, it is MOOG's
            # way of denoting one of the components of a blended line. Since 
            # the abundance calculation for this line will be listed elsewhere,
            # we can skip this line in the .out2 file
            if float(thisLine[6]) > 900.:
                continue
            
            # Abundance line, but do a touch of editing...
            lineAbs.append([float(thisLine[0]), float(thisLine[2]), float(thisLine[3]), float(thisLine[4]), float(thisLine[5]),float(thisLine[6])])

            # The following is the code for pre-2014 versions of MOOG:
            # lineAbs.append([float(x) for x in thisLine[:-1]])
            
    # Were we working on an element when the file ended?
    if len(lineAbs) > 0:
        if currentElement in elementDict.keys():
            elementDict[currentElement].extend(lineAbs)
        else:
            elementDict[currentElement] = lineAbs
   
    return elementDict
Exemplo n.º 5
0
def loadATLASModels(filename):
    # The current format (as of: Jan. 2015) for the ATLAS models subdivides
    # models into files, based on metallicity and velocity. There is only
    # one metallicity/velocity combination per file. We assume this, but leave the
    # possibility of multiple met./vel. per file, open.
    try:
        model = open(filename, 'r')
        lines = model.readlines()
    except IOError:
        print('Error in reading: {0}'.format(filename))
        exit()
    model.close()

    modelStartLines = []
    count = 0

    for thisLine in lines:
        theseWords = thisLine.split()
        if len(theseWords) is not 0:
            if theseWords[0][-3:] == 'EFF':
                # Note: several of the ATLAS model files are missing the first
                # character of each line, so some files have a first model line
                # starting with "TEFF", while others have "EFF"
                modelStartLines.append(count)
        count += 1

    tableDict = {}
    pradkValue = {}

    for startLineNo in modelStartLines:
        Tstr = lines[startLineNo].split()[1]
        Gstr = lines[startLineNo].split()[3]
        Mstr = lines[startLineNo + 1].split()[3].strip('[]')
        # Special case:
        if Mstr == 'SOLAR': Mstr = '0.0'
        Vstr = lines[startLineNo + 1].split()[5]
        # Special case:
        if Vstr == 'WITH': Vstr = '1.5'
        TabLenstr = lines[startLineNo + 22].split()[2]
        # Our table lengths need to be the same... otherwise, matrix
        # interpolation isn't gonna work! For now, we just toss short/long
        # files. In the future, it might be better to try to convert them
        # to the same length.
        if not (u.is_number(Tstr) and u.is_number(Gstr) and u.is_number(Mstr)
                and u.is_number(Vstr) and u.is_number(TabLenstr)):
            continue
        if int(TabLenstr) != 72: continue
        if len(lines[startLineNo + 24].split()) == 7:
            # Some ATLAS models omit the last two columns when they are all zeroes
            tableDict[(float(Tstr), float(Gstr))] = [
                [float(t) for t in s.split()] + [0., 0.]
                for s in lines[startLineNo + 23:startLineNo + 23 +
                               int(TabLenstr)]
            ]
        else:
            tableDict[(float(Tstr), float(Gstr))] = [[
                float(t) for t in s.split()
            ] for s in lines[startLineNo + 23:startLineNo + 23 +
                             int(TabLenstr)]]
        pradkValue[(float(Tstr), float(Gstr))] = float(
            lines[startLineNo + 23 + int(TabLenstr)].split()[1])

    theKeys = tableDict.keys()
    # Just re-use the met. & vel. values read from the final table
    met = float(Mstr)
    vel = float(Vstr)

    return met, vel, tableDict, pradkValue
Exemplo n.º 6
0
def PlotFeXx(clusterName='NGC-0752', starDataList=None, fileTag='', groupErrors=False,\
             ionList=STP.kAllIonList, filterBlends=False, referenceCorrect=False):


    # abTable = {starID:element/ion:[X/H, sigma, #, quality score]}
    abTable=STP.GetAbTable(clusterName=clusterName, starDataList=starDataList,\
             ions=ionList, filterBlends=filterBlends, referenceCorrect=referenceCorrect)

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

    for ion in ionList:
        Xs = []
        Ys = []
        XErrs = []
        YErrs = []
        colors = []
        allPts = []
        SolarY = float(PA.ptoe[int(ion)-1][PA.abIdx])
        for star in abTable.keys():
            starAbs = abTable[star]
            starFe = float(STP.GetStarFeH(starAbs))
            if ion in starAbs.keys():
                if not(u.is_number(starAbs[ion][0]) and \
                    u.is_number(starAbs[26.0][1]) and \
                    u.is_number(starAbs[ion][1])):
                    continue
                adj = SolarY
                if ion != 26.0:
                    adj+=starFe
                allPts.append([float(starFe), float(starAbs[ion][0])-adj, float(starAbs[26.0][1]), float(starAbs[ion][1]), ColorLookup(star)])
                
        yElem = EL.getIonName(ion)
        fig = pyplot.figure()
        axes = fig.gca()
        allPts = np.array(allPts)
#        allPts = np.array(zip(Xs, Ys, XErrs, YErrs, colors))

        gAbs = np.array([p[1] for p in allPts if p[4]=='r']).astype(np.float)
        gAvg = np.mean(gAbs)
        gStd = np.std(gAbs)
        gFeAbs = np.array([p[0] for p in allPts if p[4]=='r']).astype(np.float)
        gFeAvg = np.mean(gFeAbs)
        gFeStd = np.std(gFeAbs)
        dAbs = np.array([p[1] for p in allPts if p[4]=='b']).astype(np.float)
        dAvg = np.mean(dAbs)
        dStd = np.std(dAbs)
        dFeAbs = np.array([p[0] for p in allPts if p[4]=='b']).astype(np.float)
        dFeAvg = np.mean(dFeAbs)
        dFeStd = np.std(dFeAbs)
        
        axes.axhline(y=gAvg, ls='dashed', color='r', 
             label=r'Giant Avg. (${0:4.2f}\pm{1:4.2f}$)'.\
                     format(gAvg,gStd))
        axes.axhline(y=gAvg+gStd, ls='dotted', color='r')
        axes.axhline(y=gAvg-gStd, ls='dotted', color='r')
        
        axes.axhline(y=dAvg, ls='dashed', color='b', 
             label=r'Dwarf Avg. (${0:4.2f}\pm{1:4.2f}$)'.\
                     format(dAvg,dStd))
        axes.axhline(y=dAvg+dStd, ls='dotted', color='b')
        axes.axhline(y=dAvg-dStd, ls='dotted', color='b')

#        axes.axhline(y=SolarY, ls='dashed', color='g', 
#             label=r'Solar ({0:4.2f})'.format(SolarY))
        axes.axhline(y=0., ls='dashed', color='g', 
             label=r'Solar ({0:4.2f})'.format(SolarY))
        Xs = np.array(allPts[:,0]).astype(np.float)
        XErrs = np.array(allPts[:,2]).astype(np.float)
        xMin = max(np.median(Xs)-0.3, min(Xs)-0.1)
        xMax = min(np.median(Xs)+0.3, max(Xs)+0.1)
        axes.set_xlim(xMin, xMax)
        Ys = np.array(allPts[:,1]).astype(np.float)
        YErrs = np.array(allPts[:,3]).astype(np.float)
        yMin = min(np.median(Ys)-0.3, min(Ys))
        yMax = max(np.median(Ys)+0.3, max(Ys))
        axes.set_ylim(yMin, yMax)
        axes.set_xlabel('[Fe/H]', fontsize=18)
        if ion != 26.0:
            axes.set_ylabel('['+yElem+'/Fe]', fontsize=18)
        else:
            axes.set_ylabel('['+yElem+'/H]', fontsize=18)
        
        if groupErrors:
            axes.scatter(gFeAbs, gAbs, marker='o', color='r')
            eb = axes.errorbar(gFeAvg, gAvg, xerr=gFeStd,\
                linestyle='None', markersize=12.,  marker='H', color='r', ecolor='r', \
                label='Giant Mean', capsize=10., elinewidth=2, markerfacecolor='None')
            eb[-1][0].set_linestyle('--')
#            eb[-1][1].set_linestyle('--')
            eb[-1][0].set_linewidth(2.)
#            eb[-1][1].set_linewidth(2.)
            axes.scatter(dFeAbs, dAbs, marker='o', color='b')
            eb = axes.errorbar(dFeAvg, dAvg, xerr=dFeStd,\
                linestyle='None', markersize=12., marker='H', color='b', ecolor='b', \
                label='Dwarf Mean', capsize=10., elinewidth=2, markerfacecolor='None')
            eb[-1][0].set_linestyle('--')
#            eb[-1][1].set_linestyle('--')
            eb[-1][0].set_linewidth(2.)
#            eb[-1][1].set_linewidth(2.)
        else:
            eb = axes.errorbar(Xs, Ys, yerr=YErrs, xerr=XErrs,\
                linestyle='None', marker='o', ecolor=allPts[:,4])
            eb[-1][0].set_linestyle(':')
            eb[-1][1].set_linestyle(':')
            eb[-1][0].set_linewidth(0.5)
            eb[-1][1].set_linewidth(0.5)

        axes.legend()
        pyplot.savefig(dirs.RelAbsDir+'Fe_'+yElem+fileTag+'.png')
        pyplot.close()
Exemplo n.º 7
0
def evaluateParams(FeILines, FeIILines, TiILines, TiIILines):
    # The evaluation score is the product of the p-values for matching
    # I and II ionization state abundances, and having a slope of 0.0
    # (ie: no correlation between) excitation potential and measured 
    # abundance for a given line.
    #
    # Note that we are being VERY loose with our definition of "probabilities"
    # Specifically, we are using the P-score of the linear regression and of
    # the T-Test as a probability. This is technically incorrect, as the 
    # P-score should really only be used for rejection of a null hypothesis 
    # that the abundance vs. excitation potential slope is zero, or that the
    # two populations have the same mean.
    # Since we are really only interested in getting a relative scoring for the
    # quality of the linear fit to a zero slope, and the quality of the match
    # of the abundances of the two population, the use of a P-score as a 
    # scoring mechanism is valid.
    if len(FeILines) < k.MinNumStatLines:
        print('Warning: Only {0:2d} FeI Lines!'.format(len(FeILines)))
        # If the number is _really_ small, we realistically can't do anything...
        if len(FeILines) <  k.MinNumStatLines/5 or not u.is_list(FeILines): return 0., 0.

    FeIExPotList = np.array(FeILines)[:,1].tolist()
    FeIAbList = np.array(FeILines)[:,5].tolist()
    FeSlope, intercept, r_value, FeP_value, stderr = stats.linregress(FeIExPotList,FeIAbList)

    if len(FeIILines) < k.MinNumStatLines/2:
    # Not enough FeII lines, so we have to assume that the Fe I abundance is definitive
        FeAbTProb = k.BadProbability
    else:
        FeIIAbList = np.array(FeIILines)[:,5].tolist()
        FeAbTScore, FeAbTProb = stats.ttest_ind(FeIAbList, FeIIAbList)

    if len(TiILines) < k.MinNumStatLines/2:
    # Not enough TiI lines, so we will just use the Fe I line slope
        TiP_value = k.BadProbability
        TiAbTProb = k.BadProbability
    else:
        TiIExPotList = np.array(TiILines)[:,1].tolist()
        TiIAbList = np.array(TiILines)[:,5].tolist()
        TiSlope, intercept, r_value, TiP_value, stderr = stats.linregress(TiIExPotList,TiIAbList)

        if len(TiIILines) < k.MinNumStatLines/4:
        # Not enough TiII lines, so we will just use the Fe I/II comparison
            TiAbTProb = k.BadProbability
        else:
            TiIIAbList = np.array(TiIILines)[:,5].tolist()
            TiAbTScore, TiAbTProb = stats.ttest_ind(TiIAbList, TiIIAbList)
        
        if not u.is_number(TiAbTProb):
            TiAbTProb = k.BadProbability

    # Returns slope probability, ionization balance probability
    # Note that python floating point calculations should treat
    # any value of around 10**-16 as zero, so we force calculations
    # with values of < 10**-14 to 0.0
    # Testing with Fe Only:
#    slopeProb = FeP_value*TiP_value
    slopeProb = FeP_value
    if slopeProb < k.BadProbability/100.:
        slopeProb = 0.
    # I'm not sure I like using the Ti I/I abundance balance (NLTE effects?)
    # Weight Fe by 2x over Ti:
    balanceProb = (FeAbTProb**2*TiAbTProb)**(1./3.)
#    balanceProb = np.sqrt(FeAbTProb*TiAbTProb)
#    balanceProb = FeAbTProb
    if balanceProb < k.BadProbability/100.:
        balanceProb = 0.
    return slopeProb, balanceProb