Skip to main content

Radiative transfer and mass analysis for planetesimal formation simulations

Project description

Documentation Status GPLv3 License

protoRT

This is an open-source Python-based toolkit for radiative transfer and mass analysis in numerical simulations of planetesimal formation. It computes the optical depth, outgoing intensity, and the mass excess due to optically thick regions in dust-rich environments. This code was used to research the mass budget problem in protoplanetary disks, see Godines et al. 2025.

Installation

    $ pip install protoRT

Documentation

For technical details and examples of how to implement this program for numerical simulation analysis, check out our Documentation.

Getting Started

The code provides three main functionalities: Protoplanetary disk modeling, dust opacity calculations using DSHARP opacities (supports mono and polydisperse models), and the main class RadiativeTransferCube which conducts the radiative transfer, computing the optical depth, intensities, and resulting mass excess when optically thin emission is assumed.

To get started, a test dataset from a single-species streaming instability simulation without self-gravity, from Yang & Johansen (2014), is provided and automatically loaded if no data is input. This is a shearing box with a cubic domain, taken at orbit 100. The data will be loaded alongside the corresponding 1D coordinate axis array, in units of gas scale height.

from protoRT import rtcube

cube = rtcube.RadiativeTransferCube()
module_import

By default the class is initiated with a gas column density of 10 (g/cm²), a temperature of 30 (K), a gas scale height of 5 (au), and a stokes number of 0.3. The radiative transfer is also conducted at the 1 mm wavelength. There are a variety of simulation and model parameters to consider when using your own data, although note that a lot of these arguments are only required if analyzing multi-species simulations, with some others that are only necessary if the simulation is self-gravitating. Review the API documention for parameter details.

The configure class method will convert the simulation into physical units (cgs) and run through all the relevant calculations in order to perform the radiation transfer at the specified wavelength and compute the mass excess. When no opacities are input, the code will use the DSHARP opacities included in the compute_opacities module. When using the DSHARP opacities, ensure that the internal dust density of the dust grains (grain_rho) is the default value of 1.675 (g/cm³) to be consistent with the DSHARP dust model.

cube.configure()

Executing this method will automatically assign all of the relevant attributes including the optical depth at the output plane (tau), the corresponding intensity map (intensity), as well as the filling_factor, mass_excess, and the mass of each planetesimal in the simulation (proto_mass), if applicable.

import numpy as np
import pylab as plt

fig, axes = plt.subplots(1, 2, figsize=(12, 5))
extent = [cube.axis[0], cube.axis[-1], cube.axis[0], cube.axis[-1]]

# Plot optical depth with robust scaling
med_tau = np.median(cube.tau)
std_tau = np.median(np.abs(cube.tau - med_tau))
vmin_tau, vmax_tau = med_tau - 3 * std_tau, med_tau + 10 * std_tau
im0 = axes[0].imshow(cube.tau, vmin=vmin_tau, vmax=vmax_tau, cmap='viridis', extent=extent, origin='lower', aspect='equal')
axes[0].set_title('Optical Depth', fontsize=18)
axes[0].set_xlabel(r'$x/H$', fontsize=16)
axes[0].set_ylabel(r'$y/H$', fontsize=16)
cbar0 = plt.colorbar(im0, ax=axes[0], fraction=0.046, pad=0.04)
cbar0.set_label(r'$\tau_{1.0\,\mathrm{mm}}^{\mathrm{eff}}$', fontsize=14)

# Plot intensity with robust scaling
med_int = np.median(cube.intensity)
std_int = np.median(np.abs(cube.intensity - med_int))
vmin_int, vmax_int = med_int - 3 * std_int, med_int + 10 * std_int
im1 = axes[1].imshow(cube.intensity, vmin=vmin_int, vmax=vmax_int, cmap='inferno', extent=extent, origin='lower', aspect='equal')
axes[1].set_title('Outgoing Intensity', fontsize=18)
axes[1].set_xlabel(r'$x/H$', fontsize=16)
axes[1].set_ylabel(r'$y/H$', fontsize=16)
cbar1 = plt.colorbar(im1, ax=axes[1], fraction=0.046, pad=0.04)
cbar1.set_label(r'$I_{1.0\,\mathrm{mm}} \, (\mathrm{erg}~\mathrm{s}^{-1}~\mathrm{cm}^{-2}~\mathrm{Hz}^{-1}~\mathrm{sr}^{-1})$', fontsize=14)

fig.suptitle(f'RT Results (Absorption Only): Mass Excess = {float(cube.mass_excess):.3f}, Filling Factor = {float(cube.filling_factor):.3f}', fontsize=18)
plt.tight_layout()
plt.show()

