Ejemplo n.º 1
0
def main():

    progname = 'find_dist_pbdot_mc.py'
    args = get_opt(progname)
    
    ra_deg = 360.0 * (args.ra[0] + args.ra[1]/60. + args.ra[2]/3600.)/24.0
    if(args.raerr != None):
        raerr = (args.raerr/3600.)*360./24.0  # Convert to degrees
        raerr_str = ' +/- '+str(raerr)
    else:
        raerr_str = ''    

    if(args.dec[0] < 0):
        sgn = -1.
    else:
        sgn = 1.
    dec_deg =  sgn * (np.abs(args.dec[0]) + args.dec[1]/60. + args.dec[2]/3600.)
    if(args.decerr != None):
        decerr = args.decerr/3600.   # Convert to degrees
        decerr_str = ' +/- '+ str(decerr)
    else:
        decerr_str = ''
        
    print 'RA   = ', ra_deg,  raerr_str, ' deg  '
    print 'Dec  = ', dec_deg, decerr_str, ' deg  '
    # Convert nominal values of ra and dec to l and b here just for show
    c = coord.ICRSCoordinates(ra=ra_deg, dec=dec_deg, unit=(u.degree, u.degree))
    l = c.galactic.l.degrees
    b = c.galactic.b.degrees
    print 'l    = ', c.galactic.l.degrees, ' deg   =  ', c.galactic.l.radians, ' rad'
    print 'b    = ', c.galactic.b.degrees, ' deg   =  ', c.galactic.b.radians, ' rad'

    if(args.xpbdoterr != None):
        xpbdoterr = ' +/- '+str(args.xpbdoterr)
    else:
        xpbdoterr = ''    
    print 'Xpbdot = ', args.xpbdot,  xpbdoterr
    if(args.pmerr != None):
        pmerr = ' +/- '+str(args.pmerr)
    else:
        pmerr = ''        
    print 'PM   = ', args.pm, pmerr, ' mas/yr'
    
    # convert pb to seconds
    args.pb = u.day.to(u.s, args.pb)
    
    # convert velocity/ velocity error to kpc/s
    # No need to convert R0, which is already in R0
    args.v0 = u.km.to(u.kpc, args.v0)
    args.v0err = u.km.to(u.kpc, args.v0err)

    # convert pm to rad/s
    args.pm = (u.mas.to(u.radian, args.pm)) / u.year.to(u.s, 1.0)
    if(args.pmerr != None):
        args.pmerr = (u.mas.to(u.radian, args.pmerr)) / u.year.to(u.s, 1.0)

    

    # Check whether all error bars required are given for distance and proper
    # motion.  If they are, go ahead with the random number generation thing.
    # If not, just do a quick straight calculation of the pbdot correction.
    
    if((args.pmerr != None) & (args.xpbdoterr != None) & (args.raerr != None) & (args.decerr != None)):
        
        # For each of the varying parameters (dist, pm, v0, R0), generate
        # args.niter gaussian deviates, with mean = value and sigma = error
        xpbdot = np.random.normal(args.xpbdot, args.xpbdoterr, args.niter)
        pm   = np.random.normal(args.pm, args.pmerr, args.niter)
        v0   = np.random.normal(args.v0, args.v0err, args.niter)
        R0   = np.random.normal(args.R0, args.R0err, args.niter)
        ra   = np.random.normal(ra_deg, raerr, args.niter)
        dec  = np.random.normal(dec_deg, decerr, args.niter)

        # Plot distributions for each parameter:
        fig_param = plt.figure()
        # xpbdot
        ax_param = fig_param.add_subplot(321)
        hist, bin_val = np.histogram(xpbdot, bins=32)
        bin_size = (bin_val[1]-bin_val[0])
        bin_val = bin_val[0:len(bin_val)-1] + bin_size/2.
        ax_param.plot(bin_val, hist, linestyle='steps-mid', linewidth=1.4, 
                    color='blue')
        A, mu, sig = utils.fitgauss(bin_val, hist)
        #ax_param.plot(bin_val, utils.gaussian(bin_val, A, mu, sig), color='red')
        ax_param.set_xlabel('Difference in orbital decay ($10^{14}$ s/s)')
        
        # proper motion
        ax_param = fig_param.add_subplot(322)
        hist, bin_val = np.histogram(pm, bins=32)
        bin_size = (bin_val[1]-bin_val[0])
        bin_val = bin_val[0:len(bin_val)-1] + bin_size/2.
        ax_param.plot(bin_val, hist, linestyle='steps-mid', linewidth=1.4, 
                    color='blue')
        ax_param.set_xlabel('Proper motion (mas/yr)')
        
        # v0
        ax_param = fig_param.add_subplot(323)
        hist, bin_val = np.histogram(v0, bins=32)
        bin_size = (bin_val[1]-bin_val[0])
        bin_val = bin_val[0:len(bin_val)-1] + bin_size/2.
        ax_param.plot(bin_val, hist, linestyle='steps-mid', linewidth=1.4, 
                    color='blue')
        ax_param.set_xlabel('Solar velocity (km/s)')
        
        # R0
        ax_param = fig_param.add_subplot(324)
        hist, bin_val = np.histogram(R0, bins=32)
        bin_size = (bin_val[1]-bin_val[0])
        bin_val = bin_val[0:len(bin_val)-1] + bin_size/2.
        ax_param.plot(bin_val, hist, linestyle='steps-mid', linewidth=1.4, 
                    color='blue')
        ax_param.set_xlabel('Galactocentric distance (kpc)')
        
        # RA
        ax_param = fig_param.add_subplot(325)
        hist, bin_val = np.histogram(ra, bins=32)
        bin_size = (bin_val[1]-bin_val[0])
        bin_val = bin_val[0:len(bin_val)-1] + bin_size/2.
        ax_param.plot(bin_val, hist, linestyle='steps-mid', linewidth=1.4, 
                    color='blue')
        ax_param.set_xlabel('Right ascension (deg)')

        # Dec
        ax_param = fig_param.add_subplot(326)
        hist, bin_val = np.histogram(dec, bins=32)
        bin_size = (bin_val[1]-bin_val[0])
        bin_val = bin_val[0:len(bin_val)-1] + bin_size/2.
        ax_param.plot(bin_val, hist, linestyle='steps-mid', linewidth=1.4, 
                    color='blue')
        ax_param.set_xlabel('Declination (deg)')
 
        plt.show()
        
        
        # Run calcuation of pbdot correction through each iteration and build 
        # up array of values for pbdot correction
        #for i_iter in np.arange(args.niter):
        sys.stdout.write('\n {0:<7s}  {1:<7s}    {2:5s}   {3:<10s}\n'.format('Iter', '% done', 'n_bad', 'n_negative'))
        dist_array = []
        n_bad = 0
        n_negative = 0
        n_step_worked = 0
        for i_iter in np.arange(args.niter):
            c = coord.ICRSCoordinates(ra=ra[i_iter], dec=dec[i_iter], unit=(u.degree, u.degree))
            l = c.galactic.l.radians
            b = c.galactic.b.radians
            n_tries = 0
            sgn_guess = 1.0
            dist_guess = args.distguess
            dist_trial = -1.0
            try:
               # while(dist_trial < 0.001 and n_tries <= 25):             
               dist_trial = newton(pc.dist_func, dist_guess, 
                                    args=(l, b, 
                                    v0[i_iter], R0[i_iter], 
                                    pm[i_iter], args.pb, 
                                    xpbdot[i_iter]))
            #         n_tries += 1
            #        sgn_guess *= -1.0
            #        dist_guess = args.distguess + sgn_guess*np.ceil(float(n_tries)/2.0)*args.stepguess
                    
            except RuntimeError:
                n_bad+=1
            else:  # If there are no errors, then append to array
