Skip to content

Commit 6c9bb85

Browse files
ybillchenpre-commit-ci[bot]jobovy
authored
Implement the new particle spray model by Chen+24 (#670)
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Jo Bovy <bovy@astro.utoronto.ca>
1 parent 7c5ad82 commit 6c9bb85

15 files changed

+926
-451
lines changed

HISTORY.txt

+5
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@ v1.10.1 (Expected around 2024-11-01)
33

44
- Propagate general plotting keywords in Potential.plot/plotPotentials.
55

6+
- Added the generalized particle-spray model as galpy.df.basestreamspraydf with two
7+
subclasses: chen24spraydf and fadal15spraydf. Enabled integrating orbits of stream
8+
particles with the progenitor's potential. Deprecating the old particle-spray
9+
model galpy.df.streamspraydf.
10+
611
v1.10.0 (2024-07-07)
712
====================
813

Loading
Loading
Binary file not shown.

doc/source/index.rst

+2-1
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,8 @@ functionality is introduced in separate papers:
132132
* ``galpy.actionAngle.actionAngleIsochroneApprox``: please cite `Bovy (2014) <http://adsabs.harvard.edu/abs/2014ApJ...795...95B>`__.
133133
* ``galpy.df.streamdf``: please cite `Bovy (2014) <http://adsabs.harvard.edu/abs/2014ApJ...795...95B>`__.
134134
* ``galpy.df.streamgapdf``: please cite `Sanders, Bovy, & Erkal (2016) <http://adsabs.harvard.edu/abs/2016MNRAS.457.3817S>`__.
135-
* ``galpy.df.streamspraydf``: please cite `Fardal et al. (2015) <https://ui.adsabs.harvard.edu/abs/2015MNRAS.452..301F/abstract>`__ for the method and `Qian et al. (2022) <https://ui.adsabs.harvard.edu/abs/2022MNRAS.511.2339Q/abstract>`__ for the ``galpy`` implementation
135+
* ``galpy.df.chen24spraydf``: please cite `Chen et al. (2024) <https://ui.adsabs.harvard.edu/abs/2024arXiv240801496C/abstract>`__ for the method and the ``galpy`` implementation
136+
* ``galpy.df.fardal15spraydf``: please cite `Fardal et al. (2015) <https://ui.adsabs.harvard.edu/abs/2015MNRAS.452..301F/abstract>`__ for the method and `Qian et al. (2022) <https://ui.adsabs.harvard.edu/abs/2022MNRAS.511.2339Q/abstract>`__ for the ``galpy`` implementation
136137
* ``galpy.potential.ttensor`` and ``galpy.potential.rtide``: please cite `Webb et al. (2019a) <https://ui.adsabs.harvard.edu/abs/2019MNRAS.488.5748W/abstract>`__.
137138

138139
* ``galpy.potential.to_amuse``: please cite `Webb et al. (2019b) <http://arxiv.org/abs/1910.01646>`_.

doc/source/reference/df.rst

+12-2
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,9 @@ Helper routines to compute kicks
334334
The distribution function of a tidal stream using a particle-spray technique
335335
----------------------------------------------------------------------------
336336

337-
Model from `Fardal et al. (2015)
337+
Model from `Chen et al. (2024)
338+
<https://ui.adsabs.harvard.edu/abs/2024arXiv240801496C/abstract>`__ and
339+
`Fardal et al. (2015)
338340
<https://ui.adsabs.harvard.edu/abs/2015MNRAS.452..301F/abstract>`__ with full
339341
details of the ``galpy`` implementation given in `Qian et al. (2022)
340342
<https://ui.adsabs.harvard.edu/abs/2022MNRAS.511.2339Q/abstract>`__;
@@ -346,5 +348,13 @@ General instance routines
346348
.. toctree::
347349
:maxdepth: 1
348350

349-
__init__ <streamspraydf.rst>
350351
sample <streamspraydfsample.rst>
352+
353+
Specific particle-spray models
354+
+++++++++++++++++++++++++++++++
355+
356+
.. toctree::
357+
:maxdepth: 1
358+
359+
Chen et al. (2024) <streamspraydfchen24.rst>
360+
Fardal et al. (2015) <streamspraydffardal15.rst>

doc/source/reference/streamspraydf.rst

-7
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
The particle-spray stream DF using Chen et al. (2024) formalism
2+
===============================================================
3+
4+
.. autoclass:: galpy.df.chen24spraydf
5+
:members: __init__
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
.. _api_streamspraydf:
2+
3+
The particle-spray stream DF using Fardal et al. (2015) formalism
4+
==================================================================
5+
6+
.. autoclass:: galpy.df.fardal15spraydf
7+
:members: __init__
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
galpy.df.streamspraydf.sample
2-
==========================================
2+
=============================
33

44
.. automethod:: galpy.df.streamspraydf.sample

doc/source/streamdf.rst

+47-30
Original file line numberDiff line numberDiff line change
@@ -509,16 +509,24 @@ for the difference in :math:`v_Y` as a function of unperturbed :math:`X`:
509509

510510
.. _streamspray-tutorial:
511511

512-
Particle-spray modeling of streams with ``streamspraydf``
513-
---------------------------------------------------------
514-
515-
``galpy`` also contains an implementation of the particle-spray method
516-
for generating tidal streams, roughly following the parametrization of
517-
`Fardal et al. (2015)
512+
Particle-spray modeling of streams
513+
----------------------------------
514+
515+
``galpy`` also contains implementations of two particle-spray methods
516+
for generating tidal streams. ``chen24spraydf`` follows the method by
517+
`Chen et al. (2024)
518+
<https://ui.adsabs.harvard.edu/abs/2024arXiv240801496C/abstract>`__.
519+
``fardal15spraydf`` roughly follows the
520+
parametrization of `Fardal et al. (2015)
518521
<https://ui.adsabs.harvard.edu/abs/2015MNRAS.452..301F/abstract>`__. Full
519522
details on the ``galpy`` implementation are given in `Qian et al. (2022)
520523
<https://ui.adsabs.harvard.edu/abs/2022MNRAS.511.2339Q/abstract>`__. Here,
521-
we give a simple example of the method.
524+
we give a simple example of the the two methods.
525+
526+
.. note::
527+
``fardal15spraydf`` was previously known as ``streamspraydf`` before
528+
version ``v1.10.1``. While the old name is still supported until ``v.1.11.0``
529+
for backward compatibility, we recommend using the new name ``fardal15spraydf``.
522530

523531
Like in the ``streamdf`` example above, we use the same orbit, potential, and
524532
cluster mass as in
@@ -531,24 +539,31 @@ as a simple ``LogarithmicHaloPotential``):
531539
>>> o= Orbit([1.56148083,0.35081535,-1.15481504,0.88719443,-0.47713334,0.12019596])
532540
>>> lp= LogarithmicHaloPotential(normalize=1.,q=0.9)
533541