tau_intensity_abs_only

By default the scattering opacities are not considered in the radiative transfer, this is controlled via the include_scattering argument. The following shows the same analysis but with scattering.

IMPORTANT: The data cube is converted from code to physical units during the configuration, and is overwritten. As such, do not re-configure multiple times, instead re-instantiate the class object.

cube = rtcube.RadiativeTransferCube(include_scattering=True)
cube.configure() 

# Plot
fig, axes = plt.subplots(1, 2, figsize=(12, 5))
extent = [cube.axis[0], cube.axis[-1], cube.axis[0], cube.axis[-1]]

# Plot optical depth with robust scaling
med_tau = np.median(cube.tau)
std_tau = np.median(np.abs(cube.tau - med_tau))
vmin_tau, vmax_tau = med_tau - 3 * std_tau, med_tau + 10 * std_tau
im0 = axes[0].imshow(cube.tau, vmin=vmin_tau, vmax=vmax_tau, cmap='viridis', extent=extent, origin='lower', aspect='equal')
axes[0].set_title('Optical Depth', fontsize=18)
axes[0].set_xlabel(r'$x/H$', fontsize=16)
axes[0].set_ylabel(r'$y/H$', fontsize=16)
cbar0 = plt.colorbar(im0, ax=axes[0], fraction=0.046, pad=0.04)
cbar0.set_label(r'$\tau_{1.0\,\mathrm{mm}}^{\mathrm{eff}}$', fontsize=14)

# Plot intensity with robust scaling
med_int = np.median(cube.intensity)
std_int = np.median(np.abs(cube.intensity - med_int))
vmin_int, vmax_int = med_int - 3 * std_int, med_int + 10 * std_int
im1 = axes[1].imshow(cube.intensity, vmin=vmin_int, vmax=vmax_int, cmap='inferno', extent=extent, origin='lower', aspect='equal')
axes[1].set_title('Outgoing Intensity', fontsize=18)
axes[1].set_xlabel(r'$x/H$', fontsize=16)
axes[1].set_ylabel(r'$y/H$', fontsize=16)
cbar1 = plt.colorbar(im1, ax=axes[1], fraction=0.046, pad=0.04)
cbar1.set_label(r'$I_{1.0\,\mathrm{mm}} \, (\mathrm{erg}~\mathrm{s}^{-1}~\mathrm{cm}^{-2}~\mathrm{Hz}^{-1}~\mathrm{sr}^{-1})$', fontsize=14)

fig.suptitle(f'RT Results (Absorption + Scattering): Mass Excess = {float(cube.mass_excess):.3f}, Filling Factor = {float(cube.filling_factor):.3f}', fontsize=18)
plt.tight_layout()
plt.show()

tau_intensity_abs_and_sca

In this example we can see that scattering effects further suppress the emergent intensity and increase the mass excess and filling factor by approximately 16% and 13%, respectively.

To learn how to use the code, please review the following page which details how the program was used in Godines et al. 2025, which employed multi-species simulations with self-gravity, at three locations in the disk.

Citation

If you use this program in publication, we would appreciate citations to the paper, Godines et al. 2025.

How to Contribute?

Want to contribute? Bug detections? Comments? Suggestions? Please email us : godines@nmsu.edu, wlyra@nmsu.edu

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

protort-1.0.tar.gz (5.9 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

protort-1.0-py3-none-any.whl (5.9 MB view details)

Uploaded Python 3

File details

Details for the file protort-1.0.tar.gz.

File metadata

  • Download URL: protort-1.0.tar.gz
  • Upload date:
  • Size: 5.9 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.9.11

File hashes

Hashes for protort-1.0.tar.gz
Algorithm Hash digest
SHA256 00b8aa2493335259000107a5c69228238e499676e309bc6fd3444fcaa015131f
MD5 6977096a4f0e2461531f22486f574fcc
BLAKE2b-256 45a1cd55f618b52ed828704b9d19b2a1622764cdcd2c591a06ed0e91f397822a

See more details on using hashes here.

File details

Details for the file protort-1.0-py3-none-any.whl.

File metadata

  • Download URL: protort-1.0-py3-none-any.whl
  • Upload date:
  • Size: 5.9 MB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.9.11

File hashes

Hashes for protort-1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 52f9df1d1312b971d2fb7e7de5460ed9c23e4dcdadf03aa25cc82e50f4229f69
MD5 647fe5ed7b05ce1c6d95047e081ded46
BLAKE2b-256 38c380640ab53da6c7e14e2b5562e833b1e2303f797ec31aa2b50c3587626074

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page