Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Absorption with cubepy #133

Open
wants to merge 24 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
9bfc005
Merge branch 'pylint_and_flake8' of https://github.com/cosimoNigro/agnpy
pawel21 Nov 26, 2021
3bb4a33
Merge branch 'master' of https://github.com/cosimoNigro/agnpy
pawel21 Feb 3, 2022
a23cab0
calcurate absorption using cubepy
pawel21 Aug 31, 2022
0ca6f70
add set up error to integrate
pawel21 Sep 9, 2022
4b9f0e3
iterate freq to compute tau_blr
pawel21 Sep 20, 2022
be9979a
Merge branch 'master' of https://github.com/cosimoNigro/agnpy into ab…
pawel21 Nov 10, 2022
eff6965
Merge branch 'master' of https://github.com/cosimoNigro/agnpy into ab…
pawel21 Dec 6, 2022
bcd1888
add notebook with absorption in BLR with cubepy
pawel21 Jan 10, 2023
ffdecbe
Merge branch 'master' of https://github.com/cosimoNigro/agnpy into ab…
pawel21 Apr 6, 2023
403a0bb
remove l_size
pawel21 Apr 6, 2023
c0b6cfa
start develop funtion to calcurate absorption over all line for BLR
pawel21 Apr 6, 2023
8e21ba8
added fun to calculate absorption in all BLR lines
pawel21 May 16, 2023
57d67bc
nodified notebook to new function
pawel21 May 16, 2023
7039b98
add test for absorption in BLR with cubepy
pawel21 Apr 26, 2024
dd28724
remove not used parameters
pawel21 Apr 26, 2024
92eb17b
Add more clear explanations for docs string about calc tau in BLR
pawel21 Jun 3, 2024
e75d6d8
Add function to compute inegrand for cubepy
pawel21 Jun 3, 2024
d5b4778
Merge branch 'master' of https://github.com/cosimoNigro/agnpy into ab…
pawel21 Jun 3, 2024
a81e789
Add environment dependencies for cubepy
pawel21 Jun 3, 2024
eeed0a9
Fix environment dependencies
pawel21 Jun 3, 2024
3aabb7c
Check target name during calc tau
pawel21 Jun 3, 2024
e6b73df
Fix problem with cubepy instalion
pawel21 Jun 7, 2024
269eec2
add cubepy requires to setup.py
pawel21 Jun 7, 2024
70b6ef8
work on exmpale notebook
pawel21 Jul 19, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
150 changes: 149 additions & 1 deletion agnpy/absorption/absorption.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,12 @@
x_re_shell_mu_s,
)
from ..utils.conversion import nu_to_epsilon_prime, to_R_g_units
from ..targets import PointSourceBehindJet, SSDisk, SphericalShellBLR, RingDustTorus
from ..targets import PointSourceBehindJet, SSDisk, SphericalShellBLR, RingDustTorus, lines_dictionary
from ..emission_regions import Blob
from ..synchrotron import nu_synch_peak, Synchrotron

import cubepy as cp


__all__ = ["sigma", "Absorption", "ebl_files_dict", "EBL"]

Expand Down Expand Up @@ -443,6 +445,96 @@ def evaluate_tau_blr_mu_s(
)
return (prefactor * integral).to_value("")

@staticmethod
def evaluate_tau_blr_cubepy(
nu,
eps_abs,
z,
mu_s,
L_disk,
xi_line,
epsilon_line,
R_line,
r,
mu=mu_to_integrate,
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the mu and phi arguments are not used in the function, you use directly the default mu_to_integrate and phi_to_integrate

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

phi=phi_to_integrate,
):
"""Evaluates the gamma-gamma absorption produced by a spherical shell
BLR for a general set of model parameters using cubepy

Parameters
----------
nu : :class:`~astropy.units.Quantity`
array of frequencies, in Hz, to compute the tau
**note** these are observed frequencies (observer frame)
z : float
redshift of the source
mu_s : float
cosine of the angle between the blob motion and the jet axis
L_disk : :class:`~astropy.units.Quantity`
Luminosity of the disk whose radiation is being reprocessed by the BLR
xi_line : float
fraction of the disk radiation reprocessed by the BLR
epsilon_line : string
dimensionless energy of the emitted line
R_line : :class:`~astropy.units.Quantity`
radius of the BLR spherical shell
r : :class:`~astropy.units.Quantity`
distance between the Broad Line Region and the blob
mu, phi : :class:`~numpy.ndarray`
arrays of cosine of zenith and azimuth angles to integrate over

Returns
-------
:class:`~astropy.units.Quantity`
array of the tau values corresponding to each frequency
"""
# conversions
epsilon_1 = nu_to_epsilon_prime(nu, z)