534-
Then, we setup ``streamspraydf`` models for the leading and trailing arm of
535-
the stream:
542+
Then, we setup ``chen24spraydf`` and ``fardal15spraydf`` models for the leading
543+
and trailing arm of the stream. The ``chen24spraydf`` model requires integrating
544+
the orbits of stream stars with the progenitor's potential. Here, we use a
545+
Plummer potential for the prognenitor:
536546

537547
>>> from astropy import units
538-
>>> from galpy.df import streamspraydf
539-
>>> spdf= streamspraydf(2*10.**4.*units.Msun,progenitor=o,pot=lp,tdisrupt=4.5*units.Gyr)
540-
>>> spdft= streamspraydf(2*10.**4.*units.Msun,progenitor=o,pot=lp,leading=False,tdisrupt=4.5*units.Gyr)
548+
>>> from galpy.df import chen24spraydf, fardal15spraydf
549+
>>> progpot = PlummerPotential(2*10.**4.*units.Msun, 4.*units.pc)
550+
>>> spdf_c24= chen24spraydf(2*10.**4.*units.Msun,progenitor=o,pot=lp,tdisrupt=4.5*units.Gyr, progpot=progpot)
551+
>>> spdft_c24= chen24spraydf(2*10.**4.*units.Msun,progenitor=o,pot=lp,leading=False,tdisrupt=4.5*units.Gyr, progpot=progpot)
552+
>>> spdf_f15= fardal15spraydf(2*10.**4.*units.Msun,progenitor=o,pot=lp,tdisrupt=4.5*units.Gyr)
553+
>>> spdft_f15= fardal15spraydf(2*10.**4.*units.Msun,progenitor=o,pot=lp,leading=False,tdisrupt=4.5*units.Gyr)
541554

542-
To sample a set of 300 stars in both arms, we do
555+
First, we sample a set of 300 stars in both arms:
543556

544-
>>> orbs,dt= spdf.sample(n=300,returndt=True,integrate=True)
545-
>>> orbts,dt= spdft.sample(n=300,returndt=True,integrate=True)
557+
>>> orbs_c24,dt_c24= spdf_c24.sample(n=300,returndt=True,integrate=True)
558+
>>> orbts_c24,dt_c24= spdft_c24.sample(n=300,returndt=True,integrate=True)
559+
>>> orbs_f15,dt= spdf_f15.sample(n=300,returndt=True,integrate=True)
560+
>>> orbts_f15,dt= spdft_f15.sample(n=300,returndt=True,integrate=True)
546561

