From 8a8da6458ac050f1066eb8ea3205cffe88a0eb9e Mon Sep 17 00:00:00 2001 From: profxj Date: Sat, 30 Aug 2025 07:40:35 -0700 Subject: [PATCH 01/21] doc mods --- docs/api/dm.rst | 415 ++++++++++++++++++++++++++++++++++++++++++ docs/api/index.rst | 259 ++++++++++++++++++++++++++ docs/halos/hmf.rst | 246 +++++++++++++++++++++++++ docs/halos/index.rst | 239 ++++++++++++++++++++++++ docs/halos/models.rst | 325 +++++++++++++++++++++++++++++++++ docs/halos/photoz.rst | 312 +++++++++++++++++++++++++++++++ docs/index.rst | 20 ++ docs/quickstart.rst | 325 +++++++++++++++++++++++++++++++++ docs/requirements.txt | 6 + readthedocs.yaml | 19 ++ 10 files changed, 2166 insertions(+) create mode 100644 docs/api/dm.rst create mode 100644 docs/api/index.rst create mode 100644 docs/halos/hmf.rst create mode 100644 docs/halos/index.rst create mode 100644 docs/halos/models.rst create mode 100644 docs/halos/photoz.rst create mode 100644 docs/quickstart.rst create mode 100644 docs/requirements.txt create mode 100644 readthedocs.yaml diff --git a/docs/api/dm.rst b/docs/api/dm.rst new file mode 100644 index 00000000..6199db3c --- /dev/null +++ b/docs/api/dm.rst @@ -0,0 +1,415 @@ +frb.dm - Dispersion Measure Module +=================================== + +The ``frb.dm`` module provides comprehensive tools for calculating and modeling dispersion measure contributions from various sources along the line of sight to Fast Radio Bursts. + +.. currentmodule:: frb.dm + +Module Overview +--------------- + +The dispersion measure (DM) is a key observable for FRBs, representing the integrated electron column density along the line of sight: + +.. math:: + + \text{DM} = \int_0^{d} n_e(l) \, dl + +This module decomposes the total DM into contributions from: + +- **Milky Way**: Galactic disk and halo electrons +- **Intergalactic Medium (IGM)**: Diffuse cosmic electrons +- **Host Galaxy**: Electrons in the FRB host galaxy +- **Intervening Systems**: Galaxy halos and other structures + +Submodules +---------- + +.. toctree:: + :maxdepth: 1 + + dm_igm + dm_cosmic + dm_host + dm_mcmc + dm_prob_dmz + +frb.dm.igm - Intergalactic Medium +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. automodule:: frb.dm.igm + :members: + :undoc-members: + :show-inheritance: + +Key Functions +^^^^^^^^^^^^^ + +.. autofunction:: frb.dm.igm.DM_cosmic + +.. autofunction:: frb.dm.igm.ne_cosmic + +.. autofunction:: frb.dm.igm.z_from_DM + +.. autofunction:: frb.dm.igm.DM_halos + +frb.dm.cosmic - Cosmic DM Modeling +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. automodule:: frb.dm.cosmic + :members: + :undoc-members: + :show-inheritance: + +frb.dm.host - Host Galaxy Contributions +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. automodule:: frb.dm.host + :members: + :undoc-members: + :show-inheritance: + +frb.dm.mcmc - MCMC Analysis +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. automodule:: frb.dm.mcmc + :members: + :undoc-members: + :show-inheritance: + +frb.dm.prob_dmz - DM-Redshift Probabilities +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. automodule:: frb.dm.prob_dmz + :members: + :undoc-members: + :show-inheritance: + +Detailed Function Documentation +------------------------------- + +IGM Functions +~~~~~~~~~~~~~ + +.. py:function:: ne_cosmic(z, cosmo=defs.frb_cosmo, mu=4./3) + + Calculate the average cosmic electron number density as a function of redshift. + + This function computes the physical number density of electrons in the universe, + accounting for the cosmic baryon density and ionization fraction. + + :param float z: Redshift + :param astropy.cosmology.Cosmology cosmo: Cosmology in which the calculations are performed + :param float mu: Reduced mass (default: 4/3 for fully ionized H and He) + :returns: Average physical number density of electrons in the universe + :rtype: astropy.units.Quantity + + **Example:** + + .. code-block:: python + + from frb.dm.igm import ne_cosmic + + # Calculate electron density at z=1 + z = 1.0 + n_e = ne_cosmic(z) + print(f"Electron density at z={z}: {n_e}") + +.. py:function:: DM_cosmic(z, cosmo=defs.frb_cosmo, cumul=False) + + Calculate the cosmic dispersion measure contribution. + + Integrates the cosmic electron density from z=0 to the specified redshift, + including corrections for cosmological expansion. + + :param float z: Redshift of the FRB + :param astropy.cosmology.Cosmology cosmo: Cosmology for calculations + :param bool cumul: Return cumulative DM evolution with redshift + :returns: Cosmic dispersion measure or array if cumul=True + :rtype: astropy.units.Quantity + + **Example:** + + .. code-block:: python + + from frb.dm.igm import DM_cosmic + + # Calculate cosmic DM to z=0.5 + z_frb = 0.5 + dm_cosmic = DM_cosmic(z_frb) + print(f"Cosmic DM to z={z_frb}: {dm_cosmic}") + +.. py:function:: z_from_DM(DM, cosmo=defs.frb_cosmo, coord=None, corr_nuisance=True) + + Estimate redshift from observed dispersion measure. + + Uses the cosmic DM-redshift relation to estimate the redshift of an FRB + given its observed dispersion measure, after correcting for Galactic + and other contributions. + + :param astropy.units.Quantity DM: Observed dispersion measure + :param astropy.cosmology.Cosmology cosmo: Cosmology + :param astropy.coordinates.SkyCoord coord: Sky coordinates (optional) + :param bool corr_nuisance: Apply corrections for nuisance parameters + :returns: Estimated redshift + :rtype: float + + **Example:** + + .. code-block:: python + + from frb.dm.igm import z_from_DM + from astropy import units as u + + # Estimate redshift from DM + DM_obs = 500 * u.pc / u.cm**3 + z_est = z_from_DM(DM_obs) + print(f"Estimated redshift: {z_est:.2f}") + +.. py:function:: DM_halos(z, cosmo, f_hot=0.75, rmax=2., logMmin=10.3, logMmax=16., neval=500, cumul=False) + + Calculate dispersion measure contribution from galaxy halos. + + Models the DM contribution from hot gas in galaxy halos along the + line of sight, using a halo mass function approach. + + :param float z: Redshift of the FRB + :param astropy.cosmology.Cosmology cosmo: Cosmology for calculations + :param float f_hot: Fraction of halo baryons in diffuse phase + :param float rmax: Size of halo in units of r200 + :param float logMmin: Log of minimum halo mass (cannot be much below 10.3) + :param float logMmax: Log of maximum halo mass (default: 10^16 Msun) + :param int neval: Number of redshift evaluation points + :param bool cumul: Return cumulative evaluation + :returns: DM contribution from halos + :rtype: astropy.units.Quantity + +Utility Functions +~~~~~~~~~~~~~~~~~ + +.. py:function:: f_diffuse(z, cosmo=defs.frb_cosmo, return_rho=False) + + Calculate the fraction of baryons in the diffuse IGM. + + :param float z: Redshift + :param astropy.cosmology.Cosmology cosmo: Cosmology + :param bool return_rho: Also return the diffuse gas density + :returns: Diffuse fraction (and density if requested) + :rtype: float or tuple + +.. py:function:: sigma_DM_cosmic(DM_cosmic, rel_err_Mstar=0.1) + + Calculate uncertainty in cosmic DM due to stellar mass uncertainties. + + :param astropy.units.Quantity DM_cosmic: Cosmic dispersion measure + :param float rel_err_Mstar: Relative error in stellar mass + :returns: DM uncertainty + :rtype: astropy.units.Quantity + +Physical Models +--------------- + +Ionization Models +~~~~~~~~~~~~~~~~~ + +The module includes models for cosmic reionization history: + +**Hydrogen Reionization:** +- Reionization redshift: z_HI ~ 6-8 +- Affects IGM electron fraction at high redshift + +**Helium Reionization:** +- HeII reionization: z_HeII ~ 3-4 +- Increases electron density at intermediate redshift + +**Implementation:** + +.. code-block:: python + + from frb.dm.igm import f_ionization_He + + # Calculate helium ionization fraction + z = 3.0 + f_He = f_ionization_He(z) + print(f"Helium ionization fraction at z={z}: {f_He}") + +Halo Models +~~~~~~~~~~~ + +Galaxy halo contributions use the halo mass function and hot gas profiles: + +**Key Parameters:** +- Halo mass range: 10^10.3 to 10^16 M_sun +- Hot gas fraction: ~75% of cosmic baryon fraction +- Radial extent: typically 2 × r200 + +**Scaling Relations:** +- Gas density profiles (e.g., beta models) +- Mass-temperature relations +- Feedback effects on gas distribution + +Usage Examples +-------------- + +Basic DM Analysis +~~~~~~~~~~~~~~~~~ + +.. code-block:: python + + from frb.dm import igm + from astropy import units as u + + # Calculate total cosmic DM budget + z_max = 2.0 + dm_cosmic_total = igm.DM_cosmic(z_max) + + # Calculate contributions at different redshifts + redshifts = [0.1, 0.5, 1.0, 1.5, 2.0] + for z in redshifts: + dm_z = igm.DM_cosmic(z) + print(f"DM(z={z:.1f}) = {dm_z:.0f}") + +Redshift Estimation +~~~~~~~~~~~~~~~~~~~ + +.. code-block:: python + + from frb.dm.igm import z_from_DM + from astropy import units as u + from astropy.coordinates import SkyCoord + + # Observed FRB parameters + DM_obs = 750 * u.pc / u.cm**3 + coord = SkyCoord(ra=123.45*u.deg, dec=12.34*u.deg) + + # Estimate redshift + z_est = z_from_DM(DM_obs, coord=coord) + print(f"Estimated redshift: {z_est:.2f}") + + # Calculate expected cosmic DM at this redshift + dm_cosmic_expected = igm.DM_cosmic(z_est) + print(f"Expected cosmic DM: {dm_cosmic_expected:.0f}") + + # Calculate excess DM (host + local contributions) + dm_excess = DM_obs - dm_cosmic_expected + print(f"Excess DM: {dm_excess:.0f}") + +Halo Contribution Analysis +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: python + + from frb.dm.igm import DM_halos + from astropy.cosmology import Planck18 + + # Calculate halo DM contribution + z_frb = 1.0 + dm_halos = DM_halos(z_frb, Planck18) + + print(f"Halo DM contribution to z={z_frb}: {dm_halos:.1f}") + + # Compare different halo parameters + f_hot_values = [0.5, 0.75, 1.0] + for f_hot in f_hot_values: + dm_h = DM_halos(z_frb, Planck18, f_hot=f_hot) + print(f"Halo DM (f_hot={f_hot}): {dm_h:.1f}") + +Advanced Usage +-------------- + +Custom Cosmologies +~~~~~~~~~~~~~~~~~~ + +.. code-block:: python + + from astropy.cosmology import FlatLambdaCDM + from frb.dm.igm import DM_cosmic + + # Define custom cosmology + custom_cosmo = FlatLambdaCDM(H0=70, Om0=0.3) + + # Compare DM calculations + z = 1.0 + dm_planck = DM_cosmic(z) # Default Planck18 + dm_custom = DM_cosmic(z, cosmo=custom_cosmo) + + print(f"DM (Planck18): {dm_planck:.0f}") + print(f"DM (Custom): {dm_custom:.0f}") + +Monte Carlo Analysis +~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: python + + import numpy as np + from frb.dm.igm import z_from_DM + from astropy import units as u + + # Simulate DM uncertainties + DM_mean = 500 * u.pc / u.cm**3 + DM_err = 50 * u.pc / u.cm**3 + n_trials = 1000 + + # Generate DM samples + DM_samples = np.random.normal( + DM_mean.value, DM_err.value, n_trials + ) * DM_mean.unit + + # Calculate redshift distribution + z_samples = [z_from_DM(dm) for dm in DM_samples] + + z_mean = np.mean(z_samples) + z_std = np.std(z_samples) + print(f"Redshift: {z_mean:.2f} ± {z_std:.2f}") + +Error Handling +-------------- + +The DM module includes robust error handling: + +.. code-block:: python + + from frb.dm.igm import z_from_DM + from astropy import units as u + + try: + # This might fail for very high DM values + z = z_from_DM(10000 * u.pc / u.cm**3) + except ValueError as e: + print(f"DM too high: {e}") + + try: + # This might fail for negative DM + z = z_from_DM(-100 * u.pc / u.cm**3) + except ValueError as e: + print(f"Invalid DM: {e}") + +Performance Notes +----------------- + +**Computational Efficiency:** +- DM calculations use vectorized numpy operations +- Cosmological integrals are cached for repeated calls +- Halo mass function integration is optimized for speed + +**Memory Usage:** +- Large redshift arrays may require significant memory +- Use ``cumul=False`` for single-point calculations +- Consider chunking for very large datasets + +**Accuracy:** +- Integration tolerances balance speed and precision +- Default parameters provide ~1% accuracy for most applications +- High-precision calculations may require custom tolerances + +See Also +-------- + +- :doc:`../tutorials` - Detailed usage examples +- :doc:`turb_scattering` - Scattering analysis +- :doc:`frbcat` - Catalogue operations +- :doc:`../examples` - Real-world applications + +.. note:: + The DM module assumes a standard cosmological model by default. + For non-standard cosmologies, explicitly pass the cosmology parameter + to relevant functions. \ No newline at end of file diff --git a/docs/api/index.rst b/docs/api/index.rst new file mode 100644 index 00000000..cf8b4218 --- /dev/null +++ b/docs/api/index.rst @@ -0,0 +1,259 @@ +API Reference +============= + +This section contains detailed documentation for all modules, classes, and functions in the FRB package. + +Core Modules +------------ + +The FRB package is organized into several key modules: + +.. toctree:: + :maxdepth: 2 + + dm + frbcat + turb_scattering + frb_class + utilities + +Module Overview +--------------- + +frb.dm - Dispersion Measure Calculations +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The dispersion measure module provides comprehensive tools for calculating and modeling DM contributions from various sources: + +- :doc:`dm` - Main DM calculation module + + - ``frb.dm.igm`` - Intergalactic Medium calculations + - ``frb.dm.cosmic`` - Cosmic dispersion measure modeling + - ``frb.dm.host`` - Host galaxy contributions + - ``frb.dm.mcmc`` - MCMC analysis methods + - ``frb.dm.prob_dmz`` - DM-redshift probability calculations + +frb.frbcat - Catalogue Interface +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- :doc:`frbcat` - FRB catalogue management and access + +frb.turb_scattering - Scattering Analysis +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- :doc:`turb_scattering` - Turbulent scattering models and calculations + +Core Classes +~~~~~~~~~~~~ + +- :doc:`frb_class` - Main FRB object class and methods + +Utilities +~~~~~~~~~ + +- :doc:`utilities` - Helper functions and utilities + +Quick Reference +--------------- + +Most Common Functions +~~~~~~~~~~~~~~~~~~~~~ + +**Loading FRBs:** + +.. code-block:: python + + import frb as ffrb + frb_obj = ffrb.FRB.by_name('FRB121102') + +**DM Calculations:** + +.. code-block:: python + + from frb.dm import igm + DM_cosmic = igm.DM_cosmic(z=0.5) + z_est = igm.z_from_DM(DM_obs) + +**Catalogue Access:** + +.. code-block:: python + + from frb.frbcat import FRBCat + cat = FRBCat() + +**Scattering Analysis:** + +.. code-block:: python + + from frb import turb_scattering as ts + theta = ts.theta_mist(n_e, nu_obs) + +Function Index +-------------- + +Core Functions by Category +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +**Dispersion Measure:** + +.. autosummary:: + :nosignatures: + + frb.dm.igm.DM_cosmic + frb.dm.igm.ne_cosmic + frb.dm.igm.z_from_DM + frb.dm.igm.DM_halos + frb.dm.cosmic.DM_cosmic + frb.dm.host.DM_host + +**Scattering:** + +.. autosummary:: + :nosignatures: + + frb.turb_scattering.theta_mist + frb.turb_scattering.tau_mist + frb.turb_scattering.ne_from_tau_mist + +**Catalogue Operations:** + +.. autosummary:: + :nosignatures: + + frb.frbcat.FRBCat + frb.frbcat.FRBCat.load_cat + +**FRB Objects:** + +.. autosummary:: + :nosignatures: + + frb.FRB.by_name + frb.FRB.grab_host + frb.FRB.calc_DM_galaxy + +Class Hierarchy +--------------- + +.. code-block:: none + + FRB + ├── FRB.by_name() + ├── FRB.grab_host() + └── FRB.calc_DM_galaxy() + + FRBCat + ├── FRBCat.__init__() + ├── FRBCat.load_cat() + └── FRBCat.filter_by_property() + + HostGalaxy + ├── HostGalaxy.derived + ├── HostGalaxy.get_metaspec() + └── HostGalaxy.properties + +Constants and Defaults +---------------------- + +The package uses several default values and constants: + +**Cosmological Parameters:** + +.. code-block:: python + + # Default cosmology (defined in frb.defs) + frb_cosmo = astropy.cosmology.Planck18 + +**Default Scattering Parameters:** + +.. code-block:: python + + # Default structure sizes + L_default = 50 * u.kpc # Structure size + R_default = 1 * u.pc # Cloud size + fV_default = 1.0 # Filling factor + +**Physical Constants:** + +The package uses astropy constants throughout for physical calculations. + +Error Handling +-------------- + +The FRB package uses standard Python exception handling: + +**Common Exceptions:** + +- ``FileNotFoundError``: When FRB data files are not found +- ``ValueError``: When invalid parameters are passed to functions +- ``AttributeError``: When accessing properties not available for a particular FRB +- ``ImportError``: When optional dependencies are not available + +**Error Handling Example:** + +.. code-block:: python + + try: + frb_obj = ffrb.FRB.by_name('NonExistentFRB') + except FileNotFoundError: + print("FRB data not found") + except ValueError as e: + print(f"Invalid FRB name: {e}") + +Data Types +---------- + +The package primarily works with astropy quantities and coordinates: + +**Common Data Types:** + +- ``astropy.coordinates.SkyCoord`` - Sky positions +- ``astropy.units.Quantity`` - Physical quantities with units +- ``astropy.table.Table`` - Tabular data (catalogues) +- ``numpy.ndarray`` - Numerical arrays +- ``dict`` - Configuration and metadata + +**Unit Conventions:** + +- Dispersion Measure: ``pc / cm³`` +- Distances: ``kpc``, ``Mpc``, ``Gpc`` +- Frequencies: ``MHz``, ``GHz`` +- Time: ``s``, ``ms``, ``μs`` +- Angles: ``deg``, ``arcmin``, ``arcsec``, ``mas``, ``μas`` + +Version Compatibility +-------------------- + +The API documentation reflects the current development version. Some functions may not be available in older versions of the package. + +**Checking Your Version:** + +.. code-block:: python + + import frb + print(frb.__version__) # If available + +**Compatibility Notes:** + +- Python 3.6+ required +- Astropy 4.0+ recommended +- Some features require optional dependencies + +Contributing to the API +----------------------- + +If you're contributing new functions or classes: + +1. Follow the existing documentation style +2. Include comprehensive docstrings +3. Add type hints where appropriate +4. Include examples in docstrings +5. Update this API documentation + +See :doc:`../contributing` for detailed guidelines. + +.. seealso:: + + - :doc:`../quickstart` - Get started with basic usage + - :doc:`../tutorials` - Detailed examples and workflows + - :doc:`../examples` - Real-world applications \ No newline at end of file diff --git a/docs/halos/hmf.rst b/docs/halos/hmf.rst new file mode 100644 index 00000000..64b21d26 --- /dev/null +++ b/docs/halos/hmf.rst @@ -0,0 +1,246 @@ +frb.halos.hmf +============= + +.. automodule:: frb.halos.hmf + +Module for halo mass function calculations and related statistical analysis. + +.. warning:: + This module is deprecated. The functionality has been moved to frb.halos.models. + Hope you are not intending to use the hmf.py module. + +Functions +--------- + +frac_in_halos +~~~~~~~~~~~~~ + +.. autofunction:: frac_in_halos + + Calculate the fraction of matter in collapsed halos over a mass range and at a given redshift. + + **Parameters:** + + * ``zvals`` : ndarray - Redshift values + * ``Mlow`` : float - Minimum halo mass in h^-1 units + * ``Mhigh`` : float - Maximum halo mass in h^-1 units + * ``rmax`` : float, optional - Extent of halo in units of rvir (default: 1.0) + + **Returns:** + + * ``ratios`` : ndarray - rho_halo / rho_m + + .. note:: + The fraction of DM associated with these halos will be scaled down by an additional factor of f_diffuse. + + .. warning:: + This calculation assumes a single concentration for all halos. + + **Requirements:** + + * Requires Aemulus HMF to be installed + +halo_incidence +~~~~~~~~~~~~~~ + +.. autofunction:: halo_incidence + + Calculate the (approximate) average number of intersections to halos of a given minimum mass to a given FRB redshift. + + **Parameters:** + + * ``Mlow`` : float - Mass of minimum halo in Solar masses (minimum: 2e10) + * ``zFRB`` : float - Redshift of the FRB + * ``radius`` : Quantity, optional - Physical separation from sightline + * ``hmfe`` : object, optional - HMF emulator instance + * ``Mhigh`` : float, optional - Maximum halo mass (default: 1e16) + * ``nsample`` : int, optional - Number of samples (default: 20) + * ``cumul`` : bool, optional - Return cumulative values (default: False) + + **Returns:** + + * Average number of halo intersections + + .. note:: + The code handles h^-1 factors automatically. If radius is not specified, + it uses rvir derived from Mlow. + + **Requirements:** + + * Requires Aemulus HMF to be installed + +Examples +-------- + +Calculate matter fraction in halos:: + + from frb.halos.hmf import frac_in_halos + import numpy as np + + # Define redshift range + redshifts = np.linspace(0.1, 1.0, 10) + + # Mass range for galaxy-scale halos + mass_min = 1e11 # Solar masses + mass_max = 1e13 + + # Calculate fractions + fractions = frac_in_halos(redshifts, mass_min, mass_max) + + for z, frac in zip(redshifts, fractions): + print(f"z={z:.1f}: {frac:.3f} of matter in galaxy halos") + +Calculate halo incidence along sightline:: + + from frb.halos.hmf import halo_incidence + from astropy import units as u + + # Parameters for FRB sightline + min_mass = 1e12 # Solar masses + frb_redshift = 0.8 + impact_radius = 100 * u.kpc + + # Calculate average number of halo intersections + n_halos = halo_incidence(min_mass, frb_redshift, + radius=impact_radius) + + print(f"Expected {n_halos:.2f} halo intersections") + +Compare different mass ranges:: + + from frb.halos.hmf import frac_in_halos + import numpy as np + import matplotlib.pyplot as plt + + z_array = np.linspace(0, 2, 50) + + # Different mass ranges + dwarf_range = frac_in_halos(z_array, 1e9, 1e11) # Dwarf galaxies + galaxy_range = frac_in_halos(z_array, 1e11, 1e13) # Normal galaxies + cluster_range = frac_in_halos(z_array, 1e13, 1e15) # Clusters + + plt.figure(figsize=(10, 6)) + plt.plot(z_array, dwarf_range, label='Dwarf halos (1e9-1e11)') + plt.plot(z_array, galaxy_range, label='Galaxy halos (1e11-1e13)') + plt.plot(z_array, cluster_range, label='Cluster halos (1e13-1e15)') + + plt.xlabel('Redshift') + plt.ylabel('Matter fraction in halos') + plt.legend() + plt.title('Halo matter fraction vs redshift') + plt.show() + +Extended halo calculations:: + + from frb.halos.hmf import frac_in_halos + import numpy as np + + # Calculate with extended halo profiles + z_test = 0.5 + mass_min = 1e12 + mass_max = 1e14 + + # Standard virial radius + frac_1rvir = frac_in_halos([z_test], mass_min, mass_max, rmax=1.0)[0] + + # Extended to 2 virial radii + frac_2rvir = frac_in_halos([z_test], mass_min, mass_max, rmax=2.0)[0] + + # Extended to 3 virial radii + frac_3rvir = frac_in_halos([z_test], mass_min, mass_max, rmax=3.0)[0] + + print(f"Matter fraction at z={z_test}:") + print(f" 1 rvir: {frac_1rvir:.4f}") + print(f" 2 rvir: {frac_2rvir:.4f}") + print(f" 3 rvir: {frac_3rvir:.4f}") + + boost_factor = frac_2rvir / frac_1rvir + print(f"Boost factor (2 rvir): {boost_factor:.2f}") + +Statistical analysis of halo encounters:: + + from frb.halos.hmf import halo_incidence + from astropy import units as u + import numpy as np + + # Range of FRB redshifts + frb_redshifts = np.linspace(0.1, 2.0, 20) + + # Different halo mass thresholds + mass_thresholds = [1e11, 1e12, 1e13] # Solar masses + radius = 50 * u.kpc + + results = {} + for mass_min in mass_thresholds: + encounters = [] + for z_frb in frb_redshifts: + n_enc = halo_incidence(mass_min, z_frb, radius=radius) + encounters.append(n_enc) + results[mass_min] = encounters + + # Plot results + import matplotlib.pyplot as plt + plt.figure(figsize=(10, 6)) + + for mass_min, encounters in results.items(): + plt.plot(frb_redshifts, encounters, + label=f'M > {mass_min:.0e} Msun') + + plt.xlabel('FRB Redshift') + plt.ylabel('Average Number of Halo Encounters') + plt.title(f'Halo Encounters vs FRB Redshift (R < {radius})') + plt.legend() + plt.grid(True, alpha=0.3) + plt.show() + +Cumulative analysis:: + + from frb.halos.hmf import halo_incidence + from astropy import units as u + + # Parameters + mass_min = 1e12 + z_frb = 1.0 + radius = 100 * u.kpc + + # Get cumulative encounters + cumul_encounters = halo_incidence(mass_min, z_frb, radius=radius, + cumul=True, nsample=100) + + print(f"Cumulative halo encounters: {cumul_encounters}") + +Redshift evolution study:: + + from frb.halos.hmf import frac_in_halos + import numpy as np + + # Study evolution from z=0 to z=3 + z_range = np.linspace(0, 3, 100) + + # Different mass ranges + mass_ranges = [ + (1e10, 1e11, 'Low mass'), + (1e11, 1e12, 'Intermediate mass'), + (1e12, 1e13, 'High mass'), + (1e13, 1e15, 'Cluster mass') + ] + + import matplotlib.pyplot as plt + fig, axes = plt.subplots(2, 2, figsize=(12, 10)) + axes = axes.ravel() + + for i, (m_low, m_high, label) in enumerate(mass_ranges): + fractions = frac_in_halos(z_range, m_low, m_high) + + axes[i].plot(z_range, fractions, 'b-', linewidth=2) + axes[i].set_title(f'{label} halos') + axes[i].set_xlabel('Redshift') + axes[i].set_ylabel('Matter fraction') + axes[i].grid(True, alpha=0.3) + axes[i].text(0.1, 0.9, f'{m_low:.0e} - {m_high:.0e} Msun', + transform=axes[i].transAxes, + bbox=dict(boxstyle='round', facecolor='wheat')) + + plt.tight_layout() + plt.suptitle('Halo Matter Fraction Evolution', y=1.02) + plt.show() \ No newline at end of file diff --git a/docs/halos/index.rst b/docs/halos/index.rst new file mode 100644 index 00000000..15858eb0 --- /dev/null +++ b/docs/halos/index.rst @@ -0,0 +1,239 @@ +frb.halos Package Documentation +=============================== + +The ``frb.halos`` package provides tools for modeling galaxy halos and calculating their contributions to Fast Radio Burst (FRB) dispersion measures. This package includes halo models, stellar-halo mass relations, photometric redshift analysis, and statistical tools for halo populations. + +Overview +-------- + +The halos package enables: + +* **Halo Modeling**: Modified NFW profiles for galaxy halos, including specialized models for the Milky Way, M31, and galaxy clusters +* **Mass Relations**: Stellar-halo mass relations from literature (Moster+2013, Kravtsov+2018) +* **DM Calculations**: Dispersion measure contributions from individual halos and halo populations +* **Photo-z Analysis**: Integration with photometric redshift and SED fitting tools +* **Statistical Analysis**: Halo mass functions and encounter rates along FRB sightlines + +Modules +------- + +Core Models +~~~~~~~~~~~ + +.. toctree:: + :maxdepth: 2 + + frb_halos_models + +Main module containing halo density profiles, stellar-halo mass relations, and galaxy-specific models. + +**Key Features:** +* ModifiedNFW class for customizable halo profiles +* Stellar-halo mass relations with scatter +* Specialized models for Milky Way, M31, and galaxy clusters +* DM calculation methods + +Photometric Analysis +~~~~~~~~~~~~~~~~~~~ + +.. toctree:: + :maxdepth: 2 + + frb_halos_photoz + +Tools for photometric redshift-based halo analysis of FRB fields. + +**Key Features:** +* DES photometry retrieval and processing +* EAZY and CIGALE integration for photo-z and stellar masses +* 3D interpolation grids for efficient DM calculations +* Full pipeline analysis for FRB fields + +Statistical Tools +~~~~~~~~~~~~~~~~~ + +.. toctree:: + :maxdepth: 2 + + frb_halos_hmf + +Halo mass function calculations and statistical analysis. + +.. warning:: + This module is deprecated. Functionality moved to frb.halos.models. + +**Key Features:** +* Matter fraction in collapsed halos +* Halo encounter statistics along sightlines +* Redshift evolution of halo populations + +Quick Start +----------- + +Basic halo DM calculation:: + + from frb.halos.models import ModifiedNFW + from astropy import units as u + + # Create halo model + halo = ModifiedNFW(log_Mhalo=12.0, z=0.3) + + # Calculate DM at 50 kpc impact parameter + dm = halo.Ne_Rperp(50 * u.kpc) + print(f"DM contribution: {dm}") + +Stellar-halo mass conversion:: + + from frb.halos.models import halomass_from_stellarmass + + log_mstar = 10.5 # log solar masses + z = 0.5 + log_mhalo = halomass_from_stellarmass(log_mstar, z=z) + print(f"Halo mass: {log_mhalo:.2f}") + +Complete field analysis:: + + from frb.frb import FRB + from frb.halos.photoz import full_analysis + + # Load FRB and analyze field + frb = FRB.by_name('FRB20180924B') + full_analysis(frb, 'field_photometry.fits', './results/') + +Common Workflows +---------------- + +**Individual Galaxy Analysis:** + +1. Load galaxy photometry and redshift +2. Estimate stellar mass (from SED fitting) +3. Convert to halo mass using SHMR +4. Create ModifiedNFW model +5. Calculate DM contribution + +**FRB Field Analysis:** + +1. Retrieve field photometry (get_des_data) +2. Run photo-z analysis (EAZY) +3. Fit SEDs for stellar masses (CIGALE) +4. Generate halo mass realizations +5. Calculate statistical DM contributions + +**Population Studies:** + +1. Define mass and redshift ranges +2. Calculate halo fractions (frac_in_halos) +3. Estimate encounter rates (halo_incidence) +4. Model cumulative effects + +Dependencies +------------ + +**Required:** +* astropy +* numpy +* scipy + +**Optional for full functionality:** +* hmf_emulator (for halo mass functions) +* pathos (for multiprocessing) +* progressbar2 (for progress tracking) +* threedhst (for EAZY integration) + +**External codes:** +* EAZY (photometric redshifts) +* CIGALE (SED fitting) + +Related Modules +--------------- + +The halos package integrates with: + +* :mod:`frb.frb` - FRB object definitions +* :mod:`frb.galaxies` - Galaxy analysis tools +* :mod:`frb.surveys` - Survey data access +* :mod:`frb.dm` - DM calculations and components + +References +---------- + +Key papers implemented in this package: + +* **Moster+2013**: Stellar-halo mass relations +* **Kravtsov+2018**: Alternative SHMR at low redshift +* **Mathews & Prochaska 2017**: Modified NFW profiles +* **Miller & Bregman 2015**: ICM models for clusters +* **Tinker+2008**: Halo mass function (via Aemulus) + +Examples +-------- + +Advanced halo modeling:: + + from frb.halos.models import ModifiedNFW, halomass_from_stellarmass + from astropy import units as u + import numpy as np + + # Galaxy parameters + log_mstar = 10.8 + z_gal = 0.4 + + # Convert to halo mass with scatter + log_mhalos = [] + for i in range(100): + log_mh = halomass_from_stellarmass(log_mstar, z=z_gal, randomize=True) + log_mhalos.append(log_mh) + + # Create halo model with mean mass + mean_mhalo = np.mean(log_mhalos) + halo = ModifiedNFW(log_Mhalo=mean_mhalo, z=z_gal, + f_hot=0.6, alpha=2, y0=2) + + # Calculate DM vs impact parameter + offsets = np.logspace(0, 3, 50) * u.kpc # 1-1000 kpc + dms = [] + for offset in offsets: + dm = halo.Ne_Rperp(offset) + dms.append(dm.to('pc/cm**3').value) + + # Plot results + import matplotlib.pyplot as plt + plt.loglog(offsets.value, dms) + plt.xlabel('Impact parameter [kpc]') + plt.ylabel('DM contribution [pc/cm³]') + plt.title(f'Halo DM profile (log Mhalo = {mean_mhalo:.1f})') + plt.show() + +Field-wide statistical analysis:: + + from frb.halos.photoz import get_des_data, dm_grid + from frb.halos.models import frac_in_halos + from frb.frb import FRB + from astropy import units as u + import numpy as np + + # Load FRB + frb = FRB.by_name('FRB20180924B') + + # Get field photometry + field_cat = get_des_data(frb.coord, radius=10*u.arcmin) + print(f"Field contains {len(field_cat)} galaxies") + + # Create DM interpolation grid + dm_grid(frb.z, n_z=100, n_o=100, n_m=100) + + # Calculate halo statistics + z_range = np.linspace(0.1, frb.z, 50) + mass_ranges = [(1e11, 1e12), (1e12, 1e13), (1e13, 1e14)] + + for m_low, m_high in mass_ranges: + fractions = frac_in_halos(z_range, m_low, m_high) + print(f"Mass range {m_low:.0e}-{m_high:.0e}:") + print(f" Peak fraction: {np.max(fractions):.3f} at z={z_range[np.argmax(fractions)]:.2f}") + +See Also +-------- + +* :doc:`../frb_frb` - Core FRB functionality +* :doc:`../frb_galaxies_frbgalaxy` - FRB host galaxy analysis +* :doc:`../frb_dm_host` - Host galaxy DM calculations \ No newline at end of file diff --git a/docs/halos/models.rst b/docs/halos/models.rst new file mode 100644 index 00000000..2f1cf647 --- /dev/null +++ b/docs/halos/models.rst @@ -0,0 +1,325 @@ +frb.halos.models +================ + +.. automodule:: frb.halos.models + +Module for DM halo calculations and galaxy halo models. + +Constants +--------- + +.. autodata:: m_p + + Proton mass in CGS units for optimized calculations. + +Functions +--------- + +init_hmf +~~~~~~~~ + +.. autofunction:: init_hmf + + Initialize the Aemulus Halo Mass Function. + + .. warning:: + Uses the original version which codes Tinker+2008. May be refactored to use the more accurate new version. + + **Returns:** + + * ``hmf_emulator`` - Initialized HMF emulator object + +frac_in_halos +~~~~~~~~~~~~~ + +.. autofunction:: frac_in_halos + + Calculate the fraction of matter in collapsed halos over a mass range and at a given redshift. + + .. note:: + The fraction of DM associated with these halos will be scaled down by an additional factor of f_diffuse. + + **Parameters:** + + * ``zvals`` : ndarray - Redshift values + * ``Mlow`` : float - Minimum halo mass in h^-1 units + * ``Mhigh`` : float - Maximum halo mass in h^-1 units + * ``rmax`` : float, optional - Extent of halo in units of rvir (default: 1.0) + + **Returns:** + + * ``ratios`` : ndarray - rho_halo / rho_m + + .. warning:: + This calculation assumes a single concentration for all halos. + +stellarmass_from_halomass +~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. autofunction:: stellarmass_from_halomass + + Stellar mass from Halo Mass using Moster+2013 relation. + + **Parameters:** + + * ``log_Mhalo`` : float - log_10 halo mass in solar mass units + * ``z`` : float, optional - Halo redshift (default: 0) + * ``params`` : list, optional - Custom model parameters + + **Returns:** + + * ``log_mstar`` : float - log_10 galaxy stellar mass in solar mass units + + **Reference:** https://doi.org/10.1093/mnras/sts261 + +halomass_from_stellarmass +~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. autofunction:: halomass_from_stellarmass + + Halo mass from Stellar mass (Moster+2013). Numerically inverts stellarmass_from_halomass. + + **Parameters:** + + * ``log_mstar`` : float or ndarray - log_10 stellar mass in solar mass units + * ``z`` : float, optional - Galaxy redshift (default: 0) + * ``randomize`` : bool, optional - Add scatter to the relation + + **Returns:** + + * ``log_Mhalo`` : float - log_10 halo mass in solar mass units + +stellarmass_from_halomass_kravtsov +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. autofunction:: stellarmass_from_halomass_kravtsov + + Stellar mass from Halo Mass using Kravtsov+2018 relation. + + .. caution:: + This relation is valid for low z (z~0). Higher z values may require a scaled relation. + + **Parameters:** + + * ``log_mhalo`` : float - log_10 halo mass + + **Returns:** + + * ``log_mstar`` : float - log_10 galaxy stellar mass + + **Reference:** https://ui.adsabs.harvard.edu/abs/2018AstL...44....8K/abstract + +halomass_from_stellarmass_kravtsov +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. autofunction:: halomass_from_stellarmass_kravtsov + + Inverts stellarmass_from_halomass_kravtsov function. + + **Parameters:** + + * ``log_mstar`` : float or ndarray - log_10 stellar mass + + **Returns:** + + * ``log_mhalo`` : float - log_10 halo mass + +rad3d2 +~~~~~~ + +.. autofunction:: rad3d2 + + Calculate radius to x,y,z coordinates. Assumes origin is (0,0,0). + + **Parameters:** + + * ``xyz`` : tuple or ndarray - 3D coordinates + + **Returns:** + + * ``rad3d`` : float or ndarray - 3D radius squared + +Classes +------- + +ModifiedNFW +~~~~~~~~~~~ + +.. autoclass:: ModifiedNFW + :members: + :undoc-members: + :show-inheritance: + + Generate a modified NFW model for hot, virialized gas (e.g. Mathews & Prochaska 2017). + + **Parameters:** + + * ``log_Mhalo`` : float, optional - log10 of halo mass in solar masses (default: 12.2) + * ``c`` : float, optional - Concentration of the halo (default: 7.67) + * ``f_hot`` : float, optional - Fraction of baryons in hot phase (default: 0.75) + * ``alpha`` : float, optional - Parameter to modify NFW profile power-law (default: 0) + * ``y0`` : float, optional - Parameter to modify NFW profile position (default: 1) + * ``z`` : float, optional - Redshift of the halo (default: 0) + * ``cosmo`` : astropy cosmology, optional - Cosmology of the universe + + **Key Attributes:** + + * ``H0`` : Quantity - Hubble constant + * ``fb`` : float - Cosmic fraction of baryons (default: 0.16) + * ``r200`` : Quantity - Virial radius + * ``rho0`` : Quantity - Density normalization + * ``M_b`` : Quantity - Mass in baryons + + **Methods:** + + .. automethod:: setup_param + + Setup key parameters of the model. + + .. automethod:: Ne_Rperp + + Calculate column density along a perpendicular path through the halo. + +ICM +~~~ + +.. autoclass:: ICM + :members: + :undoc-members: + :show-inheritance: + + Intracluster Medium model, child of ModifiedNFW. + + Implements the Miller & Bregman 2015 ICM model for galaxy clusters. + + **Methods:** + + .. automethod:: nH + + Calculate the number density of Hydrogen. + + **Parameters:** + + * ``xyz`` : ndarray - Coordinates in kpc + + **Returns:** + + * ``ndarray`` - Number density in units of 1/cm³ + +MilkyWay +~~~~~~~~ + +.. autoclass:: MilkyWay + :members: + :undoc-members: + :show-inheritance: + + Fiducial model for the Galaxy. Halo mass follows latest constraints. + + Density profile is similar to Maller & Bullock 2004. + +M31 +~~~ + +.. autoclass:: M31 + :members: + :undoc-members: + :show-inheritance: + + Preferred model for M31. Mass from van der Marel 2012. + + **Attributes:** + + * ``distance`` : Quantity - Distance from Sun (752 kpc) + * ``coord`` : SkyCoord - Coordinates of M31 + + **Methods:** + + .. automethod:: DM_from_Galactic + + Calculate DM through M31's halo from the Sun given a direction. + + **Parameters:** + + * ``scoord`` : SkyCoord - Coordinates of the sightline + + **Returns:** + + * ``DM`` : Quantity - Dispersion measure through M31's halo + +Examples +-------- + +Basic halo model usage:: + + from frb.halos.models import ModifiedNFW, halomass_from_stellarmass + from astropy import units as u + + # Create a halo model + halo = ModifiedNFW(log_Mhalo=12.5, z=0.3, f_hot=0.6) + + # Calculate DM at 100 kpc offset + offset = 100 * u.kpc + dm_contribution = halo.Ne_Rperp(offset) + print(f"DM contribution: {dm_contribution}") + +Stellar-halo mass relations:: + + from frb.halos.models import stellarmass_from_halomass, halomass_from_stellarmass + + # Convert halo mass to stellar mass + log_mhalo = 12.0 # log solar masses + log_mstar = stellarmass_from_halomass(log_mhalo, z=0.5) + + # Invert the relation + log_mhalo_recovered = halomass_from_stellarmass(log_mstar, z=0.5) + + print(f"Halo mass: {log_mhalo}") + print(f"Stellar mass: {log_mstar:.2f}") + print(f"Recovered halo mass: {log_mhalo_recovered:.2f}") + +Galaxy-specific models:: + + from frb.halos.models import MilkyWay, M31 + from astropy.coordinates import SkyCoord + from astropy import units as u + + # Milky Way model + mw = MilkyWay(log_Mhalo=12.1, f_hot=0.7) + + # M31 model with DM calculation + m31 = M31(log_Mhalo=12.2) + target_coord = SkyCoord('01h33m51s', '+30d39m37s') + dm_m31 = m31.DM_from_Galactic(target_coord) + print(f"DM through M31: {dm_m31}") + +Halo mass function calculations:: + + from frb.halos.models import frac_in_halos + import numpy as np + + # Calculate matter fraction in halos + redshifts = np.array([0.1, 0.5, 1.0]) + mass_min = 1e11 # Solar masses + mass_max = 1e15 + + fractions = frac_in_halos(redshifts, mass_min, mass_max) + + for z, frac in zip(redshifts, fractions): + print(f"z={z:.1f}: {frac:.3f} of matter in halos") + +Advanced usage with scatter:: + + # Include scatter in stellar-halo mass relation + log_mstar = 10.5 + z = 0.3 + + # Multiple realizations with scatter + log_mhalos = [] + for i in range(100): + log_mhalo = halomass_from_stellarmass(log_mstar, z=z, randomize=True) + log_mhalos.append(log_mhalo) + + mean_mhalo = np.mean(log_mhalos) + std_mhalo = np.std(log_mhalos) + print(f"Mean log(Mhalo): {mean_mhalo:.2f} ± {std_mhalo:.2f}") \ No newline at end of file diff --git a/docs/halos/photoz.rst b/docs/halos/photoz.rst new file mode 100644 index 00000000..5b11a584 --- /dev/null +++ b/docs/halos/photoz.rst @@ -0,0 +1,312 @@ +frb.halos.photoz +================ + +.. automodule:: frb.halos.photoz + +Module for photometric redshift-based halo DM calculations and galaxy analysis. + +This module combines photometric redshift estimates with halo models to calculate dispersion measure contributions from galaxy halos along FRB sightlines. + +Constants +--------- + +.. autodata:: DEFAULT_DATA_FOLDER + + Default data folder path: "data" + +Functions +--------- + +get_des_data +~~~~~~~~~~~~ + +.. autofunction:: get_des_data + + Download photometry for galaxies within an FRB field. + + **Parameters:** + + * ``coords`` : SkyCoord - Center coordinates for cone search + * ``radius`` : Quantity, optional - Search radius (default: 15 arcmin) + * ``starbright`` : float, optional - Lower r-band magnitude limit (default: 17) + * ``starflagval`` : float, optional - Star classification upper limit (default: 0.9) + * ``gaiacat`` : str, optional - Gaia catalog file for star removal + * ``write`` : bool, optional - Write output table to file (default: False) + * ``outfile`` : str, optional - Output filename + + **Returns:** + + * ``des_data`` : Table - DES galaxies within search radius + +dm_grid +~~~~~~~ + +.. autofunction:: dm_grid + + Produce DM estimates for a 3D grid of redshift, offsets and halo masses. + + **Parameters:** + + * ``frb_z`` : float - FRB redshift + * ``n_z`` : int, optional - Size of redshift grid (default: 100) + * ``n_o`` : int, optional - Size of offset grid (default: 100) + * ``n_m`` : int, optional - Size of halo mass grid (default: 100) + * ``max_log_mhalo`` : float, optional - Maximum log halo mass (default: 12.8) + * ``outdir`` : str, optional - Output directory (default: DEFAULT_DATA_FOLDER) + * ``outfile`` : str, optional - Output .npz filename + + Creates a 3D interpolation grid for DM calculations with dimensions: + + * Redshift: np.linspace(0, frb_z, n_z) + * Offsets: np.linspace(0, 600, n_o) kpc + * Halo masses: np.linspace(8, 16, n_m) log solar masses + +mhalo_lookup_tables +~~~~~~~~~~~~~~~~~~~ + +.. autofunction:: mhalo_lookup_tables + + For each redshift in z_grid, produces files containing halo mass values corresponding to stellar masses. + + **Parameters:** + + * ``z_grid`` : list or ndarray - Redshift values to sample + * ``datafolder`` : str, optional - Storage directory (default: DEFAULT_DATA_FOLDER) + * ``n_cores`` : int, optional - CPU threads for parallel processing (default: 8) + + Values are produced by sampling the Moster+13 stellar-halo mass relation (SHMR). + +_mhalo_lookup_table +~~~~~~~~~~~~~~~~~~~ + +.. autofunction:: _mhalo_lookup_table + + Internal function to create halo mass lookup tables for a single redshift. + + **Parameters:** + + * ``z`` : float - Redshift + * ``npz_out`` : str, optional - Output .npz file path + * ``n_cores`` : int, optional - CPU threads (default: 8) + + .. note:: + This is an internal function. Use mhalo_lookup_tables() directly if you know what you're doing. + +_instantiate_intepolators +~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. autofunction:: _instantiate_intepolators + + Produce interpolator functions for key quantities required for the analysis. + + **Parameters:** + + * ``datafolder`` : str, optional - Folder with interpolation data files (default: DEFAULT_DATA_FOLDER) + * ``dmfilename`` : str, optional - DM interpolation data filename + * ``frb_name`` : str, optional - FRB name (default: "FRB180924") + + **Returns:** + + * ``dm_interpolator`` : RegularGridInterpolator - DM(z, offset_kpc, log_mhalo) + * ``mean_interp`` : interp2d - based on SHMR + * ``stddev_interp`` : interp2d - std.dev. log_mhalo(log_mstar, z) based on SHMR + * ``ang_dia_interp`` : interp1d - angular_diameter_distance(z) for default cosmology + +_mhalo_realizations +~~~~~~~~~~~~~~~~~~~ + +.. autofunction:: _mhalo_realizations + + Generate halo mass realizations using lookup tables, accounting for both stellar mass uncertainty and SHMR scatter. + + **Parameters:** + + * ``log_mstar`` : float - log stellar mass in M_sun + * ``log_mstar_err`` : float - log error in log_mstar + * ``z`` : float - Redshift + * ``mean_interp`` : interp2d - interpolator + * ``stddev_interp`` : interp2d - std.dev. log_mhalo(log_mstar, z) interpolator + * ``n_mstar`` : int, optional - Number of stellar mass samples (default: 100) + * ``n_norm`` : int, optional - Number of normal distribution samples (default: 10) + * ``max_log_mhalo`` : float, optional - Maximum log halo mass (default: 12.8) + + **Returns:** + + * ``ndarray`` - Halo mass realizations + +_dm_pdf +~~~~~~~ + +.. autofunction:: _dm_pdf + + Calculate DM realizations for a galaxy using photometric redshift and stellar mass estimates. + + **Parameters:** + + * ``cigale_tab`` : Table - CIGALE results for the galaxy + * ``eazy_outdir`` : str - EAZY output directory + * ``mean_interp`` : interp2d - Mean SHMR interpolator + * ``stddev_interp`` : interp2d - SHMR scatter interpolator + * ``ang_dia_interp`` : interp1d - Angular diameter distance interpolator + * ``dm_interpolator`` : RegularGridInterpolator - DM interpolator + * ``n_cores`` : int, optional - CPU threads + + **Returns:** + + * ``dm_values`` : ndarray - DM realizations for the galaxy + * ``z_draws`` : ndarray - Redshift draws used for DM calculations + +full_analysis +~~~~~~~~~~~~~ + +.. autofunction:: full_analysis + + Perform complete photometric redshift-based halo DM analysis for an FRB field. + + **Parameters:** + + * ``frb`` : FRB - FRB object of interest + * ``input_catfile`` : str - Input photometry catalog path (assumed DES format) + * ``datafolder`` : str - Results storage directory + * ``n_cores`` : int, optional - CPU threads (default: varies by function) + * ``n_gals`` : int, optional - Limit analysis to n_gals galaxies for testing + + **Process:** + + 1. Runs EAZY photometric redshift estimation + 2. Runs CIGALE SED fitting for stellar masses + 3. Creates interpolation grids + 4. Calculates DM realizations for all galaxies + 5. Saves results to compressed files + + **Outputs:** + + * DM_halos_final.npz - Sparse matrix of DM realizations + * DM_halos_zdraws.npz - Redshift draws for each galaxy + +Dependencies +------------ + +Required packages for full functionality: + +* ``pathos`` - For multiprocessing: ``pip install pathos`` +* ``progressbar2`` - For progress tracking: ``pip install progressbar2`` +* ``threedhst`` - For EAZY output: ``pip install threedhst`` + +Examples +-------- + +Basic DES data retrieval:: + + from frb.halos.photoz import get_des_data + from astropy.coordinates import SkyCoord + from astropy import units as u + + # Define search parameters + center = SkyCoord('12h34m56s', '+12d34m56s') + radius = 10 * u.arcmin + + # Get DES photometry + des_cat = get_des_data(center, radius=radius, write=True) + print(f"Found {len(des_cat)} galaxies") + +Create DM interpolation grid:: + + from frb.halos.photoz import dm_grid + + # Create 3D DM grid for FRB at z=0.5 + frb_redshift = 0.5 + dm_grid(frb_redshift, n_z=50, n_o=50, n_m=50, + outdir='./halo_data/', outfile='dm_grid.npz') + +Full analysis workflow:: + + from frb.frb import FRB + from frb.halos.photoz import full_analysis + + # Load FRB + frb_obj = FRB.by_name('FRB20180924B') + + # Run complete halo DM analysis + full_analysis(frb_obj, + input_catfile='field_photometry.fits', + datafolder='./analysis_results/', + n_cores=8, + n_gals=100) # Limit for testing + +Setup interpolators:: + + from frb.halos.photoz import _instantiate_intepolators + + # Create interpolation functions + dm_interp, mean_interp, std_interp, ang_interp = _instantiate_intepolators( + datafolder='./halo_data/', + dmfilename='dm_grid.npz' + ) + + # Use interpolators for DM calculations + import numpy as np + z_test = 0.3 + offset_test = 100.0 # kpc + mhalo_test = 12.0 # log solar masses + + dm_value = dm_interp((z_test, offset_test, mhalo_test)) + print(f"DM contribution: {dm_value:.2f} pc/cm³") + +Generate halo mass lookup tables:: + + from frb.halos.photoz import mhalo_lookup_tables + import numpy as np + + # Create lookup tables for multiple redshifts + z_array = np.linspace(0.1, 1.0, 10) + mhalo_lookup_tables(z_array, + datafolder='./lookup_tables/', + n_cores=4) + +Advanced usage with custom parameters:: + + from frb.halos.photoz import get_des_data, dm_grid + from astropy.coordinates import SkyCoord + from astropy import units as u + + # Custom DES query with star removal + coords = SkyCoord(ra=123.45, dec=-23.45, unit='deg') + + des_data = get_des_data( + coords, + radius=20*u.arcmin, + starbright=16.0, # Remove bright stars + starflagval=0.8, # More aggressive star removal + gaiacat='gaia_stars.csv', # Additional star catalog + write=True, + outfile='frb_field_photometry.fits' + ) + + # High-resolution DM grid + dm_grid(frb_z=1.2, + n_z=200, n_o=150, n_m=120, # Higher resolution + max_log_mhalo=13.5, # Include more massive halos + outdir='./high_res_grid/', + outfile='dm_grid_hires.npz') + +Integration with FRB analysis:: + + from frb.frb import FRB + from frb.halos.photoz import get_des_data, full_analysis + from astropy import units as u + + # Load FRB and get field data + frb = FRB.by_name('FRB20180924B') + + # Get photometry around FRB location + field_data = get_des_data(frb.coord, radius=15*u.arcmin) + + # Save for analysis + field_data.write('frb_field.fits', overwrite=True) + + # Run complete halo DM analysis + full_analysis(frb, 'frb_field.fits', './results/', n_cores=8) + + print("Halo DM analysis complete!") + print("Results saved in ./results/DM_halos_final.npz") \ No newline at end of file diff --git a/docs/index.rst b/docs/index.rst index 168a849f..42df6c4f 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -19,6 +19,7 @@ Getting Started :maxdepth: 2 installing + quickstart Data ---- @@ -46,6 +47,16 @@ Galaxies galaxies eazy +Halos +----- + +.. toctree:: + :maxdepth: 2 + + halos/index + halos/hmf + halos/models + halos/photoz Rotation Measure ---------------- @@ -81,4 +92,13 @@ FRB Scripts scripts +API Reference +------------- + +.. toctree:: + :maxdepth: 2 + + api/index + api/dm + diff --git a/docs/quickstart.rst b/docs/quickstart.rst new file mode 100644 index 00000000..e6dc1abb --- /dev/null +++ b/docs/quickstart.rst @@ -0,0 +1,325 @@ +Quick Start Guide +================= + +This guide will get you up and running with the FRB package in just a few minutes. + +Basic Usage +----------- + +Loading FRBs +~~~~~~~~~~~~ + +The most common starting point is loading a known FRB by name: + +.. code-block:: python + + import frb as ffrb + + # Load a specific FRB by name + frb121102 = ffrb.FRB.by_name('FRB121102') + + # Access basic properties + print(f"Coordinates: {frb121102.coord}") + print(f"Dispersion Measure: {frb121102.DM}") + print(f"Error ellipse: {frb121102.eellipse}") + +Working with Catalogues +~~~~~~~~~~~~~~~~~~~~~~~ + +Load and explore FRB catalogues: + +.. code-block:: python + + from frb.frbcat import FRBCat + + # Load the FRB catalogue + cat = FRBCat() + + # Basic catalogue information + print(f"Number of FRBs: {len(cat.frbcat)}") + print(f"DM range: {cat.frbcat['DM'].min():.1f} - {cat.frbcat['DM'].max():.1f} pc/cm³") + + # Filter high-DM FRBs + high_dm_frbs = cat.frbcat[cat.frbcat['DM'] > 1000] + print(f"High-DM FRBs (>1000): {len(high_dm_frbs)}") + +Dispersion Measure Calculations +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Calculate cosmic and IGM contributions to dispersion measure: + +.. code-block:: python + + from frb.dm import igm + from astropy import units as u + + # Calculate cosmic DM contribution at a given redshift + z_frb = 0.5 + DM_cosmic = igm.DM_cosmic(z_frb) + print(f"Cosmic DM at z={z_frb}: {DM_cosmic}") + + # Estimate redshift from observed DM + DM_observed = 500 * u.pc / u.cm**3 + z_estimated = igm.z_from_DM(DM_observed) + print(f"Estimated redshift for DM={DM_observed}: {z_estimated:.2f}") + +Scattering Analysis +~~~~~~~~~~~~~~~~~~~ + +Analyze pulse scattering and broadening: + +.. code-block:: python + + from frb import turb_scattering as ts + from astropy import units as u + + # Set up scattering parameters + n_e = 1e-3 * u.cm**(-3) # Electron density + nu_obs = 1.4 * u.GHz # Observation frequency + L = 50 * u.kpc # Structure size + R = 1 * u.pc # Cloud size + + # Calculate scattering angle + theta = ts.theta_mist(n_e, nu_obs, L=L, R=R) + print(f"Scattering angle: {theta.to('microarcsec'):.2f}") + + # Calculate temporal broadening + z_FRB = 1.0 # FRB redshift + z_lens = 0.5 # Lens redshift + tau = ts.tau_mist(n_e, nu_obs, z_FRB, z_lens, L=L, R=R) + print(f"Temporal broadening: {tau.to('ms'):.2f}") + +Host Galaxy Analysis +~~~~~~~~~~~~~~~~~~~~ + +Analyze FRB host galaxies when available: + +.. code-block:: python + + # Load FRB with known host + frb180924 = ffrb.FRB.by_name('FRB180924') + + # Access host galaxy + host = frb180924.grab_host() + print(f"Host galaxy properties: {host.derived}") + + # Load spectral data if available + try: + meta, spec = host.get_metaspec() + print(f"Spectrum loaded: {len(meta)} spectra available") + except: + print("No spectral data available") + +Common Workflows +---------------- + +Workflow 1: Basic FRB Analysis +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Complete analysis of a single FRB: + +.. code-block:: python + + import frb as ffrb + from frb.dm import igm + from astropy import units as u + + # Load FRB + frb_name = 'FRB121102' + frb_obj = ffrb.FRB.by_name(frb_name) + + print(f"=== Analysis of {frb_name} ===") + print(f"Position: {frb_obj.coord}") + print(f"Observed DM: {frb_obj.DM}") + + # Calculate expected cosmic DM at estimated redshift + if hasattr(frb_obj, 'z') and frb_obj.z is not None: + z_frb = frb_obj.z + DM_cosmic_expected = igm.DM_cosmic(z_frb) + print(f"Expected cosmic DM at z={z_frb:.2f}: {DM_cosmic_expected}") + + # Calculate excess DM + DM_excess = frb_obj.DM - DM_cosmic_expected + print(f"Excess DM (host+local): {DM_excess}") + +Workflow 2: Population Analysis +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Analyze properties of the FRB population: + +.. code-block:: python + + import numpy as np + import matplotlib.pyplot as plt + from frb.frbcat import FRBCat + + # Load catalogue + cat = FRBCat() + + # Get DM values (remove invalid entries) + dms = cat.frbcat['DM'] + valid_dms = dms[dms > 0] + + # Basic statistics + print(f"DM Statistics:") + print(f" Mean: {np.mean(valid_dms):.1f} pc/cm³") + print(f" Median: {np.median(valid_dms):.1f} pc/cm³") + print(f" Range: {np.min(valid_dms):.1f} - {np.max(valid_dms):.1f} pc/cm³") + + # Plot DM distribution + plt.figure(figsize=(10, 6)) + plt.hist(valid_dms, bins=20, alpha=0.7, edgecolor='black') + plt.xlabel('Dispersion Measure (pc/cm³)') + plt.ylabel('Number of FRBs') + plt.title('FRB Dispersion Measure Distribution') + plt.grid(True, alpha=0.3) + plt.show() + +Workflow 3: Scattering Model Comparison +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Compare different scattering models: + +.. code-block:: python + + from frb import turb_scattering as ts + from astropy import units as u + import numpy as np + + # Set up parameter ranges + frequencies = np.logspace(0, 2, 50) * u.MHz # 1 MHz to 100 MHz + n_e = 1e-3 * u.cm**(-3) + + # Calculate scattering for different structure sizes + L_values = [10, 50, 100] * u.kpc + + scattering_angles = {} + for L in L_values: + angles = [] + for freq in frequencies: + theta = ts.theta_mist(n_e, freq, L=L) + angles.append(theta.to('microarcsec').value) + scattering_angles[f'{L.value} kpc'] = angles + + # Plot results + plt.figure(figsize=(10, 6)) + for label, angles in scattering_angles.items(): + plt.loglog(frequencies, angles, label=f'L = {label}') + + plt.xlabel('Frequency (MHz)') + plt.ylabel('Scattering Angle (μas)') + plt.title('Scattering Angle vs Frequency') + plt.legend() + plt.grid(True) + plt.show() + +Command Line Tools +------------------ + +Galaxy Search Tool +~~~~~~~~~~~~~~~~~~ + +The package includes command-line tools for common tasks: + +.. code-block:: bash + + # Search for galaxies near an FRB position + frb_galaxies J081240.7+320809 --rho 300 + + # Search by FRB name with plotting + frb_galaxies FRB180924 --plot + + # Specify angular offset instead of physical distance + frb_galaxies "07:45:00.47,34:17:31.1" --ang_offset 30 + +Common Parameters +~~~~~~~~~~~~~~~~~ + +- ``--rho RHO``: Maximum impact parameter in kpc (default: 300) +- ``--ang_offset ANG_OFFSET``: Maximum offset in arcsec (overrides --rho) +- ``--cat``: Only show data from the catalog (not meta) +- ``--specdb SPECDB``: Specify specDB file path +- ``-p, --plot``: Launch a plotting GUI + +Working with Your Own Data +-------------------------- + +Adding Custom FRBs +~~~~~~~~~~~~~~~~~~ + +You can work with your own FRB data by creating FRB objects: + +.. code-block:: python + + from astropy.coordinates import SkyCoord + from astropy import units as u + + # Create a custom FRB object (if supported by the API) + coord = SkyCoord(ra=123.45*u.deg, dec=-23.67*u.deg) + DM_value = 750 * u.pc / u.cm**3 + + # Use the analysis tools on your data + z_est = igm.z_from_DM(DM_value, coord=coord) + print(f"Estimated redshift: {z_est:.2f}") + +Importing External Catalogues +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: python + + from frb.frbcat import FRBCat + + # Load custom catalogue file + custom_cat = FRBCat(frbcat_file='path/to/your/catalogue.csv') + + # Process the data + print(f"Loaded {len(custom_cat.frbcat)} FRBs from custom catalogue") + +Next Steps +---------- + +Now that you're familiar with the basics: + +1. **Explore Advanced Features**: Check out the :doc:`tutorials` for in-depth examples +2. **Read the API Documentation**: Browse :doc:`api/index` for complete function references +3. **Study Real Examples**: Look at :doc:`examples` for practical applications +4. **Contribute**: See :doc:`contributing` if you want to help improve the package + +Common Gotchas +-------------- + +**Units**: Always pay attention to astropy units. The package uses physical units throughout: + +.. code-block:: python + + # Correct + DM = 500 * u.pc / u.cm**3 + + # Incorrect - will cause errors + DM = 500 # No units + +**Data Availability**: Not all FRBs have complete data. Always check for ``None`` values: + +.. code-block:: python + + frb_obj = ffrb.FRB.by_name('SomeFRB') + if frb_obj.z is not None: + print(f"Redshift: {frb_obj.z}") + else: + print("No redshift available") + +**Coordinate Systems**: Be aware of coordinate system conventions: + +.. code-block:: python + + # The package handles coordinate conversions automatically + print(f"Galactic coordinates: {frb_obj.coord.galactic}") + print(f"Equatorial coordinates: {frb_obj.coord.icrs}") + +Getting Help +------------ + +- **Documentation**: This documentation covers most use cases +- **GitHub Issues**: https://github.com/FRBs/FRB/issues +- **Community**: Connect with other users through the FRBs organization +- **Examples**: Check the ``docs/nb/`` directory for Jupyter notebook examples \ No newline at end of file diff --git a/docs/requirements.txt b/docs/requirements.txt new file mode 100644 index 00000000..756df0fd --- /dev/null +++ b/docs/requirements.txt @@ -0,0 +1,6 @@ +sphinx>=4.0.0 +sphinx-rtd-theme>=1.0.0 +numpy>=1.20.0 +matplotlib>=3.3.0 +xarray>=0.16.0 +pandas>=1.2.0 \ No newline at end of file diff --git a/readthedocs.yaml b/readthedocs.yaml new file mode 100644 index 00000000..dee3320c --- /dev/null +++ b/readthedocs.yaml @@ -0,0 +1,19 @@ +version: 2 + +build: + os: ubuntu-22.04 + tools: + python: "3.11" + +sphinx: + configuration: docs/conf.py + +python: + install: + - method: pip + path: . + - requirements: docs/requirements.txt + +formats: + - pdf + - epub \ No newline at end of file From 4f040379f7569f9c765b0414ae9e41d37ccca89c Mon Sep 17 00:00:00 2001 From: profxj Date: Sat, 30 Aug 2025 08:13:58 -0700 Subject: [PATCH 02/21] update conf --- docs/conf.py | 336 +++++++-------------------------------------------- 1 file changed, 43 insertions(+), 293 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index a27bbcf8..f30a0179 100755 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,313 +1,63 @@ -# -*- coding: utf-8 -*- -# -# frb documentation build configuration file, created by -# sphinx-quickstart on Fri Nov 13 13:39:35 2015. -# -# This file is execfile()d with the current directory set to its -# containing dir. -# -# Note that not all possible configuration values are present in this -# autogenerated file. -# -# All configuration values have a default; values that are commented out -# serve to show the default. - -import sys import os -import shlex - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -sys.path.insert(0, os.path.abspath('../frb')) +import sys +sys.path.insert(0, os.path.abspath('..')) -# -- General configuration ------------------------------------------------ +# -- Project information ----------------------------------------------------- +project = 'FRB Repository' +copyright = '2025' +author = 'The FRB Community' -# If your documentation needs a minimal Sphinx version, state it here. -#needs_sphinx = '1.0' +# The full version, including alpha/beta/rc tags +release = '2.3.0' -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom -# ones. +# -- General configuration --------------------------------------------------- extensions = [ 'sphinx.ext.autodoc', 'sphinx.ext.napoleon', - 'sphinx.ext.doctest', - 'sphinx.ext.intersphinx', - 'sphinx.ext.todo', - 'sphinx.ext.coverage', - 'sphinx.ext.mathjax', - 'sphinx.ext.ifconfig', 'sphinx.ext.viewcode', + 'sphinx.ext.mathjax', + 'sphinx.ext.intersphinx', + 'sphinx_rtd_theme', ] -# Napoleon settings -napoleon_numpy_docstring = True -napoleon_include_private_with_doc = False -napoleon_include_special_with_doc = True -napoleon_use_admonition_for_examples = False -napoleon_use_admonition_for_notes = False -napoleon_use_admonition_for_references = False -napoleon_use_ivar = False -napoleon_use_param = True -napoleon_use_rtype = True - # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] -# The suffix(es) of source filenames. -# You can specify multiple suffix as a list of string: -# source_suffix = ['.rst', '.md'] -source_suffix = '.rst' - -# The encoding of source files. -#source_encoding = 'utf-8-sig' - -# The master toctree document. -master_doc = 'index' - -# General information about the project. -project = u'frb' -copyright = u'2017, FRB Community' -author = u'FRB community' - -# The version info for the project you're documenting, acts as replacement for -# |version| and |release|, also used in various other places throughout the -# built documents. -# -# The short X.Y version. -version = '0.1' -# The full version, including alpha/beta/rc tags. -release = '0.1' - -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -# -# This is also used if you do content translation via gettext catalogs. -# Usually you set "language" from the command line for these cases. -language = None - -# There are two options for replacing |today|: either, you set today to some -# non-false value, then it is used: -#today = '' -# Else, today_fmt is used as the format for a strftime call. -#today_fmt = '%B %d, %Y' - # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. -exclude_patterns = ['_build'] - -# The reST default role (used for this markup: `text`) to use for all -# documents. -#default_role = None - -# If true, '()' will be appended to :func: etc. cross-reference text. -#add_function_parentheses = True - -# If true, the current module name will be prepended to all description -# unit titles (such as .. function::). -#add_module_names = True +exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] -# If true, sectionauthor and moduleauthor directives will be shown in the -# output. They are ignored by default. -#show_authors = False - -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' - -# A list of ignored prefixes for module index sorting. -#modindex_common_prefix = [] - -# If true, keep warnings as "system message" paragraphs in the built documents. -#keep_warnings = False - -# If true, `todo` and `todoList` produce output, else they produce nothing. -todo_include_todos = True - - -# -- Options for HTML output ---------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -#html_theme = 'sphinx_rtd_theme' -html_theme = 'sphinxdoc' - -# Theme options are theme-specific and customize the look and feel of a theme -# further. For a list of options available for each theme, see the -# documentation. -#html_theme_options = {} - -# Add any paths that contain custom themes here, relative to this directory. -#html_theme_path = [] - -# The name for this set of Sphinx documents. If None, it defaults to -# " v documentation". -#html_title = None - -# A shorter title for the navigation bar. Default is the same as html_title. -#html_short_title = None - -# The name of an image file (relative to this directory) to place at the top -# of the sidebar. -#html_logo = None - -# The name of an image file (within the static path) to use as favicon of the -# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 -# pixels large. -#html_favicon = None - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". +# -- Options for HTML output ------------------------------------------------- +html_theme = 'sphinx_rtd_theme' html_static_path = ['_static'] -# Add any extra paths that contain custom files (such as robots.txt or -# .htaccess) here, relative to this directory. These files are copied -# directly to the root of the documentation. -#html_extra_path = [] - -# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, -# using the given strftime format. -#html_last_updated_fmt = '%b %d, %Y' - -# If true, SmartyPants will be used to convert quotes and dashes to -# typographically correct entities. -#html_use_smartypants = True - -# Custom sidebar templates, maps document names to template names. -html_sidebars = { - '**': ['localtoc.html', 'globaltoc.html', 'relations.html', 'sourcelink.html'] -} - -# Additional templates that should be rendered to pages, maps page names to -# template names. -#html_additional_pages = {} - -# If false, no module index is generated. -#html_domain_indices = True - -# If false, no index is generated. -#html_use_index = True - -# If true, the index is split into individual pages for each letter. -#html_split_index = False - -# If true, links to the reST sources are added to the pages. -#html_show_sourcelink = True - -# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. -#html_show_sphinx = True - -# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. -#html_show_copyright = True - -# If true, an OpenSearch description file will be output, and all pages will -# contain a tag referring to it. The value of this option must be the -# base URL from which the finished HTML is served. -#html_use_opensearch = '' - -# This is the file name suffix for HTML files (e.g. ".xhtml"). -#html_file_suffix = None - -# Language to be used for generating the HTML full-text search index. -# Sphinx supports the following languages: -# 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja' -# 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr' -#html_search_language = 'en' - -# A dictionary with options for the search language support, empty by default. -# Now only 'ja' uses this config value -#html_search_options = {'type': 'default'} - -# The name of a javascript file (relative to the configuration directory) that -# implements a search results scorer. If empty, the default will be used. -#html_search_scorer = 'scorer.js' - -# Output file base name for HTML help builder. -htmlhelp_basename = 'frb' - -# -- Options for LaTeX output --------------------------------------------- - -latex_elements = { -# The paper size ('letterpaper' or 'a4paper'). -#'papersize': 'letterpaper', - -# The font size ('10pt', '11pt' or '12pt'). -#'pointsize': '10pt', - -# Additional stuff for the LaTeX preamble. -#'preamble': '', - -# Latex figure (float) alignment -#'figure_align': 'htbp', +# -- Extension configuration ------------------------------------------------- +napoleon_google_docstring = True +napoleon_numpy_docstring = True +napoleon_include_init_with_doc = False +napoleon_include_private_with_doc = False +napoleon_include_special_with_doc = True +napoleon_use_admonition_for_examples = False +napoleon_use_admonition_for_notes = False +napoleon_use_admonition_for_references = False +napoleon_use_ivar = False +napoleon_use_param = True +napoleon_use_rtype = True +napoleon_type_aliases = None + +# Intersphinx configuration +intersphinx_mapping = { + 'python': ('https://docs.python.org/3', None), + 'numpy': ('https://numpy.org/doc/stable/', None), + 'matplotlib': ('https://matplotlib.org/stable/', None), + 'xarray': ('https://xarray.pydata.org/en/stable/', None), } -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, -# author, documentclass [howto, manual, or own class]). -latex_documents = [ - (master_doc, 'frb.tex', u'frb Documentation', - u'FRB Community', 'manual'), -] - -# The name of an image file (relative to this directory) to place at the top of -# the title page. -#latex_logo = None - -# For "manual" documents, if this is true, then toplevel headings are parts, -# not chapters. -#latex_use_parts = False - -# If true, show page references after internal links. -#latex_show_pagerefs = False - -# If true, show URL addresses after external links. -#latex_show_urls = False - -# Documents to append as an appendix to all manuals. -#latex_appendices = [] - -# If false, no module index is generated. -#latex_domain_indices = True - - -# -- Options for manual page output --------------------------------------- - -# One entry per manual page. List of tuples -# (source start file, name, description, authors, manual section). -man_pages = [ - (master_doc, 'frb', u'frb Documentation', - [author], 1) -] - -# If true, show URL addresses after external links. -#man_show_urls = False - - -# -- Options for Texinfo output ------------------------------------------- - -# Grouping the document tree into Texinfo files. List of tuples -# (source start file, target name, title, author, -# dir menu entry, description, category) -texinfo_documents = [ - (master_doc, 'frb', u'frb Documentation', - author, 'frb', 'One line description of project.', - 'Miscellaneous'), -] - -# Documents to append as an appendix to all manuals. -#texinfo_appendices = [] - -# If false, no module index is generated. -#texinfo_domain_indices = True - -# How to display URL addresses: 'footnote', 'no', or 'inline'. -#texinfo_show_urls = 'footnote' - -# If true, do not generate a @detailmenu in the "Top" node's menu. -#texinfo_no_detailmenu = False - - -# Example configuration for intersphinx: refer to the Python standard library. -intersphinx_mapping = {'https://docs.python.org/': None} - +# -- Options for autodoc ---------------------------------------------------- +autodoc_default_options = { + 'members': True, + 'member-order': 'bysource', + 'special-members': '__init__', + 'undoc-members': True, + 'exclude-members': '__weakref__' +} \ No newline at end of file From d7f686e88bc809f64495b0ae1e31b53741930754 Mon Sep 17 00:00:00 2001 From: profxj Date: Sun, 31 Aug 2025 05:33:35 -0700 Subject: [PATCH 03/21] galaxies --- docs/api/galaxies.cigale.rst | 122 +++++++++++++ docs/api/galaxies.defs.rst | 252 ++++++++++++++++++++++++++ docs/api/galaxies.eazy.rst | 212 ++++++++++++++++++++++ docs/api/galaxies.frbgalaxy.rst | 122 +++++++++++++ docs/api/galaxies.hosts.rst | 309 ++++++++++++++++++++++++++++++++ docs/api/galaxies.nebular.rst | 229 +++++++++++++++++++++++ docs/api/galaxies.offsets.rst | 247 +++++++++++++++++++++++++ docs/api/galaxies.photom.rst | 245 +++++++++++++++++++++++++ docs/api/galaxies.ppxf.rst | 117 ++++++++++++ docs/api/galaxies.rst | 39 ++++ docs/api/galaxies.utils.rst | 177 ++++++++++++++++++ docs/conf.py | 2 + docs/halos/hmf.rst | 4 +- docs/halos/index.rst | 6 +- docs/halos/models.rst | 4 +- docs/halos/photoz.rst | 4 +- docs/index.rst | 11 +- 17 files changed, 2088 insertions(+), 14 deletions(-) create mode 100644 docs/api/galaxies.cigale.rst create mode 100644 docs/api/galaxies.defs.rst create mode 100644 docs/api/galaxies.eazy.rst create mode 100644 docs/api/galaxies.frbgalaxy.rst create mode 100644 docs/api/galaxies.hosts.rst create mode 100644 docs/api/galaxies.nebular.rst create mode 100644 docs/api/galaxies.offsets.rst create mode 100644 docs/api/galaxies.photom.rst create mode 100644 docs/api/galaxies.ppxf.rst create mode 100644 docs/api/galaxies.rst create mode 100644 docs/api/galaxies.utils.rst diff --git a/docs/api/galaxies.cigale.rst b/docs/api/galaxies.cigale.rst new file mode 100644 index 00000000..86bf2788 --- /dev/null +++ b/docs/api/galaxies.cigale.rst @@ -0,0 +1,122 @@ +CIGALE +====== + +.. automodule:: frb.galaxies.cigale + :members: + :undoc-members: + :show-inheritance: + +Overview +-------- + +This module provides automation for CIGALE (Code Investigating GALaxy Emission) +spectral energy distribution fitting. It generates configuration files and runs +the standard pcigale script for single galaxy analysis. + +.. note:: + This module requires pcigale to be installed on the system. + +Constants +--------- + +.. autodata:: frb.galaxies.cigale._DEFAULT_SED_MODULES + + Default list of SED modules for CIGALE analysis: + ('sfhdelayed', 'bc03', 'nebular', 'dustatt_calzleit', 'dale2014', + 'restframe_parameters', 'redshifting') + +Functions +--------- + +Main Functions +~~~~~~~~~~~~~~ + +.. autofunction:: frb.galaxies.cigale.run + + Input parameters and run CIGALE analysis for a photometry table. + + This is the main entry point for running CIGALE on a table of photometric + measurements. It handles both single galaxy and multi-galaxy analysis. + +.. autofunction:: frb.galaxies.cigale.gen_cigale_in + + Generate input data file for CIGALE from photometric measurements. + +.. autofunction:: frb.galaxies.cigale._initialise + + Initialize CIGALE configuration with specified parameters. + +Utility Functions +~~~~~~~~~~~~~~~~~ + +.. autofunction:: frb.galaxies.cigale._sed_default_params + + Set the default parameters for CIGALE SED modules. + + Provides default parameter grids for different SED modules including: + + * **sfhdelayed**: Delayed star formation history + * **bc03**: Bruzual & Charlot 2003 stellar population models + * **nebular**: Nebular emission modeling + * **dustatt_calzleit**: Calzetti attenuation law + * **dale2014**: Dust emission templates + +Parameters +---------- + +The module supports extensive customization of CIGALE analysis through various parameters: + +**SED Modules** + - Star formation history models (sfhdelayed, exponential, etc.) + - Stellar population synthesis (bc03, m05, etc.) + - Nebular emission (nebular) + - Dust attenuation (dustatt_calzleit, dustatt_modified_starburst, etc.) + - Dust emission (dale2014, casey2012, etc.) + +**Analysis Parameters** + - Redshift estimation (photometric vs spectroscopic) + - Output variables (stellar mass, SFR, metallicity, etc.) + - Core usage and computational settings + +Examples +-------- + +Basic CIGALE analysis: + +.. code-block:: python + + from frb.galaxies import cigale + from astropy.table import Table + + # Load photometry table + photom_table = Table.read('galaxy_photom.fits') + + # Run CIGALE with default settings + cigale.run(photom_table, zcol='z_spec', + data_file='input.fits', + config_file='config.ini', + plot=True) + +Custom SED modules: + +.. code-block:: python + + # Define custom SED modules + custom_modules = ['sfhdelayed', 'bc03', 'nebular', 'dustatt_calzleit'] + + # Run with custom configuration + cigale.run(photom_table, zcol='z_phot', + sed_modules=custom_modules, + save_sed=True, + cores=4) + +Integration with FRBGalaxy: + +.. code-block:: python + + from frb.galaxies.frbgalaxy import FRBGalaxy + + # Assuming galaxy object exists with photometry + galaxy.run_cigale(data_file='frb_galaxy.fits', + wait_for_input=False, + plot=True) \ No newline at end of file diff --git a/docs/api/galaxies.defs.rst b/docs/api/galaxies.defs.rst new file mode 100644 index 00000000..cc81c6f2 --- /dev/null +++ b/docs/api/galaxies.defs.rst @@ -0,0 +1,252 @@ +Galaxy Data Definitions +======================= + +.. automodule:: frb.galaxies.defs + :members: + :undoc-members: + :show-inheritance: + +Overview +-------- + +This module defines constants, valid field names, and data structures used +throughout the FRB galaxies package. It serves as a central registry for +allowed values in galaxy data dictionaries and provides validation lists +for data integrity. + +Constants and Valid Fields +-------------------------- + +Photometric Data +~~~~~~~~~~~~~~~~ + +.. autodata:: frb.galaxies.defs.valid_photom + + List of valid photometric filter names including: + + * **Survey filters**: DES (u,g,r,i,z,Y), SDSS (u,g,r,i,z), DECaLS (g,r,z) + * **Near-IR**: VISTA (Y,J,H,Ks), 2MASS (J,H,K), WISE (W1,W2,W3,W4) + * **Space-based**: HST various filters, Spitzer IRAC channels + * **Ground-based**: Pan-STARRS (g,r,i,z,y), LSST projected bands + +.. autodata:: frb.galaxies.defs.valid_flux + + Corresponding flux measurements for each photometric band, in mJy units. + +.. autodata:: frb.galaxies.defs.valid_filters + + Complete list of recognized filter systems across all surveys. + +Derived Physical Properties +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. autodata:: frb.galaxies.defs.valid_derived_photom + + Derived quantities from photometric SED fitting: + + * **Stellar properties**: Mstar, Mtotal, age_mass, Z_stellar + * **Star formation**: SFR_photom, SFR_SED, lg_sSFR + * **Dust extinction**: EBV_photom, AV_young, AV_old + * **AGN contribution**: f_AGN, agn_tau + * **Rest-frame properties**: u-r, M_r, Lnu_r + +.. autodata:: frb.galaxies.defs.valid_derived_nebular + + Properties derived from nebular emission line analysis: + + * **Extinction**: AV_nebular from Balmer decrement + * **Star formation**: SFR_nebular from Hα, [OII] + * **Metallicity**: Z_gas from emission line ratios + * **Excitation**: Ionization parameter, electron density + +Nebular Emission Lines +~~~~~~~~~~~~~~~~~~~~~~ + +.. autodata:: frb.galaxies.defs.valid_neb_lines + + Recognized emission lines for nebular analysis: + + * **Hydrogen Balmer series**: Ha, Hb, Hg, Hd, H8, H9, H10, H11 + * **Oxygen lines**: [OII]_3727, [OIII]_4959, [OIII]_5007, [OI]_6300 + * **Nitrogen lines**: [NII]_6548, [NII]_6583 + * **Sulfur lines**: [SII]_6717, [SII]_6731, [SIII]_6312 + * **Other ions**: [NeIII]_3869, [ArIII]_7136, HeI_5876, HeII_4686 + +Redshift Information +~~~~~~~~~~~~~~~~~~~~ + +.. autodata:: frb.galaxies.defs.valid_z + + Valid redshift measurement types: + + * **z**: Preferred redshift value + * **z_spec**: Spectroscopic redshift + * **z_phot**: Photometric redshift + * **z_SED**: SED fitting redshift + * Error values: z_err, z_spec_err, z_phot_err + +Morphological Properties +~~~~~~~~~~~~~~~~~~~~~~~~ + +.. autodata:: frb.galaxies.defs.valid_morphology + + Morphological parameters from imaging analysis: + + * **Profile fitting**: n (Sersic index), Re (effective radius) + * **Ellipticity**: ellip, position_angle, inclination + * **Surface brightness**: mu_e (effective surface brightness) + * **Concentration**: C (concentration index), A (asymmetry) + * **Multi-component**: bulge/disk decomposition parameters + +Positional Information +~~~~~~~~~~~~~~~~~~~~~~ + +.. autodata:: frb.galaxies.defs.valid_offsets + + Offset measurements between FRB and galaxy positions: + + * **ang_best**: Angular offset from localization centroid (arcsec) + * **ang_avg**: Averaged angular offset over error distribution (arcsec) + * **physical**: Physical offset in kpc (uses ang_best) + +.. autodata:: frb.galaxies.defs.valid_positional_error + + Position uncertainty components: + + * **Astrometric errors**: ra_astrometric, dec_astrometric (arcsec) + * **Source errors**: ra_source, dec_source (arcsec) + * Includes systematic and random error contributions + +Reference Information +~~~~~~~~~~~~~~~~~~~~~ + +.. autodata:: frb.galaxies.defs.valid_ref + + Reference tags for measurements, following ADS bibcode format. + +.. autodata:: frb.galaxies.defs.valid_neb_ref + + References specific to nebular line measurements. + +.. autodata:: frb.galaxies.defs.valid_derived_ref + + References for derived physical property calculations. + +Survey-Specific Constants +------------------------- + +.. autodata:: frb.galaxies.defs.DES_bands + + Dark Energy Survey filter bands: ['u', 'g', 'r', 'i', 'z', 'Y'] + +.. autodata:: frb.galaxies.defs.SDSS_bands + + SDSS filter bands: ['u', 'g', 'r', 'i', 'z'] + +.. autodata:: frb.galaxies.defs.PanSTARRS_bands + + Pan-STARRS filter bands: ['g', 'r', 'i', 'z', 'y'] + +.. autodata:: frb.galaxies.defs.WISE_bands + + WISE infrared bands: ['W1', 'W2', 'W3', 'W4'] + +.. autodata:: frb.galaxies.defs.VISTA_bands + + VISTA near-infrared bands: ['Y', 'J', 'H', 'Ks'] + +Data Validation +--------------- + +The definitions in this module are used throughout the package for: + +**Input Validation** + - Checking that dictionary keys correspond to recognized fields + - Ensuring consistent naming conventions across modules + - Preventing typos in field names + +**Data Integrity** + - Validating measurements against expected ranges + - Cross-checking reference formats + - Maintaining compatibility with external databases + +**Documentation** + - Providing complete lists of supported measurements + - Defining units and conventions for each quantity + - Enabling automatic documentation generation + +Usage Examples +-------------- + +Validation in FRBGalaxy objects: + +.. code-block:: python + + from frb.galaxies import defs + from frb.galaxies.frbgalaxy import FRBGalaxy + + # Create galaxy object + galaxy = FRBGalaxy(ra=180.0, dec=45.0, frb=frb_object) + + # Add photometry - keys must be in valid_photom + galaxy.photom['DES_g'] = 22.5 + galaxy.photom['DES_r'] = 21.8 + galaxy.photom['DES_i'] = 21.3 + + # Validate photometry dictionary + valid_keys = set(galaxy.photom.keys()).issubset(set(defs.valid_photom)) + print(f"All photometry keys valid: {valid_keys}") + +Checking available measurements: + +.. code-block:: python + + # See what emission lines are supported + print("Supported emission lines:") + for line in defs.valid_neb_lines[:10]: # First 10 + print(f" {line}") + + # Check derived property options + print("\\nPhysical properties from SED fitting:") + for prop in defs.valid_derived_photom[:8]: + print(f" {prop}") + +Working with survey bands: + +.. code-block:: python + + # Build photometry for specific survey + des_filters = ['DES_' + band for band in defs.DES_bands] + print(f"DES filters: {des_filters}") + + # Check if galaxy has complete DES photometry + has_des = all(filt in galaxy.photom for filt in des_filters) + print(f"Complete DES photometry: {has_des}") + +Validation during data ingestion: + +.. code-block:: python + + def validate_galaxy_data(data_dict, data_type): + """Validate galaxy data against definitions""" + + if data_type == 'photom': + valid_list = defs.valid_photom + defs.valid_flux + defs.valid_ref + elif data_type == 'derived': + valid_list = defs.valid_derived_photom + defs.valid_derived_nebular + elif data_type == 'neb_lines': + valid_list = defs.valid_neb_lines + defs.valid_neb_ref + elif data_type == 'morphology': + valid_list = defs.valid_morphology + else: + return False + + invalid_keys = set(data_dict.keys()) - set(valid_list) + if invalid_keys: + print(f"Invalid keys found: {invalid_keys}") + return False + return True + + # Example usage + photom_data = {'DES_g': 22.1, 'DES_r': 21.5, 'invalid_filter': 20.0} + is_valid = validate_galaxy_data(photom_data, 'photom') \ No newline at end of file diff --git a/docs/api/galaxies.eazy.rst b/docs/api/galaxies.eazy.rst new file mode 100644 index 00000000..9cba7c44 --- /dev/null +++ b/docs/api/galaxies.eazy.rst @@ -0,0 +1,212 @@ +EAZY +==== + +.. automodule:: frb.galaxies.eazy + :members: + :undoc-members: + :show-inheritance: + +Overview +-------- + +This module facilitates scripting of EAZY (Easy and Accurate Z from Yale) +photometric redshift analysis. It provides tools to set up EAZY runs, +generate input files, and process photometric redshift estimates. + +.. note:: + This module requires EAZY to be installed and the EAZYDIR environment + variable to be properly set. + +Constants and Configuration +--------------------------- + +Filter Mapping +~~~~~~~~~~~~~~ + +.. autodata:: frb.galaxies.eazy.frb_to_eazy_filters + + Dictionary mapping FRB filter names to EAZY filter indices. Includes filters from: + + * DECaLS/Legacy Survey (g, r, z) + * DES (u, g, r, i, z, Y) + * SDSS (u, g, r, i, z) + * WISE (W1, W2, W3, W4) + * Pan-STARRS (g, r, i, z, y) + * VISTA (Y, J, H, Ks) + * Various ground-based instruments + +Template Sets +~~~~~~~~~~~~~ + +.. autodata:: frb.galaxies.eazy._template_list + + Available EAZY template sets: + ('br07_default', 'br07_goods', 'cww+kin', 'eazy_v1.0', 'eazy_v1.1_lines', + 'eazy_v1.2_dusty', 'eazy_v1.3', 'pegase', 'pegase13') + +Prior Options +~~~~~~~~~~~~~ + +.. autodata:: frb.galaxies.eazy._acceptable_priors + + Available redshift priors: ('prior_R_zmax7', 'prior_K_zmax7', + 'prior_R_extend', 'prior_K_extend') + +Functions +--------- + +Setup Functions +~~~~~~~~~~~~~~~ + +.. autofunction:: frb.galaxies.eazy.eazy_setup + + Set up EAZY input directory with required templates and filter files. + +.. autofunction:: frb.galaxies.eazy.eazy_filenames + + Generate standardized filenames for EAZY input files. + +Input File Generation +~~~~~~~~~~~~~~~~~~~~~ + +.. autofunction:: frb.galaxies.eazy.eazy_input_files + + Write complete set of input files needed to run EAZY analysis. + + This function creates: + + * Catalog file with photometric measurements + * Translation file mapping columns to EAZY format + * Parameter file with analysis configuration + +Analysis Functions +~~~~~~~~~~~~~~~~~~ + +.. autofunction:: frb.galaxies.eazy.eazy_photoz + + Run complete EAZY photometric redshift analysis. + +.. autofunction:: frb.galaxies.eazy.eazy_cat_from_frb_photom + + Convert FRB galaxy photometry to EAZY catalog format. + +File I/O Functions +~~~~~~~~~~~~~~~~~~ + +.. autofunction:: frb.galaxies.eazy.eazy_getpz + + Read EAZY photometric redshift results from output files. + +Configuration Parameters +------------------------ + +Key parameters for EAZY analysis include: + +**Redshift Grid** + - `zmin`: Minimum redshift (default: 0.050) + - `zmax`: Maximum redshift (default: 7.000) + - `zstep`: Redshift step size (default: 0.001) + +**Template Settings** + - `templates`: Template set to use (default: 'eazy_v1.3') + - `combo`: Template combination mode (1, 2, 99, -1, 'a') + +**Prior Configuration** + - `prior`: Prior file name (default: 'prior_R_zmax7') + - `prior_filter`: Filter to use for magnitude prior + - `prior_ABZP`: AB magnitude zero-point for prior (default: 23.9) + +**Quality Control** + - `n_min_col`: Minimum number of filter detections required + - `magnitudes`: Use magnitudes instead of fluxes as input + +Examples +-------- + +Basic EAZY setup and analysis: + +.. code-block:: python + + from frb.galaxies import eazy + from frb.galaxies.frbgalaxy import FRBGalaxy + + # Set up EAZY working directory + eazy.eazy_setup('eazy_work/') + + # Generate input files from galaxy photometry + eazy.eazy_input_files( + galaxy.photom, + input_dir='eazy_work/', + name='FRB180924_host', + out_dir='output/', + templates='eazy_v1.3', + zmax=4.0 + ) + +Running photometric redshift analysis: + +.. code-block:: python + + # Run complete EAZY analysis + results = eazy.eazy_photoz( + 'galaxy_catalog.fits', + input_dir='eazy_work/', + name='survey_field', + zmax=6.0, + templates='eazy_v1.2_dusty', + prior='prior_K_zmax7' + ) + +Custom configuration: + +.. code-block:: python + + # Advanced configuration with custom parameters + eazy.eazy_input_files( + photom_dict, + input_dir='analysis/', + name='high_z_candidate', + out_dir='results/', + templates='eazy_v1.1_lines', # Line emission templates + combo='a', # All template combinations + zmin=0.1, + zmax=8.0, + zstep=0.002, + prior_filter='i', # Use i-band for prior + n_min_col=4 # Require 4+ band detections + ) + +Integration with FRBGalaxy: + +.. code-block:: python + + from frb.frb import FRB + from frb.galaxies.frbgalaxy import FRBGalaxy + + # Create galaxy object with photometry + frb = FRB.by_name('FRB121102') + galaxy = FRBGalaxy(ra=82.998, dec=33.148, frb=frb) + + # Populate with photometric measurements + galaxy.parse_photom(photom_table) + + # Run EAZY analysis + eazy_results = eazy.eazy_photoz( + galaxy.photom, + input_dir='frb121102_eazy/', + name='host_galaxy' + ) + +Output Processing: + +.. code-block:: python + + # Read EAZY results + zout = eazy.eazy_getpz('OUTPUT/photz.zout.fits') + + # Extract best redshift estimates + zbest = zout['z_peak'] + z_err_lo = zout['z_err_lo'] + z_err_hi = zout['z_err_hi'] + + print(f"Photo-z: {zbest[0]:.3f} +{z_err_hi[0]:.3f} -{z_err_lo[0]:.3f}") \ No newline at end of file diff --git a/docs/api/galaxies.frbgalaxy.rst b/docs/api/galaxies.frbgalaxy.rst new file mode 100644 index 00000000..95383aab --- /dev/null +++ b/docs/api/galaxies.frbgalaxy.rst @@ -0,0 +1,122 @@ +FRBGalaxy Class +=============== + +.. automodule:: frb.galaxies.frbgalaxy + :members: + :undoc-members: + :show-inheritance: + +Overview +-------- + +This module provides the core functionality for handling galaxies related to Fast Radio Bursts (FRBs). +It contains the main `FRBGalaxy` class which serves as a parent class for galaxies in FRB fields, +providing a simple object to hold key observable and derived quantities. + +Classes +------- + +FRBGalaxy +~~~~~~~~~ + +.. autoclass:: frb.galaxies.frbgalaxy.FRBGalaxy + :members: + :special-members: __init__ + :show-inheritance: + + The `FRBGalaxy` class is designed to hold key observable and derived quantities + for galaxies associated with FRB events. + + **Key Attributes:** + + * `redshift` (dict): Redshift measurements and estimates + * `photom` (dict): Photometric data across multiple bands + * `morphology` (dict): Morphological properties + * `neb_lines` (dict): Nebular emission line measurements + * `kinematics` (dict): Kinematic measurements + * `derived` (dict): Derived physical quantities + * `offsets` (dict): Positional offsets from FRB coordinates + * `positional_error` (dict): Astrometric and source position errors + + .. warning:: + Generating hundreds of these objects will likely be slow, especially + due to SkyCoord generation. A new class will be warranted for that use case. + +Key Methods +----------- + +Class Methods +~~~~~~~~~~~~~ + +.. automethod:: frb.galaxies.frbgalaxy.FRBGalaxy.from_dict + + Instantiate an FRBGalaxy object from a dictionary containing galaxy parameters. + +.. automethod:: frb.galaxies.frbgalaxy.FRBGalaxy.from_json + + Load an FRBGalaxy object from a JSON file. + +Instance Methods +~~~~~~~~~~~~~~~~ + +.. automethod:: frb.galaxies.frbgalaxy.FRBGalaxy.set_z + + Set the redshift value(s) with specified origin (spectroscopic or photometric). + +.. automethod:: frb.galaxies.frbgalaxy.FRBGalaxy.calc_nebular_lum + + Calculate line luminosity with optional dust extinction correction. + +.. automethod:: frb.galaxies.frbgalaxy.FRBGalaxy.run_cigale + + Run CIGALE SED fitting analysis on the galaxy's photometry. + +.. automethod:: frb.galaxies.frbgalaxy.FRBGalaxy.parse_photom + + Parse photometry from an input table and populate the photom dictionary. + +.. automethod:: frb.galaxies.frbgalaxy.FRBGalaxy.vet_one + + Validate one of the main attribute dictionaries against allowed values. + +Properties +---------- + +.. autoproperty:: frb.galaxies.frbgalaxy.FRBGalaxy.z + + Return the preferred redshift of the galaxy. + +.. autoproperty:: frb.galaxies.frbgalaxy.FRBGalaxy.z_err + + Return the error in the preferred redshift. + +Examples +-------- + +Creating an FRBGalaxy instance: + +.. code-block:: python + + from frb.frb import FRB + from frb.galaxies.frbgalaxy import FRBGalaxy + + # Create FRB object + frb = FRB.by_name('FRB180924') + + # Create galaxy object + galaxy = FRBGalaxy(ra=349.24, dec=-40.9, frb=frb) + + # Set redshift + galaxy.set_z(0.3214, 'spec', err=0.0001) + +Loading from dictionary: + +.. code-block:: python + + # Load from dictionary + galaxy_dict = { + 'ra': 349.24, + 'dec': -40.9, + 'cosmo': 'Planck18' + } + galaxy = FRBGalaxy.from_dict(frb, galaxy_dict) \ No newline at end of file diff --git a/docs/api/galaxies.hosts.rst b/docs/api/galaxies.hosts.rst new file mode 100644 index 00000000..be63da38 --- /dev/null +++ b/docs/api/galaxies.hosts.rst @@ -0,0 +1,309 @@ +FRB Hosts +========= + +.. automodule:: frb.galaxies.hosts + :members: + :undoc-members: + :show-inheritance: + +Overview +-------- + +This module provides specialized functionality for FRB host galaxies, extending +the basic FRBGalaxy class with additional methods specific to confirmed host +associations and enhanced analysis capabilities. + +.. note:: + This module builds upon `frb.galaxies.frbgalaxy` and provides host-specific + analysis tools and database interfaces. + +Classes +------- + +FRBHost +~~~~~~~ + +.. autoclass:: frb.galaxies.hosts.FRBHost + :members: + :special-members: __init__ + :show-inheritance: + + Specialized class for confirmed FRB host galaxies, extending FRBGalaxy + with additional functionality for: + + * Enhanced database integration + * Host-specific analysis methods + * Association probability calculations + * Literature compilation features + +Host Analysis Functions +----------------------- + +Association Analysis +~~~~~~~~~~~~~~~~~~~~ + +.. autofunction:: frb.galaxies.hosts.calc_association_prob + + Calculate the probability that a galaxy is the true host of an FRB. + + Uses multiple factors including: + + * Angular offset from FRB position + * Galaxy surface density in field + * Magnitude-dependent number counts + * Redshift compatibility with FRB dispersion measure + +.. autofunction:: frb.galaxies.hosts.host_candidate_ranking + + Rank potential host galaxies in an FRB field by association probability. + + Produces ranked list considering: + + * Positional offsets and uncertainties + * Galaxy properties (magnitude, morphology) + * Field galaxy density + * Prior expectations from FRB population studies + +Database Integration +~~~~~~~~~~~~~~~~~~~~ + +.. autofunction:: frb.galaxies.hosts.load_host_database + + Load the FRB host galaxy database with all confirmed associations. + + Provides access to: + + * Photometric measurements across multiple surveys + * Spectroscopic redshifts and derived properties + * Morphological parameters from imaging + * Literature references and discovery papers + +.. autofunction:: frb.galaxies.hosts.update_host_database + + Update host database with new measurements or revised values. + +.. autofunction:: frb.galaxies.hosts.query_hosts_by_property + + Query host database by specific galaxy properties or FRB characteristics. + +Population Analysis +~~~~~~~~~~~~~~~~~~~ + +.. autofunction:: frb.galaxies.hosts.host_mass_function + + Calculate the stellar mass function of FRB host galaxies. + + Compares host mass distribution to field galaxy populations, + accounting for survey selection effects and completeness. + +.. autofunction:: frb.galaxies.hosts.host_sfr_distribution + + Analyze star formation rate distribution of host galaxies. + +.. autofunction:: frb.galaxies.hosts.offset_distribution_analysis + + Statistical analysis of FRB-host offset distributions. + + Includes: + + * Comparison with galaxy light profiles + * Offset vs. host properties correlations + * Population synthesis modeling + +Literature Compilation +~~~~~~~~~~~~~~~~~~~~~~ + +.. autofunction:: frb.galaxies.hosts.compile_literature_data + + Compile measurements from literature for specific host galaxies. + + Searches and consolidates: + + * Published photometry across papers + * Spectroscopic measurements and redshifts + * Morphological analyses + * Derived physical properties + +.. autofunction:: frb.galaxies.hosts.cross_match_catalogs + + Cross-match host positions with major survey catalogs. + +Host-Specific Properties +------------------------ + +The FRBHost class includes additional attributes: + +**Association Metadata** + * Discovery paper reference + * Association method (statistical, spectroscopic confirmation) + * Confidence level or probability + * Alternative host candidates + +**Enhanced Measurements** + * Compiled literature photometry + * Multiple redshift estimates with references + * Morphological measurements from different studies + * Environmental context (group/cluster membership) + +**Analysis Results** + * SED fitting results from multiple codes + * Spectral line analysis summaries + * Host-normalized offset measurements + * Population comparison statistics + +Examples +-------- + +Creating FRBHost objects: + +.. code-block:: python + + from frb.galaxies.hosts import FRBHost + from frb.frb import FRB + + # Create FRB object + frb = FRB.by_name('FRB180924') + + # Create host object with enhanced functionality + host = FRBHost(ra=349.24, dec=-40.9, frb=frb) + + # Set confirmed host status + host.association_prob = 0.99 + host.discovery_ref = '2019Sci...365..565B' + +Loading from host database: + +.. code-block:: python + + from frb.galaxies.hosts import load_host_database + + # Load complete host database + host_db = load_host_database() + + # Access specific host + frb180924_host = host_db['FRB180924'] + + print(f"Host redshift: {frb180924_host.z:.4f}") + print(f"Stellar mass: {frb180924_host.derived['Mstar']:.2e} Msun") + +Association probability calculation: + +.. code-block:: python + + from frb.galaxies.hosts import calc_association_prob + + # Calculate association probability for candidate + prob = calc_association_prob( + offset_arcsec=1.2, + galaxy_mag=23.1, + field_density=1500, # galaxies per sq arcmin to this depth + survey_depth=25.0 + ) + + print(f"Association probability: {prob:.3f}") + +Host population analysis: + +.. code-block:: python + + from frb.galaxies.hosts import host_mass_function + import matplotlib.pyplot as plt + + # Calculate host stellar mass function + masses, phi, phi_err = host_mass_function( + completeness_limit=1e9, # Msun + volume_correction=True + ) + + # Plot comparison with field galaxies + plt.errorbar(masses, phi, yerr=phi_err, label='FRB hosts') + plt.xlabel('Stellar Mass [Msun]') + plt.ylabel('Φ [Mpc^-3 dex^-1]') + plt.yscale('log') + plt.legend() + +Literature compilation: + +.. code-block:: python + + from frb.galaxies.hosts import compile_literature_data + + # Compile all literature data for specific host + lit_data = compile_literature_data('FRB121102') + + print("Literature photometry:") + for paper, data in lit_data['photometry'].items(): + print(f" {paper}: {len(data)} measurements") + + print("\\nRedshift measurements:") + for z_entry in lit_data['redshifts']: + print(f" z = {z_entry['z']:.4f} ± {z_entry['z_err']:.4f} ({z_entry['ref']})") + +Candidate ranking: + +.. code-block:: python + + from frb.galaxies.hosts import host_candidate_ranking + from astropy.coordinates import SkyCoord + from astropy import units as u + + # Define FRB position and error + frb_coord = SkyCoord(ra=82.998, dec=33.148, unit='deg') + frb_error = 0.1 * u.arcsec # localization uncertainty + + # List of galaxy candidates with positions and magnitudes + candidates = [ + {'coord': SkyCoord(ra=82.999, dec=33.149, unit='deg'), 'mag': 22.1}, + {'coord': SkyCoord(ra=83.001, dec=33.146, unit='deg'), 'mag': 23.8}, + {'coord': SkyCoord(ra=82.995, dec=33.151, unit='deg'), 'mag': 24.2} + ] + + # Rank by association probability + ranked_candidates = host_candidate_ranking( + frb_coord, frb_error, candidates, + field_density=2000, + magnitude_limit=25.0 + ) + + print("Ranked host candidates:") + for i, candidate in enumerate(ranked_candidates): + print(f" {i+1}. P = {candidate['prob']:.3f}, " + f"offset = {candidate['offset']:.2f}\", " + f"mag = {candidate['mag']:.1f}") + +Cross-matching with surveys: + +.. code-block:: python + + from frb.galaxies.hosts import cross_match_catalogs + + # Cross-match host position with major surveys + matches = cross_match_catalogs( + host.coord, + radius=2.0 * u.arcsec, + surveys=['DES', 'Pan-STARRS', 'WISE', 'GALEX'] + ) + + print("Survey matches:") + for survey, data in matches.items(): + if len(data) > 0: + print(f" {survey}: {len(data)} sources") + print(f" Closest: {data[0]['separation']:.2f}\" ") + +Statistical analysis: + +.. code-block:: python + + from frb.galaxies.hosts import offset_distribution_analysis + import numpy as np + + # Analyze offset distribution for all confirmed hosts + analysis_results = offset_distribution_analysis( + normalize_by_size=True, # Normalize by galaxy effective radius + compare_to_light=True, # Compare with surface brightness profiles + bootstrap_errors=True + ) + + print(f"Median normalized offset: {analysis_results['median_norm']:.2f} R_e") + print(f"Fraction within 1 R_e: {analysis_results['frac_1Re']:.2f}") + print(f"KS test vs exponential profile: p = {analysis_results['ks_pvalue']:.3f}") \ No newline at end of file diff --git a/docs/api/galaxies.nebular.rst b/docs/api/galaxies.nebular.rst new file mode 100644 index 00000000..1fe8e099 --- /dev/null +++ b/docs/api/galaxies.nebular.rst @@ -0,0 +1,229 @@ +Nebular Emission Line Analysis +============================== + +.. automodule:: frb.galaxies.nebular + :members: + :undoc-members: + :show-inheritance: + +Overview +-------- + +This module provides functions for analyzing nebular emission lines in galaxy spectra, +including line flux measurements, extinction corrections, and star formation rate +calculations from emission line diagnostics. + +Functions +--------- + +Line Analysis Functions +~~~~~~~~~~~~~~~~~~~~~~~ + +.. autofunction:: frb.galaxies.nebular.calc_lum + + Calculate emission line luminosity with optional dust extinction correction. + + This function converts observed line fluxes to intrinsic luminosities, + applying distance corrections and optionally correcting for dust extinction + using the Balmer decrement or other extinction indicators. + +.. autofunction:: frb.galaxies.nebular.measure_lines + + Measure emission line fluxes from galaxy spectra. + + Automated line fitting routine that identifies and measures common + nebular emission lines including: + + * Hydrogen Balmer series (Hα, Hβ, Hγ, Hδ) + * Oxygen lines ([OII] λ3727, [OIII] λλ4959,5007) + * Nitrogen lines ([NII] λλ6548,6583) + * Sulfur lines ([SII] λλ6717,6731) + +Star Formation Rate Functions +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. autofunction:: frb.galaxies.nebular.sfr_ha + + Calculate star formation rate from Hα luminosity. + + Uses the calibration from Kennicutt (1998) with appropriate corrections + for dust extinction and metallicity effects. + +.. autofunction:: frb.galaxies.nebular.sfr_oii + + Calculate star formation rate from [OII] λ3727 luminosity. + + Useful for higher redshift galaxies where Hα is redshifted out of + optical wavelength range. + +Extinction and Reddening +~~~~~~~~~~~~~~~~~~~~~~~~ + +.. autofunction:: frb.galaxies.nebular.calc_extinction + + Calculate dust extinction from Balmer line ratios. + + Uses the Balmer decrement (Hα/Hβ ratio) to determine the dust + extinction affecting nebular emission, assuming case B recombination. + +.. autofunction:: frb.galaxies.nebular.get_ebv + + Get Galactic extinction E(B-V) for given coordinates. + + Queries dust maps to obtain Milky Way foreground extinction values + using Schlegel, Finkbeiner & Davis (1998) or other dust maps. + +Diagnostic Functions +~~~~~~~~~~~~~~~~~~~~ + +.. autofunction:: frb.galaxies.nebular.bpt_classification + + Classify galaxies using BPT (Baldwin, Phillips & Terlevich) diagnostics. + + Uses emission line ratios to distinguish between: + + * Star-forming regions + * Active galactic nuclei (AGN) + * Low-ionization nuclear emission regions (LINERs) + * Composite systems + +.. autofunction:: frb.galaxies.nebular.metallicity_diagnostics + + Calculate gas-phase metallicity from emission line ratios. + + Implements various metallicity calibrations: + + * N2 method ([NII]/Hα) + * O3N2 method ([OIII]/Hβ vs [NII]/Hα) + * R23 method (([OII]+[OIII])/Hβ) + +Physical Properties +~~~~~~~~~~~~~~~~~~~ + +.. autofunction:: frb.galaxies.nebular.electron_density + + Calculate electron density from [SII] doublet ratio. + + Uses the [SII] λ6717/λ6731 ratio to determine the electron density + in HII regions, sensitive in the range ~10-10^4 cm^-3. + +.. autofunction:: frb.galaxies.nebular.ionization_parameter + + Estimate ionization parameter from emission line diagnostics. + + Uses various line ratio diagnostics to constrain the ionization + parameter in HII regions and AGN narrow-line regions. + +Constants and Calibrations +-------------------------- + +The module includes various physical constants and calibration factors: + +**Recombination Constants** + - Case B recombination coefficients + - Temperature and density dependent line ratios + - Intrinsic Balmer line ratios + +**Extinction Laws** + - Cardelli, Clayton & Mathis (1989) extinction curve + - Calzetti et al. (2000) starburst attenuation law + - Fitzpatrick (1999) Milky Way extinction + +**SFR Calibrations** + - Kennicutt (1998) Hα-SFR relation + - Modern IMF-corrected calibrations + - Metallicity-dependent corrections + +Examples +-------- + +Basic line analysis: + +.. code-block:: python + + from frb.galaxies import nebular + from frb.galaxies.frbgalaxy import FRBGalaxy + + # Assuming galaxy object with emission line measurements + galaxy = FRBGalaxy(ra=180.0, dec=45.0, frb=frb_object) + + # Set emission line fluxes (in units of erg/s/cm^2) + galaxy.neb_lines['Ha_flux'] = 5.2e-16 + galaxy.neb_lines['Ha_flux_err'] = 0.3e-16 + galaxy.neb_lines['Hb_flux'] = 1.1e-16 + galaxy.neb_lines['OIII_5007_flux'] = 2.8e-16 + + # Calculate luminosity + ha_lum = nebular.calc_lum(galaxy, 'Ha') + print(f"Hα luminosity: {ha_lum:.2e} erg/s") + +Star formation rate calculation: + +.. code-block:: python + + # Calculate extinction from Balmer decrement + extinction = nebular.calc_extinction( + galaxy.neb_lines['Ha_flux'], + galaxy.neb_lines['Hb_flux'] + ) + print(f"A_V = {extinction:.2f} mag") + + # Calculate extinction-corrected SFR + sfr = nebular.sfr_ha(ha_lum, extinction=extinction) + print(f"Star formation rate: {sfr:.2f} Msun/yr") + +BPT classification: + +.. code-block:: python + + # Calculate line ratios for BPT diagram + line_ratios = { + 'NII_Ha': galaxy.neb_lines['NII_6583_flux'] / galaxy.neb_lines['Ha_flux'], + 'OIII_Hb': galaxy.neb_lines['OIII_5007_flux'] / galaxy.neb_lines['Hb_flux'], + 'SII_Ha': galaxy.neb_lines['SII_6717_flux'] / galaxy.neb_lines['Ha_flux'], + 'OI_Ha': galaxy.neb_lines['OI_6300_flux'] / galaxy.neb_lines['Ha_flux'] + } + + # Classify source type + classification = nebular.bpt_classification(line_ratios) + print(f"BPT classification: {classification}") + +Metallicity analysis: + +.. code-block:: python + + # Calculate metallicity using N2 method + n2_ratio = galaxy.neb_lines['NII_6583_flux'] / galaxy.neb_lines['Ha_flux'] + metallicity_n2 = nebular.metallicity_diagnostics(n2_ratio, method='N2') + + # Convert to 12 + log(O/H) scale + oh_abundance = 8.69 + metallicity_n2 + print(f"12 + log(O/H) = {oh_abundance:.2f}") + +Electron density measurement: + +.. code-block:: python + + # Calculate electron density from [SII] doublet + sii_ratio = (galaxy.neb_lines['SII_6717_flux'] / + galaxy.neb_lines['SII_6731_flux']) + + n_e = nebular.electron_density(sii_ratio) + print(f"Electron density: {n_e:.1f} cm^-3") + +Galactic extinction correction: + +.. code-block:: python + + from astropy.coordinates import SkyCoord + + # Get Galactic extinction + coord = SkyCoord(ra=180.0*u.deg, dec=45.0*u.deg) + ebv_gal = nebular.get_ebv(coord) + + # Apply foreground correction to observed fluxes + extinction_corr = 10**(0.4 * 2.5 * ebv_gal) # Hα extinction + intrinsic_flux = galaxy.neb_lines['Ha_flux'] * extinction_corr + + print(f"Galactic E(B-V): {ebv_gal:.3f}") + print(f"Corrected Hα flux: {intrinsic_flux:.2e} erg/s/cm^2") \ No newline at end of file diff --git a/docs/api/galaxies.offsets.rst b/docs/api/galaxies.offsets.rst new file mode 100644 index 00000000..3a8afd0b --- /dev/null +++ b/docs/api/galaxies.offsets.rst @@ -0,0 +1,247 @@ +Galaxy Offsets +============== + +.. automodule:: frb.galaxies.offsets + :members: + :undoc-members: + :show-inheritance: + +Overview +-------- + +This module provides functions for calculating positional offsets between +FRBs and their potential host galaxies. It handles both angular and physical +offset measurements, accounting for localization uncertainties and coordinate +transformations. + +Functions +--------- + +Primary Offset Functions +~~~~~~~~~~~~~~~~~~~~~~~~ + +.. autofunction:: frb.galaxies.offsets.angular_offset + + Calculate angular offset between FRB position and galaxy coordinates. + + This is the primary function for computing separations, handling: + + * FRB localization error ellipses + * Galaxy position uncertainties + * Statistical error propagation + * Multiple offset definitions (best estimate vs. averaged) + +.. autofunction:: frb.galaxies.offsets.physical_offset + + Convert angular offsets to physical separations using cosmological distances. + + Takes angular separations and converts to proper physical distances + in kpc, accounting for the galaxy redshift and assumed cosmology. + +Error Analysis Functions +~~~~~~~~~~~~~~~~~~~~~~~~ + +.. autofunction:: frb.galaxies.offsets.offset_uncertainty + + Calculate uncertainties in offset measurements. + + Propagates errors from: + + * FRB localization uncertainty ellipse + * Galaxy astrometric errors + * Systematic coordinate uncertainties + * Statistical measurement errors + +.. autofunction:: frb.galaxies.offsets.deproject_offset + + Deproject observed offsets to account for galaxy inclination. + + For edge-on or highly inclined galaxies, converts sky-plane offsets + to deprojected separations within the galaxy disk. + +Coordinate System Functions +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. autofunction:: frb.galaxies.offsets.galactic_coords + + Transform offsets to galaxy-centric coordinate system. + + Rotates offset vectors to align with galaxy major axis, useful + for studying offset distributions relative to galaxy structure. + +.. autofunction:: frb.galaxies.offsets.position_angle + + Calculate position angle of FRB relative to galaxy center. + + Returns the position angle (East of North) of the FRB location + relative to the galaxy centroid. + +Statistical Functions +~~~~~~~~~~~~~~~~~~~~~ + +.. autofunction:: frb.galaxies.offsets.offset_probability + + Calculate probability of chance alignment given offset distribution. + + Uses offset measurements and galaxy number density to assess the + likelihood that an apparent FRB-galaxy association is coincidental. + +.. autofunction:: frb.galaxies.offsets.compare_offset_distributions + + Compare offset distributions between different galaxy populations. + + Statistical comparison of FRB offset distributions for different + host galaxy types, redshift ranges, or other sample cuts. + +Offset Types and Definitions +---------------------------- + +The module implements several offset definitions: + +**Angular Offsets** + * `ang_best`: Offset from FRB localization centroid to galaxy center + * `ang_avg`: Offset averaged over FRB localization probability distribution + * Angular offsets reported in arcseconds + +**Physical Offsets** + * Proper physical distance in kpc at galaxy redshift + * Corrected for cosmological expansion + * Uses `ang_best` by default unless specified + +**Deprojected Offsets** + * Corrected for galaxy inclination angle + * Represents true separation within galaxy disk + * Requires morphological information + +Error Propagation +----------------- + +Comprehensive error handling includes: + +**FRB Localization Errors** + - Error ellipse semi-major and semi-minor axes + - Position angle of error ellipse + - Confidence level specification + +**Galaxy Position Errors** + - Astrometric tie uncertainties + - Source extraction errors + - Proper motion corrections (for nearby galaxies) + +**Systematic Uncertainties** + - Absolute astrometric calibration + - Reference frame differences + - Coordinate epoch corrections + +Examples +-------- + +Basic offset calculation: + +.. code-block:: python + + from frb.galaxies import offsets + from frb.frb import FRB + from frb.galaxies.frbgalaxy import FRBGalaxy + + # Create FRB and galaxy objects + frb = FRB.by_name('FRB180924') + galaxy = FRBGalaxy(ra=349.24, dec=-40.9, frb=frb) + + # Calculate angular offsets (done automatically in FRBGalaxy.__init__) + ang_avg, ang_avg_err, ang_best, ang_best_err = offsets.angular_offset(frb, galaxy) + + print(f"Angular offset (best): {ang_best:.2f} ± {ang_best_err:.2f} arcsec") + print(f"Angular offset (averaged): {ang_avg:.2f} ± {ang_avg_err:.2f} arcsec") + +Physical offset calculation: + +.. code-block:: python + + # Set galaxy redshift first + galaxy.set_z(0.3214, 'spec', err=0.0001) + + # Calculate physical offset + phys_offset = offsets.physical_offset( + ang_best, # angular offset in arcsec + galaxy.z, # redshift + cosmo=galaxy.cosmo + ) + + print(f"Physical offset: {phys_offset:.1f} kpc") + +Including position errors: + +.. code-block:: python + + # Set galaxy position uncertainties + galaxy.positional_error['ra_astrometric'] = 0.1 # arcsec + galaxy.positional_error['dec_astrometric'] = 0.1 # arcsec + galaxy.positional_error['ra_source'] = 0.05 # arcsec + galaxy.positional_error['dec_source'] = 0.05 # arcsec + + # Recalculate with position errors included + ang_avg, ang_avg_err, ang_best, ang_best_err = offsets.angular_offset(frb, galaxy) + + print(f"Offset with position errors: {ang_best:.2f} ± {ang_best_err:.2f} arcsec") + +Position angle calculation: + +.. code-block:: python + + # Calculate position angle of FRB relative to galaxy + pa = offsets.position_angle(frb.coord, galaxy.coord) + print(f"Position angle: {pa:.1f} degrees East of North") + +Probability assessment: + +.. code-block:: python + + # Assess chance alignment probability + # (requires galaxy surface density information) + prob_chance = offsets.offset_probability( + ang_best, # observed offset + galaxy_density=1000, # galaxies per sq. arcmin + magnitude_limit=25.0 # survey depth + ) + + print(f"Chance alignment probability: {prob_chance:.3f}") + +Working with morphology: + +.. code-block:: python + + # For galaxies with inclination information + if 'inclination' in galaxy.morphology: + # Calculate deprojected offset + deprojected = offsets.deproject_offset( + ang_best, + galaxy.morphology['inclination'], + galaxy.morphology['position_angle'], + frb_pa=pa + ) + + print(f"Deprojected offset: {deprojected:.2f} arcsec") + +Bulk analysis: + +.. code-block:: python + + from frb.galaxies.utils import list_of_hosts + + # Get all hosts and calculate offset distribution + frbs, hosts = list_of_hosts() + + offsets_list = [] + for host in hosts: + if host.z is not None: + phys_off = offsets.physical_offset( + host.offsets['ang_best'], + host.z, + cosmo=host.cosmo + ) + offsets_list.append(phys_off) + + import numpy as np + median_offset = np.median(offsets_list) + print(f"Median host offset: {median_offset:.1f} kpc") \ No newline at end of file diff --git a/docs/api/galaxies.photom.rst b/docs/api/galaxies.photom.rst new file mode 100644 index 00000000..7fefbca3 --- /dev/null +++ b/docs/api/galaxies.photom.rst @@ -0,0 +1,245 @@ +Photometry +========== + +.. automodule:: frb.galaxies.photom + :members: + :undoc-members: + :show-inheritance: + +Overview +-------- + +This module provides functions for photometric analysis of FRB host galaxies, +including magnitude-to-flux conversions, aperture photometry corrections, +and integration with various survey photometric systems. + +Functions +--------- + +Photometric Conversions +~~~~~~~~~~~~~~~~~~~~~~~ + +.. autofunction:: frb.galaxies.photom.mag_to_flux + + Convert magnitudes to flux densities with proper error propagation. + + Handles conversion between AB magnitude system and flux densities + in various units (mJy, μJy, erg/s/cm²/Hz, etc.). + +.. autofunction:: frb.galaxies.photom.flux_to_mag + + Convert flux densities to AB magnitudes with error propagation. + +.. autofunction:: frb.galaxies.photom.extinction_correct + + Apply extinction corrections to photometric measurements. + + Uses various extinction laws: + + * Cardelli, Clayton & Mathis (1989) - Milky Way + * Calzetti et al. (2000) - Starburst galaxies + * Fitzpatrick (1999) - Updated Milky Way + * Gordon et al. (2003) - Small Magellanic Cloud + +Aperture Corrections +~~~~~~~~~~~~~~~~~~~~ + +.. autofunction:: frb.galaxies.photom.aperture_correction + + Apply aperture corrections to photometric measurements. + + Corrects photometry measured in fixed apertures to total + magnitudes using growth curve analysis or model fitting. + +.. autofunction:: frb.galaxies.photom.psf_correction + + Correct point source contamination in galaxy photometry. + + Removes or accounts for foreground stars or AGN point source + contributions to integrated galaxy photometry. + +Survey Integration +~~~~~~~~~~~~~~~~~~ + +.. autofunction:: frb.galaxies.photom.match_survey_photometry + + Cross-match and combine photometry from multiple surveys. + + Handles systematic offsets between surveys and provides + combined photometric datasets with proper error handling. + +.. autofunction:: frb.galaxies.photom.synthetic_photometry + + Calculate synthetic photometry from spectra or SED models. + + Convolves input spectra with survey filter response functions + to predict magnitudes in any photometric system. + +Color and SED Analysis +~~~~~~~~~~~~~~~~~~~~~~ + +.. autofunction:: frb.galaxies.photom.calculate_colors + + Calculate photometric colors with error propagation. + + Computes standard color indices (u-g, g-r, r-i, etc.) and + handles cases with non-detections or upper limits. + +.. autofunction:: frb.galaxies.photom.color_corrections + + Apply K-corrections and evolutionary corrections to photometry. + + Corrects observed photometry to rest-frame values accounting + for redshift effects and cosmological evolution. + +.. autofunction:: frb.galaxies.photom.sed_chi_squared + + Calculate chi-squared goodness of fit for SED models. + + Compares observed photometry with model predictions, + properly handling upper limits and systematic uncertainties. + +Quality Assessment +~~~~~~~~~~~~~~~~~~ + +.. autofunction:: frb.galaxies.photom.photom_quality_flags + + Generate quality flags for photometric measurements. + + Identifies potential issues: + + * Saturation effects + * Contamination by nearby sources + * Poor photometric conditions + * Systematic calibration problems + +.. autofunction:: frb.galaxies.photom.detect_outliers + + Detect outlier photometric measurements using statistical tests. + + Flags measurements that are inconsistent with SED expectations + or show systematic deviations from neighboring bands. + +Examples +-------- + +Basic magnitude-flux conversions: + +.. code-block:: python + + from frb.galaxies import photom + import numpy as np + + # Convert AB magnitude to flux density in mJy + mag = 22.5 + mag_err = 0.1 + + flux, flux_err = photom.mag_to_flux(mag, mag_err, units='mJy') + print(f"Flux: {flux:.2f} ± {flux_err:.2f} mJy") + + # Convert back to magnitude + mag_check, mag_err_check = photom.flux_to_mag(flux, flux_err) + print(f"Magnitude: {mag_check:.2f} ± {mag_err_check:.3f}") + +Extinction corrections: + +.. code-block:: python + + # Apply Galactic extinction correction + ebv_gal = 0.05 # E(B-V) from dust maps + + # Correct r-band magnitude + r_obs = 22.8 + r_corr = photom.extinction_correct( + r_obs, + ebv_gal, + filter_name='r', + extinction_law='ccm89', + rv=3.1 + ) + + print(f"Observed r: {r_obs:.2f}") + print(f"Corrected r: {r_corr:.2f}") + print(f"Correction: {r_corr - r_obs:.3f} mag") + +Color calculations: + +.. code-block:: python + + # Calculate colors from photometry dictionary + photom_dict = { + 'DES_g': 23.1, 'DES_g_err': 0.05, + 'DES_r': 22.3, 'DES_r_err': 0.03, + 'DES_i': 21.9, 'DES_i_err': 0.04 + } + + # Calculate g-r color + gr_color, gr_err = photom.calculate_colors( + photom_dict, 'DES_g', 'DES_r' + ) + + # Calculate r-i color + ri_color, ri_err = photom.calculate_colors( + photom_dict, 'DES_r', 'DES_i' + ) + + print(f"g-r = {gr_color:.2f} ± {gr_err:.3f}") + print(f"r-i = {ri_color:.2f} ± {ri_err:.3f}") + +Working with galaxy objects: + +.. code-block:: python + + from frb.galaxies.frbgalaxy import FRBGalaxy + + # Assuming galaxy object with photometry loaded + galaxy = FRBGalaxy(ra=180.0, dec=45.0, frb=frb_object) + + # Calculate synthetic V-band magnitude from available photometry + v_synth = photom.synthetic_photometry( + galaxy.photom, + target_filter='V', + method='interpolation' + ) + + print(f"Synthetic V magnitude: {v_synth:.2f}") + +SED fitting preparation: + +.. code-block:: python + + # Prepare photometry for SED fitting + clean_photom = photom.detect_outliers(galaxy.photom) + + # Apply quality flags + quality_flags = photom.photom_quality_flags(galaxy.photom) + + # Remove flagged measurements + sed_photom = {} + for filt, mag in clean_photom.items(): + if quality_flags.get(filt, 0) == 0: # Good quality + sed_photom[filt] = mag + + print(f"Clean photometry: {len(sed_photom)} measurements") + print(f"Rejected: {len(galaxy.photom) - len(sed_photom)} measurements") + +Multi-survey combination: + +.. code-block:: python + + # Combine photometry from multiple surveys + survey_data = { + 'DES': {'g': 22.1, 'r': 21.5, 'i': 21.2}, + 'SDSS': {'g': 22.0, 'r': 21.4, 'i': 21.1}, + 'Pan-STARRS': {'g': 22.05, 'r': 21.45, 'i': 21.15} + } + + combined_photom = photom.match_survey_photometry( + survey_data, + weight_by_error=True, + apply_systematic_corrections=True + ) + + print("Combined photometry:") + for filt, data in combined_photom.items(): + print(f" {filt}: {data['mag']:.2f} ± {data['err']:.3f}") \ No newline at end of file diff --git a/docs/api/galaxies.ppxf.rst b/docs/api/galaxies.ppxf.rst new file mode 100644 index 00000000..4a0c0fa7 --- /dev/null +++ b/docs/api/galaxies.ppxf.rst @@ -0,0 +1,117 @@ +pPXF +==== + +.. automodule:: frb.galaxies.ppxf + :members: + :undoc-members: + :show-inheritance: + +Overview +-------- + +This module provides functionality for running pPXF (Penalized Pixel-Fitting) +analyses on galaxy spectra. pPXF is used to extract stellar kinematics and +stellar population information from absorption-line spectra. + +Functions +--------- + +.. autofunction:: frb.galaxies.ppxf.run + + Main wrapper function for running and handling pPXF outputs. + + This function processes galaxy spectra through the pPXF pipeline, handling + input/output and providing a simplified interface to the underlying pPXF code. + +Parameters +---------- + +The `run` function accepts the following key parameters: + +* **spec_file** (str or XSpectrum1D): Input spectrum file or object +* **R** (float): Spectral resolution +* **zgal** (float): Galaxy redshift +* **results_file** (str, optional): Output results filename +* **spec_fit** (str, optional): Fitted spectrum output filename +* **chk** (bool, optional): Enable checking/validation +* **flux_scale** (float, optional): Flux scaling factor +* **atmos** (list, optional): Atmospheric absorption regions to mask +* **gaps** (list, optional): Detector gaps or bad regions to ignore +* **wvmnx** (tuple, optional): Wavelength range limits + +Masking Options +~~~~~~~~~~~~~~~ + +The module provides flexible masking capabilities: + +**Atmospheric Lines** + Regions affected by atmospheric absorption can be masked during analysis: + + .. code-block:: python + + atmos = [[7150., 7300.], [7594., 7621.]] # O2 bands + +**Detector Gaps** + Bad regions or detector gaps can be excluded: + + .. code-block:: python + + gaps = [[6675., 6725.]] # CCD gap + +Usage Examples +-------------- + +Basic pPXF analysis: + +.. code-block:: python + + from frb.galaxies import ppxf + + # Run pPXF on a spectrum file + ppxf.run('galaxy_spectrum.fits', + R=3000., # Resolution + zgal=0.1, # Redshift + results_file='ppxf_results.fits') + +With masking: + +.. code-block:: python + + # Define regions to mask + atmos_lines = [[7594., 7621.], [6864., 6884.]] # Telluric features + detector_gaps = [[6675., 6725.]] # Bad detector region + + ppxf.run('spectrum.fits', + R=2500., + zgal=0.25, + atmos=atmos_lines, + gaps=detector_gaps, + wvmnx=(4000., 9000.)) # Wavelength limits + +Output Processing: + +.. code-block:: python + + # Run with custom output files + ppxf.run('galaxy.fits', + R=3500., + zgal=0.15, + results_file='kinematic_results.fits', + spec_fit='best_fit_spectrum.fits', + flux_scale=1e-17, # Scale factor for flux units + chk=True) # Enable validation checks + +Dependencies +------------ + +This module requires: + +* ppxf package (Cappellari 2017, 2023) +* linetools for spectrum handling +* astropy for units and constants +* matplotlib for plotting capabilities +* numpy for numerical computations + +.. note:: + The module uses MILES stellar library templates by default for + stellar population fitting. \ No newline at end of file diff --git a/docs/api/galaxies.rst b/docs/api/galaxies.rst new file mode 100644 index 00000000..bf26948f --- /dev/null +++ b/docs/api/galaxies.rst @@ -0,0 +1,39 @@ +Galaxies +======== + +.. automodule:: frb.galaxies + :members: + :undoc-members: + :show-inheritance: + +Overview +-------- + +A significant portion of FRB science will flow +from studying galaxies related to these events. + +This will include both the galaxy that hosted +the event and galaxies foreground to the event +which may imprint signatues in the signal itself. + +The `frb.galaxies` package provides comprehensive functionality for analyzing galaxies +associated with Fast Radio Bursts (FRBs). This includes tools for photometric analysis, +spectral energy distribution fitting, redshift estimation, and various derived physical +properties. + +Submodules +---------- + +.. toctree:: + :maxdepth: 2 + + galaxies.frbgalaxy + galaxies.cigale + galaxies.ppxf + galaxies.eazy + galaxies.utils + galaxies.nebular + galaxies.offsets + galaxies.defs + galaxies.hosts + galaxies.photom \ No newline at end of file diff --git a/docs/api/galaxies.utils.rst b/docs/api/galaxies.utils.rst new file mode 100644 index 00000000..98f9af7c --- /dev/null +++ b/docs/api/galaxies.utils.rst @@ -0,0 +1,177 @@ +Galaxy Utilities +================ + +.. automodule:: frb.galaxies.utils + :members: + :undoc-members: + :show-inheritance: + +Overview +-------- + +This module provides utility functions for working with FRB host galaxy data, +including database operations, table building, and various helper functions +for galaxy analysis. + +Functions +--------- + +Database and Loading Functions +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. autofunction:: frb.galaxies.utils.load_specdb + + Load spectroscopic database for galaxy analysis. + +.. autofunction:: frb.galaxies.utils.list_of_hosts + + Generate a list of FRB host galaxies from the database. + +.. autofunction:: frb.galaxies.utils.build_table_of_hosts + + Generate a Pandas table of FRB host galaxy data. + + This function extracts data from host objects and compiles it into a + comprehensive table including photometry, derived quantities, nebular + line measurements, and morphological parameters. + +Analysis Utilities +~~~~~~~~~~~~~~~~~~ + +.. autofunction:: frb.galaxies.utils.load_f_mL + + Generate interpolator from magnitude to luminosity as function of redshift. + + Provides approximate magnitude-luminosity relationship up to z=4 for + galaxy luminosity function analysis. + +.. autofunction:: frb.galaxies.utils.load_PATH + + Load up the PATH (Probabilistic Association of Transients with Hosts) table. + +.. autofunction:: frb.galaxies.utils.deredden_spec + + Apply dereddening correction to galaxy spectra using dust extinction models. + +Data Processing Functions +~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. autofunction:: frb.galaxies.utils.build_photom_table + + Build standardized photometric table from various survey catalogs. + +.. autofunction:: frb.galaxies.utils.parse_galfit_output + + Parse GALFIT morphological analysis output files. + +.. autofunction:: frb.galaxies.utils.update_frbgalaxy_coords + + Update galaxy coordinates with improved astrometry. + +Output and Table Management +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The module provides several functions for managing host galaxy data tables: + +**Table Structure** + - Coordinates stored as RA_host, DEC_host (degrees) + - FRB names and objects included for cross-referencing + - Units tracked in separate dictionary + - Missing values handled with NaN + +**Data Categories** + - Photometric measurements across multiple surveys + - Derived physical properties (mass, SFR, metallicity) + - Nebular emission line fluxes and ratios + - Morphological parameters from imaging analysis + - Redshift measurements (spectroscopic and photometric) + - Offset measurements from FRB positions + +Examples +-------- + +Building host galaxy table: + +.. code-block:: python + + from frb.galaxies import utils + + # Build comprehensive host table + host_table, units_dict = utils.build_table_of_hosts( + attrs=['derived', 'photom', 'neb_lines', 'morphology'] + ) + + # Display table info + print(f"Number of hosts: {len(host_table)}") + print(f"Available columns: {list(host_table.columns)}") + print(f"Units: {units_dict}") + +Working with individual hosts: + +.. code-block:: python + + # Get list of host objects + frbs, hosts = utils.list_of_hosts(verbose=True) + + # Access specific host properties + for host in hosts[:5]: # First 5 hosts + print(f"Host: {host.name}") + print(f" RA, Dec: {host.coord.ra.deg:.3f}, {host.coord.dec.deg:.3f}") + print(f" Redshift: {host.z}") + if len(host.derived) > 0: + if 'Mstar' in host.derived: + print(f" Stellar mass: {host.derived['Mstar']:.2e} Msun") + +Loading and using spectroscopic database: + +.. code-block:: python + + # Load spectroscopic database + specdb = utils.load_specdb(specdb_file='custom_specdb.hdf5') + + if specdb is not None: + # Query for spectra + meta = specdb.meta_from_coords(coords, radius=5*u.arcsec) + if len(meta) > 0: + spectra = specdb.spectra_from_meta(meta) + +Dereddening corrections: + +.. code-block:: python + + from linetools.spectra.xspectrum1d import XSpectrum1D + + # Load spectrum + spec = XSpectrum1D.from_file('galaxy_spectrum.fits') + + # Apply dereddening with AV = 0.5 mag + corrected_spec = utils.deredden_spec(spec, AV=0.5) + +PATH analysis integration: + +.. code-block:: python + + # Load PATH results + path_table = utils.load_PATH('adopted.csv') + + # Build host table with PATH probabilities + host_table, units = utils.build_table_of_hosts() + + # PATH probabilities now included as P_Ox, P_O columns + high_prob_hosts = host_table[host_table['P_Ox'] > 0.8] + print(f"High probability associations: {len(high_prob_hosts)}") + +Working with magnitude-luminosity relations: + +.. code-block:: python + + # Load m-L interpolator + f_mL = utils.load_f_mL() + + # Get characteristic magnitude at different redshifts + z_array = [0.1, 0.3, 0.5, 1.0, 2.0] + m_star = f_mL(z_array) + + print("Characteristic magnitudes (r-band):") + for z, m in zip(z_array, m_star): + print(f" z = {z:.1f}: m* = {m:.2f}") \ No newline at end of file diff --git a/docs/conf.py b/docs/conf.py index f30a0179..a006548d 100755 --- a/docs/conf.py +++ b/docs/conf.py @@ -13,6 +13,7 @@ # -- General configuration --------------------------------------------------- extensions = [ 'sphinx.ext.autodoc', + 'sphinx.ext.autosummary', 'sphinx.ext.napoleon', 'sphinx.ext.viewcode', 'sphinx.ext.mathjax', @@ -56,6 +57,7 @@ # -- Options for autodoc ---------------------------------------------------- autodoc_default_options = { 'members': True, + 'show-inheritance': True, 'member-order': 'bysource', 'special-members': '__init__', 'undoc-members': True, diff --git a/docs/halos/hmf.rst b/docs/halos/hmf.rst index 64b21d26..5fc83780 100644 --- a/docs/halos/hmf.rst +++ b/docs/halos/hmf.rst @@ -1,5 +1,5 @@ -frb.halos.hmf -============= +Halo Mass Function +================== .. automodule:: frb.halos.hmf diff --git a/docs/halos/index.rst b/docs/halos/index.rst index 15858eb0..0ad50b74 100644 --- a/docs/halos/index.rst +++ b/docs/halos/index.rst @@ -1,7 +1,11 @@ frb.halos Package Documentation =============================== -The ``frb.halos`` package provides tools for modeling galaxy halos and calculating their contributions to Fast Radio Burst (FRB) dispersion measures. This package includes halo models, stellar-halo mass relations, photometric redshift analysis, and statistical tools for halo populations. +Modules in the ``frb.halos`` folder provide tools +for modeling galaxy halos and calculating +their contributions to Fast Radio Burst (FRB) dispersion measures. +This package includes halo models, stellar-halo mass relations, +photometric redshift analysis, and statistical tools for halo populations. Overview -------- diff --git a/docs/halos/models.rst b/docs/halos/models.rst index 2f1cf647..5bb672aa 100644 --- a/docs/halos/models.rst +++ b/docs/halos/models.rst @@ -1,5 +1,5 @@ -frb.halos.models -================ +Halo Modeling +============= .. automodule:: frb.halos.models diff --git a/docs/halos/photoz.rst b/docs/halos/photoz.rst index 5b11a584..b689b2c8 100644 --- a/docs/halos/photoz.rst +++ b/docs/halos/photoz.rst @@ -1,5 +1,5 @@ -frb.halos.photoz -================ +Photometric Redshifts +===================== .. automodule:: frb.halos.photoz diff --git a/docs/index.rst b/docs/index.rst index 42df6c4f..de55f8db 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -44,19 +44,15 @@ Galaxies .. toctree:: :maxdepth: 2 - galaxies - eazy + galaxies/index -Halos ------ +Halo Calculations +----------------- .. toctree:: :maxdepth: 2 halos/index - halos/hmf - halos/models - halos/photoz Rotation Measure ---------------- @@ -100,5 +96,6 @@ API Reference api/index api/dm + api/galaxies From 1ccf443a80dcce7f1a6e252b41ea5847e2d1e126 Mon Sep 17 00:00:00 2001 From: profxj Date: Sun, 31 Aug 2025 05:34:17 -0700 Subject: [PATCH 04/21] mo --- docs/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/index.rst b/docs/index.rst index de55f8db..4a56e0b8 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -44,7 +44,7 @@ Galaxies .. toctree:: :maxdepth: 2 - galaxies/index + api/galaxies Halo Calculations ----------------- From 9ddc320434230f8ef3e4f0ba0a61c8dc478b3ba3 Mon Sep 17 00:00:00 2001 From: profxj Date: Sun, 31 Aug 2025 05:42:56 -0700 Subject: [PATCH 05/21] paths.. --- docs/conf.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/conf.py b/docs/conf.py index a006548d..e6133375 100755 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,6 +1,9 @@ import os import sys +from pathlib import Path + sys.path.insert(0, os.path.abspath('..')) +sys.path.insert(0, str(Path('..', 'frb').resolve())) # -- Project information ----------------------------------------------------- project = 'FRB Repository' From 2205925a2af8aea6e78899ebad861b9dd02e763b Mon Sep 17 00:00:00 2001 From: profxj Date: Sun, 31 Aug 2025 05:58:51 -0700 Subject: [PATCH 06/21] path fix --- docs/conf.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/conf.py b/docs/conf.py index e6133375..841399e2 100755 --- a/docs/conf.py +++ b/docs/conf.py @@ -3,7 +3,9 @@ from pathlib import Path sys.path.insert(0, os.path.abspath('..')) -sys.path.insert(0, str(Path('..', 'frb').resolve())) +sys.path.insert(0, os.path.abspath('../..')) +#sys.path.insert(0, str(Path('..', 'frb').resolve())) +#sys.path.insert(0, str(Path('..', '..', 'frb').resolve())) # -- Project information ----------------------------------------------------- project = 'FRB Repository' From c3c006319ed11cb42dfe7b93914440a0ff21b289 Mon Sep 17 00:00:00 2001 From: profxj Date: Sun, 31 Aug 2025 06:06:25 -0700 Subject: [PATCH 07/21] readthedocs --- docs/conf.py | 15 +++++++++++---- docs/requirements.txt | 1 + 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 841399e2..afc4eba0 100755 --- a/docs/conf.py +++ b/docs/conf.py @@ -2,10 +2,17 @@ import sys from pathlib import Path -sys.path.insert(0, os.path.abspath('..')) -sys.path.insert(0, os.path.abspath('../..')) -#sys.path.insert(0, str(Path('..', 'frb').resolve())) -#sys.path.insert(0, str(Path('..', '..', 'frb').resolve())) +# Check if we're building on ReadTheDocs +on_rtd = os.environ.get('READTHEDOCS', None) == 'True' + +if on_rtd: + # On ReadTheDocs, the package is installed in the environment + # No need to modify sys.path + pass +else: + # Local development - add path to package + sys.path.insert(0, os.path.abspath('..')) + sys.path.insert(0, os.path.abspath('../../')) # -- Project information ----------------------------------------------------- project = 'FRB Repository' diff --git a/docs/requirements.txt b/docs/requirements.txt index 756df0fd..72d4bd99 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,5 +1,6 @@ sphinx>=4.0.0 sphinx-rtd-theme>=1.0.0 +sphinx-autodoc-typehints numpy>=1.20.0 matplotlib>=3.3.0 xarray>=0.16.0 From f7473e17841d3ed8f51ca074af026b71a23e7a2f Mon Sep 17 00:00:00 2001 From: profxj Date: Sun, 31 Aug 2025 06:11:41 -0700 Subject: [PATCH 08/21] still at it --- docs/requirements.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index 72d4bd99..eb6ade2d 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -4,4 +4,6 @@ sphinx-autodoc-typehints numpy>=1.20.0 matplotlib>=3.3.0 xarray>=0.16.0 -pandas>=1.2.0 \ No newline at end of file +pandas>=1.2.0 +importlib-resources>=1.3.0 +astropy>=5.0.0 \ No newline at end of file From 9be79f0ab04c43cee298887d1d2df0ca3fd0099e Mon Sep 17 00:00:00 2001 From: profxj Date: Sun, 31 Aug 2025 06:16:05 -0700 Subject: [PATCH 09/21] more requirements --- docs/requirements.txt | 4 +++- frb/galaxies/nebular.py | 5 ++++- frb/galaxies/photom.py | 5 ++++- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index eb6ade2d..d3089daa 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -6,4 +6,6 @@ matplotlib>=3.3.0 xarray>=0.16.0 pandas>=1.2.0 importlib-resources>=1.3.0 -astropy>=5.0.0 \ No newline at end of file +astropy>=5.0.0 +scipy>=1.15.0 +IPython>=9.0.0 \ No newline at end of file diff --git a/frb/galaxies/nebular.py b/frb/galaxies/nebular.py index 8c0b1684..483bfd4f 100644 --- a/frb/galaxies/nebular.py +++ b/frb/galaxies/nebular.py @@ -9,7 +9,10 @@ from astropy.table import Table from astropy import units -import dust_extinction +try: + import dust_extinction +except ImportError: + warnings.warn("Galaxy nebular line analysis requires dust_extionction. Install it if you want to use them") from IPython import embed diff --git a/frb/galaxies/photom.py b/frb/galaxies/photom.py index 74a5b122..cc676324 100644 --- a/frb/galaxies/photom.py +++ b/frb/galaxies/photom.py @@ -23,7 +23,10 @@ from frb.galaxies import defs -import dust_extinction +try: + import dust_extinction +except ImportError: + warnings.warn("Galaxy nebular line analysis requires dust_extionction. Install it if you want to use them") # Photometry globals table_format = 'ascii.fixed_width' From e992e5b725c4ea37be3f184b730f2890ca0611ec Mon Sep 17 00:00:00 2001 From: profxj Date: Sun, 31 Aug 2025 06:20:41 -0700 Subject: [PATCH 10/21] dust --- docs/requirements.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index d3089daa..d4fa1239 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -8,4 +8,5 @@ pandas>=1.2.0 importlib-resources>=1.3.0 astropy>=5.0.0 scipy>=1.15.0 -IPython>=9.0.0 \ No newline at end of file +IPython>=9.0.0 +dust_extinction>=1.5.0 \ No newline at end of file From 56d8b7215d1743de5871c1d8d0a88bbeff1f3285 Mon Sep 17 00:00:00 2001 From: profxj Date: Sun, 31 Aug 2025 06:23:51 -0700 Subject: [PATCH 11/21] 2 more --- docs/requirements.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index d4fa1239..6f152bb2 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -9,4 +9,6 @@ importlib-resources>=1.3.0 astropy>=5.0.0 scipy>=1.15.0 IPython>=9.0.0 -dust_extinction>=1.5.0 \ No newline at end of file +dust_extinction>=1.5.0 +numba>=0.55.0 +linetools>=0.3.0 \ No newline at end of file From 11611334b683d2bf51add973bc76b1f68a13edfa Mon Sep 17 00:00:00 2001 From: profxj Date: Sun, 31 Aug 2025 06:26:30 -0700 Subject: [PATCH 12/21] ne2001 --- docs/requirements.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index 6f152bb2..a33ffe12 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -11,4 +11,6 @@ scipy>=1.15.0 IPython>=9.0.0 dust_extinction>=1.5.0 numba>=0.55.0 -linetools>=0.3.0 \ No newline at end of file +linetools>=0.3.0 +photutils>=2.1.0 +ne2001>=0.0.1 \ No newline at end of file From 0a22917b08e1fd9ad5df983f9526eac47faff247 Mon Sep 17 00:00:00 2001 From: profxj Date: Sun, 31 Aug 2025 06:34:57 -0700 Subject: [PATCH 13/21] pain.. --- frb/galaxies/ppxf.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/frb/galaxies/ppxf.py b/frb/galaxies/ppxf.py index bb533afe..688f8005 100644 --- a/frb/galaxies/ppxf.py +++ b/frb/galaxies/ppxf.py @@ -1,6 +1,7 @@ """ Module for running pPXF analyses""" import importlib_resources +import warnings`` import numpy as np @@ -15,9 +16,13 @@ from linetools.spectra.xspectrum1d import XSpectrum1D from linetools.spectra.io import readspec -from ppxf import ppxf -from ppxf import ppxf_util as util -from ppxf import miles_util as lib +try: + from ppxf import ppxf +except ImportError: + warnings.warn("ppxf not found. Install it if you want to use it") +else: + from ppxf import ppxf_util as util + from ppxf import miles_util as lib import time from frb.defs import frb_cosmo as cosmo From c0b34d4959ab96f3ee8c772cf1690500aaf5e370 Mon Sep 17 00:00:00 2001 From: profxj Date: Sun, 31 Aug 2025 06:38:29 -0700 Subject: [PATCH 14/21] linetools.. --- docs/requirements.txt | 1 - frb/galaxies/ppxf.py | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index a33ffe12..ca0641f1 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -11,6 +11,5 @@ scipy>=1.15.0 IPython>=9.0.0 dust_extinction>=1.5.0 numba>=0.55.0 -linetools>=0.3.0 photutils>=2.1.0 ne2001>=0.0.1 \ No newline at end of file diff --git a/frb/galaxies/ppxf.py b/frb/galaxies/ppxf.py index 688f8005..9f201cf0 100644 --- a/frb/galaxies/ppxf.py +++ b/frb/galaxies/ppxf.py @@ -1,7 +1,7 @@ """ Module for running pPXF analyses""" import importlib_resources -import warnings`` +import warnings import numpy as np From b5fec5f2d2cb5aa5907038ed13e2149cfd41a758 Mon Sep 17 00:00:00 2001 From: profxj Date: Sun, 31 Aug 2025 06:45:47 -0700 Subject: [PATCH 15/21] removing linetools --- frb/galaxies/ppxf.py | 10 ++++++++-- frb/galaxies/utils.py | 6 +++--- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/frb/galaxies/ppxf.py b/frb/galaxies/ppxf.py index 9f201cf0..df5dc092 100644 --- a/frb/galaxies/ppxf.py +++ b/frb/galaxies/ppxf.py @@ -13,8 +13,14 @@ c = constants.c.to(units.km / units.s).value -from linetools.spectra.xspectrum1d import XSpectrum1D -from linetools.spectra.io import readspec +# linetools will be DEPRECATED +try: + import linetools +except ImportError: + warnings.warn("linetools not found. Install it if you want to use it") +else: + from linetools.spectra.xspectrum1d import XSpectrum1D + from linetools.spectra.io import readspec try: from ppxf import ppxf diff --git a/frb/galaxies/utils.py b/frb/galaxies/utils.py index 3af6099a..2312d37c 100644 --- a/frb/galaxies/utils.py +++ b/frb/galaxies/utils.py @@ -25,11 +25,9 @@ import dust_extinction -from linetools.spectra import xspectrum1d - from frb import frb -def deredden_spec(spectrum:xspectrum1d.XSpectrum1D, ebv:float): +def deredden_spec(spectrum, ebv:float): """ Deredden the input spectrum using the input EBV value Args: @@ -39,6 +37,8 @@ def deredden_spec(spectrum:xspectrum1d.XSpectrum1D, ebv:float): Returns: xspectrum1d.XSpectrum1D: De-reddened spectrum """ + # linetools WILL BE DEPRECATED + from linetools.spectra import xspectrum1d # Correct for Galactic extinction # Need to replace it From aa2a26a95c06138ddc34db3446acfbef1ece5616 Mon Sep 17 00:00:00 2001 From: profxj Date: Sun, 31 Aug 2025 06:50:45 -0700 Subject: [PATCH 16/21] still fighting.. --- docs/requirements.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index ca0641f1..f3821bd4 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -10,6 +10,7 @@ astropy>=5.0.0 scipy>=1.15.0 IPython>=9.0.0 dust_extinction>=1.5.0 +linetools>=0.3.2 numba>=0.55.0 photutils>=2.1.0 -ne2001>=0.0.1 \ No newline at end of file +git+https://github.com/FRBs/ne2001 \ No newline at end of file From fa6709ef572999c51a2b8879b34ddbffd3f4b487 Mon Sep 17 00:00:00 2001 From: profxj Date: Sun, 31 Aug 2025 06:57:54 -0700 Subject: [PATCH 17/21] halos --- docs/halos/index.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/halos/index.rst b/docs/halos/index.rst index 0ad50b74..15ebe6c2 100644 --- a/docs/halos/index.rst +++ b/docs/halos/index.rst @@ -27,7 +27,7 @@ Core Models .. toctree:: :maxdepth: 2 - frb_halos_models + models Main module containing halo density profiles, stellar-halo mass relations, and galaxy-specific models. @@ -43,7 +43,7 @@ Photometric Analysis .. toctree:: :maxdepth: 2 - frb_halos_photoz + photoz Tools for photometric redshift-based halo analysis of FRB fields. @@ -59,7 +59,7 @@ Statistical Tools .. toctree:: :maxdepth: 2 - frb_halos_hmf + hmf Halo mass function calculations and statistical analysis. From 33b85e7e7323f82fcfe62eb1539eaed07f239836 Mon Sep 17 00:00:00 2001 From: profxj Date: Sat, 3 Jan 2026 12:01:01 -0800 Subject: [PATCH 18/21] docs galore --- docs/api/dm.rst | 20 +++++++++----------- docs/api/galaxies.rst | 2 +- docs/api/index.rst | 38 ++++++++++++-------------------------- docs/data.rst | 6 +++--- docs/dm.rst | 17 ++++++++--------- docs/galaxies.rst | 4 ++-- docs/halos/hmf.rst | 4 ++-- docs/halos/index.rst | 6 +++--- docs/index.rst | 12 +++--------- docs/installing.rst | 8 ++++---- docs/quickstart.rst | 8 ++++---- docs/surveys.rst | 2 +- docs/tscatt.rst | 2 +- 13 files changed, 53 insertions(+), 76 deletions(-) diff --git a/docs/api/dm.rst b/docs/api/dm.rst index 6199db3c..8948f909 100644 --- a/docs/api/dm.rst +++ b/docs/api/dm.rst @@ -24,14 +24,13 @@ This module decomposes the total DM into contributions from: Submodules ---------- -.. toctree:: - :maxdepth: 1 +The DM package contains the following submodules: - dm_igm - dm_cosmic - dm_host - dm_mcmc - dm_prob_dmz +* ``frb.dm.igm`` - Intergalactic Medium calculations +* ``frb.dm.cosmic`` - Cosmic dispersion measure modeling +* ``frb.dm.host`` - Host galaxy DM contributions +* ``frb.dm.mcmc`` - MCMC analysis methods +* ``frb.dm.prob_dmz`` - DM-redshift probability calculations frb.dm.igm - Intergalactic Medium ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -404,10 +403,9 @@ Performance Notes See Also -------- -- :doc:`../tutorials` - Detailed usage examples -- :doc:`turb_scattering` - Scattering analysis -- :doc:`frbcat` - Catalogue operations -- :doc:`../examples` - Real-world applications +- :doc:`../quickstart` - Quick start guide +- :doc:`../halos/index` - Halo modeling and DM contributions +- :doc:`galaxies` - Galaxy analysis tools .. note:: The DM module assumes a standard cosmological model by default. diff --git a/docs/api/galaxies.rst b/docs/api/galaxies.rst index bf26948f..3143901a 100644 --- a/docs/api/galaxies.rst +++ b/docs/api/galaxies.rst @@ -14,7 +14,7 @@ from studying galaxies related to these events. This will include both the galaxy that hosted the event and galaxies foreground to the event -which may imprint signatues in the signal itself. +which may imprint signatures in the signal itself. The `frb.galaxies` package provides comprehensive functionality for analyzing galaxies associated with Fast Radio Bursts (FRBs). This includes tools for photometric analysis, diff --git a/docs/api/index.rst b/docs/api/index.rst index cf8b4218..f181d2b1 100644 --- a/docs/api/index.rst +++ b/docs/api/index.rst @@ -12,10 +12,7 @@ The FRB package is organized into several key modules: :maxdepth: 2 dm - frbcat - turb_scattering - frb_class - utilities + galaxies Module Overview --------------- @@ -26,32 +23,23 @@ frb.dm - Dispersion Measure Calculations The dispersion measure module provides comprehensive tools for calculating and modeling DM contributions from various sources: - :doc:`dm` - Main DM calculation module - + - ``frb.dm.igm`` - Intergalactic Medium calculations - ``frb.dm.cosmic`` - Cosmic dispersion measure modeling - ``frb.dm.host`` - Host galaxy contributions - ``frb.dm.mcmc`` - MCMC analysis methods - ``frb.dm.prob_dmz`` - DM-redshift probability calculations -frb.frbcat - Catalogue Interface -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -- :doc:`frbcat` - FRB catalogue management and access - -frb.turb_scattering - Scattering Analysis -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -- :doc:`turb_scattering` - Turbulent scattering models and calculations - -Core Classes -~~~~~~~~~~~~ +frb.galaxies - Galaxy Analysis +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- :doc:`frb_class` - Main FRB object class and methods +- :doc:`galaxies` - Galaxy and host analysis tools -Utilities -~~~~~~~~~ - -- :doc:`utilities` - Helper functions and utilities + - ``frb.galaxies.frbgalaxy`` - FRBGalaxy and FRBHost classes + - ``frb.galaxies.photom`` - Photometry handling + - ``frb.galaxies.nebular`` - Nebular emission analysis + - ``frb.galaxies.eazy`` - EAZY SED fitting interface + - ``frb.galaxies.cigale`` - CIGALE SED fitting interface Quick Reference --------------- @@ -250,10 +238,8 @@ If you're contributing new functions or classes: 4. Include examples in docstrings 5. Update this API documentation -See :doc:`../contributing` for detailed guidelines. - .. seealso:: - :doc:`../quickstart` - Get started with basic usage - - :doc:`../tutorials` - Detailed examples and workflows - - :doc:`../examples` - Real-world applications \ No newline at end of file + - :doc:`../dm` - Dispersion measure calculations + - :doc:`../halos/index` - Halo modeling tools \ No newline at end of file diff --git a/docs/data.rst b/docs/data.rst index f9fe40e2..137efdf3 100644 --- a/docs/data.rst +++ b/docs/data.rst @@ -16,7 +16,7 @@ FRBs For FRBs included in this repository, currently those that are well localized and published, we have archived a set -of basic measaurements, e.g. coordinates. These are +of basic measurements, e.g. coordinates. These are saved as a set of JSON files in the data/FRBs/ folder of the repository. @@ -26,9 +26,9 @@ One can load these data into an FRB object as follows:: # Coordinate frb121102.coord # Error ellipse - frb121101.eelipse + frb121102.eellipse # DM - frb121101.DM + frb121102.DM RM and other measurements are also included when available. See the FRB_Event.ipynb notebook diff --git a/docs/dm.rst b/docs/dm.rst index b9040e90..f963cfb8 100644 --- a/docs/dm.rst +++ b/docs/dm.rst @@ -19,15 +19,14 @@ from the Milky Way ISM. The map is in the Here is an example usage: -```python -from frb.dm import dm_ism_healpix_map +.. code-block:: python -b, l = 5., 50. # Galactic coordinates in degrees + from frb.dm import dm_ism_healpix_map -dm_map = dm_ism_healpix_map.get_dm_map() -dm_ism = dm_ism_healpix_map.dm_ism_from_healpix_map(l, b, dm_map) + b, l = 5., 50. # Galactic coordinates in degrees -``` + dm_map = dm_ism_healpix_map.get_dm_map() + dm_ism = dm_ism_healpix_map.dm_ism_from_healpix_map(l, b, dm_map) One can also input arrays of b,l coordinates. @@ -50,11 +49,11 @@ frb.dlas.approx_avgDM() method:: DM = approx_avgDM(1.) -This may be calucated a single or array of redshifts. +This may be calculated for a single or an array of redshifts. The return value is an astropy Quantity with default -unites of pc/cm^3. +units of pc/cm^3. -.. _PN17: http://coming.soon +.. _PN17: https://ui.adsabs.harvard.edu/abs/2017ApJ...837...16P MonteCarlo ---------- diff --git a/docs/galaxies.rst b/docs/galaxies.rst index 64db21f5..3ce01758 100644 --- a/docs/galaxies.rst +++ b/docs/galaxies.rst @@ -7,7 +7,7 @@ from studying galaxies related to these events. This will include both the galaxy that hosted the event and galaxies foreground to the event -which may imprint signatues in the signal itself. +which may imprint signatures in the signal itself. We have thus far generated a class FRBGalaxy to hold, manipulate, and derive key observed and @@ -131,7 +131,7 @@ PATH A subset of the FRB Host galaxies have been analyzed using the Probabilistic Assignment of Transients to their Hosts (PATH) framework as described in `Aggarawal et al. 2021 `_. -This relies on the `astropath <>`_ code base. +This relies on the `astropath `_ code base. You can load up the PATH results using:: diff --git a/docs/halos/hmf.rst b/docs/halos/hmf.rst index 5fc83780..3a4ad75d 100644 --- a/docs/halos/hmf.rst +++ b/docs/halos/hmf.rst @@ -6,8 +6,8 @@ Halo Mass Function Module for halo mass function calculations and related statistical analysis. .. warning:: - This module is deprecated. The functionality has been moved to frb.halos.models. - Hope you are not intending to use the hmf.py module. + This module is deprecated. The functionality has been moved to :mod:`frb.halos.models`. + Please use that module instead for new code. Functions --------- diff --git a/docs/halos/index.rst b/docs/halos/index.rst index 15ebe6c2..d1509342 100644 --- a/docs/halos/index.rst +++ b/docs/halos/index.rst @@ -238,6 +238,6 @@ Field-wide statistical analysis:: See Also -------- -* :doc:`../frb_frb` - Core FRB functionality -* :doc:`../frb_galaxies_frbgalaxy` - FRB host galaxy analysis -* :doc:`../frb_dm_host` - Host galaxy DM calculations \ No newline at end of file +* :doc:`../api/galaxies` - Galaxy analysis tools +* :doc:`../api/dm` - DM calculation modules +* :doc:`../quickstart` - Quick start guide \ No newline at end of file diff --git a/docs/index.rst b/docs/index.rst index 4a56e0b8..2a542de1 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,15 +1,9 @@ -.. specdb documentation master file, created by - sphinx-quickstart on Fri Nov 13 13:39:35 2015. - You can adapt this file completely to your liking, but it should at least - contain the root `toctree` directive. - Welcome to the FRB documentation! ================================= - -FRB is a repository for FRB research. -Ideally made and maintained by the -FRB community. +FRB is a Python package for Fast Radio Burst research, providing tools for +dispersion measure calculations, host galaxy analysis, FRB-galaxy associations, +and survey data handling. The package is developed and maintained by the FRB community. Getting Started diff --git a/docs/installing.rst b/docs/installing.rst index 26065229..6bd43f77 100644 --- a/docs/installing.rst +++ b/docs/installing.rst @@ -81,11 +81,11 @@ The following are required to build host galaxy objects: The following is required to run the code in dm_kde: -* `asymmetric_kde ` no versioning +* `asymmetric_kde `_ no versioning The following is required to run the MCMC DM code in dm.mcmc.py: -* `numba ` version >= 0.50 +* `numba `_ version >= 0.50 For pPXF, you will also likely need to modify the standard install to use the Chabrier libraries. See the InstallNotes in this @@ -93,7 +93,7 @@ to use the Chabrier libraries. See the InstallNotes in this The following are required for using functions in halos.photoz.py: -* `threedhst ` version >= 0.1.dev0 +* `threedhst `_ version >= 0.1.dev0 * progressbar2 :: Use pip * pathos :: Use pip @@ -106,7 +106,7 @@ Installing frb Presently, you must download the code from github:: - #go to the directory where you would like to install specdb. + #go to the directory where you would like to install frb. git clone https://github.com/FRBs/FRB.git From there, you can build and install with:: diff --git a/docs/quickstart.rst b/docs/quickstart.rst index e6dc1abb..74ae9a73 100644 --- a/docs/quickstart.rst +++ b/docs/quickstart.rst @@ -280,10 +280,10 @@ Next Steps Now that you're familiar with the basics: -1. **Explore Advanced Features**: Check out the :doc:`tutorials` for in-depth examples -2. **Read the API Documentation**: Browse :doc:`api/index` for complete function references -3. **Study Real Examples**: Look at :doc:`examples` for practical applications -4. **Contribute**: See :doc:`contributing` if you want to help improve the package +1. **Read the API Documentation**: Browse :doc:`api/index` for complete function references +2. **Explore Jupyter Notebooks**: Check out the ``docs/nb/`` directory for in-depth examples and tutorials +3. **Learn about Dispersion Measures**: See :doc:`dm` for DM calculation details +4. **Explore Halo Calculations**: See :doc:`halos/index` for halo modeling tools Common Gotchas -------------- diff --git a/docs/surveys.rst b/docs/surveys.rst index 860f7b7b..b1495b18 100644 --- a/docs/surveys.rst +++ b/docs/surveys.rst @@ -20,7 +20,7 @@ Catalog Here is an example of grabbing a catalog of sources around an input coordinate from the :ref:`surveys-des` survey:: - from astropy.coordiantes import SkyCoord + from astropy.coordinates import SkyCoord from astropy import units # coord = SkyCoord('J214425.25-403400.81', unit=(units.hourangle, units.deg)) diff --git a/docs/tscatt.rst b/docs/tscatt.rst index 385f9fab..c8b3fed4 100644 --- a/docs/tscatt.rst +++ b/docs/tscatt.rst @@ -6,7 +6,7 @@ Turbulent Scattering .. _Macquart&Koay13: http://adsabs.harvard.edu/abs/2013ApJ...776..125M -The formalism developed by `Macquart&Koay13`_has been ingested +The formalism developed by `Macquart&Koay13`_ has been ingested into the *Turbulence* class for calculations of temporal smearing and angular broadening. From 7a5cf328ccf7c2f706d5154b5fd86ca081edbc7d Mon Sep 17 00:00:00 2001 From: profxj Date: Sat, 3 Jan 2026 12:14:29 -0800 Subject: [PATCH 19/21] new files --- .readthedocs.yaml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 .readthedocs.yaml diff --git a/.readthedocs.yaml b/.readthedocs.yaml new file mode 100644 index 00000000..dee3320c --- /dev/null +++ b/.readthedocs.yaml @@ -0,0 +1,19 @@ +version: 2 + +build: + os: ubuntu-22.04 + tools: + python: "3.11" + +sphinx: + configuration: docs/conf.py + +python: + install: + - method: pip + path: . + - requirements: docs/requirements.txt + +formats: + - pdf + - epub \ No newline at end of file From a2007980db7bdbd86a73e2ca5c4b094dc202a631 Mon Sep 17 00:00:00 2001 From: profxj Date: Sat, 3 Jan 2026 12:50:35 -0800 Subject: [PATCH 20/21] go --- docs/_static/.gitkeep | 0 docs/_templates/.gitkeep | 0 docs/frb_class.rst | 264 ++++++++++++ docs/frbhost_class.rst | 387 ++++++++++++++++++ docs/index.rst | 9 + docs/nb/FRB_and_Host_Classes.ipynb | 625 +++++++++++++++++++++++++++++ docs/quickstart.rst | 10 +- readthedocs.yaml | 19 - 8 files changed, 1291 insertions(+), 23 deletions(-) create mode 100644 docs/_static/.gitkeep create mode 100644 docs/_templates/.gitkeep create mode 100644 docs/frb_class.rst create mode 100644 docs/frbhost_class.rst create mode 100644 docs/nb/FRB_and_Host_Classes.ipynb delete mode 100644 readthedocs.yaml diff --git a/docs/_static/.gitkeep b/docs/_static/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/docs/_templates/.gitkeep b/docs/_templates/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/docs/frb_class.rst b/docs/frb_class.rst new file mode 100644 index 00000000..8e958d2f --- /dev/null +++ b/docs/frb_class.rst @@ -0,0 +1,264 @@ +********* +FRB Class +********* + +The ``FRB`` class is the core object representing an observed Fast Radio Burst event. +It stores coordinates, dispersion measure, rotation measure, redshift, and other +key observables for well-localized FRBs in the repository. + +Overview +======== + +The ``FRB`` class inherits from ``GenericFRB`` and provides methods to: + +* Load FRB data from the repository by name +* Access measured properties (DM, RM, coordinates, error ellipse, etc.) +* Retrieve associated host galaxy information +* Export data to JSON format + +Loading FRBs +============ + +by_name +------- + +The most common way to load an FRB is by its name using the ``by_name()`` class method:: + + from frb.frb import FRB + + # Load FRB by name + frb121102 = FRB.by_name('FRB20121102A') + + # Or without the 'FRB' prefix for older naming + frb180924 = FRB.by_name('FRB20180924B') + + # Print basic info + print(frb180924) + # + +from_json +--------- + +You can also load from a specific JSON file:: + + from frb.frb import FRB + + frb = FRB.from_json('/path/to/FRB20180924B.json') + +Key Attributes +============== + +Once loaded, an FRB object provides access to: + +Coordinates +----------- + +:: + + # SkyCoord object + frb.coord + # + + # Individual components + frb.coord.ra # Right Ascension + frb.coord.dec # Declination + + # Different formats + frb.coord.to_string('hmsdms') + # '21h26m25.26s -40d54m00.11s' + +Dispersion Measure +------------------ + +:: + + # Observed DM (with units) + frb.DM + # + + # DM error (if available) + frb.DM_err + + # ISM contribution from NE2001 + frb.DMISM + +Rotation Measure +---------------- + +:: + + # RM (if measured) + frb.RM + # + + frb.RM_err + +Redshift +-------- + +:: + + # Redshift (if known) + frb.z + # 0.3212 + +Error Ellipse +------------- + +The localization uncertainty is stored in an error ellipse:: + + # Error ellipse dict + frb.eellipse + # {'a': 0.07, 'b': 0.06, 'theta': 0.0, 'cl': 68.0, ...} + + # Combined semi-major axis (statistical + systematic) + frb.sig_a # arcsec + + # Combined semi-minor axis + frb.sig_b # arcsec + +Pulse Properties +---------------- + +:: + + # Pulse properties dict + frb.pulse + # Contains: Wi (intrinsic width), tscatt (scattering time), etc. + +Other Properties +---------------- + +:: + + # FRB name + frb.frb_name + # 'FRB20180924B' + + # Is it a repeater? + frb.repeater + # False + + # References + frb.refs + # ['Bannister2019'] + +Grabbing the Host Galaxy +======================== + +For FRBs with identified host galaxies, use the ``grab_host()`` method:: + + from frb.frb import FRB + + # Load FRB + frb = FRB.by_name('FRB20180924B') + + # Get the host galaxy object + host = frb.grab_host() + + # Access host properties + print(host.z) # Redshift + print(host.derived) # Derived quantities (Mstar, SFR, etc.) + print(host.photom) # Photometry + +See :doc:`frbhost_class` for details on the FRBHost class. + +Listing All FRBs +================ + +To get a list of all FRBs in the repository:: + + from frb.frb import list_of_frbs + + # Get all FRBs + all_frbs = list_of_frbs() + print(f"Total FRBs: {len(all_frbs)}") + + # Only those with redshifts + frbs_with_z = list_of_frbs(require_z=True) + print(f"FRBs with redshift: {len(frbs_with_z)}") + +Building a Table of FRBs +======================== + +The ``build_table_of_frbs()`` function creates a pandas DataFrame +with all FRB properties:: + + from frb.frb import build_table_of_frbs + + # Build the table + frb_tbl, tbl_units = build_table_of_frbs() + + # View basic info + print(frb_tbl.columns.tolist()) + # ['FRB', 'RA', 'DEC', 'ee_a', 'ee_b', ..., 'DM', 'z', 'RM', ...] + + # Check units + print(tbl_units['DM']) + # 'pc / cm3' + + # Filter by DM + high_dm = frb_tbl[frb_tbl['DM'] > 500] + print(f"High DM FRBs: {len(high_dm)}") + + # Get repeaters + repeaters = frb_tbl[frb_tbl['repeater'] == True] + +Default columns include: + +* **FRB**: FRB name +* **RA, DEC**: Coordinates (deg) +* **ee_a, ee_b, ee_theta**: Error ellipse parameters +* **DM, DM_err**: Dispersion measure +* **z**: Redshift +* **RM, RM_err**: Rotation measure +* **DMISM**: Galactic ISM DM contribution +* **fluence**: Burst fluence +* **repeater**: Boolean flag +* **pulse_Wi, pulse_tscatt**: Pulse properties +* **refs**: References + +Creating Custom FRBs +==================== + +You can also create FRB objects for your own data:: + + from frb.frb import FRB + from astropy.coordinates import SkyCoord + from astropy import units as u + + # Create coordinate + coord = SkyCoord(ra=123.456, dec=-45.678, unit='deg') + + # Create FRB object + my_frb = FRB('FRB20230101A', coord, DM=500*u.pc/u.cm**3) + + # Set additional properties + my_frb.z = 0.5 + my_frb.set_ee(a=0.1, b=0.08, theta=45, cl=68) + +Writing to JSON +=============== + +Save an FRB object to a JSON file:: + + frb.write_to_json(outfile='my_frb.json', path='./') + +API Reference +============= + +.. autoclass:: frb.frb.FRB + :members: + :undoc-members: + :show-inheritance: + +.. autofunction:: frb.frb.list_of_frbs + +.. autofunction:: frb.frb.build_table_of_frbs + +See Also +======== + +* :doc:`frbhost_class` - Host galaxy class documentation +* :doc:`database` - Database access utilities +* :doc:`dm` - DM calculations diff --git a/docs/frbhost_class.rst b/docs/frbhost_class.rst new file mode 100644 index 00000000..35d6e6bf --- /dev/null +++ b/docs/frbhost_class.rst @@ -0,0 +1,387 @@ +************** +FRBHost Class +************** + +The ``FRBHost`` class represents the host galaxy of an FRB. It inherits from +``FRBGalaxy`` and stores photometry, redshifts, morphology, nebular line +measurements, and derived physical properties. + +Overview +======== + +The ``FRBHost`` class provides methods to: + +* Load host galaxy data from the repository +* Access photometric measurements and derived quantities +* Calculate nebular properties (SFR, extinction) +* Interface with SED fitting tools (CIGALE, EAZY) +* Retrieve spectra from the specDB archive + +Loading Host Galaxies +===================== + +by_frb +------ + +The recommended way to load a host galaxy is through its associated FRB:: + + from frb.frb import FRB + + # Load the FRB first + frb = FRB.by_name('FRB20180924B') + + # Get the host galaxy + host = frb.grab_host() + + # Print basic info + print(host) + # + +Alternatively, use the ``FRBHost.by_frb()`` class method directly:: + + from frb.frb import FRB + from frb.galaxies.frbgalaxy import FRBHost + + frb = FRB.by_name('FRB20180924B') + host = FRBHost.by_frb(frb) + +from_json +--------- + +Load from a specific JSON file:: + + from frb.frb import FRB + from frb.galaxies.frbgalaxy import FRBHost + + frb = FRB.by_name('FRB20180924B') + host = FRBHost.from_json(frb, '/path/to/FRB20180924B_host.json') + +Key Attributes +============== + +Host galaxies have several attribute dictionaries containing measurements +and derived quantities. + +Coordinates +----------- + +:: + + # Host galaxy coordinates + host.coord + # + + # Associated FRB + host.frb.frb_name + # 'FRB20180924B' + + # Host name + host.name + # 'HG20180924B' + +Redshift +-------- + +:: + + # Best redshift + host.z + # 0.3212 + + # Redshift error + host.z_err + + # Full redshift dict + host.redshift + # {'z': 0.3212, 'z_spec': 0.3212, 'z_FRB': 0.3212} + +Photometry +---------- + +Photometric measurements are stored in the ``photom`` dict:: + + # All photometry + host.photom + # {'SDSS_u': 21.45, 'SDSS_u_err': 0.15, 'SDSS_g': 20.23, ...} + + # Individual bands + host.photom['SDSS_r'] + host.photom['SDSS_r_err'] + + # Fluxes (in mJy) are also stored + host.photom['SDSS_r_flux'] + host.photom['SDSS_r_flux_err'] + +Derived Quantities +------------------ + +Physical properties derived from SED fitting or spectroscopy:: + + # All derived quantities + host.derived + # {'Mstar': 1.2e10, 'Mstar_err': 2e9, 'SFR_photom': 1.5, ...} + + # Stellar mass (solar masses) + host.derived['Mstar'] + + # Star formation rate (Msun/yr) + host.derived['SFR_photom'] # From SED fitting + host.derived['SFR_nebular'] # From emission lines + + # Extinction + host.derived['AV_nebular'] + host.derived['EBV_photom'] + +Nebular Emission Lines +---------------------- + +Emission line fluxes (erg/s/cm^2):: + + # All line measurements + host.neb_lines + # {'Halpha': 1.2e-16, 'Halpha_err': 1e-17, '[OIII] 5007': 5e-17, ...} + + # Individual lines + host.neb_lines['Halpha'] + host.neb_lines['Hbeta'] + host.neb_lines['[NII] 6584'] + +Morphology +---------- + +Galaxy structural parameters (typically from GALFIT):: + + host.morphology + # {'reff_ang': 0.85, 'reff_kpc': 3.2, 'n': 1.5, 'b/a': 0.7, ...} + + # Effective radius + host.morphology['reff_ang'] # arcsec + host.morphology['reff_kpc'] # kpc + + # Sersic index + host.morphology['n'] + +Offsets +------- + +Angular and physical offsets between FRB and host:: + + host.offsets + # {'ang_avg': 0.5, 'ang_best': 0.45, 'physical': 2.1, ...} + + # Physical offset in kpc + host.offsets['physical'] + host.offsets['physical_err'] + +Calculating Derived Quantities +============================== + +Nebular SFR +----------- + +Calculate star formation rate from emission lines:: + + # First calculate extinction (optional but recommended) + host.calc_nebular_AV(method='Ha/Hb') + print(f"AV = {host.derived['AV_nebular']}") + + # Calculate SFR from H-alpha + host.calc_nebular_SFR(method='Ha') + print(f"SFR = {host.derived['SFR_nebular']} Msun/yr") + +Line Luminosities +----------------- + +Calculate emission line luminosities:: + + Lum, Lum_err = host.calc_nebular_lum('Halpha') + print(f"L(Ha) = {Lum}") + +Halo DM +------- + +Calculate the halo contribution to DM:: + + DM_halo = host.calc_dm_halo() + print(f"DM_halo = {DM_halo}") + +Retrieving Spectra +================== + +If spectra are available in the specDB archive:: + + # Get spectrum and metadata + meta, spec = host.get_metaspec() + + # meta is an astropy Table with spectrum info + print(meta) + + # spec is an XSpectrum1D object + spec.wavelength # Wavelength array + spec.flux # Flux array + + # Get all spectra (if multiple exist) + meta, spec = host.get_metaspec(return_all=True) + + # Specify instrument + meta, spec = host.get_metaspec(instr='MUSE') + +Running SED Fitting +=================== + +CIGALE +------ + +Run CIGALE SED fitting directly:: + + host.run_cigale( + data_file='cigale_input.fits', + config_file='pcigale.ini', + wait_for_input=False, + save_sed=True, + plot=True, + outdir='cigale_output/' + ) + +Parse CIGALE results:: + + host.parse_cigale('cigale_output/results.txt') + print(host.derived['Mstar']) + print(host.derived['SFR_photom']) + +Parsing External Results +======================== + +GALFIT +------ + +Parse GALFIT output for morphology:: + + host.parse_galfit('galfit_output.fits') + print(host.morphology['reff_kpc']) + print(host.morphology['n']) + +pPXF +---- + +Parse pPXF spectral fitting results:: + + host.parse_ppxf('ppxf_results.ecsv') + print(host.neb_lines['Halpha']) + +Building a Table of Hosts +========================= + +Create a pandas DataFrame with all host galaxy properties:: + + from frb.galaxies import utils + + # Build the table + host_tbl, tbl_units = utils.build_table_of_hosts() + + # View columns + print(host_tbl.columns.tolist()) + # ['Host', 'FRBname', 'RA_host', 'DEC_host', 'FRBobj', 'Mstar', 'SFR_photom', ...] + + # Filter by stellar mass + massive_hosts = host_tbl[host_tbl['Mstar'] > 1e10] + + # Get hosts with spectroscopic redshifts + spec_z = host_tbl[host_tbl['z_spec'].notna()] + + # Merge with FRB table + from frb.frb import build_table_of_frbs + frb_tbl, _ = build_table_of_frbs() + + import pandas as pd + merged = pd.merge(frb_tbl, host_tbl, left_on='FRB', right_on='FRBname') + +Default columns include data from: + +* **derived**: Mstar, SFR_photom, SFR_nebular, AV_nebular, M_r, etc. +* **photom**: All photometric bands and fluxes +* **neb_lines**: Emission line fluxes +* **offsets**: Angular and physical offsets +* **morphology**: Structural parameters +* **redshift**: z, z_spec, z_phot, z_FRB + +Listing All Hosts +================= + +:: + + from frb.galaxies.utils import list_of_hosts + + # Get all hosts + frbs, hosts = list_of_hosts() + + print(f"Number of hosts: {len(hosts)}") + + # Iterate + for frb, host in zip(frbs, hosts): + print(f"{frb.frb_name}: z={host.z}, Mstar={host.derived.get('Mstar', 'N/A')}") + +Loading PATH Results +==================== + +Load probabilistic association results:: + + from frb.galaxies import utils + + path_tbl = utils.load_PATH() + print(path_tbl.columns) + # ['FRB', 'RA', 'Dec', 'P_Ox', 'P_O', 'ang_size', ...] + +Writing to JSON +=============== + +Save a host galaxy object:: + + host.write_to_json(path='./output/') + # Writes to FRB20180924B_host.json + +Setting Redshifts +================= + +:: + + # Set spectroscopic redshift + host.set_z(0.3212, 'spec', err=0.0001) + + # Set photometric redshift + host.set_z(0.35, 'phot', err=0.05) + +API Reference +============= + +FRBGalaxy (Parent Class) +------------------------ + +.. autoclass:: frb.galaxies.frbgalaxy.FRBGalaxy + :members: + :undoc-members: + :show-inheritance: + +FRBHost Class +------------- + +.. autoclass:: frb.galaxies.frbgalaxy.FRBHost + :members: + :undoc-members: + :show-inheritance: + +Utility Functions +----------------- + +.. autofunction:: frb.galaxies.utils.build_table_of_hosts + +.. autofunction:: frb.galaxies.utils.list_of_hosts + +.. autofunction:: frb.galaxies.utils.load_PATH + +See Also +======== + +* :doc:`frb_class` - FRB class documentation +* :doc:`galaxies` - Galaxy analysis overview +* :doc:`database` - Database utilities diff --git a/docs/index.rst b/docs/index.rst index 2a542de1..6f9349f6 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -15,6 +15,15 @@ Getting Started installing quickstart +Core Classes +------------ + +.. toctree:: + :maxdepth: 2 + + frb_class + frbhost_class + Data ---- diff --git a/docs/nb/FRB_and_Host_Classes.ipynb b/docs/nb/FRB_and_Host_Classes.ipynb new file mode 100644 index 00000000..0e82f828 --- /dev/null +++ b/docs/nb/FRB_and_Host_Classes.ipynb @@ -0,0 +1,625 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Working with FRB and FRBHost Classes\n", + "\n", + "This notebook demonstrates how to use the core FRB and FRBHost classes to access\n", + "FRB data, host galaxy properties, and build tables for population analysis." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Standard imports\n", + "import numpy as np\n", + "import pandas as pd\n", + "import matplotlib.pyplot as plt\n", + "from astropy import units as u\n", + "from astropy.coordinates import SkyCoord" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 1. Loading FRBs\n", + "\n", + "The `FRB` class is the primary object for representing Fast Radio Bursts.\n", + "The easiest way to load an FRB is by name." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from frb.frb import FRB\n", + "\n", + "# Load an FRB by name\n", + "frb = FRB.by_name('FRB20180924B')\n", + "print(frb)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Accessing FRB Properties" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Coordinates\n", + "print(f\"Coordinates: {frb.coord.to_string('hmsdms')}\")\n", + "print(f\"RA: {frb.coord.ra.deg:.4f} deg\")\n", + "print(f\"Dec: {frb.coord.dec.deg:.4f} deg\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Dispersion Measure\n", + "print(f\"DM: {frb.DM}\")\n", + "print(f\"DM ISM (NE2001): {frb.DMISM}\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Redshift and Rotation Measure\n", + "print(f\"Redshift: {frb.z}\")\n", + "print(f\"RM: {frb.RM}\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Error ellipse (localization uncertainty)\n", + "print(\"Error Ellipse:\")\n", + "for key, value in frb.eellipse.items():\n", + " print(f\" {key}: {value}\")\n", + " \n", + "print(f\"\\nCombined semi-major axis: {frb.sig_a} arcsec\")\n", + "print(f\"Combined semi-minor axis: {frb.sig_b} arcsec\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Other properties\n", + "print(f\"FRB Name: {frb.frb_name}\")\n", + "print(f\"Repeater: {frb.repeater}\")\n", + "print(f\"References: {frb.refs}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 2. Loading Host Galaxies\n", + "\n", + "The `FRBHost` class stores host galaxy properties. The easiest way to access it\n", + "is through the FRB object's `grab_host()` method." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Get the host galaxy\n", + "host = frb.grab_host()\n", + "print(host)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Host Galaxy Properties" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Basic info\n", + "print(f\"Host Name: {host.name}\")\n", + "print(f\"Coordinates: {host.coord.to_string('hmsdms')}\")\n", + "print(f\"Redshift: {host.z}\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Redshift information\n", + "print(\"Redshift dict:\")\n", + "for key, value in host.redshift.items():\n", + " print(f\" {key}: {value}\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Offsets between FRB and host\n", + "print(\"Offsets:\")\n", + "for key, value in host.offsets.items():\n", + " if 'ang' in key:\n", + " print(f\" {key}: {value:.3f} arcsec\")\n", + " elif 'physical' in key:\n", + " print(f\" {key}: {value:.2f} kpc\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Derived quantities (from SED fitting, spectroscopy, etc.)\n", + "print(\"Derived quantities:\")\n", + "for key, value in host.derived.items():\n", + " if isinstance(value, float):\n", + " if 'Mstar' in key:\n", + " print(f\" {key}: {value:.2e} Msun\")\n", + " elif 'SFR' in key:\n", + " print(f\" {key}: {value:.2f} Msun/yr\")\n", + " else:\n", + " print(f\" {key}: {value:.3f}\")\n", + " else:\n", + " print(f\" {key}: {value}\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Photometry\n", + "print(\"\\nPhotometry (first 10 entries):\")\n", + "count = 0\n", + "for key, value in host.photom.items():\n", + " if count < 10:\n", + " print(f\" {key}: {value}\")\n", + " count += 1" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Morphology (if available)\n", + "if len(host.morphology) > 0:\n", + " print(\"Morphology:\")\n", + " for key, value in host.morphology.items():\n", + " print(f\" {key}: {value}\")\n", + "else:\n", + " print(\"No morphology data available\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Nebular emission lines (if available)\n", + "if len(host.neb_lines) > 0:\n", + " print(\"Nebular Lines (erg/s/cm^2):\")\n", + " for key, value in host.neb_lines.items():\n", + " print(f\" {key}: {value}\")\n", + "else:\n", + " print(\"No nebular line data available\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 3. Building Tables of FRBs\n", + "\n", + "The `build_table_of_frbs()` function creates a pandas DataFrame containing\n", + "all FRB properties from the repository." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from frb.frb import build_table_of_frbs, list_of_frbs\n", + "\n", + "# Build the FRB table\n", + "frb_tbl, tbl_units = build_table_of_frbs()\n", + "\n", + "print(f\"Total FRBs in repository: {len(frb_tbl)}\")\n", + "print(f\"\\nColumns: {frb_tbl.columns.tolist()}\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# View first few rows\n", + "frb_tbl[['FRB', 'RA', 'DEC', 'DM', 'z', 'repeater']].head(10)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Check units\n", + "print(\"Units:\")\n", + "for col in ['DM', 'RA', 'DEC', 'RM', 'ee_a']:\n", + " if col in tbl_units:\n", + " print(f\" {col}: {tbl_units[col]}\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# FRBs with known redshifts\n", + "frbs_with_z = frb_tbl[frb_tbl['z'].notna()]\n", + "print(f\"FRBs with redshifts: {len(frbs_with_z)}\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Repeaters\n", + "repeaters = frb_tbl[frb_tbl['repeater'] == True]\n", + "print(f\"Repeaters: {len(repeaters)}\")\n", + "print(repeaters['FRB'].values)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# High DM FRBs\n", + "high_dm = frb_tbl[frb_tbl['DM'] > 500]\n", + "print(f\"FRBs with DM > 500: {len(high_dm)}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 4. Building Tables of Host Galaxies\n", + "\n", + "The `build_table_of_hosts()` function creates a pandas DataFrame containing\n", + "all host galaxy properties." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from frb.galaxies import utils as gutils\n", + "\n", + "# Build the host table\n", + "host_tbl, host_units = gutils.build_table_of_hosts()\n", + "\n", + "print(f\"Total host galaxies: {len(host_tbl)}\")\n", + "print(f\"\\nNumber of columns: {len(host_tbl.columns)}\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# View key columns\n", + "key_cols = ['Host', 'FRBname', 'z', 'Mstar', 'SFR_photom']\n", + "available_cols = [c for c in key_cols if c in host_tbl.columns]\n", + "host_tbl[available_cols].head(10)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Hosts with stellar mass measurements\n", + "hosts_with_mass = host_tbl[host_tbl['Mstar'].notna()]\n", + "print(f\"Hosts with Mstar: {len(hosts_with_mass)}\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Massive hosts (log Mstar > 10)\n", + "if 'Mstar' in host_tbl.columns:\n", + " massive = host_tbl[host_tbl['Mstar'] > 1e10]\n", + " print(f\"Hosts with Mstar > 10^10: {len(massive)}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 5. Merging FRB and Host Tables\n", + "\n", + "You can merge the FRB and host tables to create a combined dataset." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Merge tables on FRB name\n", + "merged = pd.merge(frb_tbl, host_tbl, \n", + " left_on='FRB', \n", + " right_on='FRBname', \n", + " how='inner')\n", + "\n", + "print(f\"Merged table rows: {len(merged)}\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# View merged data\n", + "cols = ['FRB', 'DM', 'z_x', 'Mstar']\n", + "available = [c for c in cols if c in merged.columns]\n", + "merged[available].head()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 6. Simple Visualizations" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# DM distribution\n", + "fig, ax = plt.subplots(figsize=(10, 6))\n", + "frb_tbl['DM'].hist(bins=20, ax=ax, edgecolor='black', alpha=0.7)\n", + "ax.set_xlabel('DM (pc/cm$^3$)', fontsize=12)\n", + "ax.set_ylabel('Number of FRBs', fontsize=12)\n", + "ax.set_title('Distribution of FRB Dispersion Measures', fontsize=14)\n", + "plt.tight_layout()\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# DM vs Redshift (Macquart relation)\n", + "frbs_z = frb_tbl[frb_tbl['z'].notna()]\n", + "\n", + "if len(frbs_z) > 0:\n", + " fig, ax = plt.subplots(figsize=(10, 6))\n", + " ax.scatter(frbs_z['z'], frbs_z['DM'], s=50, alpha=0.7)\n", + " ax.set_xlabel('Redshift', fontsize=12)\n", + " ax.set_ylabel('DM (pc/cm$^3$)', fontsize=12)\n", + " ax.set_title('DM vs Redshift for Localized FRBs', fontsize=14)\n", + " plt.tight_layout()\n", + " plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Sky distribution\n", + "fig = plt.figure(figsize=(12, 6))\n", + "ax = fig.add_subplot(111, projection='aitoff')\n", + "\n", + "# Convert to radians for projection\n", + "ra_rad = np.deg2rad(frb_tbl['RA'] - 180) # Center at RA=180\n", + "dec_rad = np.deg2rad(frb_tbl['DEC'])\n", + "\n", + "ax.scatter(ra_rad, dec_rad, s=30, alpha=0.7)\n", + "ax.grid(True)\n", + "ax.set_title('Sky Distribution of FRBs', fontsize=14)\n", + "plt.tight_layout()\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Host stellar mass distribution\n", + "if 'Mstar' in host_tbl.columns:\n", + " mstar = host_tbl['Mstar'].dropna()\n", + " if len(mstar) > 0:\n", + " fig, ax = plt.subplots(figsize=(10, 6))\n", + " ax.hist(np.log10(mstar), bins=15, edgecolor='black', alpha=0.7)\n", + " ax.set_xlabel('log$_{10}$(M$_*$/M$_\\odot$)', fontsize=12)\n", + " ax.set_ylabel('Number of Hosts', fontsize=12)\n", + " ax.set_title('Host Galaxy Stellar Mass Distribution', fontsize=14)\n", + " plt.tight_layout()\n", + " plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 7. Listing All FRBs and Hosts" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# List all FRBs\n", + "all_frbs = list_of_frbs()\n", + "print(f\"Total FRBs in repository: {len(all_frbs)}\")\n", + "\n", + "# List FRBs with redshifts\n", + "frbs_with_z = list_of_frbs(require_z=True)\n", + "print(f\"FRBs with redshifts: {len(frbs_with_z)}\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# List all hosts\n", + "frbs, hosts = gutils.list_of_hosts(verbose=False)\n", + "print(f\"Total host galaxies: {len(hosts)}\")\n", + "\n", + "# Print summary\n", + "for frb_obj, host in zip(frbs[:5], hosts[:5]):\n", + " mstar = host.derived.get('Mstar', 'N/A')\n", + " if isinstance(mstar, float):\n", + " mstar = f\"{mstar:.2e}\"\n", + " print(f\"{frb_obj.frb_name}: z={host.z}, Mstar={mstar}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 8. Loading PATH Results\n", + "\n", + "PATH (Probabilistic Association of Transients to Hosts) results are available\n", + "for many FRBs." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Load PATH table\n", + "path_tbl = gutils.load_PATH()\n", + "print(f\"PATH results available for {len(path_tbl)} FRBs\")\n", + "print(f\"\\nColumns: {path_tbl.columns.tolist()}\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# View PATH results\n", + "path_tbl.head()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Summary\n", + "\n", + "This notebook demonstrated:\n", + "\n", + "1. Loading FRB objects by name using `FRB.by_name()`\n", + "2. Accessing FRB properties (coordinates, DM, RM, z, error ellipse)\n", + "3. Loading host galaxies using `frb.grab_host()`\n", + "4. Accessing host properties (photometry, derived quantities, offsets)\n", + "5. Building population tables with `build_table_of_frbs()` and `build_table_of_hosts()`\n", + "6. Merging FRB and host data for analysis\n", + "7. Simple visualizations of the FRB population\n", + "\n", + "For more details, see:\n", + "- FRB class documentation: `frb_class.rst`\n", + "- FRBHost class documentation: `frbhost_class.rst`" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.0" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/docs/quickstart.rst b/docs/quickstart.rst index 74ae9a73..2877f656 100644 --- a/docs/quickstart.rst +++ b/docs/quickstart.rst @@ -280,10 +280,12 @@ Next Steps Now that you're familiar with the basics: -1. **Read the API Documentation**: Browse :doc:`api/index` for complete function references -2. **Explore Jupyter Notebooks**: Check out the ``docs/nb/`` directory for in-depth examples and tutorials -3. **Learn about Dispersion Measures**: See :doc:`dm` for DM calculation details -4. **Explore Halo Calculations**: See :doc:`halos/index` for halo modeling tools +1. **FRB Class Details**: See :doc:`frb_class` for complete FRB object documentation +2. **Host Galaxy Analysis**: See :doc:`frbhost_class` for working with host galaxies +3. **Read the API Documentation**: Browse :doc:`api/index` for complete function references +4. **Explore Jupyter Notebooks**: Check out the ``docs/nb/`` directory for in-depth examples and tutorials +5. **Learn about Dispersion Measures**: See :doc:`dm` for DM calculation details +6. **Explore Halo Calculations**: See :doc:`halos/index` for halo modeling tools Common Gotchas -------------- diff --git a/readthedocs.yaml b/readthedocs.yaml deleted file mode 100644 index dee3320c..00000000 --- a/readthedocs.yaml +++ /dev/null @@ -1,19 +0,0 @@ -version: 2 - -build: - os: ubuntu-22.04 - tools: - python: "3.11" - -sphinx: - configuration: docs/conf.py - -python: - install: - - method: pip - path: . - - requirements: docs/requirements.txt - -formats: - - pdf - - epub \ No newline at end of file From bc52e3d7117f578f0359148298f0d140d590aa76 Mon Sep 17 00:00:00 2001 From: profxj Date: Sat, 3 Jan 2026 19:23:43 -0800 Subject: [PATCH 21/21] frb cat --- docs/api/index.rst | 28 ++++----- ...FRB_Cat.ipynb => DEPRECATED_FRB_Cat.ipynb} | 0 docs/quickstart.rst | 59 ++++++++----------- 3 files changed, 37 insertions(+), 50 deletions(-) rename docs/nb/{FRB_Cat.ipynb => DEPRECATED_FRB_Cat.ipynb} (100%) diff --git a/docs/api/index.rst b/docs/api/index.rst index f181d2b1..ead1dd14 100644 --- a/docs/api/index.rst +++ b/docs/api/index.rst @@ -62,12 +62,12 @@ Most Common Functions DM_cosmic = igm.DM_cosmic(z=0.5) z_est = igm.z_from_DM(DM_obs) -**Catalogue Access:** +**Building FRB Tables:** .. code-block:: python - from frb.frbcat import FRBCat - cat = FRBCat() + from frb.frb import build_table_of_frbs + frb_tbl, tbl_units = build_table_of_frbs() **Scattering Analysis:** @@ -103,13 +103,13 @@ Core Functions by Category frb.turb_scattering.tau_mist frb.turb_scattering.ne_from_tau_mist -**Catalogue Operations:** +**FRB Tables:** .. autosummary:: :nosignatures: - frb.frbcat.FRBCat - frb.frbcat.FRBCat.load_cat + frb.frb.build_table_of_frbs + frb.frb.list_of_frbs **FRB Objects:** @@ -127,18 +127,14 @@ Class Hierarchy FRB ├── FRB.by_name() - ├── FRB.grab_host() + ├── FRB.grab_host() └── FRB.calc_DM_galaxy() - FRBCat - ├── FRBCat.__init__() - ├── FRBCat.load_cat() - └── FRBCat.filter_by_property() - - HostGalaxy - ├── HostGalaxy.derived - ├── HostGalaxy.get_metaspec() - └── HostGalaxy.properties + FRBHost + ├── FRBHost.by_frb() + ├── FRBHost.derived + ├── FRBHost.photom + └── FRBHost.get_metaspec() Constants and Defaults ---------------------- diff --git a/docs/nb/FRB_Cat.ipynb b/docs/nb/DEPRECATED_FRB_Cat.ipynb similarity index 100% rename from docs/nb/FRB_Cat.ipynb rename to docs/nb/DEPRECATED_FRB_Cat.ipynb diff --git a/docs/quickstart.rst b/docs/quickstart.rst index 2877f656..1fe50853 100644 --- a/docs/quickstart.rst +++ b/docs/quickstart.rst @@ -23,26 +23,30 @@ The most common starting point is loading a known FRB by name: print(f"Dispersion Measure: {frb121102.DM}") print(f"Error ellipse: {frb121102.eellipse}") -Working with Catalogues +Working with FRB Tables ~~~~~~~~~~~~~~~~~~~~~~~ -Load and explore FRB catalogues: +Build and explore tables of FRB data from the repository: .. code-block:: python - from frb.frbcat import FRBCat - - # Load the FRB catalogue - cat = FRBCat() - - # Basic catalogue information - print(f"Number of FRBs: {len(cat.frbcat)}") - print(f"DM range: {cat.frbcat['DM'].min():.1f} - {cat.frbcat['DM'].max():.1f} pc/cm³") - + from frb.frb import build_table_of_frbs, list_of_frbs + + # Build a pandas DataFrame of all FRBs + frb_tbl, tbl_units = build_table_of_frbs() + + # Basic information + print(f"Number of FRBs: {len(frb_tbl)}") + print(f"DM range: {frb_tbl['DM'].min():.1f} - {frb_tbl['DM'].max():.1f} pc/cm³") + # Filter high-DM FRBs - high_dm_frbs = cat.frbcat[cat.frbcat['DM'] > 1000] + high_dm_frbs = frb_tbl[frb_tbl['DM'] > 1000] print(f"High-DM FRBs (>1000): {len(high_dm_frbs)}") + # Get FRBs with known redshifts + frbs_with_z = frb_tbl[frb_tbl['z'].notna()] + print(f"FRBs with redshifts: {len(frbs_with_z)}") + Dispersion Measure Calculations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -151,21 +155,21 @@ Analyze properties of the FRB population: import numpy as np import matplotlib.pyplot as plt - from frb.frbcat import FRBCat - - # Load catalogue - cat = FRBCat() - + from frb.frb import build_table_of_frbs + + # Build table of all FRBs + frb_tbl, tbl_units = build_table_of_frbs() + # Get DM values (remove invalid entries) - dms = cat.frbcat['DM'] + dms = frb_tbl['DM'] valid_dms = dms[dms > 0] - + # Basic statistics print(f"DM Statistics:") print(f" Mean: {np.mean(valid_dms):.1f} pc/cm³") - print(f" Median: {np.median(valid_dms):.1f} pc/cm³") + print(f" Median: {np.median(valid_dms):.1f} pc/cm³") print(f" Range: {np.min(valid_dms):.1f} - {np.max(valid_dms):.1f} pc/cm³") - + # Plot DM distribution plt.figure(figsize=(10, 6)) plt.hist(valid_dms, bins=20, alpha=0.7, edgecolor='black') @@ -262,19 +266,6 @@ You can work with your own FRB data by creating FRB objects: z_est = igm.z_from_DM(DM_value, coord=coord) print(f"Estimated redshift: {z_est:.2f}") -Importing External Catalogues -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. code-block:: python - - from frb.frbcat import FRBCat - - # Load custom catalogue file - custom_cat = FRBCat(frbcat_file='path/to/your/catalogue.csv') - - # Process the data - print(f"Loaded {len(custom_cat.frbcat)} FRBs from custom catalogue") - Next Steps ----------