def f(x):
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's not a good idea to define a function within another function.
I think the nested function will be recompiled each time the outer function is called. Could you move it outside?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

# mu -> x[0], phi -> x[1], log_l -> x[2]
mu = x[0]
phi = x[1]
log_l = x[2]
l = np.exp(log_l)
mu_star = mu_star_shell(mu, R_line.to_value('cm'), l)
_cos_psi = cos_psi(mu_s, mu_star, phi)
x = x_re_shell(mu, R_line.to_value('cm'), l)
s = epsilon_1 * epsilon_line * (1 - _cos_psi) / 2
integrand = (1 - _cos_psi)*l / x ** 2 * sigma(s).to_value("cm**2")
return integrand

# set boundary for integration
low = np.array(
[
[min(mu_to_integrate)],
[min(phi_to_integrate)],
[np.log(r.to_value('cm'))]
]
)

high = np.array(
[
[max(mu_to_integrate)],
[max(phi_to_integrate)],
[np.log(1e5*r.to_value('cm'))]
jsitarek marked this conversation as resolved.
Show resolved Hide resolved
]
)


prefactor = (L_disk * xi_line) / (
(4 * np.pi) ** 2 * epsilon_line * m_e * c ** 3
)

prefactor = prefactor.to("cm-1")
eps = eps_abs / prefactor.to_value("cm-1")
value, error = cp.integrate(f, low, high, abstol=eps)
integral = value[0]*u.cm
return (prefactor * integral[0]).to_value("")



def tau_blr(self, nu):
"""Evaluates the gamma-gamma absorption produced by a spherical shell
BLR for a general set of model parameters
Expand Down Expand Up @@ -479,6 +571,62 @@ def tau_blr_mu_s(self, nu):
phi=self.phi,
)

def tau_blr_cubepy(self, nu, eps_abs=1e-6):
"""Evaluates the gamma-gamma absorption produced by a spherical shell
BLR for a general set of model parameters with cubepy integration
method
"""

tau_blr_list = []
for freq in nu:
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the problem of using integrators as cubepy, that rely on functions, instead of trapz is that you do not get directly the output as an array but you are forced to loop over each frequency value. Anyhow, I think this is good for the moment.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

true, but since you do not have arrays you have much smaller memory usage, and the integration module automatically selects the points to evaluate the function in an optimal way, so a simple loop over frequencies is a small price to pay :-)

tau_blr_list.append(
self.evaluate_tau_blr_cubepy(
freq,
eps_abs,
self.z,
self.mu_s,
self.target.L_disk,
self.target.xi_line,
self.target.epsilon_line,
self.target.R_line,
self.r,
mu=self.mu,
phi=self.phi,
))
return tau_blr_list

def tau_blr_all_lines_cubepy(self, nu, eps_abs=1e-6):
"""
Calculate the absorption in all available BLR (Broad Line Region) shells.
The radius and luminosity are normalized to Hbeta.

Parameters
----------
nu: numpy array
Frequency array with unit
eps_abs: float, optional
Absolute precision for the calculation, default is 1e-6
"""
SUM_RATIO_LINES_BLR = 30.652
XI_TARGET_LINE = self.target.xi_line
tau_z_all = np.zeros(nu.shape)

blr_shells = dict()
absorption_shells = dict()

for line_key in lines_dictionary.keys():
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am a bit lost with the calculations in this for loop.
Are you assuming that the target is a SphericalShellBLR emitting the Hbeta line? If this is not the case then I have troubles in understanding why you scale radius and luminosity to the current (arbitrary) line.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If, on the other hand, the user has to use the Hbeta line as a target, then this should be stated explicitly somewhere.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hbeta is used as a reference line for radius and luminosity scaling to ensure consistency in calculations for different BLR lines.

xi_line_current = lines_dictionary[line_key]['L_Hbeta_ratio']
xi_line = (xi_line_current * XI_TARGET_LINE) / SUM_RATIO_LINES_BLR
R_line_current = self.target.R_line * lines_dictionary[line_key]['R_Hbeta_ratio']

blr_shells[line_key] = SphericalShellBLR(self.target.L_disk, xi_line, line_key, R_line_current)
absorption_shells[line_key] = Absorption(blr_shells[line_key], r=self.r, z=self.z)

tau_z_current = absorption_shells[line_key].tau_blr_cubepy(nu, eps_abs=eps_abs)
tau_z_all += tau_z_current

return tau_z_all

@staticmethod
def evaluate_tau_dt(
nu,
Expand Down
Loading