547562
which returns a ``galpy.orbit.Orbit`` instance with all 300 stars. We can plot
548-
these in :math:`Z` versus :math:`X` and compare to Fig. 1 in
549-
Bovy (2014). First, we also integrate the orbit of the progenitor forward
550-
and backward in time for a brief period to show its location in the area
551-
of the stream:
563+
the ``galpy.orbit.Orbit`` instance in :math:`Z` versus :math:`X`
564+
and compare to Fig. 1 in Bovy (2014). First, we also integrate the orbit of the
565+
progenitor forward and backward in time for a brief period to show its location
566+
in the area of the stream:
552567

553568
>>> ts= numpy.linspace(0.,3.,301)
554569
>>> o.integrate(ts,lp)
@@ -559,19 +574,21 @@ Then we plot
559574

560575
>>> o.plot(d1='x',d2='z',color='k',xrange=[0.,2.],yrange=[-0.1,1.45])
561576
>>> of.plot(d1='x',d2='z',overplot=True,color='k')
562-
>>> plot(orbs.x(),orbs.z(),'r.')
563-
>>> plot(orbts.x(),orbts.z(),'b.')
577+
>>> plot(orbs_c24.x(),orbs_c24.z(),'r.', alpha=0.5)
578+
>>> plot(orbts_c24.x(),orbts_c24.z(),'r.', alpha=0.5)
579+
>>> plot(orbs_f15.x(),orbs_f15.z(),'b.', alpha=0.5)
580+
>>> plot(orbts_f15.x(),orbts_f15.z(),'b.', alpha=0.5)
564581

565582
which gives
566583

567-
.. image:: images/streamspraydf-b14-xz.png
584+
.. image:: images/chen24spraydf-fardal15spraydf-b14-xz.png
568585
:width: 600
569586

570587
We can also compare to the track for this stream as predicted by ``streamdf``.
571588
For this, we first setup a similar ``streamdf`` model (they are not exactly
572589
the same, as ``streamdf`` uses a velocity dispersion to set the progenitor's
573-
mass, while ``streamspraydf`` uses the mass directly); see the ``streamdf``
574-
documentation for a full explanation of this code:
590+
mass, while ``fardal15spraydf`` and ``chen15spraydf`` uses the mass directly);
591+
see the ``streamdf`` documentation for a full explanation of this code:
575592

576593
>>> from galpy.actionAngle import actionAngleIsochroneApprox
577594
>>> from galpy.df import streamdf
@@ -586,23 +603,23 @@ Then, we can overplot the track predicted by ``streamdf``:
586603

587604
>>> o.plot(d1='x',d2='z',color='k',xrange=[0.,2.],yrange=[-0.1,1.45])
588605
>>> of.plot(d1='x',d2='z',overplot=True,color='k')
589-
>>> plot(orbs.x(),orbs.z(),'r.',alpha=0.1)
590-
>>> plot(orbts.x(),orbts.z(),'b.',alpha=0.1)
606+
>>> plot(orbs_c24.x(),orbs_c24.z(),'r.',alpha=0.1)
607+
>>> plot(orbts_c24.x(),orbts_c24.z(),'r.',alpha=0.1)
591608
>>> sdf.plotTrack(d1='x',d2='z',interp=True,color='r',overplot=True,lw=1.)
592609
>>> sdft.plotTrack(d1='x',d2='z',interp=True,color='b',overplot=True,lw=1.)
593610

594611
This gives then
595612

596-
.. image:: images/streamspraydf-b14-xz-wstreamdf.png
613+
.. image:: images/chen24spraydf-b14-xz-wstreamdf.png
597614
:width: 600
598615

599616
We see that the track from ``streamdf`` agrees very well with the location
600-
of the points sampled from ``streamspraydf``.
617+
of the points sampled from ``chen24spraydf``.
601618

602-
The ``streamspraydf`` ``sample`` function can also return the points at
619+
The ``sample`` function can also return the points at
603620
the time of stripping, that is, not integrated to the present time
604621
(when using ``integrate=False``); this can be useful for visualizing where
605-
stars get stripped from the progenitor. When initializing ``streamspraydf``,
622+
stars get stripped from the progenitor. When initializing a particle-spray DF,
606623
you can also specify a different potential for computing the tidal radius
607624
and velocity distribution of the tidal debris, which can be useful when the
608625
overall potential contains pieces that are irrelevant for computing the tidal

galpy/df/__init__.py

+2
Original file line numberDiff line numberDiff line change
@@ -66,4 +66,6 @@
6666
osipkovmerrittdf = osipkovmerrittdf.osipkovmerrittdf
6767
osipkovmerrittNFWdf = osipkovmerrittNFWdf.osipkovmerrittNFWdf
6868
constantbetadf = constantbetadf.constantbetadf
69+
chen24spraydf = streamspraydf.chen24spraydf
70+
fardal15spraydf = streamspraydf.fardal15spraydf
6971
streamspraydf = streamspraydf.streamspraydf

0 commit comments

Comments
 (0)