-
Notifications
You must be signed in to change notification settings - Fork 194
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
Make jfactor
a parameter for DarkMatter models
#5097
base: main
Are you sure you want to change the base?
Changes from all commits
c06570a
95fefd4
870e051
cbe5aaa
8495cc5
ebab4a6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -219,7 +219,8 @@ | |
massDM = 10 * u.TeV | ||
diff_flux = DarkMatterAnnihilationSpectralModel(mass=massDM, channel=channel) | ||
int_flux = ( | ||
jfact * diff_flux.integral(energy_min=0.1 * u.TeV, energy_max=10 * u.TeV) | ||
jfact.to_value("GeV2 cm-5") | ||
* diff_flux.integral(energy_min=0.1 * u.TeV, energy_max=10 * u.TeV) | ||
).to("cm-2 s-1") | ||
|
||
flux_map = WcsNDMap(geom=geom, data=int_flux.value, unit="cm-2 s-1") | ||
|
@@ -243,7 +244,8 @@ | |
massDM = 10 * u.TeV | ||
diff_flux = DarkMatterDecaySpectralModel(mass=massDM, channel=channel) | ||
int_flux = ( | ||
jfact_decay * diff_flux.integral(energy_min=0.1 * u.TeV, energy_max=10 * u.TeV) | ||
jfact_decay.to_value("GeV cm-2") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Wouldn't it be better to directly rewrite the definition of |
||
* diff_flux.integral(energy_min=0.1 * u.TeV, energy_max=10 * u.TeV) | ||
).to("cm-2 s-1") | ||
|
||
flux_map = WcsNDMap(geom=geom, data=int_flux.value, unit="cm-2 s-1") | ||
|
Original file line number | Diff line number | Diff line change | ||||||
---|---|---|---|---|---|---|---|---|
|
@@ -178,8 +178,7 @@ class DarkMatterAnnihilationSpectralModel(SpectralModel): | |||||||
scale : float | ||||||||
Scale parameter for model fitting. | ||||||||
jfactor : `~astropy.units.Quantity` | ||||||||
Integrated J-Factor needed when `~gammapy.modeling.models.PointSpatialModel` | ||||||||
is used. | ||||||||
Integrated J-Factor for model fitting. | ||||||||
z: float | ||||||||
Redshift value. | ||||||||
k: int | ||||||||
|
@@ -194,8 +193,7 @@ class DarkMatterAnnihilationSpectralModel(SpectralModel): | |||||||
|
||||||||
>>> channel = "b" | ||||||||
>>> massDM = 5000*u.Unit("GeV") | ||||||||
>>> jfactor = 3.41e19 * u.Unit("GeV2 cm-5") | ||||||||
>>> modelDM = DarkMatterAnnihilationSpectralModel(mass=massDM, channel=channel, jfactor=jfactor) # noqa: E501 | ||||||||
>>> modelDM = DarkMatterAnnihilationSpectralModel(mass=massDM, channel=channel) # noqa: E501 | ||||||||
Comment on lines
-197
to
+196
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why removing the jfactor from the example, this pattern should still work no ? |
||||||||
|
||||||||
References | ||||||||
---------- | ||||||||
|
@@ -212,22 +210,28 @@ class DarkMatterAnnihilationSpectralModel(SpectralModel): | |||||||
interp="log", | ||||||||
) | ||||||||
scale._is_norm = True | ||||||||
|
||||||||
jfactor = Parameter( | ||||||||
"jfactor", | ||||||||
1, | ||||||||
unit="GeV2 cm-5", | ||||||||
interp="log", | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
I assume this has to be frozne by default. |
||||||||
) | ||||||||
tag = ["DarkMatterAnnihilationSpectralModel", "dm-annihilation"] | ||||||||
|
||||||||
def __init__(self, mass, channel, scale=scale.quantity, jfactor=1, z=0, k=2): | ||||||||
def __init__(self, mass, channel, scale=scale.quantity, jfactor=jfactor, z=0, k=2): | ||||||||
self.k = k | ||||||||
self.z = z | ||||||||
self.mass = u.Quantity(mass) | ||||||||
self.channel = channel | ||||||||
self.jfactor = u.Quantity(jfactor) | ||||||||
self.primary_flux = PrimaryFlux(mass, channel=self.channel) | ||||||||
super().__init__(scale=scale) | ||||||||
super().__init__(scale=scale, jfactor=jfactor) | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree on all four changes above, along the philosophy of making the |
||||||||
|
||||||||
def evaluate(self, energy, scale): | ||||||||
def evaluate(self, energy, scale, jfactor): | ||||||||
"""Evaluate dark matter annihilation model.""" | ||||||||
flux = ( | ||||||||
scale | ||||||||
* self.jfactor | ||||||||
* jfactor | ||||||||
* self.THERMAL_RELIC_CROSS_SECTION | ||||||||
* self.primary_flux(energy=energy * (1 + self.z)) | ||||||||
/ self.k | ||||||||
|
@@ -242,31 +246,10 @@ def to_dict(self, full_output=False): | |||||||
data = super().to_dict(full_output=full_output) | ||||||||
data["spectral"]["channel"] = self.channel | ||||||||
data["spectral"]["mass"] = self.mass.to_string() | ||||||||
data["spectral"]["jfactor"] = self.jfactor.to_string() | ||||||||
data["spectral"]["z"] = self.z | ||||||||
data["spectral"]["k"] = self.k | ||||||||
return data | ||||||||
|
||||||||
@classmethod | ||||||||
def from_dict(cls, data): | ||||||||
"""Create spectral model from a dictionary. | ||||||||
|
||||||||
Parameters | ||||||||
---------- | ||||||||
data : dict | ||||||||
Dictionary with model data. | ||||||||
|
||||||||
Returns | ||||||||
------- | ||||||||
model : `DarkMatterAnnihilationSpectralModel` | ||||||||
Dark matter annihilation spectral model. | ||||||||
""" | ||||||||
data = data["spectral"] | ||||||||
data.pop("type") | ||||||||
parameters = data.pop("parameters") | ||||||||
scale = [p["value"] for p in parameters if p["name"] == "scale"][0] | ||||||||
return cls(scale=scale, **data) | ||||||||
|
||||||||
|
||||||||
class DarkMatterDecaySpectralModel(SpectralModel): | ||||||||
r"""Dark matter decay spectral model. | ||||||||
|
@@ -276,7 +259,7 @@ class DarkMatterDecaySpectralModel(SpectralModel): | |||||||
.. math:: | ||||||||
\frac{\mathrm d \phi}{\mathrm d E} = | ||||||||
\frac{\Gamma}{4\pi m_{\mathrm{DM}}} | ||||||||
\frac{\mathrm d N}{\mathrm dE} \times J(\Delta\Omega) | ||||||||
\frac{\mathrm d N}{\mathrm dE} \times D(\Delta\Omega) | ||||||||
|
||||||||
Parameters | ||||||||
---------- | ||||||||
|
@@ -287,23 +270,21 @@ class DarkMatterDecaySpectralModel(SpectralModel): | |||||||
See `PrimaryFlux.channel_registry` for more. | ||||||||
scale : float | ||||||||
Scale parameter for model fitting | ||||||||
jfactor : `~astropy.units.Quantity` | ||||||||
Integrated J-Factor needed when `~gammapy.modeling.models.PointSpatialModel` | ||||||||
is used. | ||||||||
dfactor : `~astropy.units.Quantity` | ||||||||
Integrated D-Factor for model fitting. | ||||||||
z: float | ||||||||
Redshift value. | ||||||||
|
||||||||
Examples | ||||||||
-------- | ||||||||
This is how to instantiate a `DarkMatterAnnihilationSpectralModel` model:: | ||||||||
This is how to instantiate a `DarkMatterDecaySpectralModel` model:: | ||||||||
|
||||||||
>>> import astropy.units as u | ||||||||
>>> from gammapy.astro.darkmatter import DarkMatterDecaySpectralModel | ||||||||
|
||||||||
>>> channel = "b" | ||||||||
>>> massDM = 5000*u.Unit("GeV") | ||||||||
>>> jfactor = 3.41e19 * u.Unit("GeV cm-2") | ||||||||
>>> modelDM = DarkMatterDecaySpectralModel(mass=massDM, channel=channel, jfactor=jfactor) # noqa: E501 | ||||||||
>>> modelDM = DarkMatterDecaySpectralModel(mass=massDM, channel=channel) # noqa: E501 | ||||||||
Comment on lines
-305
to
+287
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same here why removing the jfactor from the example ? this pattern should still work |
||||||||
|
||||||||
References | ||||||||
---------- | ||||||||
|
@@ -321,21 +302,27 @@ class DarkMatterDecaySpectralModel(SpectralModel): | |||||||
) | ||||||||
scale._is_norm = True | ||||||||
|
||||||||
dfactor = Parameter( | ||||||||
"dfactor", | ||||||||
1, | ||||||||
unit="GeV cm-2", | ||||||||
interp="log", | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||
) | ||||||||
|
||||||||
tag = ["DarkMatterDecaySpectralModel", "dm-decay"] | ||||||||
|
||||||||
def __init__(self, mass, channel, scale=scale.quantity, jfactor=1, z=0): | ||||||||
def __init__(self, mass, channel, scale=scale.quantity, dfactor=dfactor, z=0): | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The mass could be a parameter frozen by default, but it could be done in a separate PR. |
||||||||
self.z = z | ||||||||
self.mass = u.Quantity(mass) | ||||||||
self.channel = channel | ||||||||
self.jfactor = u.Quantity(jfactor) | ||||||||
self.primary_flux = PrimaryFlux(mass, channel=self.channel) | ||||||||
super().__init__(scale=scale) | ||||||||
super().__init__(scale=scale, dfactor=dfactor) | ||||||||
|
||||||||
def evaluate(self, energy, scale): | ||||||||
def evaluate(self, energy, scale, dfactor): | ||||||||
"""Evaluate dark matter decay model.""" | ||||||||
flux = ( | ||||||||
scale | ||||||||
* self.jfactor | ||||||||
* dfactor | ||||||||
* self.primary_flux(energy=energy * (1 + self.z)) | ||||||||
/ self.LIFETIME_AGE_OF_UNIVERSE | ||||||||
/ self.mass | ||||||||
|
@@ -347,26 +334,5 @@ def to_dict(self, full_output=False): | |||||||
data = super().to_dict(full_output=full_output) | ||||||||
data["spectral"]["channel"] = self.channel | ||||||||
data["spectral"]["mass"] = self.mass.to_string() | ||||||||
data["spectral"]["jfactor"] = self.jfactor.to_string() | ||||||||
data["spectral"]["z"] = self.z | ||||||||
return data | ||||||||
|
||||||||
@classmethod | ||||||||
def from_dict(cls, data): | ||||||||
"""Create spectral model from dictionary. | ||||||||
|
||||||||
Parameters | ||||||||
---------- | ||||||||
data : dict | ||||||||
Dictionary with model data. | ||||||||
|
||||||||
Returns | ||||||||
------- | ||||||||
model : `DarkMatterDecaySpectralModel` | ||||||||
Dark matter decay spectral model. | ||||||||
""" | ||||||||
data = data["spectral"] | ||||||||
data.pop("type") | ||||||||
parameters = data.pop("parameters") | ||||||||
scale = [p["value"] for p in parameters if p["name"] == "scale"][0] | ||||||||
return cls(scale=scale, **data) |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -279,6 +279,10 @@ def from_dict(cls, data, **kwargs): | |
data["parameters"], cls.default_parameters | ||
) | ||
|
||
for key in data.keys(): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How does this replace other There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It applies only to DM models. |
||
if key not in ["type", "parameters"] and key not in kwargs: | ||
kwargs[key] = data[key] | ||
|
||
return cls.from_parameters(parameters, **kwargs) | ||
|
||
def __str__(self): | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @StFroese, thanks a lot for all your work on this! I'm going to comment on the changes you've made.
The purpose of adding this
to_value()
here is just to write the Jfactor units explicitly, isn't it? It would not be needed because thejfact
units are already GeV2 cm-5, am I right? Anyway, I think it is ok.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it is needed because the change of default unit in
jfactor
changes the dimensionality ofdiff_flux
.