#                if(dist_trial > 0.000001 and n_tries <= 25):
                if(dist_trial > 0.001):
                    dist_array.append(dist_trial)
                #    if(n_tries > 1):
                #        n_step_worked += 1
                else:
                    n_negative += 1
                
            
#            dist_array.append(pc.get_dist_pbdot(ra[i_iter], dec[i_iter], 
#                                    pm[i_iter], xpbdot[i_iter],
#                                    args.pb,
#                                    v0=v0[i_iter],
#                                    R0=R0[i_iter],
#                                    dist_guess=args.distguess))
            if(np.fmod(i_iter, 16)==0):
                display_status(i_iter, args.niter, n_bad, n_negative)
                
        dist_array = np.array(dist_array)
        print '\nNumber of Runtime Errors = ', n_bad
        print 'Number of times stepping guess value worked = ', n_step_worked
        # Create histogram of pbdot correction, and fit a gsaussian to it.
        # Extract median (mean?) and sigma as our final value and error.
        if(args.distlim == None):
            distlim = (np.amin(dist_array)-0.1*np.abs(np.amin(dist_array)), 
                       np.amax(dist_array)+0.1*np.abs(np.amax(dist_array)))
        else:
            distlim = (args.distlim[0], args.distlim[1])
           
        dist_pdf, bin_val = np.histogram(dist_array, 
                      range=distlim, bins=96, density=True)
        bin_size = bin_val[1]-bin_val[0]
        dist_x = bin_val[0:len(bin_val)-1] + 0.5*bin_size
        #fig_pbdot = plt.figure()
        #ax_pbdot = fig_pbdot.add_axes([0.12, 0.1, 0.8, 0.85])
        #ax_pbdot.plot(pbdot_x, pbdot_pdf, linestyle='steps-mid', linewidth=1.4, 
        #            color='blue')
        
        # Get upper limit from distance distribution
