Example #1
0
def test_lb_to_radec():
    ra, dec= 120, 60.
    lb= bovy_coords.radec_to_lb(ra,dec,degree=True,epoch=2000.)
    rat, dect= bovy_coords.lb_to_radec(lb[0],lb[1],degree=True,epoch=2000.)
    assert numpy.fabs(ra-rat) < 10.**-10., 'lb_to_radec is not the inverse of radec_to_lb'
    assert numpy.fabs(dec-dect) < 10.**-10., 'lb_to_radec is not the inverse of radec_to_lb'
    # Also test this for degree=False
    lb= bovy_coords.radec_to_lb(ra/180.*numpy.pi,dec/180.*numpy.pi,
                                degree=False,epoch=2000.)
    rat, dect= bovy_coords.lb_to_radec(lb[0],lb[1],degree=False,epoch=2000.)
    assert numpy.fabs(ra/180.*numpy.pi-rat) < 10.**-10., 'lb_to_radec is not the inverse of radec_to_lb'
    assert numpy.fabs(dec/180.*numpy.pi-dect) < 10.**-10., 'lb_to_radec is not the inverse of radec_to_lb'
    # And also test this for arrays
    os= numpy.ones(2)
    lb= bovy_coords.radec_to_lb(os*ra/180.*numpy.pi,os*dec/180.*numpy.pi,
                                degree=False,epoch=2000.)
    ratdect= bovy_coords.lb_to_radec(lb[:,0],lb[:,1],degree=False,epoch=2000.)
    rat= ratdect[:,0]
    dect= ratdect[:,1]
    assert numpy.all(numpy.fabs(ra/180.*numpy.pi-rat) < 10.**-10.), 'lb_to_radec is not the inverse of radec_to_lb'
    assert numpy.all(numpy.fabs(dec/180.*numpy.pi-dect) < 10.**-10.), 'lb_to_radec is not the inverse of radec_to_lb'   
    #Also test for a negative l
    l,b= 240., 60.
    ra,dec= bovy_coords.lb_to_radec(l,b,degree=True)
    lt,bt= bovy_coords.radec_to_lb(ra,dec,degree=True)
    assert numpy.fabs(lt-l) < 10.**-10., 'lb_to_radec is not the inverse of radec_to_lb'   
    assert numpy.fabs(bt-b) < 10.**-10., 'lb_to_radec is not the inverse of radec_to_lb'   
    return None
