sfhdelayed.py 4.58 KB
Newer Older
1
# -*- coding: utf-8 -*-
2
# Copyright (C) 2013 Centre de données Astrophysiques de Marseille
3
# Copyright (C) 2014, 2016 Laboratoire d'Astrophysique de Marseille
4
# Copyright (C) 2014 University of Cambridge
5
# Copyright (C) 2018 Universidad de Antofagasta
6
7
8
# Licensed under the CeCILL-v2 licence - see Licence_CeCILL_V2-en.txt

"""
9
10
Delayed tau model for star formation history with an optional exponential burst
===============================================================================
11
12

This module implements a star formation history (SFH) described as a delayed
13
14
15
rise of the SFR up to a maximum, followed by an exponential decrease. Optionally
a decreasing exponential burst can be added to model a recent episode of star
formation.
16
17
18

"""

19
from collections import OrderedDict
20

21
import numpy as np
22

23
from . import SedModule
24

25

26
class SFHDelayed(SedModule):
27
28
    """Delayed tau model for Star Formation History with an optionally
    exponential burst.
29
30

    This module sets the SED star formation history (SFH) proportional to time,
31
32
33
    with a declining exponential parametrised with a time-scale τ. Optionally
    an exp(-t_/τ_burst) component can be added to model the latest episode of
    star formation.
34
35
36

    """

37
    parameter_list = OrderedDict([
38
        ("tau_main", (
39
            "cigale_list()",
40
            "e-folding time of the main stellar population model in Myr.",
41
            2000.
42
        )),
43
        ("age_main", (
44
            "cigale_list(dtype=int, minvalue=0.)",
45
46
            "Age of the main stellar population in the galaxy in Myr. The "
            "precision is 1 Myr.",
47
            5000
Denis's avatar
Denis committed
48
        )),
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
        ("tau_burst", (
            "cigale_list()",
            "e-folding time of the late starburst population model in Myr.",
            50.
        )),
        ("age_burst", (
            "cigale_list(dtype=int, minvalue=1.)",
            "Age of the late burst in Myr. The precision is 1 Myr.",
            20
        )),
        ("f_burst", (
            "cigale_list(minvalue=0., maxvalue=0.9999)",
            "Mass fraction of the late burst population.",
            0.
        )),
Médéric Boquien's avatar
Médéric Boquien committed
64
        ("sfr_A", (
65
            "cigale_list(minvalue=0.)",
66
67
            "Multiplicative factor controlling the SFR if normalise is False. "
            "For instance without any burst: SFR(t)=sfr_A×t×exp(-t/τ)/τ²",
68
69
70
            1.
        )),
        ("normalise", (
71
            "boolean()",
72
            "Normalise the SFH to produce one solar mass.",
73
            True
74
        )),
Médéric Boquien's avatar
Médéric Boquien committed
75
    ])
76

77
78
    def _init_code(self):
        self.tau_main = float(self.parameters["tau_main"])
79
        self.age_main = int(self.parameters["age_main"])
80
81
82
        self.tau_burst = float(self.parameters["tau_burst"])
        self.age_burst = int(self.parameters["age_burst"])
        self.f_burst = float(self.parameters["f_burst"])
83
        sfr_A = float(self.parameters["sfr_A"])
84
85
86
87
        if type(self.parameters["normalise"]) is str:
            normalise = self.parameters["normalise"].lower() == 'true'
        else:
            normalise = bool(self.parameters["normalise"])
88

89
        # Time grid for each component
90
        t = np.arange(self.age_main)
91
        t_burst = np.arange(self.age_burst)
92

93
94
95
96
97
98
99
100
101
102
103
104
105
106
        # SFR for each component
        self.sfr = t * np.exp(-t / self.tau_main) / self.tau_main**2
        sfr_burst = np.exp(-t_burst / self.tau_burst)

        # Height of the late burst to have the desired produced mass fraction
        sfr_burst *= (self.f_burst / (1.-self.f_burst) * np.sum(self.sfr) /
                      np.sum(sfr_burst))

        # We add the age burst exponential for ages superior to age_main -
        # age_burst
        self.sfr[-(t_burst[-1]+1):] += sfr_burst

        # Compute the integral of the SFH and normalise it to 1 solar mass
        # if asked to.
107
        self.sfr_integrated = np.sum(self.sfr) * 1e6
108
        if normalise:
109
110
            self.sfr /= self.sfr_integrated
            self.sfr_integrated = 1.
111
        else:
112
113
114
115
116
117
118
119
120
121
            self.sfr *= sfr_A
            self.sfr_integrated *= sfr_A

    def process(self, sed):
        """
        Parameters
        ----------
        sed : pcigale.sed.SED object

        """
122

123
124
125
        sed.add_module(self.name, self.parameters)

        # Add the sfh and the output parameters to the SED.
126
        sed.sfh = self.sfr
127
        sed.add_info("sfh.integrated", self.sfr_integrated, True)
128
        sed.add_info("sfh.age_main", self.age_main)
129
        sed.add_info("sfh.tau_main", self.tau_main)
130
131
132
        sed.add_info("sfh.age_burst", self.age_burst)
        sed.add_info("sfh.tau_burst", self.tau_burst)
        sed.add_info("sfh.f_burst", self.f_burst)
133

134
# SedModule to be returned by get_module
135
Module = SFHDelayed