#        dist_med, dist_min, dist_max = \
        dist_upper = get_pdf_prob(dist_x, dist_pdf, prob_intervals, 
                        norm=True, upper=True) #, \
        plot_pdf(dist_x, dist_pdf, \
###                     weights=alpha_weights, \
             xlabel='Distance (kpc)', \
             ylabel='Probability density',\
             prob_lines=dist_upper,\
#             prob_lines=np.append(dist_min, dist_max),\
             prob_linestyle=['dashed','dashdot','dotted'] #, \
                #                 'dashed','dashdot','dotted'], \
             )
             
        print " "
        print "DISTANCE (kpc): "
        print "  68%: < ", dist_upper[0]
        print "  95%: < ", dist_upper[1]
        print "  99%: < ", dist_upper[2]
        print " "
        
             
#        plt.axvline(dist_med)
#        dist_err_high = np.abs(dist_max-dist_med)
#        dist_err_low  = np.abs(dist_min-dist_med)
        
        #A, pbdot_corr, pbdot_corr_err = utils.fitgauss(pbdot_x, pbdot_pdf)
        #ax_pbdot.plot(pbdot_x, utils.gaussian(pbdot_x, A, pbdot_corr, pbdot_corr_err), 
                    #linestyle='solid', linewidth=1.4, color='red')
        plt.savefig('dist_pbdot.pdf')
        
        #print 'Corrected Pbdot = ', pbdot_corr, ' +/- ', pbdot_corr_err
#        print 'Distance (kpc) = ', dist_med, ' -', dist_err_low[0], \
#                                            ' +', dist_err_high[0]
#        print 'Distance peak = ', dist_x[np.argmax(dist_pdf)]
        
#        pbdot_new = args.pbdot + pbdot_corr_med
        #pbdot_corr_err_mean = np.mean(np.array([pbdot_corr_err_low[0],pbdot_corr_err_high[0]]))
        #pbdot_new_err = np.sqrt(args.pbdoterr**2.0 + pbdot_corr_err_mean**2.0)
#        pbdot_new_err_low = np.sqrt(args.pbdoterr**2.0 + pbdot_corr_err_low**2.0)
#        pbdot_new_err_high = np.sqrt(args.pbdoterr**2.0 + pbdot_corr_err_high**2.0)
        # print 'Pbdot new (median and mean error) = ', pbdot_new, ' +/- ', pbdot_new_err
        # print 'Pbdot new range (68%) = ', pbdot_corr_min[0], ' , ', pbdot_corr_max[0]