Example #2
0
def process_mock_densdata(options):
    print ("Using mock Pal 5 data from %s" % options.mockfilename)
    # Read and prep data for mocks
    xvid = numpy.loadtxt(options.mockfilename)
    xv = xvid[:, :6]
    xv = xv[numpy.argsort(xvid[:, 6])]
    XYZ = bovy_coords.galcenrect_to_XYZ(xv[:, 0], xv[:, 1], xv[:, 2], Xsun=R0, Zsun=0.025)
    lbd = bovy_coords.XYZ_to_lbd(XYZ[0], XYZ[1], XYZ[2], degree=True)
    radec = bovy_coords.lb_to_radec(lbd[:, 0], lbd[:, 1], degree=True)
    xieta = pal5_util.radec_to_pal5xieta(radec[:, 0], radec[:, 1], degree=True)
    # make sure the progenitor is at (0,0)
    xieta[:, 0] -= numpy.median(xieta[:, 0])
    xieta[:, 1] -= numpy.median(xieta[:, 1])
    h, e = numpy.histogram(xieta[:, 0], range=[0.2, 14.3], bins=141)
    xdata = numpy.arange(0.25, 14.35, 0.1)
    # Compute power spectrum
    tdata = h - 0.0
    pp = Polynomial.fit(xdata, tdata, deg=options.polydeg, w=1.0 / numpy.sqrt(h + 1.0))
    tdata /= pp(xdata)
    ll = xdata
    py = signal.csd(tdata, tdata, fs=1.0 / (ll[1] - ll[0]), scaling="spectrum", nperseg=len(ll))[1]
    py = py.real
    # Also compute the bispectrum
    Bspec, Bpx = bispectrum.bispectrum(numpy.vstack((tdata, tdata)).T, nfft=len(tdata), wind=7, nsamp=1, overlap=0)
    ppyr = numpy.fabs(Bspec[len(Bspec) // 2 + _BISPECIND, len(Bspec) // 2 :].real)
    ppyi = numpy.fabs(Bspec[len(Bspec) // 2 + _BISPECIND, len(Bspec) // 2 :].imag)
    return (numpy.sqrt(py * (ll[-1] - ll[0])), numpy.sqrt(h + 1.0) / pp(xdata), ppyr, ppyi)
def vdisp_trailing(sdf) -> float:
    """Return the velocity dispersion in km/s for the trailing tail.

    Parameters
    ----------
    sdf: streamdf

    Returns
    -------
    vdisp: float
        the width of the stream

    """
    # Go out to RA=245 deg
    trackRADec_trailing = bovy_coords.lb_to_radec(
        sdf._interpolatedObsTrackLB[:, 0],
        sdf._interpolatedObsTrackLB[:, 1],
        degree=True,
    )
    cindx = range(len(trackRADec_trailing))[np.argmin(
        np.fabs(trackRADec_trailing[:, 0] - 245.0))]

    ws = np.zeros(cindx)
    for ii, cc in enumerate(range(1, cindx + 1)):
        xy = [sdf._interpolatedObsTrackLB[cc, 0], None, None, None, None, None]
        ws[ii] = np.sqrt(sdf.gaussApprox(xy=xy, lb=True, cindx=cc)[1][2, 2])

    return np.mean(ws)
def process_mock_densdata(options):
    print("Using mock Pal 5 data from %s" % options.mockfilename)
    # Read and prep data for mocks
    xvid= numpy.loadtxt(options.mockfilename)
    xv= xvid[:,:6]
    xv= xv[numpy.argsort(xvid[:,6])]
    XYZ= bovy_coords.galcenrect_to_XYZ(xv[:,0],xv[:,1],xv[:,2],
                                       Xsun=R0,Zsun=0.025)
    lbd= bovy_coords.XYZ_to_lbd(XYZ[0],XYZ[1],XYZ[2],degree=True)
    radec= bovy_coords.lb_to_radec(lbd[:,0],lbd[:,1],degree=True)
    xieta= pal5_util.radec_to_pal5xieta(radec[:,0],radec[:,1],degree=True)
    # make sure the progenitor is at (0,0)
    xieta[:,0]-= numpy.median(xieta[:,0])
    xieta[:,1]-= numpy.median(xieta[:,1])
    h,e= numpy.histogram(xieta[:,0],range=[0.2,14.3],bins=141)
    xdata= numpy.arange(0.25,14.35,0.1)
    # Compute power spectrum
    tdata= h-0.
    pp= Polynomial.fit(xdata,tdata,deg=options.polydeg,w=1./numpy.sqrt(h+1.))
    tdata/= pp(xdata)
    ll= xdata
    py= signal.csd(tdata,tdata,fs=1./(ll[1]-ll[0]),scaling='spectrum',
                   nperseg=len(ll))[1]
    py= py.real
    # Also compute the bispectrum
    Bspec, Bpx= bispectrum.bispectrum(numpy.vstack((tdata,tdata)).T,
                                      nfft=len(tdata),wind=7,nsamp=1,overlap=0)
    ppyr= numpy.fabs(Bspec[len(Bspec)//2+_BISPECIND,len(Bspec)//2:].real)
    ppyi= numpy.fabs(Bspec[len(Bspec)//2+_BISPECIND,len(Bspec)//2:].imag)
    return (numpy.sqrt(py*(ll[-1]-ll[0])),numpy.sqrt(h+1.)/pp(xdata),
            ppyr,ppyi)
def get_track_RADec(*sdfs):
    """get_track_RaDec.

    Parameters
    ----------
    *sdfs : streamdf(s)

    Returns
    -------
    trackRADec(s) : (n, 2) array, or list of trackRADecs
        the track in ra, dec of the streamdf

    """
    if len(sdfs) == 0:
        raise ValueError

    trackRADec = []

    for sdf in sdfs:
        trackRADec.append(
            lb_to_radec(
                sdf._interpolatedObsTrackLB[:, 0],
                sdf._interpolatedObsTrackLB[:, 1],
                degree=True,
            ))
    if len(trackRADec) == 1:
        return trackRADec[0]
    return trackRADec
def convert():

    global req_params

    #if position given in ra & dec, convert to l & b
    if (req_params.get('l') == -9.999):
        req_params['l'], req_params['b'] = b_c.radec_to_lb(req_params['ra'],
                                                           req_params['dec'],
                                                           degree=True,
                                                           epoch=2000.0)

    #if position given in l & b, convert to ra & dec
    if (req_params.get('ra') == -9.999):
        req_params['ra'], req_params['dec'] = b_c.lb_to_radec(req_params['l'],
                                                              req_params['b'],
                                                              degree=True,
                                                              epoch=2000.0)

    #if proper motion given in pmra & pmdec, convert to pml & pmb
    if (req_params.get('pml') == -9.999):
        req_params['pml'], req_params['pmb'] = b_c.pmrapmdec_to_pmllpmbb(
            req_params['pmra'],
            req_params['pmdec'],
            req_params['ra'],
            req_params['dec'],
            degree=True,
            epoch=2000.0)
def lb_to_phi12(l,b,degree=False):
    """
    NAME:
       lb_to_phi12
    PURPOSE:
       Transform Galactic coordinates (l,b) to (phi1,phi2)
    INPUT:
       l - Galactic longitude (rad or degree)
       b - Galactic latitude (rad or degree)
       degree= (False) if True, input and output are in degrees
    OUTPUT:
       (phi1,phi2) for scalar input
       [:,2] array for vector input
    HISTORY:
        2014-11-04 - Written - Bovy (IAS)
    """
    #First convert to ra and dec
    radec= bovy_coords.lb_to_radec(l,b)
    ra= radec[:,0]
    dec= radec[:,1]
    XYZ= numpy.array([numpy.cos(dec)*numpy.cos(ra),
                      numpy.cos(dec)*numpy.sin(ra),
                      numpy.sin(dec)])
    phiXYZ= numpy.dot(_TKOP,XYZ)
    phi2= numpy.arcsin(phiXYZ[2])
    phi1= numpy.arctan2(phiXYZ[1],phiXYZ[0])
    phi1[phi1<0.]+= 2.*numpy.pi
    return numpy.array([phi1,phi2]).T
Example #8
0
def convert_dens_to_obs(sdf_pepper, apars, dens, mO, dens_smooth, minxi=0.25, maxxi=14.35):
    """
    NAME:
        convert_dens_to_obs
    PURPOSE:
        Convert track to observed coordinates
    INPUT:
        sdf_pepper - streampepperdf object
        apars - parallel angles
        dens - density(apars)
        dens_smooth - smooth density(apars)
        mO= (None) mean parallel frequency (1D) 
            [needs to be set to get density on same grid as track]
        minxi= (0.25) minimum xi to consider
    OUTPUT:
        (xi,dens/smooth)
    """
    mT = sdf_pepper.meanTrack(apars, _mO=mO, coord="lb")
    mradec = bovy_coords.lb_to_radec(mT[0], mT[1], degree=True)
    mxieta = pal5_util.radec_to_pal5xieta(mradec[:, 0], mradec[:, 1], degree=True)
    outll = numpy.arange(minxi, maxxi, 0.1)
    # Interpolate density
    ipll = interpolate.InterpolatedUnivariateSpline(mxieta[:, 0], apars)
    ipdens = interpolate.InterpolatedUnivariateSpline(apars, dens / dens_smooth)
    return (outll, ipdens(ipll(outll)))
def convert_dens_to_obs(sdf_pepper,
                        apars,
                        dens,
                        mO,
                        dens_smooth,
                        minxi=0.25,
                        maxxi=14.35):
    """
    NAME:
        convert_dens_to_obs
    PURPOSE:
        Convert track to observed coordinates
    INPUT:
        sdf_pepper - streampepperdf object
        apars - parallel angles
        dens - density(apars)
        dens_smooth - smooth density(apars)
        mO= (None) mean parallel frequency (1D) 
            [needs to be set to get density on same grid as track]
        minxi= (0.25) minimum xi to consider
    OUTPUT:
        (xi,dens/smooth)
    """
    mT = sdf_pepper.meanTrack(apars, _mO=mO, coord='lb')
    mradec = bovy_coords.lb_to_radec(mT[0], mT[1], degree=True)
    mxieta = pal5_util.radec_to_pal5xieta(mradec[:, 0],
                                          mradec[:, 1],
                                          degree=True)
    outll = np.arange(minxi, maxxi, 0.1)
    # Interpolate density
    ipll = interpolate.InterpolatedUnivariateSpline(mxieta[:, 0], apars)
    ipdens = interpolate.InterpolatedUnivariateSpline(apars,
                                                      dens / dens_smooth)
    return (outll, ipdens(ipll(outll)))
Example #10
0
def sky_coords(cluster):
    """Get the sky coordinates of every star in the cluster

    Parameters
    ----------
    cluster : class
        StarCluster

    Returns
    -------
    ra,dec,d0,pmra,pmdec,vr0 : float
      on-sky positions and velocities of cluster stars
      
    History
    -------
    2018 - Written - Webb (UofT)
    """
    origin0 = cluster.origin

    if origin0 != "galaxy":
        cluster.to_galaxy()

    x0, y0, z0 = bovy_coords.galcenrect_to_XYZ(cluster.x,
                                               cluster.y,
                                               cluster.z,
                                               Xsun=8.0,
                                               Zsun=0.025).T
    vx0, vy0, vz0 = bovy_coords.galcenrect_to_vxvyvz(
        cluster.vx,
        cluster.vy,
        cluster.vz,
        Xsun=8.0,
        Zsun=0.025,
        vsun=[-11.1, 244.0, 7.25],
    ).T

    l0, b0, d0 = bovy_coords.XYZ_to_lbd(x0, y0, z0, degree=True).T
    ra, dec = bovy_coords.lb_to_radec(l0, b0, degree=True).T

    vr0, pmll0, pmbb0 = bovy_coords.vxvyvz_to_vrpmllpmbb(vx0,
                                                         vy0,
                                                         vz0,
                                                         l0,
                                                         b0,
                                                         d0,
                                                         degree=True).T
    pmra, pmdec = bovy_coords.pmllpmbb_to_pmrapmdec(pmll0,
                                                    pmbb0,
                                                    l0,
                                                    b0,
                                                    degree=True).T

    if origin0 == "centre":
        cluster.to_centre()
    elif origin0 == "cluster":
        cluster.to_cluster()

    return ra, dec, d0, pmra, pmdec, vr0
def pmllpmbb_to_pmphi12(pmll,pmbb,l,b,degree=False):
    """
    NAME:
       pmllpmbb_to_pmphi12
    PURPOSE:
       Transform proper motions in Galactic coordinates (l,b) to (phi1,phi2)
    INPUT:
       pmll - proper motion Galactic longitude (rad or degree); contains xcosb
       pmbb - Galactic latitude (rad or degree)
       l - Galactic longitude (rad or degree)
       b - Galactic latitude (rad or degree)
       degree= (False) if True, input (l,b) are in degrees
    OUTPUT:
       (pmphi1,pmphi2) for scalar input
       [:,2] array for vector input
    HISTORY:
        2014-11-04 - Written - Bovy (IAS)
    """
    #First go to ra and dec
    radec= bovy_coords.lb_to_radec(l,b)
    ra= radec[:,0]
    dec= radec[:,1]
    pmradec= bovy_coords.pmllpmbb_to_pmrapmdec(pmll,pmbb,l,b,degree=False)
    pmra= pmradec[:,0]
    pmdec= pmradec[:,1]
    #Now transform ra,dec pm to phi1,phi2
    phi12= lb_to_phi12(l,b,degree=False)
    phi1= phi12[:,0]
    phi2= phi12[:,1]
    #Build A and Aphi matrices
    A= numpy.zeros((3,3,len(ra)))
    A[0,0]= numpy.cos(ra)*numpy.cos(dec)
    A[0,1]= -numpy.sin(ra)
    A[0,2]= -numpy.cos(ra)*numpy.sin(dec)
    A[1,0]= numpy.sin(ra)*numpy.cos(dec)
    A[1,1]= numpy.cos(ra)
    A[1,2]= -numpy.sin(ra)*numpy.sin(dec)
    A[2,0]= numpy.sin(dec)
    A[2,1]= 0.
    A[2,2]= numpy.cos(dec)
    AphiInv= numpy.zeros((3,3,len(ra)))
    AphiInv[0,0]= numpy.cos(phi1)*numpy.cos(phi2)
    AphiInv[0,1]= numpy.cos(phi2)*numpy.sin(phi1)
    AphiInv[0,2]= numpy.sin(phi2)
    AphiInv[1,0]= -numpy.sin(phi1)
    AphiInv[1,1]= numpy.cos(phi1)
    AphiInv[1,2]= 0.
    AphiInv[2,0]= -numpy.cos(phi1)*numpy.sin(phi2)
    AphiInv[2,1]= -numpy.sin(phi1)*numpy.sin(phi2)
    AphiInv[2,2]= numpy.cos(phi2)
    TA= numpy.dot(_TKOP,numpy.swapaxes(A,0,1))
    #Got lazy...
    trans= numpy.zeros((2,2,len(ra)))
    for ii in range(len(ra)):
        trans[:,:,ii]= numpy.dot(AphiInv[:,:,ii],TA[:,:,ii])[1:,1:]
    return (trans*numpy.array([[pmra,pmdec],[pmra,pmdec]])).sum(1).T
Example #12
0
def pmphi12_to_pmllpmbb(pmphi1, pmphi2, phi1, phi2, degree=False):
    """
    NAME:
       pmllpmbb_to_pmphi12
    PURPOSE:
       Transform proper motions in (phi1,phi2) to Galactic coordinates (l,b)
    INPUT:
       pmphi1 - proper motion Galactic longitude (rad or degree); contains xcosphi2
       pmphi2 - Galactic latitude (rad or degree)
       phi1 - phi longitude (rad or degree)
       phi2 - phi latitude (rad or degree)
       degree= (False) if True, input (phi1,phi2) are in degrees
    OUTPUT:
       (pmll,pmbb) for scalar input
       [:,2] array for vector input
    HISTORY:
        2014-11-04 - Written - Bovy (IAS)
    """
    #First go from phi12 to ra and dec
    lb = phi12_to_lb(phi1, phi2)
    radec = bovy_coords.lb_to_radec(lb[:, 0], lb[:, 1])
    ra = radec[:, 0]
    dec = radec[:, 1]
    #Build A and Aphi matrices
    AInv = numpy.zeros((3, 3, len(ra)))
    AInv[0, 0] = numpy.cos(ra) * numpy.cos(dec)
    AInv[0, 1] = numpy.sin(ra) * numpy.cos(dec)
    AInv[0, 2] = numpy.sin(dec)
    AInv[1, 0] = -numpy.sin(ra)
    AInv[1, 1] = numpy.cos(ra)
    AInv[1, 2] = 0.
    AInv[2, 0] = -numpy.cos(ra) * numpy.sin(dec)
    AInv[2, 1] = -numpy.sin(ra) * numpy.sin(dec)
    AInv[2, 2] = numpy.cos(dec)
    Aphi = numpy.zeros((3, 3, len(ra)))
    Aphi[0, 0] = numpy.cos(phi1) * numpy.cos(phi2)
    Aphi[0, 1] = -numpy.sin(phi1)
    Aphi[0, 2] = -numpy.cos(phi1) * numpy.sin(phi2)
    Aphi[1, 0] = numpy.sin(phi1) * numpy.cos(phi2)
    Aphi[1, 1] = numpy.cos(phi1)
    Aphi[1, 2] = -numpy.sin(phi1) * numpy.sin(phi2)
    Aphi[2, 0] = numpy.sin(phi2)
    Aphi[2, 1] = 0.
    Aphi[2, 2] = numpy.cos(phi2)
    TAphi = numpy.dot(_TKOP.T, numpy.swapaxes(Aphi, 0, 1))
    #Got lazy...
    trans = numpy.zeros((2, 2, len(ra)))
    for ii in range(len(ra)):
        trans[:, :, ii] = numpy.dot(AInv[:, :, ii], TAphi[:, :, ii])[1:, 1:]
    pmradec = (trans *
               numpy.array([[pmphi1, pmphi2], [pmphi1, pmphi2]])).sum(1).T
    pmra = pmradec[:, 0]
    pmdec = pmradec[:, 1]
    #Now convert to pmll
    return bovy_coords.pmrapmdec_to_pmllpmbb(pmra, pmdec, ra, dec)
Example #13
0
def sky_coords(cluster):
    """
    NAME:

       sky_coords

    PURPOSE:

       Get the sky coordinates of every star in the cluster

    INPUT:

       cluster - a StarCluster-class object

    OUTPUT:

       ra,dec,d0,pmra,pmdec,vr0

    HISTORY:

       2018 - Written - Webb (UofT)

    """
    origin0 = cluster.origin

    if origin0 != "galaxy":
        cluster.to_galaxy()

    x0, y0, z0 = bovy_coords.galcenrect_to_XYZ(
        cluster.x, cluster.y, cluster.z, Xsun=8.0, Zsun=0.025
    ).T
    vx0, vy0, vz0 = bovy_coords.galcenrect_to_vxvyvz(
        cluster.vx,
        cluster.vy,
        cluster.vz,
        Xsun=8.0,
        Zsun=0.025,
        vsun=[-11.1, 244.0, 7.25],
    ).T

    l0, b0, d0 = bovy_coords.XYZ_to_lbd(x0, y0, z0, degree=True).T
    ra, dec = bovy_coords.lb_to_radec(l0, b0, degree=True).T

    vr0, pmll0, pmbb0 = bovy_coords.vxvyvz_to_vrpmllpmbb(
        vx0, vy0, vz0, l0, b0, d0, degree=True
    ).T
    pmra, pmdec = bovy_coords.pmllpmbb_to_pmrapmdec(pmll0, pmbb0, l0, b0, degree=True).T

    if origin0 == "centre":
        cluster.to_centre()
    elif origin0 == "cluster":
        cluster.to_cluster()

    return ra, dec, d0, pmra, pmdec, vr0
Example #14
0
def looks_funny(tsdf_trailing, tsdf_leading):
    radecs_trailing=\
        bovy_coords.lb_to_radec(tsdf_trailing._interpolatedObsTrackLB[:,0],
                                tsdf_trailing._interpolatedObsTrackLB[:,1],
                                degree=True)
    if not tsdf_leading is None:
        radecs_leading=\
            bovy_coords.lb_to_radec(tsdf_leading._interpolatedObsTrackLB[:,0],
                                    tsdf_leading._interpolatedObsTrackLB[:,1],
                                    degree=True)
    try:
        if radecs_trailing[0, 1] > 0.625:
            return True
        elif radecs_trailing[0, 1] < -0.1:
            return True
        elif numpy.any((numpy.roll(radecs_trailing[:,0],-1)-radecs_trailing[:,0])\
                           [(radecs_trailing[:,0] < 250.)\
                                *(radecs_trailing[:,1] > -1.)\
                                *(radecs_trailing[:,1] < 10.)] < 0.):
            return True
        elif not tsdf_leading is None and \
                numpy.any((numpy.roll(radecs_leading[:,0],-1)-radecs_leading[:,0])\
                              [(radecs_leading[:,0] > 225.)\
                                   *(radecs_leading[:,1] > -4.5)\
                                   *(radecs_leading[:,1] < 0.)] > 0.):
            return True
        elif False:  #numpy.isnan(width_trailing(tsdf_trailing)):
            return True
        elif numpy.isnan(
                tsdf_trailing.length(ang=True, coord='customra',
                                     threshold=0.3)):
            return True
        elif numpy.fabs(tsdf_trailing._dOdJpEig[0][2]\
                            /tsdf_trailing._dOdJpEig[0][1]) < 0.05:
            return True
        else:
            return False
    except:
        return True
Example #15
0
def vdisp_trailing(sdf):
    """Return the velocity dispersion in km/s for the trailing tail"""
    # Go out to RA=245 deg
    trackRADec_trailing=\
        bovy_coords.lb_to_radec(sdf._interpolatedObsTrackLB[:,0],
                                sdf._interpolatedObsTrackLB[:,1],
                                degree=True)
    cindx= range(len(trackRADec_trailing))[\
        numpy.argmin(numpy.fabs(trackRADec_trailing[:,0]-245.))]
    ws = numpy.zeros(cindx)
    for ii, cc in enumerate(range(1, cindx + 1)):
        xy = [sdf._interpolatedObsTrackLB[cc, 0], None, None, None, None, None]
        ws[ii] = numpy.sqrt(sdf.gaussApprox(xy=xy, lb=True, cindx=cc)[1][2, 2])
    return numpy.mean(ws)
Example #16
0
def width_trailing(sdf):
    """Return the FWHM width in arcmin for the trailing tail"""
    # Go out to RA=245 deg
    trackRADec_trailing=\
        bovy_coords.lb_to_radec(sdf._interpolatedObsTrackLB[:,0],
                                sdf._interpolatedObsTrackLB[:,1],
                                degree=True)
    cindx= range(len(trackRADec_trailing))[\
        numpy.argmin(numpy.fabs(trackRADec_trailing[:,0]-245.))]
    ws = numpy.zeros(cindx)
    for ii, cc in enumerate(range(1, cindx + 1)):
        xy = [sdf._interpolatedObsTrackLB[cc, 0], None, None, None, None, None]
        ws[ii] = numpy.sqrt(sdf.gaussApprox(xy=xy, lb=True, cindx=cc)[1][0, 0])


#    return 2.355*60.*ws
    return 2.355 * 60. * numpy.mean(ws)
Example #17
0
def xyzuvw_to_skycoord(xyzuvw_in, solarmotion='schoenrich', reverse_x_sign=True):
    """Converts XYZUVW with respect to the LSR or the sun
    to RAdeg, DEdeg, plx, pmra, pmdec, RV
    
    Parameters
    ----------
    xyzuvw_in:
        XYZUVW with respect to the LSR.
        
    solarmotion: string
        The reference of assumed solar motion. "schoenrich" or None if inputs are already 
        relative to the sun.
        
    reverse_x_sign: bool
        Do we reverse the sign of the X co-ordinate? This is needed for dealing with 
        galpy sign conventions.

    TODO: not working at all... fix this
    """
    if solarmotion==None:
        xyzuvw_sun = np.zeros(6)
    elif solarmotion=='schoenrich':
        xyzuvw_sun = [0,0,25,11.1,12.24,7.25]
    else:
        raise UserWarning
        
    #Make coordinates relative to sun
    xyzuvw = xyzuvw_in - xyzuvw_sun
    
    #Special for the sun itself...
    #FIXME: This seems like a hack. 
    #if (np.sum(xyzuvw**2) < 1) and solarmotion != None:
    #    return [0,0,1e5, 0,0,0]
    
    #Find l, b and distance.
    #!!! WARNING: the X-coordinate may have to be reversed here, just like everywhere else, 
    #because of the convention in Orbit.x(), which doesn't seem to match X.
    if reverse_x_sign:
        lbd = bovy_coords.XYZ_to_lbd(-xyzuvw[0]/1e3, xyzuvw[1]/1e3, xyzuvw[2]/1e3, degree=True)
    else:
        lbd = bovy_coords.XYZ_to_lbd(xyzuvw[0]/1e3, xyzuvw[1]/1e3, xyzuvw[2]/1e3, degree=True)
    radec = bovy_coords.lb_to_radec(lbd[0], lbd[1], degree=True)
    vrpmllpmbb = bovy_coords.vxvyvz_to_vrpmllpmbb(xyzuvw[3],xyzuvw[4], xyzuvw[5],\
                    lbd[0],lbd[1],lbd[2], degree=True)
    pmrapmdec = bovy_coords.pmllpmbb_to_pmrapmdec(vrpmllpmbb[1],vrpmllpmbb[2],lbd[0],lbd[1],degree=True)
    return [radec[0], radec[1], 1.0/lbd[2], pmrapmdec[0], pmrapmdec[1], vrpmllpmbb[0]]
def get_star_dx(pepperdf, n=1000, returnapar=False, returnxi=False):
    (Omega, angle, dt) = pepperdf.sample(n=n, returnaAdt=True)
    RvR = pepperdf._approxaAInv(Omega[0], Omega[1], Omega[2], angle[0],
                                angle[1], angle[2])
    vo = pepperdf._vo
    ro = pepperdf._ro
    R0 = pepperdf._R0
    Zsun = pepperdf._Zsun
    vsun = pepperdf._vsun
    XYZ = bovy_coords.galcencyl_to_XYZ(RvR[0] * ro,
                                       RvR[5],
                                       RvR[3] * ro,
                                       Xsun=R0,
                                       Zsun=Zsun).T
    slbd = bovy_coords.XYZ_to_lbd(XYZ[0], XYZ[1], XYZ[2], degree=True)
    sradec = bovy_coords.lb_to_radec(slbd[:, 0], slbd[:, 1], degree=True)
    xieta = pal5_util.radec_to_pal5xieta(sradec[:, 0],
                                         sradec[:, 1],
                                         degree=True)
    l = slbd[:, 0]
    b = slbd[:, 1]
    r = slbd[:, 2]
    if returnapar:
        closesttrackindexes = np.zeros(len(r))
        for i in np.arange(len(r)):
            closesttrackindexes[i] = pepperdf.find_closest_trackpoint(
                RvR[0][i],
                RvR[1][i],
                RvR[2][i],
                RvR[3][i],
                RvR[4][i],
                RvR[5][i],
                interp=True)
        starapar = pepperdf._interpolatedThetasTrack[(
            closesttrackindexes).astype(int)]
        return starapar
    if returnxi: return xieta[:, 0]
    else: return None
def convert_track_to_obs(apars,mO,coord):
    """
    NAME:
        convert_track_to_obs
    PURPOSE:
        Convert track to observed coordinates
    INPUT:
        apars - parallel angles
        mO - mean parallel frequency (1D)
        coord - coordinate to convert to (1: eta, 2: distance, 3: vlos, 4: pmll, 5: pmbb)
    OUTPUT:
        (longitude,(track-smooth)[coord])
    """
    mT= sdf_pepper.meanTrack(apars,_mO=mO,coord='lb')
    mradec= bovy_coords.lb_to_radec(mT[0],mT[1],degree=True)
    mxieta= pal5_util.radec_to_pal5xieta(mradec[:,0],mradec[:,1],degree=True)
    mT[0]= mxieta[:,0]
    mT[1]= mxieta[:,1]
    # Interpolate
    ipll= interpolate.InterpolatedUnivariateSpline(mT[0],apars)
    ipcoord= interpolate.InterpolatedUnivariateSpline(apars,mT[coord])
    outll= numpy.arange(minxi,14.35,0.1)
    return (outll,ipcoord(ipll(outll))-smooth_track[coord](smooth_ll(outll)))    
def convertHelioCentricToRADEC(xyzuvw_hc, kpc=False):
    """
    Generate astrometry values from cartesian coordinates centred on sun

    Parameters
    ----------
    xyzuvw_hc : [6] array
        [kpc, kpc, kpc, km/s, km/s, km/s]

    Returns
    -------
    astrometry : [6] array
        [RA, DEC, pi, pm_ra, pm_dec, vr]
    """
    #    if not kpc:
    #        xyzuvw_hc = xyzuvw_hc.copy()
    #        xyzuvw_hc[:3] /= 1e3
    logging.debug("Positions is: {}".format(xyzuvw_hc[:3]))
    logging.debug("Velocity is: {}".format(xyzuvw_hc[3:]))
    lbdist = convertHelioCentricTolbdist(xyzuvw_hc)
    radec = bovy_coords.lb_to_radec(lbdist[0], lbdist[1], degree=True)
    vrpmllpmbb = bovy_coords.vxvyvz_to_vrpmllpmbb(xyzuvw_hc[3],
                                                  xyzuvw_hc[4],
                                                  xyzuvw_hc[5],
                                                  lbdist[0],
                                                  lbdist[1],
                                                  lbdist[2],
                                                  degree=True)
    pmrapmdec = bovy_coords.pmllpmbb_to_pmrapmdec(vrpmllpmbb[1],
                                                  vrpmllpmbb[2],
                                                  lbdist[0],
                                                  lbdist[1],
                                                  degree=True)
    return [
        radec[0], radec[1], 1.0 / lbdist[2], pmrapmdec[0], pmrapmdec[1],
        vrpmllpmbb[0]
    ]
Example #21
0
def lb_to_phi12(l,b,degree=False):
    """
    NAME:
       lb_to_phi12
    PURPOSE:
       Transform Galactic coordinates (l,b) to (phi1,phi2)
    INPUT:
       l - Galactic longitude (rad or degree)
       b - Galactic latitude (rad or degree)
       degree= (False) if True, input and output are in degrees
    OUTPUT:
       (phi1,phi2) for scalar input
       [:,2] array for vector input
    HISTORY:
        2014-11-04 - Written - Bovy (IAS)
    """
    import numpy
    from   galpy.util import bovy_coords
    
    
    _TKOP= numpy.zeros((3,3))
    _TKOP[0,:]= [-0.4776303088,-0.1738432154,0.8611897727]
    _TKOP[1,:]= [0.510844589,-0.8524449229,0.111245042]
    _TKOP[2,:]= [0.7147776536,0.4930681392,0.4959603976]
    
    #First convert to ra and dec
    radec= bovy_coords.lb_to_radec(l,b)
    ra= radec[:,0]
    dec= radec[:,1]
    XYZ= numpy.array([numpy.cos(dec)*numpy.cos(ra),
                      numpy.cos(dec)*numpy.sin(ra),
                      numpy.sin(dec)])
    phiXYZ= numpy.dot(_TKOP,XYZ)
    phi2= numpy.arcsin(phiXYZ[2])
    phi1= numpy.arctan2(phiXYZ[1],phiXYZ[0])
    phi1[phi1<0.]+= 2.*numpy.pi
    return numpy.array([phi1,phi2]).T
def convert_dens_to_obs(apars,dens,dens_smooth,mO,poly_deg=3):
    """
    NAME:
        convert_dens_to_obs
    PURPOSE:
        Convert track to observed coordinates
    INPUT:
        apars - parallel angles
        dens - density(apars)
        dens_smooth - smooth-stream density(apars)
        mO= (None) mean parallel frequency (1D) 
            [needs to be set to get density on same grid as track]
        poly_deg= (3) degree of the polynomial to fit for the 'smooth' stream
    OUTPUT:
        (xi,dens/smooth)
    """
    mT= sdf_pepper.meanTrack(apars,_mO=mO,coord='lb')
    mradec= bovy_coords.lb_to_radec(mT[0],mT[1],degree=True)
    mxieta= pal5_util.radec_to_pal5xieta(mradec[:,0],mradec[:,1],degree=True)
    outll= numpy.arange(minxi,14.35,0.1)
    # Interpolate density
    ipll= interpolate.InterpolatedUnivariateSpline(mxieta[:,0],apars)
    ipdens= interpolate.InterpolatedUnivariateSpline(apars,dens/dens_smooth)
    return (outll,ipdens(ipll(outll)))
def looks_funny(tsdf_trailing: streamdf,
                tsdf_leading: Optional[streamdf]) -> bool:
    """looks funny.

    Parameters
    ----------
    tsdf_trailing
    tsdf_leading

    Returns
    -------
    bool

    """
    isfunny = False

    radecs_trailing = bovy_coords.lb_to_radec(
        tsdf_trailing._interpolatedObsTrackLB[:, 0],
        tsdf_trailing._interpolatedObsTrackLB[:, 1],
        degree=True,
    )

    if tsdf_leading is not None:
        radecs_leading = bovy_coords.lb_to_radec(
            tsdf_leading._interpolatedObsTrackLB[:, 0],
            tsdf_leading._interpolatedObsTrackLB[:, 1],
            degree=True,
        )

    try:
        if radecs_trailing[0, 1] > 0.625:
            isfunny = True
        elif radecs_trailing[0, 1] < -0.1:
            isfunny = True
        elif np.any(
            (np.roll(radecs_trailing[:, 0], -1) -
             radecs_trailing[:, 0])[(radecs_trailing[:, 0] < 250.0) *
                                    (radecs_trailing[:, 1] > -1.0) *
                                    (radecs_trailing[:, 1] < 10.0)] < 0.0):
            isfunny = True
        elif tsdf_leading is not None and np.any(
            (np.roll(radecs_leading[:, 0], -1) -
             radecs_leading[:, 0])[(radecs_leading[:, 0] > 225.0) *
                                   (radecs_leading[:, 1] > -4.5) *
                                   (radecs_leading[:, 1] < 0.0)] > 0.0):
            isfunny = True
        elif False:  # np.isnan(width_trailing(tsdf_trailing)):  # FIXME
            isfunny = True
        elif np.isnan(
                tsdf_trailing.length(ang=True, coord="customra",
                                     threshold=0.3)):
            isfunny = True
        elif (np.fabs(tsdf_trailing._dOdJpEig[0][2] /
                      tsdf_trailing._dOdJpEig[0][1]) < 0.05):
            isfunny = True
        else:
            isfunny = False

    except:
        isfunny = True

    return isfunny
Example #24
0
def to_radec(cluster, do_order=False, do_key_params=False, ro=8.0, vo=220.0):
    """Convert to on-sky position, proper motion, and radial velocity of cluster
    
    Parameters
    ----------
    cluster : class
        StarCluster
    do_order : bool
        sort star by radius after coordinate change (default: False)
    do_key_params : bool
        call key_params to calculate key parameters after unit change (default: False)
    ro : float
        galpy radius scaling parameter
    vo : float
        galpy velocity scaling parameter

    Returns
    -------
    None

    History:
    -------
   2018 - Written - Webb (UofT)
    """
    if len(cluster.ra) == len(cluster.x):
        cluster.x = copy(cluster.ra)
        cluster.y = copy(cluster.dec)
        cluster.z = copy(cluster.dist)
        cluster.vx = copy(cluster.pmra)
        cluster.vy = copy(cluster.pmdec)
        cluster.vz = copy(cluster.vlos)

        cluster.units = "radec"
        cluster.origin = "sky"

    else:

        units0, origin0 = cluster.units, cluster.origin

        cluster.to_galaxy()
        cluster.to_kpckms()

        x0, y0, z0 = bovy_coords.galcenrect_to_XYZ(cluster.x,
                                                   cluster.y,
                                                   cluster.z,
                                                   Xsun=8.0,
                                                   Zsun=0.025).T

        cluster.dist = np.sqrt(x0**2.0 + y0**2.0 + z0**2.0)

        vx0, vy0, vz0 = bovy_coords.galcenrect_to_vxvyvz(
            cluster.vx,
            cluster.vy,
            cluster.vz,
            Xsun=8.0,
            Zsun=0.025,
            vsun=[-11.1, 244.0, 7.25],
        ).T

        cluster.vlos = (vx0 * x0 + vy0 * y0 +
                        vz0 * z0) / np.sqrt(x0**2.0 + y0**2.0 + z0**2.0)

        l0, b0, cluster.dist = bovy_coords.XYZ_to_lbd(x0, y0, z0,
                                                      degree=True).T
        cluster.ra, cluster.dec = bovy_coords.lb_to_radec(l0, b0,
                                                          degree=True).T

        vr0, pmll0, pmbb0 = bovy_coords.vxvyvz_to_vrpmllpmbb(vx0,
                                                             vy0,
                                                             vz0,
                                                             l0,
                                                             b0,
                                                             cluster.dist,
                                                             degree=True).T
        cluster.pmra, cluster.pmdec = bovy_coords.pmllpmbb_to_pmrapmdec(
            pmll0, pmbb0, l0, b0, degree=True).T

        x0, y0, z0 = bovy_coords.galcenrect_to_XYZ(cluster.xgc,
                                                   cluster.ygc,
                                                   cluster.zgc,
                                                   Xsun=8.0,
                                                   Zsun=0.025)
        vx0, vy0, vz0 = bovy_coords.galcenrect_to_vxvyvz(
            cluster.vxgc,
            cluster.vygc,
            cluster.vzgc,
            Xsun=8.0,
            Zsun=0.025,
            vsun=[-11.1, 244.0, 7.25],
        )

        cluster.vlos_gc = (vx0 * x0 + vy0 * y0 +
                           vz0 * z0) / np.sqrt(x0**2.0 + y0**2.0 + z0**2.0)

        l0, b0, cluster.dist_gc = bovy_coords.XYZ_to_lbd(x0,
                                                         y0,
                                                         z0,
                                                         degree=True)
        cluster.ra_gc, cluster.dec_gc = bovy_coords.lb_to_radec(l0,
                                                                b0,
                                                                degree=True)

        vr0, pmll0, pmbb0 = bovy_coords.vxvyvz_to_vrpmllpmbb(vx0,
                                                             vy0,
                                                             vz0,
                                                             l0,
                                                             b0,
                                                             cluster.dist_gc,
                                                             degree=True)
        cluster.pmra_gc, cluster.pmdec_gc = bovy_coords.pmllpmbb_to_pmrapmdec(
            pmll0, pmbb0, l0, b0, degree=True)

        cluster.x = copy(cluster.ra)
        cluster.y = copy(cluster.dec)
        cluster.z = copy(cluster.dist)
        cluster.vx = copy(cluster.pmra)
        cluster.vy = copy(cluster.pmdec)
        cluster.vz = copy(cluster.vlos)

        cluster.xgc = copy(cluster.ra_gc)
        cluster.ygc = copy(cluster.dec_gc)
        cluster.zgc = copy(cluster.dist_gc)
        cluster.vxgc = copy(cluster.pmra_gc)
        cluster.vygc = copy(cluster.pmdec_gc)
        cluster.vzgc = copy(cluster.vlos_gc)

        cluster.units = "radec"
        cluster.origin = "sky"

    cluster.rv3d()

    if do_key_params:
        cluster.key_params(do_order=do_order)
Example #25
0
def predict_pal5obs(pot_params,
                    c,
                    b=1.,
                    pa=0.,
                    sigv=0.2,
                    td=10.,
                    dist=23.2,
                    pmra=-2.296,
                    pmdec=-2.257,
                    vlos=-58.7,
                    ro=_REFR0,
                    vo=_REFV0,
                    singlec=False,
                    interpcs=None,
                    interpk=None,
                    isob=None,
                    nTrackChunks=8,
                    multi=None,
                    trailing_only=False,
                    useTM=False,
                    verbose=True):
    """
    NAME:
       predict_pal5obs
    PURPOSE:
       Function that generates the location and velocity of the Pal 5 stream, its width, and its length for a given potential and progenitor phase-space position
    INPUT:
       pot_params- array with the parameters of a potential model (see MWPotential2014Likelihood.setup_potential; only the basic parameters of the disk and halo are used, flattening is specified separately)
       c- halo flattening
       b= (1.) halo-squashed
       pa= (0.) halo PA
       sigv= (0.4) velocity dispersion in km/s (can be array of same len as interpcs)
       td= (5.) stream age in Gyr (can be array of same len as interpcs)
       dist= (23.2) progenitor distance in kpc
       pmra= (-2.296) progenitor proper motion in RA * cos(Dec) in mas/yr
       pmdec= (-2.257) progenitor proper motion in Dec in mas/yr
       vlos= (-58.7) progenitor line-of-sight velocity in km/s
       ro= (project default) distance to the GC in kpc
       vo= (project default) circular velocity at R0 in km/s
       singlec= (False) if True, just compute the observables for a single c
       interpcs= (None) values of c at which to compute the model for interpolation
       nTrackChunks= (8) nTrackChunks input to streamdf
       multi= (None) multi input to streamdf
       isob= (None) if given, b parameter of actionAngleIsochroneApprox
       trailing_only= (False) if True, only predict the trailing arm
       useTM= (True) use the TorusMapper to compute the track
       verbose= (True) print messages
    OUTPUT:
       (trailing track in RA,Dec,
        leading track in RA,Dec,
        trailing track in RA,Vlos,
        leading track in RA,Vlos,
        trailing width in arcmin,
        trailing length in deg)
        all arrays with the shape of c
    HISTORY:
       2016-06-24 - Written - Bovy (UofT)
    """
    # First compute the model for all cs at which we will interpolate
    if singlec:
        interpcs = [c]
    elif interpcs is None:
        interpcs = [0.5, 0.75, 1., 1.25, 1.55, 1.75, 2., 2.25, 2.5, 2.75, 3.]
    else:
        interpcs = copy.deepcopy(interpcs)  # bc we might want to remove some
    if isinstance(sigv, float):
        sigv = [sigv for i in interpcs]
    if isinstance(td, float):
        td = [td for i in interpcs]
    if isinstance(isob, float) or isob is None:
        isob = [isob for i in interpcs]
    prog = Orbit([229.018, -0.124, dist, pmra, pmdec, vlos],
                 radec=True,
                 ro=ro,
                 vo=vo,
                 solarmotion=[-11.1, 24., 7.25])
    # Setup the model
    sdf_trailing_varyc = []
    sdf_leading_varyc = []
    ii = 0
    ninterpcs = len(interpcs)
    this_useTM = copy.deepcopy(useTM)
    this_nTrackChunks = nTrackChunks
    ntries = 0
    while ii < ninterpcs:
        ic = interpcs[ii]
        pot = MWPotential2014Likelihood.setup_potential(pot_params,
                                                        ic,
                                                        False,
                                                        False,
                                                        ro,
                                                        vo,
                                                        b=b,
                                                        pa=pa)
        success = True
        wentIn = ntries != 0
        # Make sure this doesn't run forever
        signal.signal(signal.SIGALRM, timeout_handler)
        signal.alarm(300)
        try:
            tsdf_trailing, tsdf_leading = setup_sdf(
                pot,
                prog,
                sigv[ii],
                td[ii],
                ro,
                vo,
                multi=multi,
                isob=isob[ii],
                nTrackChunks=this_nTrackChunks,
                trailing_only=trailing_only,
                verbose=verbose,
                useTM=this_useTM)
        except:
            # Catches errors and time-outs
            success = False
        signal.alarm(0)
        # Check for calc. issues
        if not success or \
                (not this_useTM and looks_funny(tsdf_trailing,tsdf_leading)):
            # Try again with TM
            this_useTM = True
            this_nTrackChunks = 21  # might as well

            #wentIn= True
            #print("Here",ntries,success)
            #sys.stdout.flush()

            ntries += 1
        else:
            success = not this_useTM
            #if wentIn:
            #    print(success)
            #    sys.stdout.flush()
            ii += 1
            # reset
            this_useTM = useTM
            this_nTrackChunks = nTrackChunks
            ntries = 0
            # Add to the list
            sdf_trailing_varyc.append(tsdf_trailing)
            sdf_leading_varyc.append(tsdf_leading)
    if not singlec and len(sdf_trailing_varyc) <= 1:
        # Almost everything bad!!
        return (numpy.zeros((len(c), 1001, 2)), numpy.zeros(
            (len(c), 1001, 2)), numpy.zeros(
                (len(c), 1001, 2)), numpy.zeros(
                    (len(c), 1001, 2)), numpy.zeros(
                        (len(c))), numpy.zeros((len(c))), [], success)
    # Compute the track properties for each model
    trackRADec_trailing= numpy.zeros((len(interpcs),
                                      sdf_trailing_varyc[0]\
                                          .nInterpolatedTrackChunks,2))
    trackRADec_leading= numpy.zeros((len(interpcs),
                                     sdf_trailing_varyc[0]\
                                         .nInterpolatedTrackChunks,2))
    trackRAVlos_trailing= numpy.zeros((len(interpcs),
                                       sdf_trailing_varyc[0]\
                                          .nInterpolatedTrackChunks,2))
    trackRAVlos_leading= numpy.zeros((len(interpcs),
                                      sdf_trailing_varyc[0]\
                                          .nInterpolatedTrackChunks,2))
    width = numpy.zeros(len(interpcs))
    length = numpy.zeros(len(interpcs))
    for ii in range(len(interpcs)):
        trackRADec_trailing[ii]= bovy_coords.lb_to_radec(\
            sdf_trailing_varyc[ii]._interpolatedObsTrackLB[:,0],
            sdf_trailing_varyc[ii]._interpolatedObsTrackLB[:,1],
            degree=True)
        if not trailing_only:
            trackRADec_leading[ii]= bovy_coords.lb_to_radec(\
                sdf_leading_varyc[ii]._interpolatedObsTrackLB[:,0],
                sdf_leading_varyc[ii]._interpolatedObsTrackLB[:,1],
                degree=True)
        trackRAVlos_trailing[ii][:, 0] = trackRADec_trailing[ii][:, 0]
        trackRAVlos_trailing[ii][:,1]= \
            sdf_trailing_varyc[ii]._interpolatedObsTrackLB[:,3]
        if not trailing_only:
            trackRAVlos_leading[ii][:, 0] = trackRADec_leading[ii][:, 0]
            trackRAVlos_leading[ii][:,1]= \
                sdf_leading_varyc[ii]._interpolatedObsTrackLB[:,3]
        width[ii] = width_trailing(sdf_trailing_varyc[ii])
        length[ii]=\
            sdf_trailing_varyc[ii].length(ang=True,coord='customra',
                                          threshold=0.3)
    if singlec:
        #if wentIn:
        #    print(success)
        #    sys.stdout.flush()
        return (trackRADec_trailing, trackRADec_leading, trackRAVlos_trailing,
                trackRAVlos_leading, width, length, interpcs, success)
    # Interpolate; output grids
    trackRADec_trailing_out= numpy.zeros((len(c),sdf_trailing_varyc[0]\
                                              .nInterpolatedTrackChunks,2))
    trackRADec_leading_out= numpy.zeros((len(c),sdf_trailing_varyc[0]\
                                             .nInterpolatedTrackChunks,2))
    trackRAVlos_trailing_out= numpy.zeros((len(c),sdf_trailing_varyc[0]\
                                               .nInterpolatedTrackChunks,2))
    trackRAVlos_leading_out= numpy.zeros((len(c),sdf_trailing_varyc[0]\
                                              .nInterpolatedTrackChunks,2))
    if interpk is None:
        interpk = numpy.amin([len(interpcs) - 1, 3])
    for ii in range(sdf_trailing_varyc[0].nInterpolatedTrackChunks):
        ip= interpolate.InterpolatedUnivariateSpline(\
            interpcs,trackRADec_trailing[:,ii,0],k=interpk,ext=0)
        trackRADec_trailing_out[:, ii, 0] = ip(c)
        ip= interpolate.InterpolatedUnivariateSpline(\
            interpcs,trackRADec_trailing[:,ii,1],k=interpk,ext=0)
        trackRADec_trailing_out[:, ii, 1] = ip(c)
        ip= interpolate.InterpolatedUnivariateSpline(\
            interpcs,trackRAVlos_trailing[:,ii,0],k=interpk,ext=0)
        trackRAVlos_trailing_out[:, ii, 0] = ip(c)
        ip= interpolate.InterpolatedUnivariateSpline(\
            interpcs,trackRAVlos_trailing[:,ii,1],k=interpk,ext=0)
        trackRAVlos_trailing_out[:, ii, 1] = ip(c)
        if not trailing_only:
            ip= interpolate.InterpolatedUnivariateSpline(\
                interpcs,trackRADec_leading[:,ii,0],k=interpk,ext=0)
            trackRADec_leading_out[:, ii, 0] = ip(c)
            ip= interpolate.InterpolatedUnivariateSpline(\
                interpcs,trackRADec_leading[:,ii,1],k=interpk,ext=0)
            trackRADec_leading_out[:, ii, 1] = ip(c)
            ip= interpolate.InterpolatedUnivariateSpline(\
                interpcs,trackRAVlos_leading[:,ii,0],k=interpk,ext=0)
            trackRAVlos_leading_out[:, ii, 0] = ip(c)
            ip= interpolate.InterpolatedUnivariateSpline(\
                interpcs,trackRAVlos_leading[:,ii,1],k=interpk,ext=0)
            trackRAVlos_leading_out[:, ii, 1] = ip(c)
    ip= interpolate.InterpolatedUnivariateSpline(\
        interpcs,width,k=interpk,ext=0)
    width_out = ip(c)
    ip= interpolate.InterpolatedUnivariateSpline(\
        interpcs,length,k=interpk,ext=0)
    length_out = ip(c)
    return (trackRADec_trailing_out, trackRADec_leading_out,
            trackRAVlos_trailing_out, trackRAVlos_leading_out, width_out,
            length_out, interpcs, success)
Example #26
0
    def propagate(self, potential, dt=0.01 * u.Myr, threshold=None):
        '''
            Propagates the sample in the Galaxy, changes cattype from 0 to 1.

            Parameters
            ----------
                potential : galpy potential instance
                    Potential instance of the galpy library used to integrate the orbits
                dt : Quantity
                    Integration timestep. Defaults to 0.01 Myr
                threshold : float
                    Maximum relative energy difference between the initial energy and the energy at any point needed
                    to consider an integration step an energy outliar. E.g. for threshold=0.01, any excess or
                    deficit of 1% (or more) of the initial energy is enough to be registered as outliar.
                    A table E_data.fits is created in the working directory containing for every orbit the percentage
                    of outliar points (pol)

        '''
        from galpy.orbit import Orbit
        from galpy.util.bovy_coords import pmllpmbb_to_pmrapmdec, lb_to_radec, vrpmllpmbb_to_vxvyvz, lbd_to_XYZ

        if (self.cattype > 0):
            raise RuntimeError('This sample is already propagated!')

        if (threshold is None):
            check = False
        else:
            check = True

        # Integration time step
        self.dt = dt
        nsteps = np.ceil((self.tflight / self.dt).to('1').value)
        nsteps[nsteps < 100] = 100

        # Initialize position in cylindrical coords
        rho = self.r0 * np.sin(self.theta0)
        z = self.r0 * np.cos(self.theta0)
        phi = self.phi0

        #... and velocity
        vR = self.v0 * np.sin(self.thetav0) * np.cos(self.phiv0)
        vT = self.v0 * np.sin(self.thetav0) * np.sin(self.phiv0)
        vz = self.v0 * np.cos(self.thetav0)

        # Initialize empty arrays to save orbit data and integration steps
        self.pmll, self.pmbb, self.ll, self.bb, self.vlos, self.dist, self.energy_var = \
                                                                            (np.zeros(self.size) for i in xrange(7))
        self.orbits = [None] * self.size

        #Integration loop for the self.size orbits
        for i in xrange(self.size):
            ts = np.linspace(0, 1, nsteps[i]) * self.tflight[i]

            self.orbits[i] = Orbit(
                vxvv=[rho[i], vR[i], vT[i], z[i], vz[i], phi[i]],
                solarmotion=self.solarmotion)
            self.orbits[i].integrate(ts, potential, method='dopr54_c')

            # Export the final position
            self.dist[i], self.ll[i], self.bb[i], self.pmll[i], self.pmbb[i], self.vlos[i] = \
                                                self.orbits[i].dist(self.tflight[i], use_physical=True), \
                                                self.orbits[i].ll(self.tflight[i], use_physical=True), \
                                                self.orbits[i].bb(self.tflight[i], use_physical=True), \
                                                self.orbits[i].pmll(self.tflight[i], use_physical=True) , \
                                                self.orbits[i].pmbb(self.tflight[i], use_physical=True)  , \
                                                self.orbits[i].vlos(self.tflight[i], use_physical=True)

            # Energy check
            if (check):
                energy_array = self.orbits[i].E(ts)
                idx_energy = np.absolute(energy_array / energy_array[0] -
                                         1) > threshold
                self.energy_var[i] = float(
                    idx_energy.sum()) / nsteps[i]  # percentage of outliars

        # Radial velocity and distance + distance modulus
        self.vlos, self.dist = self.vlos * u.km / u.s, self.dist * u.kpc

        # Sky coordinates and proper motion
        data = pmllpmbb_to_pmrapmdec(
            self.pmll, self.pmbb, self.ll, self.bb,
            degree=True) * u.mas / u.year
        self.pmra, self.pmdec = data[:, 0], data[:, 1]
        data = lb_to_radec(self.ll, self.bb, degree=True) * u.deg
        self.ra, self.dec = data[:, 0], data[:, 1]

        # Done propagating
        self.cattype = 1

        # Save the energy check information
        if (check):
            from astropy.table import Table
            e_data = Table([self.m, self.tflight, self.energy_var],
                           names=['m', 'tflight', 'pol'])
            e_data.write('E_data.fits', overwrite=True)
Example #27
0
         plotvlos= vlos*218.-218
         save_pickles(mean_savefilename,
                      plotds,plotvlos)
 #Now calculate the whole vlos distribution at each d
 dist_savefilename= 'vhelio_l90_dist.sav'
 if os.path.exists(dist_savefilename):
     savefile= open(dist_savefilename,'rb')
     plotds= pickle.load(savefile)
     plotvloss= pickle.load(savefile)
     vlos_dist= pickle.load(savefile)
     savefile.close()
 else:
     nvloss= 101
     vloss= numpy.linspace(-0.7,0.25,nvloss)
     vlos_dist= numpy.zeros((nds,nvloss))
     ra, dec= bovy_coords.lb_to_radec(90.,0.,degree=True)
     for ii in range(nds):
         print ii
         for jj in range(nvloss):
             #Setup this Orbit
             o= Orbit([ra,dec,ds[ii],0.,0.,vloss[jj]],
                      radec=True,vo=1.,ro=1.,zo=0.,
                      solarmotion=[0.,25./218.,0.])
             vlos_dist[ii,jj]= dfc(o,marginalizeVperp=True)
     plotds= ds*8.
     plotvloss= vloss*218.
     save_pickles(dist_savefilename,plotds,plotvloss,vlos_dist)
 #Now plot
 bovy_plot.bovy_print()
 for ii in range(nds):
     vlos_dist[ii,:]/= numpy.sum(vlos_dist[ii,:])
Example #28
0
    threshold = 0.3
    print("Angular length: %f deg (leading,trailing)=(%f,%f) deg" % (
        sdf_leading.length(ang=True, coord="customra", threshold=threshold) +
        sdf_trailing.length(ang=True, coord="customra", threshold=threshold),
        sdf_leading.length(ang=True, coord="customra", threshold=threshold),
        sdf_trailing.length(ang=True, coord="customra", threshold=threshold),
    ))
    print("Angular width (FWHM): %f arcmin" % (width_trailing(sdf_trailing)))
    print("Velocity dispersion: %f km/s" %
          (pal5_util.vdisp_trailing(sdf_trailing)))

    # ----------------------------------------------------------

    trackRADec_trailing = bovy_coords.lb_to_radec(
        sdf_trailing._interpolatedObsTrackLB[:, 0],
        sdf_trailing._interpolatedObsTrackLB[:, 1],
        degree=True,
    )
    trackRADec_leading = bovy_coords.lb_to_radec(
        sdf_leading._interpolatedObsTrackLB[:, 0],
        sdf_leading._interpolatedObsTrackLB[:, 1],
        degree=True,
    )
    lb_sample_trailing = sdf_trailing.sample(n=10000, lb=True)
    lb_sample_leading = sdf_leading.sample(n=10000, lb=True)
    radec_sample_trailing = bovy_coords.lb_to_radec(lb_sample_trailing[0],
                                                    lb_sample_trailing[1],
                                                    degree=True)
    radec_sample_leading = bovy_coords.lb_to_radec(lb_sample_leading[0],
                                                   lb_sample_leading[1],
                                                   degree=True)
Example #29
0
def xyzuvw_to_skycoord(xyzuvw_in,
                       solarmotion='schoenrich',
                       reverse_x_sign=True):
    """Converts XYZUVW with respect to the LSR or the sun
    to RAdeg, DEdeg, plx, pmra, pmdec, RV
    
    Parameters
    ----------
    xyzuvw_in:
        XYZUVW with respect to the LSR.
        
    solarmotion: string
        The reference of assumed solar motion. "schoenrich" or None if inputs are already 
        relative to the sun.
        
    reverse_x_sign: bool
        Do we reverse the sign of the X co-ordinate? This is needed for dealing with 
        galpy sign conventions.

    TODO: not working at all... fix this
    """
    if solarmotion == None:
        xyzuvw_sun = np.zeros(6)
    elif solarmotion == 'schoenrich':
        xyzuvw_sun = [0, 0, 25, 11.1, 12.24, 7.25]
    else:
        raise UserWarning

    #Make coordinates relative to sun
    xyzuvw = xyzuvw_in - xyzuvw_sun

    #Special for the sun itself...
    #FIXME: This seems like a hack.
    #if (np.sum(xyzuvw**2) < 1) and solarmotion != None:
    #    return [0,0,1e5, 0,0,0]

    #Find l, b and distance.
    #!!! WARNING: the X-coordinate may have to be reversed here, just like everywhere else,
    #because of the convention in Orbit.x(), which doesn't seem to match X.
    if reverse_x_sign:
        lbd = bovy_coords.XYZ_to_lbd(-xyzuvw[0] / 1e3,
                                     xyzuvw[1] / 1e3,
                                     xyzuvw[2] / 1e3,
                                     degree=True)
    else:
        lbd = bovy_coords.XYZ_to_lbd(xyzuvw[0] / 1e3,
                                     xyzuvw[1] / 1e3,
                                     xyzuvw[2] / 1e3,
                                     degree=True)
    radec = bovy_coords.lb_to_radec(lbd[0], lbd[1], degree=True)
    vrpmllpmbb = bovy_coords.vxvyvz_to_vrpmllpmbb(xyzuvw[3],xyzuvw[4], xyzuvw[5],\
                    lbd[0],lbd[1],lbd[2], degree=True)
    pmrapmdec = bovy_coords.pmllpmbb_to_pmrapmdec(vrpmllpmbb[1],
                                                  vrpmllpmbb[2],
                                                  lbd[0],
                                                  lbd[1],
                                                  degree=True)
    return [
        radec[0], radec[1], 1.0 / lbd[2], pmrapmdec[0], pmrapmdec[1],
        vrpmllpmbb[0]
    ]
Example #30
0
    def propagate_initial(self,
                          potential,
                          index,
                          dt=0.01 * u.Myr,
                          size=100,
                          deltav=5. * u.km / u.s,
                          deltat=0.5 * u.Myr):
        '''
            Propagates the index-th star and _size_ more stars with random spread in
            initial velocity and flight time dictated by deltav, deltat.

            This overwrites the original catalogue!

            Parameters
            ----------
                index : int
                    Index of the star to propagate this in.
                size : int

                dv, dt : Quantity
                    Spread in initial velocity and
                See self.propagate() for the other parameters.

        '''
        from galpy.orbit import Orbit
        from galpy.util.bovy_coords import pmllpmbb_to_pmrapmdec, lb_to_radec, vrpmllpmbb_to_vxvyvz, lbd_to_XYZ

        self.r0, self.theta0, self.phi0, self.v0, self.phiv0, self.thetav0, self.tflight, self.tage, self.m = np.ones(size)*self.r0[index], np.ones(size)*self.theta0[index], \
                                        np.ones(size)*self.phi0[index], np.ones(size)*self.v0[index], np.ones(size)*self.phiv0[index], np.ones(size)*self.thetav0[index], \
                                        np.ones(size)*self.tflight[index], np.ones(size)*self.tage[index], np.ones(size)*self.m[index]

        self.v0 = self.v0 + np.random.normal(size=size) * deltav
        self.tflight = self.tflight + np.random.normal(size=size) * deltat
        self.size = size

        # Integration time step
        self.dt = dt
        nsteps = np.ceil((self.tflight / self.dt).to('1').value)
        nsteps[nsteps < 100] = 100

        # Initialize position in cylindrical coords
        rho = self.r0 * np.sin(self.theta0)
        z = self.r0 * np.cos(self.theta0)
        phi = self.phi0

        #... and velocity
        vR = self.v0 * np.sin(self.thetav0) * np.cos(self.phiv0)
        vT = self.v0 * np.sin(self.thetav0) * np.sin(self.phiv0)
        vz = self.v0 * np.cos(self.thetav0)

        # Initialize empty arrays to save orbit data and integration steps
        self.pmll, self.pmbb, self.ll, self.bb, self.vlos, self.dist, self.energy_var = \
                                                                            (np.zeros(self.size) for i in xrange(7))
        self.orbits = [None] * self.size

        #Integration loop for the self.size orbits
        for i in xrange(self.size):
            ts = np.linspace(0, 1, nsteps[i]) * self.tflight[i]

            self.orbits[i] = Orbit(
                vxvv=[rho[i], vR[i], vT[i], z[i], vz[i], phi[i]],
                solarmotion=self.solarmotion)
            self.orbits[i].integrate(ts, potential, method='dopr54_c')

            # Export the final position
            self.dist[i], self.ll[i], self.bb[i], self.pmll[i], self.pmbb[i], self.vlos[i] = \
                                                self.orbits[i].dist(self.tflight[i], use_physical=True), \
                                                self.orbits[i].ll(self.tflight[i], use_physical=True), \
                                                self.orbits[i].bb(self.tflight[i], use_physical=True), \
                                                self.orbits[i].pmll(self.tflight[i], use_physical=True) , \
                                                self.orbits[i].pmbb(self.tflight[i], use_physical=True)  , \
                                                self.orbits[i].vlos(self.tflight[i], use_physical=True)

        # Radial velocity and distance + distance modulus
        self.vlos, self.dist = self.vlos * u.km / u.s, self.dist * u.kpc

        # Sky coordinates and proper motion
        data = pmllpmbb_to_pmrapmdec(
            self.pmll, self.pmbb, self.ll, self.bb,
            degree=True) * u.mas / u.year
        self.pmra, self.pmdec = data[:, 0], data[:, 1]
        data = lb_to_radec(self.ll, self.bb, degree=True) * u.deg
        self.ra, self.dec = data[:, 0], data[:, 1]

        # Done propagating
        self.cattype = 1
Example #31
0
def fakeDFData(binned,qdf,ii,params,fehs,afes,options,
               rmin,rmax,
               platelb,
               grmin,grmax,
               fehrange,
               colordist,
               fehdist,feh,sf,
               mapfehs,mapafes,
               ro=None,vo=None,
               ndata=None,#If set, supersedes binned, only to be used w/ returnlist=True
               returnlist=False): #last one useful for pixelFitDF normintstuff
    if ro is None:
        ro= get_ro(params,options)
    if vo is None:
        vo= get_vo(params,options,len(fehs))
    thishr= qdf.estimate_hr(1.,z=0.125)*_REFR0*ro #qdf._hr*_REFR0*ro
    thishz= qdf.estimate_hz(1.,z=0.125)*_REFR0*ro
    if thishr < 0.: thishr= 10. #Probably close to flat
    if thishz  < 0.1: thishz= 0.2
    thissr= qdf._sr*_REFV0*vo
    thissz= qdf._sz*_REFV0*vo
    thishsr= qdf._hsr*_REFR0*ro
    thishsz= qdf._hsz*_REFR0*ro
    if True:
        if options.aAmethod.lower() == 'staeckel':
            #Make everything 10% larger
            thishr*= 1.2
            thishz*= 1.2
            thishsr*= 1.2
            thishsz*= 1.2
            thissr*= 2.
            thissz*= 2.
        else:
            #Make everything 20% larger
            thishr*= 1.2
            thishz*= 1.2
            thishsr*= 1.2
            thishsz*= 1.2
            thissr*= 2.
            thissz*= 2.
    #Find nearest mono-abundance bin that has a measurement
    abindx= numpy.argmin((fehs[ii]-mapfehs)**2./0.01 \
                             +(afes[ii]-mapafes)**2./0.0025)
    #Calculate the r-distribution for each plate
    nrs= 1001
    ngr, nfeh= 11, 11 #BOVY: INCREASE?
    tgrs= numpy.linspace(grmin,grmax,ngr)
    tfehs= numpy.linspace(fehrange[0]+0.00001,fehrange[1]-0.00001,nfeh)
    #Calcuate FeH and gr distriutions
    fehdists= numpy.zeros(nfeh)
    for jj in range(nfeh): fehdists[jj]= fehdist(tfehs[jj])
    fehdists= numpy.cumsum(fehdists)
    fehdists/= fehdists[-1]
    colordists= numpy.zeros(ngr)
    for jj in range(ngr): colordists[jj]= colordist(tgrs[jj])
    colordists= numpy.cumsum(colordists)
    colordists/= colordists[-1]
    rs= numpy.linspace(rmin,rmax,nrs)
    rdists= numpy.zeros((len(sf.plates),nrs,ngr,nfeh))
    #outlier model that we want to sample (not the one to aid in the sampling)
    srhalo= _SRHALO/vo/_REFV0
    sphihalo= _SPHIHALO/vo/_REFV0
    szhalo= _SZHALO/vo/_REFV0
    logoutfrac= numpy.log(get_outfrac(params,ii,options))
    loghalodens= numpy.log(ro*outDens(1.,0.,None))
    #Calculate surface(R=1.) for relative outlier normalization
    logoutfrac+= numpy.log(qdf.surfacemass_z(1.,ngl=options.ngl))
    if options.mcout:
        fidoutfrac= get_outfrac(params,ii,options)
        rdistsout= numpy.zeros((len(sf.plates),nrs,ngr,nfeh))
    lagoutfrac= 0.15 #.0000000000000000000000001 #seems good
    #Setup density model
    use_real_dens= True
    if use_real_dens:
        #nrs, nzs= 101, 101
        nrs, nzs= 64, 64
        thisRmin, thisRmax= 4./_REFR0, 15./_REFR0
        thiszmin, thiszmax= 0., .8
        Rgrid= numpy.linspace(thisRmin,thisRmax,nrs)
        zgrid= numpy.linspace(thiszmin,thiszmax,nzs)
        surfgrid= numpy.empty((nrs,nzs))
        for ll in range(nrs):
            for jj in range(nzs):
                sys.stdout.write('\r'+"Working on grid-point %i/%i" % (jj+ll*nzs+1,nzs*nrs))
                sys.stdout.flush()
                surfgrid[ll,jj]= qdf.density(Rgrid[ll],zgrid[jj],
                                             nmc=options.nmcv,
                                             ngl=options.ngl)
        sys.stdout.write('\r'+_ERASESTR+'\r')
        sys.stdout.flush()
        if _SURFSUBTRACTEXPON:
            Rs= numpy.tile(Rgrid,(nzs,1)).T
            Zs= numpy.tile(zgrid,(nrs,1))
            ehr= qdf.estimate_hr(1.,z=0.125)
#            ehz= qdf.estimate_hz(1.,zmin=0.5,zmax=0.7)#Get large z behavior right
            ehz= qdf.estimate_hz(1.,z=0.125)
            surfInterp= interpolate.RectBivariateSpline(Rgrid,zgrid,
                                                        numpy.log(surfgrid)
                                                        +Rs/ehr+numpy.fabs(Zs)/ehz,
                                                        kx=3,ky=3,
                                                        s=0.)
#                                                        s=10.*float(nzs*nrs))
        else:
            surfInterp= interpolate.RectBivariateSpline(Rgrid,zgrid,
                                                        numpy.log(surfgrid),
                                                        kx=3,ky=3,
                                                        s=0.)
#                                                        s=10.*float(nzs*nrs))
        if _SURFSUBTRACTEXPON:
            compare_func= lambda x,y,du: numpy.exp(surfInterp.ev(x/ro/_REFR0,numpy.fabs(y)/ro/_REFR0)-x/ro/_REFR0/ehr-numpy.fabs(y)/ehz/ro/_REFR0)
        else:
            compare_func= lambda x,y,du: numpy.exp(surfInterp.ev(x/ro/_REFR0,numpy.fabs(y)/ro/_REFR0))
    else:
        compare_func= lambda x,y,z: fidDens(x,y,thishr,thishz,z)
    for jj in range(len(sf.plates)):
        p= sf.plates[jj]
        sys.stdout.write('\r'+"Working on plate %i (%i/%i)" % (p,jj+1,len(sf.plates)))
        sys.stdout.flush()
        rdists[jj,:,:,:]= _predict_rdist_plate(rs,
                                               compare_func,
                                               None,rmin,rmax,
                                               platelb[jj,0],platelb[jj,1],
                                               grmin,grmax,
                                               fehrange[0],fehrange[1],feh,
                                               colordist,
                                               fehdist,sf,sf.plates[jj],
                                               dontmarginalizecolorfeh=True,
                                               ngr=ngr,nfeh=nfeh)
        if options.mcout:
            rdistsout[jj,:,:,:]= _predict_rdist_plate(rs,
                                                      lambda x,y,z: outDens(x,y,z),
                                                      None,rmin,rmax,
                                                      platelb[jj,0],platelb[jj,1],
                                                      grmin,grmax,
                                                      fehrange[0],fehrange[1],feh,
                                                      colordist,
                                                      fehdist,sf,sf.plates[jj],
                                                      dontmarginalizecolorfeh=True,
                                                      ngr=ngr,nfeh=nfeh)
    sys.stdout.write('\r'+_ERASESTR+'\r')
    sys.stdout.flush()
    numbers= numpy.sum(rdists,axis=3)
    numbers= numpy.sum(numbers,axis=2)
    numbers= numpy.sum(numbers,axis=1)
    numbers= numpy.cumsum(numbers)
    if options.mcout:
        totfid= numbers[-1]
    numbers/= numbers[-1]
    rdists= numpy.cumsum(rdists,axis=1)
    for ll in range(len(sf.plates)):
        for jj in range(ngr):
            for kk in range(nfeh):
                rdists[ll,:,jj,kk]/= rdists[ll,-1,jj,kk]
    if options.mcout:
        numbersout= numpy.sum(rdistsout,axis=3)
        numbersout= numpy.sum(numbersout,axis=2)
        numbersout= numpy.sum(numbersout,axis=1)
        numbersout= numpy.cumsum(numbersout)
        totout= fidoutfrac*numbersout[-1]
        totnumbers= totfid+totout
        totfid/= totnumbers
        totout/= totnumbers
        if _DEBUG:
            print totfid, totout
        numbersout/= numbersout[-1]
        rdistsout= numpy.cumsum(rdistsout,axis=1)
        for ll in range(len(sf.plates)):
            for jj in range(ngr):
                for kk in range(nfeh):
                    rdistsout[ll,:,jj,kk]/= rdistsout[ll,-1,jj,kk]
    #Now sample
    thisout= []
    newrs= []
    newls= []
    newbs= []
    newplate= []
    newgr= []
    newfeh= []
    newds= []
    newzs= []
    newvas= []
    newRs= []
    newphi= []
    newvr= []
    newvt= []
    newvz= []
    newlogratio= []
    newfideval= []
    newqdfeval= []
    newpropeval= []
    if ndata is None:
        thisdata= binned(fehs[ii],afes[ii])
        thisdataIndx= binned.callIndx(fehs[ii],afes[ii])
        ndata= len(thisdata)
    #First sample from spatial density
    for ll in range(ndata):
        #First sample a plate
        ran= numpy.random.uniform()
        kk= 0
        while numbers[kk] < ran: kk+= 1
        #Also sample a FeH and a color
        ran= numpy.random.uniform()
        ff= 0
        while fehdists[ff] < ran: ff+= 1
        ran= numpy.random.uniform()
        cc= 0
        while colordists[cc] < ran: cc+= 1
        #plate==kk, feh=ff,color=cc; now sample from the rdist of this plate
        ran= numpy.random.uniform()
        jj= 0
        if options.mcout and numpy.random.uniform() < totout: #outlier
            while rdistsout[kk,jj,cc,ff] < ran: jj+= 1
            thisoutlier= True
        else:
            while rdists[kk,jj,cc,ff] < ran: jj+= 1
            thisoutlier= False
        #r=jj
        newrs.append(rs[jj])
        newls.append(platelb[kk,0])
        newbs.append(platelb[kk,1])
        newplate.append(sf.plates[kk])
        newgr.append(tgrs[cc])
        newfeh.append(tfehs[ff])
        dist= _ivezic_dist(tgrs[cc],rs[jj],tfehs[ff])
        newds.append(dist)
        #calculate R,z
        XYZ= bovy_coords.lbd_to_XYZ(platelb[kk,0],platelb[kk,1],
                                    dist,degree=True)
        R= ((_REFR0-XYZ[0])**2.+XYZ[1]**2.)**(0.5)
        newRs.append(R)
        phi= numpy.arcsin(XYZ[1]/R)
        if (_REFR0-XYZ[0]) < 0.:
            phi= numpy.pi-phi
        newphi.append(phi)
        z= XYZ[2]+_ZSUN
        newzs.append(z)
    newrs= numpy.array(newrs)
    newls= numpy.array(newls)
    newbs= numpy.array(newbs)
    newplate= numpy.array(newplate)
    newgr= numpy.array(newgr)
    newfeh= numpy.array(newfeh)
    newds= numpy.array(newds)
    newRs= numpy.array(newRs)
    newzs= numpy.array(newzs)
    newphi= numpy.array(newphi)
    #Add mock velocities
    newvr= numpy.empty_like(newrs)
    newvt= numpy.empty_like(newrs)
    newvz= numpy.empty_like(newrs)
    use_sampleV= True
    if use_sampleV:
        for kk in range(ndata):
            newv= qdf.sampleV(newRs[kk]/_REFR0,newzs[kk]/_REFR0,n=1)
            newvr[kk]= newv[0,0]*_REFV0*vo
            newvt[kk]= newv[0,1]*_REFV0*vo
            newvz[kk]= newv[0,2]*_REFV0*vo
    else:
        accept_v= numpy.zeros(ndata,dtype='bool')
        naccept= numpy.sum(accept_v)
        sigz= thissz*numpy.exp(-(newRs-_REFR0)/thishsz)
        sigr= thissr*numpy.exp(-(newRs-_REFR0)/thishsr)
        va= numpy.empty_like(newrs)
        sigphi= numpy.empty_like(newrs)
        maxqdf= numpy.empty_like(newrs)
        nvt= 101
        tvt= numpy.linspace(0.1,1.2,nvt)
        for kk in range(ndata):
            #evaluate qdf for vt
            pvt= qdf(newRs[kk]/ro/_REFR0+numpy.zeros(nvt),
                     numpy.zeros(nvt),
                     tvt,
                     newzs[kk]/ro/_REFR0+numpy.zeros(nvt),
                     numpy.zeros(nvt),log=True)
            pvt_maxindx= numpy.argmax(pvt)
            va[kk]= (1.-tvt[pvt_maxindx])*_REFV0*vo
            if options.aAmethod.lower() == 'adiabaticgrid' and options.flatten >= 0.9:
                maxqdf[kk]= pvt[pvt_maxindx]+numpy.log(250.)
            elif options.aAmethod.lower() == 'adiabaticgrid' and options.flatten >= 0.8:
                maxqdf[kk]= pvt[pvt_maxindx]+numpy.log(250.)
            else:
                maxqdf[kk]= pvt[pvt_maxindx]+numpy.log(40.)
            sigphi[kk]= _REFV0*vo*4.*numpy.sqrt(numpy.sum(numpy.exp(pvt)*tvt**2.)/numpy.sum(numpy.exp(pvt))-(numpy.sum(numpy.exp(pvt)*tvt)/numpy.sum(numpy.exp(pvt)))**2.)
        ntries= 0
        ngtr1= 0
        while naccept < ndata:
            sys.stdout.write('\r %i %i %i \r' % (ntries,naccept,ndata))
            sys.stdout.flush()
            #print ntries, naccept, ndata
            ntries+= 1
            accept_v_comp= True-accept_v
            prop_vr= numpy.random.normal(size=ndata)*sigr
            prop_vt= numpy.random.normal(size=ndata)*sigphi+vo*_REFV0-va
            prop_vz= numpy.random.normal(size=ndata)*sigz
            qoverp= numpy.zeros(ndata)-numpy.finfo(numpy.dtype(numpy.float64)).max
            qoverp[accept_v_comp]= (qdf(newRs[accept_v_comp]/ro/_REFR0,
                                        prop_vr[accept_v_comp]/vo/_REFV0,
                                        prop_vt[accept_v_comp]/vo/_REFV0,
                                        newzs[accept_v_comp]/ro/_REFR0,
                                        prop_vz[accept_v_comp]/vo/_REFV0,log=True)
                                    -maxqdf[accept_v_comp] #normalize max to 1
                                    -(-0.5*(prop_vr[accept_v_comp]**2./sigr[accept_v_comp]**2.+prop_vz[accept_v_comp]**2./sigz[accept_v_comp]**2.+(prop_vt[accept_v_comp]-_REFV0*vo+va[accept_v_comp])**2./sigphi[accept_v_comp]**2.)))
            if numpy.any(qoverp > 0.):
                ngtr1+= numpy.sum((qoverp > 0.))
                if ngtr1 > 5:
                    qindx= (qoverp > 0.)
                    print naccept, ndata, newRs[qindx], newzs[qindx], prop_vr[qindx], va[qindx], sigphi[qindx], prop_vt[qindx], prop_vz[qindx], qoverp[qindx]
                    raise RuntimeError("max qoverp = %f > 1, but shouldn't be" % (numpy.exp(numpy.amax(qoverp))))
            accept_these= numpy.log(numpy.random.uniform(size=ndata))
            #print accept_these, (accept_these < qoverp)
            accept_these= (accept_these < qoverp)        
            newvr[accept_these]= prop_vr[accept_these]
            newvt[accept_these]= prop_vt[accept_these]
            newvz[accept_these]= prop_vz[accept_these]
            accept_v[accept_these]= True
            naccept= numpy.sum(accept_v)
        sys.stdout.write('\r'+_ERASESTR+'\r')
        sys.stdout.flush()
    """
    ntot= 0
    nsamples= 0
    itt= 0
    fracsuccess= 0.
    fraccomplete= 0.
    while fraccomplete < 1.:
        if itt == 0:
            nthis= numpy.amax([ndata,_NMIN])
        else:
            nthis= int(numpy.ceil((1-fraccomplete)/fracsuccess*ndata))
        itt+= 1
        count= 0
        while count < nthis:
            count+= 1
            sigz= thissz*numpy.exp(-(R-_REFR0)/thishsz)
            sigr= thissr*numpy.exp(-(R-_REFR0)/thishsr)
            sigphi= sigr #/numpy.sqrt(2.) #BOVY: FOR NOW
            #Estimate asymmetric drift
            va= sigr**2./2./_REFV0/vo\
                *(-.5+R*(1./thishr+2./thishsr))+10.*numpy.fabs(z)
            newvas.append(va)
            if options.mcout and thisoutlier:
                #Sample from outlier gaussian
                newvz.append(numpy.random.normal()*_SZHALOFAKE*2.)
                newvr.append(numpy.random.normal()*_SRHALOFAKE*2.)
                newvt.append(numpy.random.normal()*_SPHIHALOFAKE*2.)
            elif numpy.random.uniform() < lagoutfrac:
                #Sample from lagging gaussian
                newvz.append(numpy.random.normal()*_SZHALOFAKE)
                newvr.append(numpy.random.normal()*_SRHALOFAKE)
                newvt.append(numpy.random.normal()*_SPHIHALOFAKE*2.+_REFV0*vo/4.)
            else:
                #Sample from disk gaussian
                newvz.append(numpy.random.normal()*sigz)
                newvr.append(numpy.random.normal()*sigr)
                newvt.append(numpy.random.normal()*sigphi+_REFV0*vo-va)
            newlogratio= list(newlogratio)
            fidlogeval= numpy.log(1.-lagoutfrac)\
                     -numpy.log(sigr)-numpy.log(sigphi)-numpy.log(sigz)-0.5*(newvr[-1]**2./sigr**2.+newvz[-1]**2./sigz**2.+(newvt[-1]-_REFV0*vo+va)**2./sigphi**2.)
            lagoutlogeval= numpy.log(lagoutfrac)\
                     -numpy.log(_SRHALOFAKE)\
                     -numpy.log(_SPHIHALOFAKE*2.)\
                     -numpy.log(_SZHALOFAKE)\
                     -0.5*(newvr[-1]**2./_SRHALOFAKE**2.+newvz[-1]**2./_SZHALOFAKE**2.+(newvt[-1]-_REFV0*vo/4.)**2./_SPHIHALOFAKE**2./4.)
            if use_real_dens:
                fidlogeval+= numpy.log(compare_func(R,z,None)[0])
                lagoutlogeval+= numpy.log(compare_func(R,z,None)[0])
            else:
                fidlogeval+= numpy.log(fidDens(R,z,thishr,thishz,None))
                lagoutlogeval+= numpy.log(fidDens(R,z,thishr,thishz,None))
            newfideval.append(fidlogeval)
            if options.mcout:
                fidoutlogeval= numpy.log(fidoutfrac)\
                    +numpy.log(outDens(R,z,None))\
                    -numpy.log(_SRHALOFAKE*2.)\
                    -numpy.log(_SPHIHALOFAKE*2.)\
                    -numpy.log(_SZHALOFAKE*2.)\
                    -0.5*(newvr[-1]**2./_SRHALOFAKE**2./4.+newvz[-1]**2./_SZHALOFAKE**2./4.+newvt[-1]**2./_SPHIHALOFAKE**2./4.)
                newpropeval.append(logsumexp([fidoutlogeval,fidlogeval,
                                              lagoutlogeval]))
            else:
                newpropeval.append(logsumexp([lagoutlogeval,fidlogeval]))
            qdflogeval= qdf(R/ro/_REFR0,newvr[-1]/vo/_REFV0,newvt[-1]/vo/_REFV0,z/ro/_REFR0,newvz[-1]/vo/_REFV0,log=True)
            if isinstance(qdflogeval,(list,numpy.ndarray)):
                qdflogeval= qdflogeval[0]
            if options.mcout:
                outlogeval= logoutfrac+loghalodens\
                    -numpy.log(srhalo)-numpy.log(sphihalo)-numpy.log(szhalo)\
                    -0.5*((newvr[-1]/vo/_REFV0)**2./srhalo**2.+(newvz[-1]/vo/_REFV0)**2./szhalo**2.+(newvt[-1]/vo/_REFV0)**2./sphihalo**2.)\
                    -1.5*numpy.log(2.*numpy.pi)
                newqdfeval.append(logsumexp([qdflogeval,outlogeval]))
            else:
                newqdfeval.append(qdflogeval)
            newlogratio.append(qdflogeval
                               -newpropeval[-1])#logsumexp([fidlogeval,fidoutlogeval]))
        newlogratio= numpy.array(newlogratio)
        thisnewlogratio= copy.copy(newlogratio)
        maxnewlogratio= numpy.amax(thisnewlogratio)
        if False:
            argsort_thisnewlogratio= numpy.argsort(thisnewlogratio)[::-1]
            thisnewlogratio-= thisnewlogratio[argsort_thisnewlogratio[2]] #3rd largest
        else:
            thisnewlogratio-= numpy.amax(thisnewlogratio)
        thisnewratio= numpy.exp(thisnewlogratio)
        if len(thisnewratio.shape) > 1 and thisnewratio.shape[1] == 1:
            thisnewratio= numpy.reshape(thisnewratio,(thisnewratio.shape[0]))
        #Rejection sample
        accept= numpy.random.uniform(size=len(thisnewratio))
        accept= (accept < thisnewratio)
        fraccomplete= float(numpy.sum(accept))/ndata
        fracsuccess= float(numpy.sum(accept))/len(thisnewratio)
        if _DEBUG:
            print fraccomplete, fracsuccess, ndata
            print numpy.histogram(thisnewratio,bins=16)
            indx= numpy.argmax(thisnewratio)
            print numpy.array(newvr)[indx], \
                numpy.array(newvt)[indx], \
                numpy.array(newvz)[indx], \
                numpy.array(newrs)[indx], \
                numpy.array(newds)[indx], \
                numpy.array(newls)[indx], \
                numpy.array(newbs)[indx], \
                numpy.array(newfideval)[indx]
            bovy_plot.bovy_print()
            bovy_plot.bovy_plot(numpy.array(newvt),
                                numpy.exp(numpy.array(newqdfeval)),'b,',
                                xrange=[-300.,500.],yrange=[0.,1.])
            bovy_plot.bovy_plot(newvt,
                                numpy.exp(numpy.array(newpropeval+maxnewlogratio)),
                                'g,',
                                overplot=True)
            bovy_plot.bovy_plot(numpy.array(newvt),
                                numpy.exp(numpy.array(newlogratio-maxnewlogratio)),
                                'b,',
                                xrange=[-300.,500.],
                                #                            xrange=[0.,20.],
                                #                            xrange=[0.,3.],
                                #                            xrange=[6.,9.],
                                yrange=[0.001,1.],semilogy=True)
            bovy_plot.bovy_end_print('/home/bovy/public_html/segue-local/test.png')
    #Now collect the samples
    newrs= numpy.array(newrs)[accept][0:ndata]
    newls= numpy.array(newls)[accept][0:ndata]
    newbs= numpy.array(newbs)[accept][0:ndata]
    newplate= numpy.array(newplate)[accept][0:ndata]
    newgr= numpy.array(newgr)[accept][0:ndata]
    newfeh= numpy.array(newfeh)[accept][0:ndata]
    newvr= numpy.array(newvr)[accept][0:ndata]
    newvt= numpy.array(newvt)[accept][0:ndata]
    newvz= numpy.array(newvz)[accept][0:ndata]
    newphi= numpy.array(newphi)[accept][0:ndata]
    newds= numpy.array(newds)[accept][0:ndata]
    newqdfeval= numpy.array(newqdfeval)[accept][0:ndata]
    """
    vx, vy, vz= bovy_coords.galcencyl_to_vxvyvz(newvr,newvt,newvz,newphi,
                                                vsun=[_VRSUN,_VTSUN,_VZSUN])
    vrpmllpmbb= bovy_coords.vxvyvz_to_vrpmllpmbb(vx,vy,vz,newls,newbs,newds,
                                                 XYZ=False,degree=True)
    pmrapmdec= bovy_coords.pmllpmbb_to_pmrapmdec(vrpmllpmbb[:,1],
                                                 vrpmllpmbb[:,2],
                                                 newls,newbs,
                                                 degree=True)
    #Dump everything for debugging the coordinate transformation
    from galpy.util import save_pickles
    save_pickles('dump.sav',
                 newds,newls,newbs,newphi,
                 newvr,newvt,newvz,
                 vx, vy, vz,
                 vrpmllpmbb,
                 pmrapmdec)
    if returnlist:
        out= []
        for ii in range(ndata):
            out.append([newrs[ii],
                        newgr[ii],
                        newfeh[ii],
                        newls[ii],
                        newbs[ii],
                        newplate[ii],
                        newds[ii],
                        False, #outlier?
                        vrpmllpmbb[ii,0],
                        vrpmllpmbb[ii,1],
                        vrpmllpmbb[ii,2]])#,
#                        newqdfeval[ii]])
        return out
    #Load into data
    binned.data.feh[thisdataIndx]= newfeh
    oldgr= thisdata.dered_g-thisdata.dered_r
    oldr= thisdata.dered_r
    if options.noerrs:
        binned.data.dered_r[thisdataIndx]= newrs
    else:
        binned.data.dered_r[thisdataIndx]= newrs\
            +numpy.random.normal(size=numpy.sum(thisdataIndx))\
            *ivezic_dist_gr(oldgr,0., #g-r is all that counts
                            binned.data.feh[thisdataIndx],
                            dg=binned.data[thisdataIndx].g_err,
                            dr=binned.data[thisdataIndx].r_err,
                            dfeh=binned.data[thisdataIndx].feh_err,
                            return_error=True,
                            _returndmr=True)
    binned.data.dered_r[(binned.data.dered_r >= rmax)]= rmax #tweak to make sure everything stays within the observed range
    if False:
        binned.data.dered_r[(binned.data.dered_r <= rmin)]= rmin
    binned.data.dered_g[thisdataIndx]= oldgr+binned.data[thisdataIndx].dered_r
    #Also change plate and l and b
    binned.data.plate[thisdataIndx]= newplate
    radec= bovy_coords.lb_to_radec(newls,newbs,degree=True)
    binned.data.ra[thisdataIndx]= radec[:,0]
    binned.data.dec[thisdataIndx]= radec[:,1]
    binned.data.l[thisdataIndx]= newls
    binned.data.b[thisdataIndx]= newbs
    if options.noerrs:
        binned.data.vr[thisdataIndx]= vrpmllpmbb[:,0]
        binned.data.pmra[thisdataIndx]= pmrapmdec[:,0]
        binned.data.pmdec[thisdataIndx]= pmrapmdec[:,1]
    else:
        binned.data.vr[thisdataIndx]= vrpmllpmbb[:,0]+numpy.random.normal(size=numpy.sum(thisdataIndx))*binned.data.vr_err[thisdataIndx]
        binned.data.pmra[thisdataIndx]= pmrapmdec[:,0]+numpy.random.normal(size=numpy.sum(thisdataIndx))*binned.data.pmra_err[thisdataIndx]
        binned.data.pmdec[thisdataIndx]= pmrapmdec[:,1]+numpy.random.normal(size=numpy.sum(thisdataIndx))*binned.data.pmdec_err[thisdataIndx]
    return binned
Example #32
0
def pmllpmbb_to_pmphi12(pmll,pmbb,l,b,degree=False):
    """
    NAME:
       pmllpmbb_to_pmphi12
    PURPOSE:
       Transform proper mtions in Galactic coordinates (l,b) to (phi1,phi2)
    INPUT:
       pmll - proper motion Galactic longitude (rad or degree); contains xcosb
       pmbb - Galactic latitude (rad or degree)
       l - Galactic longitude (rad or degree)
       b - Galactic latitude (rad or degree)
       degree= (False) if True, input (l,b) are in degrees
    OUTPUT:
       (pmphi1,pmphi2) for scalar input
       [:,2] array for vector input
    HISTORY:
        2014-11-04 - Written - Bovy (IAS)
    """
    import numpy
    from   galpy.util import bovy_coords
    
    
    _TKOP= numpy.zeros((3,3))
    _TKOP[0,:]= [-0.4776303088,-0.1738432154,0.8611897727]
    _TKOP[1,:]= [0.510844589,-0.8524449229,0.111245042]
    _TKOP[2,:]= [0.7147776536,0.4930681392,0.4959603976]
    
    #First go to ra and dec
    radec= bovy_coords.lb_to_radec(l,b)
    ra= radec[:,0]
    dec= radec[:,1]
    pmradec= bovy_coords.pmllpmbb_to_pmrapmdec(pmll,pmbb,l,b,degree=False)
    pmra= pmradec[:,0]
    pmdec= pmradec[:,1]
    #Now transform ra,dec pm to phi1,phi2
    phi12= lb_to_phi12(l,b,degree=False)
    phi1= phi12[:,0]
    phi2= phi12[:,1]
    #Build A and Aphi matrices
    A= numpy.zeros((3,3,len(ra)))
    A[0,0]= numpy.cos(ra)*numpy.cos(dec)
    A[0,1]= -numpy.sin(ra)
    A[0,2]= -numpy.cos(ra)*numpy.sin(dec)
    A[1,0]= numpy.sin(ra)*numpy.cos(dec)
    A[1,1]= numpy.cos(ra)
    A[1,2]= -numpy.sin(ra)*numpy.sin(dec)
    A[2,0]= numpy.sin(dec)
    A[2,1]= 0.
    A[2,2]= numpy.cos(dec)
    AphiInv= numpy.zeros((3,3,len(ra)))
    AphiInv[0,0]= numpy.cos(phi1)*numpy.cos(phi2)
    AphiInv[0,1]= numpy.cos(phi2)*numpy.sin(phi1)
    AphiInv[0,2]= numpy.sin(phi2)
    AphiInv[1,0]= -numpy.sin(phi1)
    AphiInv[1,1]= numpy.cos(phi1)
    AphiInv[1,2]= 0.
    AphiInv[2,0]= -numpy.cos(phi1)*numpy.sin(phi2)
    AphiInv[2,1]= -numpy.sin(phi1)*numpy.sin(phi2)
    AphiInv[2,2]= numpy.cos(phi2)
    TA= numpy.dot(_TKOP,numpy.swapaxes(A,0,1))
    #Got lazy...
    trans= numpy.zeros((2,2,len(ra)))
    for ii in range(len(ra)):
        trans[:,:,ii]= numpy.dot(AphiInv[:,:,ii],TA[:,:,ii])[1:,1:]
    return (trans*numpy.array([[pmra,pmdec],[pmra,pmdec]])).sum(1).T
sdf_smooth= pal5_util.setup_pal5model()
pepperfilename= 'pal5pepper1sampling.pkl'
if os.path.exists(pepperfilename):
    with open(pepperfilename,'rb') as savefile:
        sdf_pepper= pickle.load(savefile)
else:
    import simulate_streampepper
    timpacts= simulate_streampepper.parse_times('1sampling',9.)
    sdf_pepper= pal5_util.setup_pal5model(timpact=timpacts,
                                        hernquist=True)
    save_pickles(pepperfilename,sdf_pepper)

# Convert track to xi, eta
trackRADec=\
  bovy_coords.lb_to_radec(sdf_smooth._interpolatedObsTrackLB[:,0],
                          sdf_smooth._interpolatedObsTrackLB[:,1],
                          degree=True)
trackXiEta=\
  pal5_util.radec_to_pal5xieta(trackRADec[:,0],
                    trackRADec[:,1],degree=True)
smooth_track= []
for coord in range(6):
    if coord < 2:
        smooth_track.append(\
            interpolate.InterpolatedUnivariateSpline(sdf_smooth._interpolatedThetasTrack,
                                                     trackXiEta[:,coord]))
    else:
        smooth_track.append(\
            interpolate.InterpolatedUnivariateSpline(sdf_smooth._interpolatedThetasTrack,
                                                     sdf_smooth._interpolatedObsTrackLB[:,coord]))
smooth_ll= interpolate.InterpolatedUnivariateSpline(trackXiEta[:,0],
def predict_pal5obs(
    pot_params: list,
    c: float,
    b: float = 1.0,
    pa: float = 0.0,
    sigv: Union[float, list] = 0.2,
    td: float = 10.0,
    dist: float = 23.2,
    pmra: float = -2.296,
    pmdec: float = -2.257,
    vlos: float = -58.7,
    ro: float = REFR0,
    vo: float = REFV0,
    singlec: bool = False,
    interpcs: Optional[float] = None,
    interpk: Optional[float] = None,
    isob: Optional[float] = None,
    nTrackChunks: int = 8,
    multi: Optional = None,
    trailing_only: bool = False,
    useTM: bool = False,
    verbose: bool = True,
) -> TrackTuple:
    """Predict Pal 5 Observed.

    Function that generates the location and velocity of the Pal 5 stream,
    its width, and its length for a given potential and progenitor
    phase-space position

    Parameters
    ----------
    pot_params: array
        parameters of a potential model
        (see mw_pot.setup_potential; only the basic
         parameters of the disk and halo are used,
         flattening is specified separately)
    c : float
        halo flattening
    b : float, optional
        (1.) halo-squashed
    pa: float, optional
        (0.) halo PA
    sigv : float, optional
        (0.4) velocity dispersion in km/s
        (can be array of same len as interpcs)
    td : float, optional
        (5.) stream age in Gyr (can be array of same len as interpcs)
    dist : float, optional
        (23.2) progenitor distance in kpc
    pmra : float, optional
        (-2.296) progenitor proper motion in RA * cos(Dec) in mas/yr
    pmdec : float, optional
        (-2.257) progenitor proper motion in Dec in mas/yr
    vlos : float, optional
        (-58.7) progenitor line-of-sight velocity in km/s
    ro : float, optional
        (project default) distance to the GC in kpc
    vo : float, optional
        (project default) circular velocity at R0 in km/s
    singlec : bool, optional
        (False) if True, just compute the observables for a single c
    interpcs : float or None, optional
        (None) values of c at which to compute the model for interpolation
    nTrackChunks : int, optional
        (8) nTrackChunks input to streamdf
    multi : float or None, optional
        (None) multi input to streamdf
    isob : float or None, optional
        (None) if given, b parameter of actionAngleIsochroneApprox
    trailing_only : bool, optional
        (False) if True, only predict the trailing arm
    useTM : bool, optional
        (True) use the TorusMapper to compute the track
    verbose : bool, optional
        (True) print messages


    Returns
    -------
    trackRADec_trailing_out : array
        trailing track in RA, Dec
        all arrays with the shape of c
    trackRADec_leading_out : array
        leading track in RA, Dec
        all arrays with the shape of c
    trackRAVlos_trailing_out : array
        trailing track in RA, Vlos
        all arrays with the shape of c
    trackRAVlos_leading_out : array
        leading track in RA, Vlos
        all arrays with the shape of c
    width_out : float
        trailing width in arcmin
    length_out : float
        trailing length in deg
    interpcs : array
    success : bool

    """

    # First compute the model for all cs at which we will interpolate
    interpcs: list
    if singlec:
        interpcs = [c]
    elif interpcs is None:
        interpcs = [
            0.5,
            0.75,
            1.0,
            1.25,
            1.55,
            1.75,
            2.0,
            2.25,
            2.5,
            2.75,
            3.0,
        ]
    else:
        interpcs = copy.deepcopy(interpcs)  # bc we might want to remove some
    if isinstance(sigv, float):
        sigv: list = [sigv for i in interpcs]
    if isinstance(td, float):
        td: list = [td for i in interpcs]
    if isinstance(isob, float) or isob is None:
        isob: list = [isob for i in interpcs]

    prog: Orbit = Orbit(
        [229.018, -0.124, dist, pmra, pmdec, vlos],
        radec=True,
        ro=ro,
        vo=vo,
        solarmotion=[-11.1, 24.0, 7.25],
    )

    # Setup the model
    sdf_trailing_varyc: list = []
    sdf_leading_varyc: list = []
    ii: int = 0
    ninterpcs: int = len(interpcs)
    this_useTM: bool = copy.deepcopy(useTM)
    this_nTrackChunks: int = nTrackChunks
    ntries: int = 0

    while ii < ninterpcs:
        ic = interpcs[ii]
        pot = mw_pot.setup_potential(pot_params,
                                     ic,
                                     False,
                                     False,
                                     ro,
                                     vo,
                                     b=b,
                                     pa=pa)
        success: bool = True
        # wentIn = ntries != 0
        # Make sure this doesn't run forever
        signal.signal(signal.SIGALRM, timeout_handler)
        signal.alarm(300)
        try:
            tsdf_trailing, tsdf_leading = setup_sdf(
                pot,
                prog,
                sigv[ii],
                td[ii],
                ro,
                vo,
                multi=multi,
                isob=isob[ii],
                nTrackChunks=this_nTrackChunks,
                trailing_only=trailing_only,
                verbose=verbose,
                useTM=this_useTM,
            )
        except Exception:
            # Catches errors and time-outs
            success = False
        signal.alarm(0)
        # Check for calc. issues
        if not success or (not this_useTM
                           and looks_funny(tsdf_trailing, tsdf_leading)):
            # Try again with TM
            this_useTM = True
            this_nTrackChunks = 21  # might as well

            # wentIn= True
            # print("Here",ntries,success)
            # sys.stdout.flush()

            ntries += 1
        else:
            success = not this_useTM
            # if wentIn:
            #    print(success)
            #    sys.stdout.flush()
            ii += 1
            # reset
            this_useTM = useTM
            this_nTrackChunks = nTrackChunks
            ntries = 0
            # Add to the list
            sdf_trailing_varyc.append(tsdf_trailing)
            sdf_leading_varyc.append(tsdf_leading)

    if not singlec and len(sdf_trailing_varyc) <= 1:
        # Almost everything bad!!
        return (
            np.zeros((len(c), 1001, 2)),
            np.zeros((len(c), 1001, 2)),
            np.zeros((len(c), 1001, 2)),
            np.zeros((len(c), 1001, 2)),
            np.zeros((len(c))),
            np.zeros((len(c))),
            [],
            success,
        )
    # Compute the track properties for each model
    trackRADec_trailing: np.ndarray = np.zeros(
        (len(interpcs), sdf_trailing_varyc[0].nInterpolatedTrackChunks, 2))
    trackRADec_leading: np.ndarray = np.zeros(
        (len(interpcs), sdf_trailing_varyc[0].nInterpolatedTrackChunks, 2))
    trackRAVlos_trailing: np.ndarray = np.zeros(
        (len(interpcs), sdf_trailing_varyc[0].nInterpolatedTrackChunks, 2))
    trackRAVlos_leading: np.ndarray = np.zeros(
        (len(interpcs), sdf_trailing_varyc[0].nInterpolatedTrackChunks, 2))
    # TODO put in distances (can use _interpolatedObsTrackLB[:,2],)
    width: np.ndarray = np.zeros(len(interpcs))
    length: np.ndarray = np.zeros(len(interpcs))
    for ii in range(len(interpcs)):
        trackRADec_trailing[ii] = bovy_coords.lb_to_radec(
            sdf_trailing_varyc[ii]._interpolatedObsTrackLB[:, 0],
            sdf_trailing_varyc[ii]._interpolatedObsTrackLB[:, 1],
            degree=True,
        )
        if not trailing_only:
            trackRADec_leading[ii] = bovy_coords.lb_to_radec(
                sdf_leading_varyc[ii]._interpolatedObsTrackLB[:, 0],
                sdf_leading_varyc[ii]._interpolatedObsTrackLB[:, 1],
                degree=True,
            )
        trackRAVlos_trailing[ii][:, 0] = trackRADec_trailing[ii][:, 0]
        trackRAVlos_trailing[ii][:, 1] = sdf_trailing_varyc[
            ii]._interpolatedObsTrackLB[:, 3]
        if not trailing_only:
            trackRAVlos_leading[ii][:, 0] = trackRADec_leading[ii][:, 0]
            trackRAVlos_leading[ii][:, 1] = sdf_leading_varyc[
                ii]._interpolatedObsTrackLB[:, 3]
        width[ii] = width_trailing(sdf_trailing_varyc[ii])
        length[ii] = sdf_trailing_varyc[ii].length(ang=True,
                                                   coord="customra",
                                                   threshold=0.3)
    if singlec:
        # if wentIn:
        #    print(success)
        #    sys.stdout.flush()
        return (
            trackRADec_trailing,
            trackRADec_leading,
            trackRAVlos_trailing,
            trackRAVlos_leading,
            width,
            length,
            interpcs,
            success,
        )
    # Interpolate; output grids
    trackRADec_trailing_out: np.ndarray = np.zeros(
        (len(c), sdf_trailing_varyc[0].nInterpolatedTrackChunks, 2))
    trackRADec_leading_out: np.ndarray = np.zeros(
        (len(c), sdf_trailing_varyc[0].nInterpolatedTrackChunks, 2))
    trackRAVlos_trailing_out: np.ndarray = np.zeros(
        (len(c), sdf_trailing_varyc[0].nInterpolatedTrackChunks, 2))
    trackRAVlos_leading_out: np.ndarray = np.zeros(
        (len(c), sdf_trailing_varyc[0].nInterpolatedTrackChunks, 2))

    if interpk is None:
        interpk = np.amin([len(interpcs) - 1, 3])

    for ii in range(sdf_trailing_varyc[0].nInterpolatedTrackChunks):
        ip = interpolate.InterpolatedUnivariateSpline(interpcs,
                                                      trackRADec_trailing[:,
                                                                          ii,
                                                                          0],
                                                      k=interpk,
                                                      ext=0)
        trackRADec_trailing_out[:, ii, 0] = ip(c)
        ip = interpolate.InterpolatedUnivariateSpline(interpcs,
                                                      trackRADec_trailing[:,
                                                                          ii,
                                                                          1],
                                                      k=interpk,
                                                      ext=0)
        trackRADec_trailing_out[:, ii, 1] = ip(c)
        ip = interpolate.InterpolatedUnivariateSpline(interpcs,
                                                      trackRAVlos_trailing[:,
                                                                           ii,
                                                                           0],
                                                      k=interpk,
                                                      ext=0)
        trackRAVlos_trailing_out[:, ii, 0] = ip(c)
        ip = interpolate.InterpolatedUnivariateSpline(interpcs,
                                                      trackRAVlos_trailing[:,
                                                                           ii,
                                                                           1],
                                                      k=interpk,
                                                      ext=0)
        trackRAVlos_trailing_out[:, ii, 1] = ip(c)

        if not trailing_only:
            ip = interpolate.InterpolatedUnivariateSpline(
                interpcs, trackRADec_leading[:, ii, 0], k=interpk, ext=0)
            trackRADec_leading_out[:, ii, 0] = ip(c)
            ip = interpolate.InterpolatedUnivariateSpline(
                interpcs, trackRADec_leading[:, ii, 1], k=interpk, ext=0)
            trackRADec_leading_out[:, ii, 1] = ip(c)
            ip = interpolate.InterpolatedUnivariateSpline(
                interpcs, trackRAVlos_leading[:, ii, 0], k=interpk, ext=0)
            trackRAVlos_leading_out[:, ii, 0] = ip(c)
            ip = interpolate.InterpolatedUnivariateSpline(
                interpcs, trackRAVlos_leading[:, ii, 1], k=interpk, ext=0)
            trackRAVlos_leading_out[:, ii, 1] = ip(c)
    # /for

    ip = interpolate.InterpolatedUnivariateSpline(interpcs,
                                                  width,
                                                  k=interpk,
                                                  ext=0)
    width_out = ip(c)
    ip = interpolate.InterpolatedUnivariateSpline(interpcs,
                                                  length,
                                                  k=interpk,
                                                  ext=0)
    length_out = ip(c)

    return TrackTuple(
        trackRADec_trailing_out=trackRADec_trailing_out,
        trackRADec_leading_out=trackRADec_leading_out,
        trackRAVlos_trailing_out=trackRAVlos_trailing_out,
        trackRAVlos_leading_out=trackRAVlos_leading_out,
        width_out=width_out,
        length_out=length_out,
        interpcs=interpcs,
        success=success,
    )
Example #35
0
def _fit_orbit_mlogl(new_vxvv,vxvv,vxvv_err,pot,radec,lb,tmockAA,
                     ro,vo,obs):
    """The log likelihood for fitting an orbit"""
    #Use this _parse_args routine, which does forward and backward integration
    iR,ivR,ivT,iz,ivz,iphi= tmockAA._parse_args(True,False,
                                                new_vxvv[0],
                                                new_vxvv[1],
                                                new_vxvv[2],
                                                new_vxvv[3],
                                                new_vxvv[4],
                                                new_vxvv[5])
    if radec or lb:
        #Need to transform to ra,dec
        #First transform to X,Y,Z,vX,vY,vZ (Galactic)
        X,Y,Z = coords.galcencyl_to_XYZ(iR.flatten(),iphi.flatten(),
                                        iz.flatten(),
                                        Xsun=obs[0]/ro,
                                        Ysun=obs[1]/ro,
                                        Zsun=obs[2]/ro)
        vX,vY,vZ = coords.galcencyl_to_vxvyvz(ivR.flatten(),ivT.flatten(),
                                              ivz.flatten(),iphi.flatten(),
                                              vsun=nu.array(\
                obs[3:6])/vo)
        bad_indx= (X == 0.)*(Y == 0.)*(Z == 0.)
        if True in bad_indx: X[bad_indx]+= ro/10000.
        lbdvrpmllpmbb= coords.rectgal_to_sphergal(X*ro,Y*ro,Z*ro,
                                                  vX*vo,vY*vo,vZ*vo,
                                                  degree=True)
        if lb:
            orb_vxvv= nu.array([lbdvrpmllpmbb[:,0],
                                lbdvrpmllpmbb[:,1],
                                lbdvrpmllpmbb[:,2],
                                lbdvrpmllpmbb[:,4],
                                lbdvrpmllpmbb[:,5],
                                lbdvrpmllpmbb[:,3]]).T
        else:
            #Further transform to ra,dec,pmra,pmdec
            radec= coords.lb_to_radec(lbdvrpmllpmbb[:,0],
                                      lbdvrpmllpmbb[:,1],degree=True)
            pmrapmdec= coords.pmllpmbb_to_pmrapmdec(lbdvrpmllpmbb[:,4],
                                                    lbdvrpmllpmbb[:,5],
                                                    lbdvrpmllpmbb[:,0],
                                                    lbdvrpmllpmbb[:,1],
                                                    degree=True)
            orb_vxvv= nu.array([radec[:,0],radec[:,1],
                                lbdvrpmllpmbb[:,2],
                                pmrapmdec[:,0],pmrapmdec[:,1],
                                lbdvrpmllpmbb[:,3]]).T
    else:
        #shape=(2tintJ-1,6)
        orb_vxvv= nu.array([iR.flatten(),ivR.flatten(),ivT.flatten(),
                            iz.flatten(),ivz.flatten(),iphi.flatten()]).T 
    out= 0.
    for ii in range(vxvv.shape[0]):
        sub_vxvv= (orb_vxvv-vxvv[ii,:].flatten())**2.
        #print sub_vxvv[nu.argmin(nu.sum(sub_vxvv,axis=1))]
        if not vxvv_err is None:
            sub_vxvv/= vxvv_err[ii,:]**2.
        else:
            sub_vxvv/= 0.01**2.
        out+= logsumexp(-0.5*nu.sum(sub_vxvv,axis=1))
    return -out
Example #36
0
def example_integrate_orbit():
    # Use 'MWPotential2014' as an example
    my_potential = MWPotential2014

    # integration time in units of (_R0/_V0)
    time_start = 0.
    time_end = 100.
    my_time_step = numpy.linspace(time_start, time_end, 1001)

    # read 6D astrometric data
    # (0) [mas] parallax
    # (1) [deg] ell
    # (2) [deg] b
    # (3) [km/s] heliocentric line-of-sight velocity
    # (4) [mas/yr] proper motion along ell direction (mu_ellstar = mu_ell * cos(b))
    # (5) [mas/yr] proper motion along b direction (mu_b)

    my_filename = 'parallax_ell_b_heliocentricLineOfSightVelocity_properMotionEllStar_properMotionB.txt'
    my_file = open(my_filename, 'r')
    my_data = numpy.loadtxt(my_file, comments='#')

    my_parallax_mas = my_data[:, 0]
    my_ell_deg = my_data[:, 1]
    my_b_deg = my_data[:, 2]
    my_hlosv_kms = my_data[:, 3]
    my_muellstar_masyr = my_data[:, 4]
    my_mub_masyr = my_data[:, 5]

    # count sample size
    my_sample_size = len(my_ell_deg)

    for i in range(my_sample_size):
        print('star ID=%d' % (i))

        # convert parallax to distance
        distance_kpc = 1. / my_parallax_mas[i]

        # convert (ell, b) to (RA, DEC)
        RA_deg, DEC_deg = bovy_coords.lb_to_radec(my_ell_deg[i],
                                                  my_b_deg[i],
                                                  degree=True,
                                                  epoch=_my_epoch)

        # heliocentric line-of-sight velocity
        hlosv_kms = my_hlosv_kms[i]

        # convert (mu_ellstar, mu_b) to (mu_RAstar, mu_DEC)
        muRAstar_masyr, muDEC_masyr = bovy_coords.pmllpmbb_to_pmrapmdec(
            my_muellstar_masyr[i],
            my_mub_masyr[i],
            my_ell_deg[i],
            my_b_deg[i],
            degree=True,
            epoch=_my_epoch)

        # create orbit instance
        obs_6D = Orbit(vxvv=[
            RA_deg, DEC_deg, distance_kpc, muRAstar_masyr, muDEC_masyr,
            hlosv_kms
        ],
                       radec=True,
                       ro=_R0,
                       vo=_V0,
                       zo=0.,
                       solarmotion=[_Usun, _Vsun, _Wsun])

        # integrate orbit in my_potential
        obs_6D.integrate(my_time_step, my_potential)

        # file on which we write 6D data at each time step
        outfile_i = open("t_x_y_z_vx_vy_vz_R__orbitID%03d.txt" % (i), 'w')

        # For illustrative purpose, I use an explicit expression to access 6D data at each time.
        for j in range(len(my_time_step)):
            # Here I assume that
            # (a) Galactic Center is located at (x,y)=(0,0) kpc
            # (b) Sun is located at (x,y)=(-8,0) kpc
            # (c) Nearby disc stars with circular orbits move towards (vx,vy)=(0,220) km/s
            # This is why I add a minus sign (-) to x and vx.
            x = -obs_6D.x(my_time_step[j])
            y = obs_6D.y(my_time_step[j])
            z = obs_6D.z(my_time_step[j])
            vx = -obs_6D.vx(my_time_step[j])
            vy = obs_6D.vy(my_time_step[j])
            vz = obs_6D.vz(my_time_step[j])
            R = obs_6D.R(my_time_step[j])
            printline = '%lf %lf %lf %lf %lf %lf %lf %lf\n' % (
                my_time_step[j], x, y, z, vx, vy, vz, R)
            outfile_i.write(printline)

        # close file
        outfile_i.close()

    return None
Example #37
0
def pmphi12_to_pmllpmbb(pmphi1,pmphi2,phi1,phi2,degree=False):
    """
        NAME:
        pmllpmbb_to_pmphi12
        PURPOSE:
        Transform proper motions in (phi1,phi2) to Galactic coordinates (l,b)
        INPUT:
        pmphi1 - proper motion Galactic longitude (rad or degree); contains xcosphi2
        pmphi2 - Galactic latitude (rad or degree)
        phi1 - phi longitude (rad or degree)
        phi2 - phi latitude (rad or degree)
        degree= (False) if True, input (phi1,phi2) are in degrees
        OUTPUT:
        (pmll,pmbb) for scalar input
        [:,2] array for vector input
        HISTORY:
        2014-11-04 - Written - Bovy (IAS)
        """
    import numpy
    
    _TKOP= numpy.zeros((3,3))
    _TKOP[0,:]= [-0.4776303088,-0.1738432154,0.8611897727]
    _TKOP[1,:]= [0.510844589,-0.8524449229,0.111245042]
    _TKOP[2,:]= [0.7147776536,0.4930681392,0.4959603976]
    
    #First go from phi12 to ra and dec
    lb= phi12_to_lb(phi1,phi2)
    radec= bovy_coords.lb_to_radec(lb[:,0],lb[:,1])
    ra= radec[:,0]
    dec= radec[:,1]
    #Build A and Aphi matrices
    AInv= numpy.zeros((3,3,len(ra)))
    AInv[0,0]= numpy.cos(ra)*numpy.cos(dec)
    AInv[0,1]= numpy.sin(ra)*numpy.cos(dec)
    AInv[0,2]= numpy.sin(dec)
    AInv[1,0]= -numpy.sin(ra)
    AInv[1,1]= numpy.cos(ra)
    AInv[1,2]= 0.
    AInv[2,0]= -numpy.cos(ra)*numpy.sin(dec)
    AInv[2,1]= -numpy.sin(ra)*numpy.sin(dec)
    AInv[2,2]= numpy.cos(dec)
    Aphi= numpy.zeros((3,3,len(ra)))
    Aphi[0,0]= numpy.cos(phi1)*numpy.cos(phi2)
    Aphi[0,1]= -numpy.sin(phi1)
    Aphi[0,2]= -numpy.cos(phi1)*numpy.sin(phi2)
    Aphi[1,0]= numpy.sin(phi1)*numpy.cos(phi2)
    Aphi[1,1]= numpy.cos(phi1)
    Aphi[1,2]= -numpy.sin(phi1)*numpy.sin(phi2)
    Aphi[2,0]= numpy.sin(phi2)
    Aphi[2,1]= 0.
    Aphi[2,2]= numpy.cos(phi2)
    TAphi= numpy.dot(_TKOP.T,numpy.swapaxes(Aphi,0,1))
    #Got lazy...
    trans= numpy.zeros((2,2,len(ra)))
    for ii in range(len(ra)):
        trans[:,:,ii]= numpy.dot(AInv[:,:,ii],TAphi[:,:,ii])[1:,1:]
    pmradec= (trans*numpy.array([[pmphi1,pmphi2],[pmphi1,pmphi2]])).sum(1).T
    pmra= pmradec[:,0]
    pmdec= pmradec[:,1]
    #Now convert to pmll
    return bovy_coords.pmrapmdec_to_pmllpmbb(pmra,pmdec,ra,dec)
Example #38
0
def fiducial_model(
    sdf_trailing="output/sdf_trailing.pkl",
    sdf_leading="output/sdf_leading.pkl",
    threshold=0.3,
    ro=REFR0,
    vo=REFV0,
):
    """Fiducial Model.

    The fiducial model assumes a spherical halo, with the best-fit
    parameters from fitting to the MWPotential2014 data

    """
    p_b15 = [
        0.60122692,
        0.36273147,
        -0.97591502,
        -3.34169377,
        0.71877924,
        -0.01519337,
        -0.01928001,
    ]

    pot = mw_pot.setup_potential(p_b15, 1.0, False, False, ro, vo)

    prog = Orbit(
        [229.018, -0.124, 23.2, -2.296, -2.257, -58.7],
        radec=True,
        ro=ro,
        vo=vo,
        solarmotion=[-11.1, 24.0, 7.25],
    )
    aAI = actionAngleIsochroneApprox(pot=pot, b=0.8)
    sigv = 0.2

    # ----------------------------------------------------------

    try:
        with open(sdf_trailing, "rb") as file:
            sdf_trailing = pickle.load(file)
    except Exception:
        sdf_trailing = streamdf(
            sigv / vo,
            progenitor=prog,
            pot=pot,
            aA=aAI,
            leading=False,
            nTrackChunks=11,
            tdisrupt=10.0 / bovy_conversion.time_in_Gyr(vo, ro),
            ro=ro,
            vo=vo,
            R0=ro,
            vsun=[-11.1, vo + 24.0, 7.25],
            custom_transform=pal5_util._TPAL5,
        )
        with open(sdf_trailing, "wb") as file:
            pickle.dump(sdf_trailing, file)

    try:
        with open(sdf_leading, "rb") as file:
            sdf_leading = pickle.load(file)
    except Exception:
        sdf_leading = streamdf(
            sigv / vo,
            progenitor=prog,
            pot=pot,
            aA=aAI,
            leading=True,
            nTrackChunks=11,
            tdisrupt=10.0 / bovy_conversion.time_in_Gyr(vo, ro),
            ro=ro,
            vo=vo,
            R0=ro,
            vsun=[-11.1, vo + 24.0, 7.25],
            custom_transform=pal5_util._TPAL5,
        )
        with open(sdf_leading, "wb") as file:
            pickle.dump(sdf_leading, file)

    # ----------------------------------------------------------

    print("Angular length: %f deg (leading,trailing)=(%f,%f) deg" % (
        sdf_leading.length(ang=True, coord="customra", threshold=threshold) +
        sdf_trailing.length(ang=True, coord="customra", threshold=threshold),
        sdf_leading.length(ang=True, coord="customra", threshold=threshold),
        sdf_trailing.length(ang=True, coord="customra", threshold=threshold),
    ))
    print("Angular width (FWHM): %f arcmin" %
          (pal5_util.width_trailing(sdf_trailing)))
    print("Velocity dispersion: %f km/s" %
          (pal5_util.vdisp_trailing(sdf_trailing)))

    # ----------------------------------------------------------

    trackRADec_trailing = bovy_coords.lb_to_radec(
        sdf_trailing._interpolatedObsTrackLB[:, 0],
        sdf_trailing._interpolatedObsTrackLB[:, 1],
        degree=True,
    )
    trackRADec_leading = bovy_coords.lb_to_radec(
        sdf_leading._interpolatedObsTrackLB[:, 0],
        sdf_leading._interpolatedObsTrackLB[:, 1],
        degree=True,
    )
    lb_sample_trailing = sdf_trailing.sample(n=10000, lb=True)
    lb_sample_leading = sdf_leading.sample(n=10000, lb=True)
    radec_sample_trailing = bovy_coords.lb_to_radec(lb_sample_trailing[0],
                                                    lb_sample_trailing[1],
                                                    degree=True)
    radec_sample_leading = bovy_coords.lb_to_radec(lb_sample_leading[0],
                                                   lb_sample_leading[1],
                                                   degree=True)

    # ----------------------------------------------------------
    # plotting

    plt.figure(figsize=(12, 4))
    plt.subplot(1, 2, 1)
    bovy_plot.bovy_plot(
        trackRADec_trailing[:, 0],
        trackRADec_trailing[:, 1],
        color=sns.color_palette()[0],
        xrange=[250.0, 210.0],
        yrange=[-15.0, 9.0],
        xlabel=r"$\mathrm{RA}\,(\mathrm{degree})$",
        ylabel=r"$\mathrm{Dec}\,(\mathrm{degree})$",
        gcf=True,
    )
    bovy_plot.bovy_plot(
        trackRADec_leading[:, 0],
        trackRADec_leading[:, 1],
        color=sns.color_palette()[0],
        overplot=True,
    )
    plt.plot(
        radec_sample_trailing[:, 0],
        radec_sample_trailing[:, 1],
        "k.",
        alpha=0.01,
        zorder=0,
    )
    plt.plot(
        radec_sample_leading[:, 0],
        radec_sample_leading[:, 1],
        "k.",
        alpha=0.01,
        zorder=0,
    )
    plt.errorbar(
        pos_radec[:, 0],
        pos_radec[:, 1],
        yerr=pos_radec[:, 2],
        ls="none",
        marker="o",
        color=sns.color_palette()[2],
    )
    plt.subplot(1, 2, 2)
    bovy_plot.bovy_plot(
        trackRADec_trailing[:, 0],
        sdf_trailing._interpolatedObsTrackLB[:, 3],
        color=sns.color_palette()[0],
        xrange=[250.0, 210.0],
        yrange=[-80.0, 0.0],
        xlabel=r"$\mathrm{RA}\,(\mathrm{degree})$",
        ylabel=r"$V_{\mathrm{los}}\,(\mathrm{km\,s}^{-1})$",
        gcf=True,
    )
    bovy_plot.bovy_plot(
        trackRADec_leading[:, 0],
        sdf_leading._interpolatedObsTrackLB[:, 3],
        color=sns.color_palette()[0],
        overplot=True,
    )
    plt.plot(
        radec_sample_trailing[:, 0],
        lb_sample_trailing[3],
        "k.",
        alpha=0.01,
        zorder=0,
    )
    plt.plot(
        radec_sample_leading[:, 0],
        lb_sample_leading[3],
        "k.",
        alpha=0.01,
        zorder=0,
    )
    plt.errorbar(
        rvel_ra[:, 0],
        rvel_ra[:, 1],
        yerr=rvel_ra[:, 2],
        ls="none",
        marker="o",
        color=sns.color_palette()[2],
    )

    plt.savefig("figures/fiducial_model.pdf")

    return
Example #39
0
def _fit_orbit_mlogl(new_vxvv, vxvv, vxvv_err, pot, radec, lb, customsky,
                     lb_to_customsky, pmllpmbb_to_customsky, tmockAA, ro, vo,
                     obs):
    """The log likelihood for fitting an orbit"""
    #Use this _parse_args routine, which does forward and backward integration
    iR, ivR, ivT, iz, ivz, iphi = tmockAA._parse_args(True, False, new_vxvv[0],
                                                      new_vxvv[1], new_vxvv[2],
                                                      new_vxvv[3], new_vxvv[4],
                                                      new_vxvv[5])
    if radec or lb or customsky:
        #Need to transform to (l,b), (ra,dec), or a custom set
        #First transform to X,Y,Z,vX,vY,vZ (Galactic)
        X, Y, Z = coords.galcencyl_to_XYZ(iR.flatten(),
                                          iphi.flatten(),
                                          iz.flatten(),
                                          Xsun=obs[0] / ro,
                                          Zsun=obs[2] / ro).T
        vX,vY,vZ = coords.galcencyl_to_vxvyvz(ivR.flatten(),ivT.flatten(),
                                              ivz.flatten(),iphi.flatten(),
                                              vsun=nu.array(\
                obs[3:6])/vo,Xsun=obs[0]/ro,Zsun=obs[2]/ro).T
        bad_indx = (X == 0.) * (Y == 0.) * (Z == 0.)
        if True in bad_indx: X[bad_indx] += ro / 10000.
        lbdvrpmllpmbb = coords.rectgal_to_sphergal(X * ro,
                                                   Y * ro,
                                                   Z * ro,
                                                   vX * vo,
                                                   vY * vo,
                                                   vZ * vo,
                                                   degree=True)
        if lb:
            orb_vxvv = nu.array([
                lbdvrpmllpmbb[:, 0], lbdvrpmllpmbb[:, 1], lbdvrpmllpmbb[:, 2],
                lbdvrpmllpmbb[:, 4], lbdvrpmllpmbb[:, 5], lbdvrpmllpmbb[:, 3]
            ]).T
        elif radec:
            #Further transform to ra,dec,pmra,pmdec
            radec = coords.lb_to_radec(lbdvrpmllpmbb[:, 0],
                                       lbdvrpmllpmbb[:, 1],
                                       degree=True,
                                       epoch=None)
            pmrapmdec = coords.pmllpmbb_to_pmrapmdec(lbdvrpmllpmbb[:, 4],
                                                     lbdvrpmllpmbb[:, 5],
                                                     lbdvrpmllpmbb[:, 0],
                                                     lbdvrpmllpmbb[:, 1],
                                                     degree=True,
                                                     epoch=None)
            orb_vxvv = nu.array([
                radec[:, 0], radec[:, 1], lbdvrpmllpmbb[:, 2], pmrapmdec[:, 0],
                pmrapmdec[:, 1], lbdvrpmllpmbb[:, 3]
            ]).T
        elif customsky:
            #Further transform to ra,dec,pmra,pmdec
            customradec = lb_to_customsky(lbdvrpmllpmbb[:, 0],
                                          lbdvrpmllpmbb[:, 1],
                                          degree=True)
            custompmrapmdec = pmllpmbb_to_customsky(lbdvrpmllpmbb[:, 4],
                                                    lbdvrpmllpmbb[:, 5],
                                                    lbdvrpmllpmbb[:, 0],
                                                    lbdvrpmllpmbb[:, 1],
                                                    degree=True)
            orb_vxvv = nu.array([
                customradec[:, 0], customradec[:, 1], lbdvrpmllpmbb[:, 2],
                custompmrapmdec[:, 0], custompmrapmdec[:, 1], lbdvrpmllpmbb[:,
                                                                            3]
            ]).T
    else:
        #shape=(2tintJ-1,6)
        orb_vxvv = nu.array([
            iR.flatten(),
            ivR.flatten(),
            ivT.flatten(),
            iz.flatten(),
            ivz.flatten(),
            iphi.flatten()
        ]).T
    out = 0.
    for ii in range(vxvv.shape[0]):
        sub_vxvv = (orb_vxvv - vxvv[ii, :].flatten())**2.
        #print(sub_vxvv[nu.argmin(nu.sum(sub_vxvv,axis=1))])
        if not vxvv_err is None:
            sub_vxvv /= vxvv_err[ii, :]**2.
        else:
            sub_vxvv /= 0.01**2.
        out += logsumexp(-0.5 * nu.sum(sub_vxvv, axis=1))
    return -out
def main(args: Optional[list] = None, opts: Optional[Namespace] = None):
    """Fit MWPotential2014 Script Function.

    Parameters
    ----------
    args : list, optional
        an optional single argument that holds the sys.argv list,
        except for the script name (e.g., argv[1:])
    opts : Namespace, optional
        pre-constructed results of parsed args
        if not None, used ONLY if args is None

    """
    if opts is not None and args is None:
        pass
    else:
        if opts is not None:
            warnings.warn("Not using `opts` because `args` are given")
        parser = make_parser()
        opts = parser.parse_args(args)

    fpath = opts.fpath + "/" if not opts.fpath.endswith("/") else opts.fpath
    opath = opts.opath + "/" if not opts.opath.endswith("/") else opts.opath

    # plot chains
    print("Plotting Chains")
    fig = mcmc_util.plot_chains(opath)
    fig.savefig(fpath + "chains.pdf")
    plt.close(fig)

    print("Need to continue chains:", end=" ")
    for i in range(32):
        ngood = mcmc_util.determine_nburn(
            filename=opath + f"mwpot14-fitsigma-{i:02}.dat", return_nsamples=True,
        )
        if ngood < 4000:
            print(f"{i:02} (N={ngood})", end=", ")

    ###############################################################
    # RESULTING PDFS

    data, _, weights, _ = read_mcmc(nburn=None, skip=1, evi_func=lambda x: 1.0)

    plot_corner(data, weights=weights)
    plt.savefig("figures/PDFs/corner.pdf")
    plt.close()

    # --------------

    savefilename = "output/pal5_forces_mcmc.pkl"
    if not os.path.exists(savefilename):
        data_wf, index_wf, weights_wf, evi_wf = read_mcmc(
            nburn=None, addforces=True, skip=1, evi_func=lambda x: 1.0
        )
        save_pickles(savefilename, data_wf, index_wf, weights_wf, evi_wf)
    else:
        with open(savefilename, "rb") as savefile:
            data_wf = pickle.load(savefile)
            index_wf = pickle.load(savefile)
            weights_wf = pickle.load(savefile)
            evi_wf = pickle.load(savefile)

    # --------------
    plot_corner(data_wf, weights=weights_wf, addvcprior=False)
    plt.savefig("figures/PDFs/corner_wf.pdf")
    plt.close()

    # --------------
    # Which potential is preferred?
    data_noforce, potindx, weights, evidences = read_mcmc(evi_func=evi_harmonic)

    fig = plt.figure(figsize=(6, 4))
    bovy_plot.bovy_plot(
        potindx,
        np.log(evidences),
        "o",
        xrange=[-1, 34],
        yrange=[-35, -22],
        xlabel=r"$\mathrm{Potential\ index}$",
        ylabel=r"$\ln\ \mathrm{evidence}$",
    )
    data_noforce, potindx, weights, evidences = read_mcmc(evi_func=evi_laplace)
    bovy_plot.bovy_plot(potindx, np.log(evidences) - 30.0, "d", overplot=True)
    data_noforce, potindx, weights, evidences = read_mcmc(
        evi_func=lambda x: np.exp(np.amax(x[:, -1]))
    )
    bovy_plot.bovy_plot(potindx, np.log(evidences) - 8.0, "s", overplot=True)
    data_noforce, potindx, weights, evidences = read_mcmc(
        evi_func=lambda x: np.exp(-25.0)
        if (np.log(evi_harmonic(x)) > -25.0)
        else np.exp(-50.0)
    )
    bovy_plot.bovy_plot(potindx, np.log(evidences), "o", overplot=True)
    plt.savefig("figures/PDFs/preferred_pot.pdf")
    plt.close()

    ###############################################################
    # Look at the results for individual potentials

    # --------------
    # The flattening $c$
    npot = 32
    nwalkers = 12

    plt.figure(figsize=(16, 6))
    cmap = cm.plasma
    maxl = np.zeros((npot, 2))
    for en, ii in enumerate(range(npot)):
        data_ip, _, weights_ip, evi_ip = read_mcmc(singlepot=ii, evi_func=evi_harmonic)
        try:
            maxl[en, 0] = np.amax(data_ip[:, -1])
            maxl[en, 1] = np.log(evi_ip[0])
        except ValueError:
            maxl[en] = -10000000.0
        plt.subplot(2, 4, en // 4 + 1)
        bovy_plot.bovy_hist(
            data_ip[:, 0],
            range=[0.5, 2.0],
            bins=26,
            histtype="step",
            color=cmap((en % 4) / 3.0),
            normed=True,
            xlabel=r"$c$",
            lw=1.5,
            overplot=True,
        )
        if en % 4 == 0:
            bovy_plot.bovy_text(
                r"$\mathrm{Potential\ %i\ to\ % i}$" % (en, en + 3),
                size=17.0,
                top_left=True,
            )
    plt.tight_layout()
    plt.savefig("figures/flattening_c.pdf")
    plt.close()

    ###############################################################
    # What is the effective prior in $(F_R,F_Z)$?

    frfzprior_savefilename = "frfzprior.pkl"
    if not os.path.exists(frfzprior_savefilename):
        # Compute for each potential separately
        nvoc = 10000
        ro = 8.0
        npot = 32
        fs = np.zeros((2, nvoc, npot))
        for en, ii in tqdm(enumerate(range(npot))):
            fn = f"output/fitsigma/mwpot14-fitsigma-{i:02}.dat"
            # Read the potential parameters
            with open(fn, "r") as savefile:
                line1 = savefile.readline()
            potparams = [float(s) for s in (line1.split(":")[1].split(","))]
            for jj in range(nvoc):
                c = np.random.uniform() * 1.5 + 0.5
                tvo = np.random.uniform() * 50.0 + 200.0
                pot = mw_pot.setup_potential(potparams, c, False, False, REFR0, tvo)
                fs[:, jj, ii] = np.array(pal5_util.force_pal5(pot, 23.46, REFR0, tvo))[
                    :2
                ]
        save_pickles(frfzprior_savefilename, fs)
    else:
        with open(frfzprior_savefilename, "rb") as savefile:
            fs = pickle.load(savefile)

    # --------------
    plt.figure(figsize=(6, 6))
    bovy_plot.scatterplot(
        fs[0].flatten(),
        fs[1].flatten(),
        "k,",
        xrange=[-1.75, -0.25],
        yrange=[-2.5, -1.2],
        xlabel=r"$F_R(\mathrm{Pal\ 5})$",
        ylabel=r"$F_Z(\mathrm{Pal\ 5})$",
        onedhists=True,
    )
    bovy_plot.scatterplot(
        data_wf[:, 7],
        data_wf[:, 8],
        weights=weights_wf,
        bins=26,
        xrange=[-1.75, -0.25],
        yrange=[-2.5, -1.2],
        justcontours=True,
        cntrcolors="w",
        overplot=True,
        onedhists=True,
    )
    plt.axvline(-0.81, color=sns.color_palette()[0])
    plt.axhline(-1.85, color=sns.color_palette()[0])
    plt.savefig("figures/effective_force_prior.pdf")
    plt.close()

    # --------------
    # The ratio of the posterior and the prior

    bovy_plot.bovy_print(
        axes_labelsize=17.0,
        text_fontsize=12.0,
        xtick_labelsize=14.0,
        ytick_labelsize=14.0,
    )
    plt.figure(figsize=(12.5, 4))

    def axes_white():
        for k, spine in plt.gca().spines.items():  # ax.spines is a dictionary
            spine.set_color("w")
        plt.gca().tick_params(axis="x", which="both", colors="w")
        plt.gca().tick_params(axis="y", which="both", colors="w")
        [t.set_color("k") for t in plt.gca().xaxis.get_ticklabels()]
        [t.set_color("k") for t in plt.gca().yaxis.get_ticklabels()]
        return None

    bins = 32
    trange = [[-1.75, -0.25], [-2.5, -1.2]]
    tw = copy.deepcopy(weights_wf)
    tw[index_wf == 14] = 0.0  # Didn't converge properly
    H_prior, xedges, yedges = np.histogram2d(
        fs[0].flatten(), fs[1].flatten(), bins=bins, range=trange, normed=True
    )
    H_post, xedges, yedges = np.histogram2d(
        data_wf[:, 7], data_wf[:, 8], weights=tw, bins=bins, range=trange, normed=True,
    )
    H_like = H_post / H_prior
    H_like[H_prior == 0.0] = 0.0
    plt.subplot(1, 3, 1)
    bovy_plot.bovy_dens2d(
        H_prior.T,
        origin="lower",
        cmap="viridis",
        interpolation="nearest",
        xrange=[xedges[0], xedges[-1]],
        yrange=[yedges[0], yedges[-1]],
        xlabel=r"$F_R(\mathrm{Pal\ 5})\,(\mathrm{km\,s}^{-1}\,\mathrm{Myr}^{-1})$",
        ylabel=r"$F_Z(\mathrm{Pal\ 5})\,(\mathrm{km\,s}^{-1}\,\mathrm{Myr}^{-1})$",
        gcf=True,
    )
    bovy_plot.bovy_text(r"$\mathbf{Prior}$", top_left=True, size=19.0, color="w")
    axes_white()
    plt.subplot(1, 3, 2)
    bovy_plot.bovy_dens2d(
        H_post.T,
        origin="lower",
        cmap="viridis",
        interpolation="nearest",
        xrange=[xedges[0], xedges[-1]],
        yrange=[yedges[0], yedges[-1]],
        xlabel=r"$F_R(\mathrm{Pal\ 5})\,(\mathrm{km\,s}^{-1}\,\mathrm{Myr}^{-1})$",
        gcf=True,
    )
    bovy_plot.bovy_text(r"$\mathbf{Posterior}$", top_left=True, size=19.0, color="w")
    axes_white()
    plt.subplot(1, 3, 3)
    bovy_plot.bovy_dens2d(
        H_like.T,
        origin="lower",
        cmap="viridis",
        interpolation="nearest",
        vmin=0.1,
        vmax=4.0,
        xrange=[xedges[0], xedges[-1]],
        yrange=[yedges[0], yedges[-1]],
        xlabel=r"$F_R(\mathrm{Pal\ 5})\,(\mathrm{km\,s}^{-1}\,\mathrm{Myr}^{-1})$",
        gcf=True,
    )
    bovy_plot.bovy_text(r"$\mathbf{Likelihood}$", top_left=True, size=19.0, color="w")
    axes_white()

    def qline(FR, q=0.95):
        return 2.0 * FR / q ** 2.0

    q = 0.94
    plt.plot([-1.25, -0.2], [qline(-1.25, q=q), qline(-0.2, q=q)], "w--")
    bovy_plot.bovy_text(-1.7, -2.2, r"$q_\Phi = 0.94$", size=16.0, color="w")
    plt.plot((-1.25, -1.02), (-2.19, qline(-1.02, q=q)), "w-", lw=0.8)

    plt.tight_layout()
    plt.savefig(
        "figures/pal5post.pdf", bbox_inches="tight",
    )
    plt.close()

    # --------------
    # Projection onto the direction perpendicular to constant $q = 0.94$:
    frs = np.tile(0.5 * (xedges[:-1] + xedges[1:]), (len(yedges) - 1, 1)).T
    fzs = np.tile(0.5 * (yedges[:-1] + yedges[1:]), (len(xedges) - 1, 1))
    plt.figure(figsize=(6, 4))
    txlabel = r"$F_\perp$"
    dum = bovy_plot.bovy_hist(
        (-2.0 * (frs + 0.8) + 0.94 ** 2.0 * (fzs + 1.82)).flatten(),
        weights=H_prior.flatten(),
        bins=21,
        histtype="step",
        lw=2.0,
        xrange=[-1.5, 1.5],
        xlabel=txlabel,
        normed=True,
    )
    dum = bovy_plot.bovy_hist(
        (-2.0 * (frs + 0.8) + 0.94 ** 2.0 * (fzs + 1.82)).flatten(),
        weights=H_post.flatten(),
        bins=21,
        histtype="step",
        lw=2.0,
        overplot=True,
        xrange=[-1.5, 1.5],
        normed=True,
    )
    dum = bovy_plot.bovy_hist(
        (-2.0 * (frs + 0.8) + 0.94 ** 2.0 * (fzs + 1.82)).flatten(),
        weights=H_like.flatten(),
        bins=21,
        histtype="step",
        lw=2.0,
        overplot=True,
        xrange=[-1.5, 1.5],
        normed=True,
    )
    plt.savefig("figures/PDFs/projection_perp_to_q0p94.pdf")
    plt.close()

    mq = (
        np.sum(
            (-2.0 * (frs + 0.8) + 0.94 ** 2.0 * (fzs + 1.82)).flatten()
            * H_like.flatten()
        )
    ) / np.sum(H_like.flatten())

    print(
        mq,
        np.sqrt(
            (
                np.sum(
                    ((-2.0 * (frs + 0.8) + 0.94 ** 2.0 * (fzs + 1.82)).flatten() - mq)
                    ** 2.0
                    * H_like.flatten()
                )
            )
            / np.sum(H_like.flatten())
        ),
    )

    # --------------
    # Projection onto the direction parallel to constant $q = 0.94$:
    frs = np.tile(0.5 * (xedges[:-1] + xedges[1:]), (len(yedges) - 1, 1)).T
    fzs = np.tile(0.5 * (yedges[:-1] + yedges[1:]), (len(xedges) - 1, 1))
    plt.figure(figsize=(6, 4))
    txlabel = r"$F_\parallel$"
    dum = bovy_plot.bovy_hist(
        (0.94 ** 2.0 * (frs + 0.8) + 2.0 * (fzs + 1.82)).flatten(),
        weights=H_prior.flatten(),
        bins=21,
        histtype="step",
        lw=2.0,
        xrange=[-2.5, 2.5],
        xlabel=txlabel,
        normed=True,
    )
    dum = bovy_plot.bovy_hist(
        (0.94 ** 2.0 * (frs + 0.8) + 2.0 * (fzs + 1.82)).flatten(),
        weights=H_post.flatten(),
        bins=21,
        histtype="step",
        lw=2.0,
        overplot=True,
        xrange=[-2.5, 2.5],
        normed=True,
    )
    dum = bovy_plot.bovy_hist(
        (0.94 ** 2.0 * (frs + 0.8) + 2.0 * (fzs + 1.82)).flatten(),
        weights=H_like.flatten(),
        bins=21,
        histtype="step",
        lw=2.0,
        overplot=True,
        xrange=[-2.5, 2.5],
        normed=True,
    )
    plt.savefig("figures/PDFs/projection_prll_to_q0p94.pdf")
    plt.close()
    mq = (
        np.sum(
            (0.94 ** 2.0 * (frs + 0.8) + 2.0 * (fzs + 1.82)).flatten()
            * H_like.flatten()
        )
    ) / np.sum(H_like.flatten())
    print(
        mq,
        np.sqrt(
            (
                np.sum(
                    ((0.94 ** 2.0 * (frs + 0.8) + 2.0 * (fzs + 1.82)).flatten() - mq)
                    ** 2.0
                    * H_like.flatten()
                )
            )
            / np.sum(H_like.flatten())
        ),
    )

    # --------------
    # Thus, there is only a weak constraint on $F_\parallel$.

    nrow = int(np.ceil(npot / 4.0))
    plt.figure(figsize=(16, nrow * 4))
    for en, ii in enumerate(range(npot)):
        plt.subplot(nrow, 4, en + 1)
        if ii % 4 == 0:
            tylabel = r"$F_Z(\mathrm{Pal\ 5})$"
        else:
            tylabel = None
        if ii // 4 == nrow - 1:
            txlabel = r"$F_R(\mathrm{Pal\ 5})$"
        else:
            txlabel = None
        bovy_plot.scatterplot(
            fs[0][:, en],
            fs[1][:, en],
            "k,",
            xrange=[-1.75, -0.25],
            yrange=[-2.5, -1.0],
            xlabel=txlabel,
            ylabel=tylabel,
            gcf=True,
        )
        bovy_plot.scatterplot(
            data_wf[:, 7],
            data_wf[:, 8],
            weights=weights_wf,
            bins=26,
            xrange=[-1.75, -0.25],
            yrange=[-2.5, -1.0],
            justcontours=True,
            cntrcolors="w",
            overplot=True,
        )
        bovy_plot.scatterplot(
            data_wf[index_wf == ii, 7],
            data_wf[index_wf == ii, 8],
            weights=weights_wf[index_wf == ii],
            bins=26,
            xrange=[-1.75, -0.25],
            yrange=[-2.5, -1.0],
            justcontours=True,
            # cntrcolors=sns.color_palette()[2],
            overplot=True,
        )
        plt.axvline(-0.80, color=sns.color_palette()[0])
        plt.axhline(-1.83, color=sns.color_palette()[0])
        bovy_plot.bovy_text(r"$\mathrm{Potential}\ %i$" % ii, size=17.0, top_left=True)
    plt.savefig("figures/PDFs/constain_F_prll.pdf")
    plt.close()

    # --------------
    # Let's plot four representative ones for the paper:

    bovy_plot.bovy_print(
        axes_labelsize=17.0,
        text_fontsize=12.0,
        xtick_labelsize=14.0,
        ytick_labelsize=14.0,
    )
    nullfmt = NullFormatter()
    nrow = 1

    plt.figure(figsize=(15, nrow * 4))
    for en, ii in enumerate([0, 15, 24, 25]):
        plt.subplot(nrow, 4, en + 1)
        if en % 4 == 0:
            tylabel = (
                r"$F_Z(\mathrm{Pal\ 5})\,(\mathrm{km\,s}^{-1}\,\mathrm{Myr}^{-1})$"
            )
        else:
            tylabel = None
        if en // 4 == nrow - 1:
            txlabel = (
                r"$F_R(\mathrm{Pal\ 5})\,(\mathrm{km\,s}^{-1}\,\mathrm{Myr}^{-1})$"
            )
        else:
            txlabel = None
        bovy_plot.scatterplot(
            fs[0][:, ii],
            fs[1][:, ii],
            "k,",
            bins=31,
            xrange=[-1.75, -0.25],
            yrange=[-2.5, -1.0],
            xlabel=txlabel,
            ylabel=tylabel,
            gcf=True,
        )
        bovy_plot.scatterplot(
            data_wf[:, 7],
            data_wf[:, 8],
            weights=weights_wf,
            bins=21,
            xrange=[-1.75, -0.25],
            yrange=[-2.5, -1.0],
            justcontours=True,
            cntrcolors=sns.color_palette("colorblind")[2],
            cntrls="--",
            cntrlw=2.0,
            overplot=True,
        )
        bovy_plot.scatterplot(
            data_wf[index_wf == ii, 7],
            data_wf[index_wf == ii, 8],
            weights=weights_wf[index_wf == ii],
            bins=21,
            xrange=[-1.75, -0.25],
            yrange=[-2.5, -1.0],
            justcontours=True,
            cntrcolors=sns.color_palette("colorblind")[0],
            cntrlw=2.5,
            overplot=True,
        )
        if en > 0:
            plt.gca().yaxis.set_major_formatter(nullfmt)

    plt.tight_layout()
    plt.savefig(
        "figures/pal5post_examples.pdf", bbox_inches="tight",
    )
    plt.close()

    ###############################################################
    # What about $q_\Phi$?

    bins = 47
    plt.figure(figsize=(6, 4))
    dum = bovy_plot.bovy_hist(
        np.sqrt(2.0 * fs[0].flatten() / fs[1].flatten()),
        histtype="step",
        lw=2.0,
        bins=bins,
        xlabel=r"$q_\mathrm{\Phi}$",
        xrange=[0.7, 1.25],
        normed=True,
    )
    dum = bovy_plot.bovy_hist(
        np.sqrt(16.8 / 8.4 * data_wf[:, -2] / data_wf[:, -1]),
        weights=weights_wf,
        histtype="step",
        lw=2.0,
        bins=bins,
        overplot=True,
        xrange=[0.7, 1.25],
        normed=True,
    )
    mq = np.sum(
        np.sqrt(16.8 / 8.4 * data_wf[:, -2] / data_wf[:, -1]) * weights_wf
    ) / np.sum(weights_wf)
    sq = np.sqrt(
        np.sum(
            (np.sqrt(16.8 / 8.4 * data_wf[:, -2] / data_wf[:, -1]) - mq) ** 2.0
            * weights_wf
        )
        / np.sum(weights_wf)
    )
    print("From posterior samples: q = %.3f +/- %.3f" % (mq, sq))
    Hq_post, xedges = np.histogram(
        np.sqrt(16.8 / 8.4 * data_wf[:, -2] / data_wf[:, -1]),
        weights=weights_wf,
        bins=bins,
        range=[0.7, 1.25],
        normed=True,
    )
    Hq_prior, xedges = np.histogram(
        np.sqrt(2.0 * fs[0].flatten() / fs[1].flatten()),
        bins=bins,
        range=[0.7, 1.25],
        normed=True,
    )
    qs = 0.5 * (xedges[:-1] + xedges[1:])
    Hq_like = Hq_post / Hq_prior
    Hq_like[Hq_post == 0.0] = 0.0
    mq = np.sum(qs * Hq_like) / np.sum(Hq_like)
    sq = np.sqrt(np.sum((qs - mq) ** 2.0 * Hq_like) / np.sum(Hq_like))
    print("From likelihood of samples: q = %.3f +/- %.3f" % (mq, sq))

    plt.savefig("figures/q_phi.pdf")
    plt.close()

    # It appears that $q_\Phi$ is the quantity that is the most strongly constrained by the Pal 5 data.

    ###############################################################
    # A sampling of tracks from the MCMC

    savefilename = "mwpot14-pal5-mcmcTracks.pkl"
    pmdecpar = 2.257 / 2.296
    pmdecperp = -2.296 / 2.257
    if os.path.exists(savefilename):
        with open(savefilename, "rb") as savefile:
            pal5_track_samples = pickle.load(savefile)
            forces = pickle.load(savefile)
            all_potparams = pickle.load(savefile)
            all_params = pickle.load(savefile)
    else:
        np.random.seed(1)
        ntracks = 21
        multi = 8
        pal5_track_samples = np.zeros((ntracks, 2, 6, pal5varyc[0].shape[1]))
        forces = np.zeros((ntracks, 2))
        all_potparams = np.zeros((ntracks, 5))
        all_params = np.zeros((ntracks, 7))
        for ii in range(ntracks):
            # Pick a random potential from among the set, but leave 14 out
            pindx = 14
            while pindx == 14:
                pindx = np.random.permutation(32)[0]
            # Load this potential
            fn = f"output/fitsigma/mwpot14-fitsigma-{pindx:02}.dat"
            with open(fn, "r") as savefile:
                line1 = savefile.readline()
            potparams = [float(s) for s in (line1.split(":")[1].split(","))]
            all_potparams[ii] = potparams
            # Now pick a random sample from this MCMC chain
            tnburn = mcmc_util.determine_nburn(fn)
            tdata = np.loadtxt(fn, comments="#", delimiter=",")
            tdata = tdata[tnburn::]
            tdata = tdata[np.random.permutation(len(tdata))[0]]
            all_params[ii] = tdata
            tvo = tdata[1] * REFV0
            pot = mw_pot.setup_potential(potparams, tdata[0], False, False, REFR0, tvo)
            forces[ii, :] = pal5_util.force_pal5(pot, 23.46, REFR0, tvo)[:2]
            # Now compute the stream model for this setup
            dist = tdata[2] * 22.0
            pmra = -2.296 + tdata[3] + tdata[4]
            pmdecpar = 2.257 / 2.296
            pmdecperp = -2.296 / 2.257
            pmdec = -2.257 + tdata[3] * pmdecpar + tdata[4] * pmdecperp
            vlos = -58.7
            sigv = 0.4 * np.exp(tdata[5])
            prog = Orbit(
                [229.018, -0.124, dist, pmra, pmdec, vlos],
                radec=True,
                ro=REFR0,
                vo=tvo,
                solarmotion=[-11.1, 24.0, 7.25],
            )
            tsdf_trailing, tsdf_leading = pal5_util.setup_sdf(
                pot,
                prog,
                sigv,
                10.0,
                REFR0,
                tvo,
                multi=multi,
                nTrackChunks=8,
                trailing_only=False,
                verbose=True,
                useTM=False,
            )
            # Compute the track
            for jj, sdf in enumerate([tsdf_trailing, tsdf_leading]):
                trackRADec = bovy_coords.lb_to_radec(
                    sdf._interpolatedObsTrackLB[:, 0],
                    sdf._interpolatedObsTrackLB[:, 1],
                    degree=True,
                )
                trackpmRADec = bovy_coords.pmllpmbb_to_pmrapmdec(
                    sdf._interpolatedObsTrackLB[:, 4],
                    sdf._interpolatedObsTrackLB[:, 5],
                    sdf._interpolatedObsTrackLB[:, 0],
                    sdf._interpolatedObsTrackLB[:, 1],
                    degree=True,
                )
                # Store the track
                pal5_track_samples[ii, jj, 0] = trackRADec[:, 0]
                pal5_track_samples[ii, jj, 1] = trackRADec[:, 1]
                pal5_track_samples[ii, jj, 2] = sdf._interpolatedObsTrackLB[:, 2]
                pal5_track_samples[ii, jj, 3] = sdf._interpolatedObsTrackLB[:, 3]
                pal5_track_samples[ii, jj, 4] = trackpmRADec[:, 0]
                pal5_track_samples[ii, jj, 5] = trackpmRADec[:, 1]
        save_pickles(
            savefilename, pal5_track_samples, forces, all_potparams, all_params
        )

    # --------------
    bovy_plot.bovy_print(
        axes_labelsize=17.0,
        text_fontsize=12.0,
        xtick_labelsize=14.0,
        ytick_labelsize=14.0,
    )
    plt.figure(figsize=(12, 8))
    gs = gridspec.GridSpec(2, 2, wspace=0.225, hspace=0.1, right=0.94)
    ntracks = pal5_track_samples.shape[0]
    cmap = cm.plasma
    alpha = 0.7
    for ii in range(ntracks):
        tc = cmap((forces[ii, 1] + 2.5) / 1.0)
        for jj in range(2):
            # RA, Dec
            plt.subplot(gs[0])
            plt.plot(
                pal5_track_samples[ii, jj, 0],
                pal5_track_samples[ii, jj, 1],
                "-",
                color=tc,
                alpha=alpha,
            )
            # RA, Vlos
            plt.subplot(gs[1])
            plt.plot(
                pal5_track_samples[ii, jj, 0],
                pal5_track_samples[ii, jj, 3],
                "-",
                color=tc,
                alpha=alpha,
            )
            # RA, Dist
            plt.subplot(gs[2])
            plt.plot(
                pal5_track_samples[ii, jj, 0],
                pal5_track_samples[ii, jj, 2] - all_params[ii, 2] * 22.0,
                "-",
                color=tc,
                alpha=alpha,
            )
            # RA, pm_parallel
            plt.subplot(gs[3])
            plt.plot(
                pal5_track_samples[ii, jj, 0, : 500 + 500 * (1 - jj)],
                np.sqrt(1.0 + (2.257 / 2.296) ** 2.0)
                * (
                    (pal5_track_samples[ii, jj, 4, : 500 + 500 * (1 - jj)] + 2.296)
                    * pmdecperp
                    - (pal5_track_samples[ii, jj, 5, : 500 + 500 * (1 - jj)] + 2.257)
                )
                / (pmdecpar - pmdecperp),
                "-",
                color=tc,
                alpha=alpha,
            )
    plot_data_add_labels(
        p1=(gs[0],), p2=(gs[1],), noxlabel_dec=True, noxlabel_vlos=True
    )
    plt.subplot(gs[2])
    plt.xlim(250.0, 221.0)
    plt.ylim(-3.0, 1.5)
    bovy_plot._add_ticks()
    plt.xlabel(r"$\mathrm{RA}\,(\mathrm{degree})$")
    plt.ylabel(r"$\Delta\mathrm{Distance}\,(\mathrm{kpc})$")
    plt.subplot(gs[3])
    plt.xlim(250.0, 221.0)
    plt.ylim(-0.5, 0.5)
    bovy_plot._add_ticks()
    plt.xlabel(r"$\mathrm{RA}\,(\mathrm{degree})$")
    plt.ylabel(r"$\Delta\mu_\parallel\,(\mathrm{mas\,yr}^{-1})$")
    # Colorbar
    gs2 = gridspec.GridSpec(2, 1, wspace=0.0, left=0.95, right=0.975)
    plt.subplot(gs2[:, -1])
    sm = plt.cm.ScalarMappable(cmap=cmap, norm=plt.Normalize(vmin=-2.5, vmax=-1.5))
    sm._A = []
    CB1 = plt.colorbar(sm, orientation="vertical", cax=plt.gca())
    CB1.set_label(
        r"$F_Z(\mathrm{Pal\ 5})\,(\mathrm{km\,s}^{-1}\,\mathrm{Myr}^{-1})$",
        fontsize=18.0,
    )
    plt.savefig(
        "figures/pal5tracksamples.pdf", bbox_inches="tight",
    )
    plt.close()

    ###############################################################
    # What about Kuepper et al. (2015)?

    # Can we recover the Kuepper et al. (2015) result as prior + $q_\Phi =
    # 0.94 \pm 0.05$ + $V_c(R_0)$ between 200 and 280 km/s? For simplicity
    # we will not vary $R_0$, which should not have a big impact.

    s = sample_kuepper_flattening_post(50000, 0.94, 0.05)
    plot_kuepper_samples(s)
    plt.savefig("figures/kuepper_samples.pdf")
    plt.close()

    # The constraint on the potential flattening gets you far, but there
    # is more going on (the constraint on the halo mass and scale
    # parameter appear to come completely from the $V_c(R_0)$ constraint).
    # Let's add the weak constraint on the sum of the forces, scaled to
    # Kuepper et al.'s best-fit acceleration (which is higher than ours):

    s = sample_kuepper_flatteningforce_post(50000, 0.94, 0.05, -0.83, 0.36)
    plot_kuepper_samples(s)
    plt.savefig("figures/kuepper_samples_flatF.pdf")
    plt.close()

    # This gets a tight relation between $M_\mathrm{halo}$ and the scale
    # parameter of the halo, but does not lead to a constraint on either
    # independently; the halo potential flattening constraint is that of
    # Kuepper et al. Based on this, it appears that the information that
    # ties down $M_\mathrm{halo}$ comes from the overdensities, which may
    # be spurious (Thomas et al. 2016) and whose use in dynamical modeling
    # is dubious anyway.

    # What is Kuepper et al.'s prior on $a_{\mathrm{Pal\ 5}}$?

    apal5s = []
    ns = 100000
    for ii in range(ns):
        Mh = np.random.uniform() * (10.0 - 0.001) + 0.001
        a = np.random.uniform() * (100.0 - 0.1) + 0.1
        q = np.random.uniform() * (1.8 - 0.2) + 0.2
        pot = setup_potential_kuepper(Mh, a)
        FR, FZ = force_pal5_kuepper(pot, q)
        apal5s.append(np.sqrt(FR ** 2.0 + FZ ** 2.0))
    apal5s = np.array(apal5s)

    plt.figure(figsize=(6, 4))
    dum = bovy_plot.bovy_hist(
        apal5s, range=[0.0, 10.0], lw=2.0, bins=51, histtype="step", normed=True,
    )
    plt.savefig("figures/kuepper_samples_prior.pdf")
    plt.close()