#        pbdot_new_mid = np.mean(np.array([pbdot_new - pbdot_new_err_low[0], pbdot_new + pbdot_new_err_high[0]]))
#        print 'Pbdot new (using midpoint between ranges) = ', pbdot_new_mid, ' - ', pbdot_new_mid - (pbdot_new-pbdot_new_err_low[0]), '   + ', (pbdot_new+pbdot_new_err_high[0])-pbdot_new_mid 
#        print 'Pbdot new (median corr and asymmetric error)   = ', pbdot_new, ' - ', pbdot_new_err_low[0], '   + ', pbdot_new_err_high[0]
        
    else:

        c = coord.ICRSCoordinates(ra=ra_deg, dec=dec_deg, 
                                unit=(u.degree, u.degree))
        l = c.galactic.l.radians
        b = c.galactic.b.radians
        
        dist_pbdot = newton(pc.dist_func, args.distguess, 
                                        args=(l, b, args.v0, args.R0, 
                                              args.pm, args.pb, args.xpbdot))
            
        #pbdot_new = args.pbdot - pbdot_corr
        
        print '\nWill not calculate final uncertainties...\n'
        print 'Distance (kpc) = ', dist_pbdot
        
        return
Ejemplo n.º 2
0
def main():

    progname = "find_pbdot_corr_mc.py"
    args = get_opt(progname)

    ra_deg = 360.0 * (args.ra[0] + args.ra[1] / 60.0 + args.ra[2] / 3600.0) / 24.0
    if args.raerr != None:
        raerr = (args.raerr / 3600.0) * 360.0 / 24.0  # Convert to degrees
        raerr_str = " +/- " + str(raerr)
    else:
        raerr_str = ""

    if args.dec[0] < 0:
        sgn = -1.0
    else:
        sgn = 1.0
    dec_deg = sgn * (np.abs(args.dec[0]) + args.dec[1] / 60.0 + args.dec[2] / 3600.0)
    if args.decerr != None:
        decerr = args.decerr / 3600.0  # Convert to degrees
        decerr_str = " +/- " + str(decerr)
    else:
        decerr_str = ""

    print "RA   = ", ra_deg, raerr_str, " deg  "
    print "Dec  = ", dec_deg, decerr_str, " deg  "
    # Convert nominal values of ra and dec to l and b here just for show
    c = coord.ICRSCoordinates(ra=ra_deg, dec=dec_deg, unit=(u.degree, u.degree))
    l = c.galactic.l.degrees
    b = c.galactic.b.degrees
    print "l    = ", l, " deg"
    print "b    = ", b, " deg"

    if args.disterr != None:
        derr = " +/- " + str(args.disterr)
    else:
        derr = ""
    print "dist = ", args.dist, derr, " kpc"
    if args.pmerr != None:
        pmerr = " +/- " + str(args.pmerr)
    else:
        pmerr = ""
    print "PM   = ", args.pm, pmerr, " mas/yr"

    print "Pbdot = ", args.pbdot
    if args.pbdoterr != None:
        print "Pbdot error = ", args.pbdoterr

    # convert pb to seconds
    args.pb = u.day.to(u.s, args.pb)

    # Check whether all error bars required are given for distance and proper
    # motion.  If they are, go ahead with the random number generation thing.
    # If not, just do a quick straight calculation of the pbdot correction.

    if (
        (args.disterr != None)
        & (args.pmerr != None)
        & (args.pbdoterr != None)
        & (args.raerr != None)
        & (args.decerr != None)
    ):

        # For each of the varying parameters (dist, pm, v0, R0), generate
        # args.niter gaussian deviates, with mean = value and sigma = error
        dist = np.random.normal(args.dist, args.disterr, args.niter)
        pm = np.random.normal(args.pm, args.pmerr, args.niter)
        v0 = np.random.normal(args.v0, args.v0err, args.niter)
        R0 = np.random.normal(args.R0, args.R0err, args.niter)
        ra = np.random.normal(ra_deg, raerr, args.niter)
        dec = np.random.normal(dec_deg, decerr, args.niter)

        # Plot distributions for each parameter:
        fig_param = plt.figure()
        # distance
        ax_param = fig_param.add_subplot(321)
        hist, bin_val = np.histogram(dist, bins=32)
        bin_size = bin_val[1] - bin_val[0]
        bin_val = bin_val[0 : len(bin_val) - 1] + bin_size / 2.0
        ax_param.plot(bin_val, hist, linestyle="steps-mid", linewidth=1.4, color="blue")
        A, mu, sig = utils.fitgauss(bin_val, hist)
        # ax_param.plot(bin_val, utils.gaussian(bin_val, A, mu, sig), color='red')
        ax_param.set_xlabel("Distance (kpc)")

        # proper motion
        ax_param = fig_param.add_subplot(322)
        hist, bin_val = np.histogram(pm, bins=32)
        bin_size = bin_val[1] - bin_val[0]
        bin_val = bin_val[0 : len(bin_val) - 1] + bin_size / 2.0
        ax_param.plot(bin_val, hist, linestyle="steps-mid", linewidth=1.4, color="blue")
        ax_param.set_xlabel("Proper motion (mas/yr)")

        # v0
        ax_param = fig_param.add_subplot(323)
        hist, bin_val = np.histogram(v0, bins=32)
        bin_size = bin_val[1] - bin_val[0]
        bin_val = bin_val[0 : len(bin_val) - 1] + bin_size / 2.0
        ax_param.plot(bin_val, hist, linestyle="steps-mid", linewidth=1.4, color="blue")
        ax_param.set_xlabel("Solar velocity (km/s)")
        # R0
        ax_param = fig_param.add_subplot(324)
        hist, bin_val = np.histogram(R0, bins=32)
        bin_size = bin_val[1] - bin_val[0]
        bin_val = bin_val[0 : len(bin_val) - 1] + bin_size / 2.0
        ax_param.plot(bin_val, hist, linestyle="steps-mid", linewidth=1.4, color="blue")
        ax_param.set_xlabel("Galactocentric distance (kpc)")

        # RA
        ax_param = fig_param.add_subplot(325)
        hist, bin_val = np.histogram(ra, bins=32)
        bin_size = bin_val[1] - bin_val[0]
        bin_val = bin_val[0 : len(bin_val) - 1] + bin_size / 2.0
        ax_param.plot(bin_val, hist, linestyle="steps-mid", linewidth=1.4, color="blue")
        ax_param.set_xlabel("Right ascension (deg)")

        # Dec
        ax_param = fig_param.add_subplot(326)
        hist, bin_val = np.histogram(dec, bins=32)
        bin_size = bin_val[1] - bin_val[0]
        bin_val = bin_val[0 : len(bin_val) - 1] + bin_size / 2.0
        ax_param.plot(bin_val, hist, linestyle="steps-mid", linewidth=1.4, color="blue")
        ax_param.set_xlabel("Declination (deg)")

        plt.show()

        # Run calcuation of pbdot correction through each iteration and build
        # up array of values for pbdot correction
        # for i_iter in np.arange(args.niter):
        sys.stdout.write("\n {0:<7s}  {1:<7s} \n".format("Iter", "% done"))
        pbdot_corr_array = []
        for i_iter in np.arange(args.niter):
            pbdot_corr_array.append(
                pc.get_pbdot_corr(
                    ra[i_iter], dec[i_iter], pm[i_iter], dist[i_iter], args.pb, v0=v0[i_iter], R0=R0[i_iter]
                )
            )
            if np.fmod(i_iter, 16) == 0:
                display_status(i_iter, args.niter)

        pbdot_corr_array = np.array(pbdot_corr_array)

        # Create histogram of pbdot correction, and fit a gsaussian to it.
        # Extract median (mean?) and sigma as our final value and error.
        if args.corrlim == None:
            corrlim = (
                np.amin(pbdot_corr_array) - 0.1 * np.abs(np.amin(pbdot_corr_array)),
                np.amax(pbdot_corr_array) + 0.1 * np.abs(np.amax(pbdot_corr_array)),
            )
        else:
            corrlim = (args.corrlim[0] * 10.0 ** (-12), args.corrlim[1] * 10 ** (-12))

        pbdot_pdf, bin_val = np.histogram(pbdot_corr_array, range=corrlim, bins=192, density=True)
        bin_size = bin_val[1] - bin_val[0]
        pbdot_x = bin_val[0 : len(bin_val) - 1] + 0.5 * bin_size
        # fig_pbdot = plt.figure()
        # ax_pbdot = fig_pbdot.add_axes([0.12, 0.1, 0.8, 0.85])
        # ax_pbdot.plot(pbdot_x, pbdot_pdf, linestyle='steps-mid', linewidth=1.4,
        #            color='blue')

        pbdot_corr_med, pbdot_corr_min, pbdot_corr_max = get_pdf_prob(
            pbdot_x, pbdot_pdf, prob_intervals, norm=True
        )  # , \
        plot_pdf(
            pbdot_x,
            pbdot_pdf,
            ###                     weights=alpha_weights, \
            xlabel="$\\dot{P}_{b, corr}}$",
            ylabel="Probability density",
            prob_lines=np.append(pbdot_corr_min, pbdot_corr_max),
            prob_linestyle=["dashed", "dashdot", "dotted", "dashed", "dashdot", "dotted"],
        )
        plt.axvline(pbdot_corr_med)
        pbdot_corr_err_high = np.abs(pbdot_corr_max - pbdot_corr_med)
        pbdot_corr_err_low = np.abs(pbdot_corr_min - pbdot_corr_med)

        # A, pbdot_corr, pbdot_corr_err = utils.fitgauss(pbdot_x, pbdot_pdf)
        # ax_pbdot.plot(pbdot_x, utils.gaussian(pbdot_x, A, pbdot_corr, pbdot_corr_err),
        # linestyle='solid', linewidth=1.4, color='red')
        plt.savefig("pbdot_new.png")

        print ""
        print "Original Pbdot = ", args.pbdot
        print ""
        # print 'Corrected Pbdot = ', pbdot_corr, ' +/- ', pbdot_corr_err
        print "Pbdot correction = ", pbdot_corr_med, " +", pbdot_corr_err_high[0], " -", pbdot_corr_err_low[0]
        print "Pbdot correction peak = ", pbdot_x[np.argmax(pbdot_pdf)]

        pbdot_new = args.pbdot - pbdot_corr_med
        # pbdot_corr_err_mean = np.mean(np.array([pbdot_corr_err_low[0],pbdot_corr_err_high[0]]))
        # pbdot_new_err = np.sqrt(args.pbdoterr**2.0 + pbdot_corr_err_mean**2.0)
        pbdot_new_err_low = np.sqrt(args.pbdoterr ** 2.0 + pbdot_corr_err_low ** 2.0)
        pbdot_new_err_high = np.sqrt(args.pbdoterr ** 2.0 + pbdot_corr_err_high ** 2.0)
        # print 'Pbdot new (median and mean error) = ', pbdot_new, ' +/- ', pbdot_new_err
        # print 'Pbdot new range (68%) = ', pbdot_corr_min[0], ' , ', pbdot_corr_max[0]
        pbdot_new_mid = np.mean(np.array([pbdot_new - pbdot_new_err_low[0], pbdot_new + pbdot_new_err_high[0]]))
        print "Pbdot new (using midpoint between ranges) = ", pbdot_new_mid, " - ", pbdot_new_mid - (
            pbdot_new - pbdot_new_err_low[0]
        ), "   + ", (pbdot_new + pbdot_new_err_high[0]) - pbdot_new_mid
        print "Pbdot new (median corr and asymmetric error)   = ", pbdot_new, " - ", pbdot_new_err_low[
            0
        ], "   + ", pbdot_new_err_high[0]

    else:

        pbdot_corr = pc.get_pbdot_corr(
            args.ra, args.dec, args.pm, args.dist, args.pb, v0=args.v0, R0=args.R0, verbose=True
        )

        pbdot_new = args.pbdot - pbdot_corr

        print "\nWill not calculate final uncertainties...\n"
        print "Original Pbdot = ", args.pbdot
        print "Corrected Pbdot = ", pbdot_new

        return