예제 #1
0
    def estimate_init(obs_x, obs_y, param_info):
        """
        Estimate and return updated starting point in param_info based on the input spectrum.

        Parameters
        ----------
        obs_x and obs_y: np.array
            input spectrum

        param_info: tuple of dics
            The dictonaries contain info for each type of component.
        """

        # simple linear interpolation function for spectrum
        sp = interpolate.interp1d(obs_x, obs_y)

        # guess starting point of bb
        for i, (fix, temp) in enumerate(
                zip(param_info[0]["amps_fixed"], param_info[0]["temps"])):

            if (fix is False) & (
                    temp >= 2500
            ):  # stellar comoponent is defined by BB that has T>=2500 K
                bb = BlackBody1D(1, temp)
                if min(obs_x) < 5:
                    lam = min(obs_x) + 0.1  # the wavelength used to compare
                else:  # if min(obs_x) > 5, use 5.5 um
                    lam = 5.5
                amp_guess = sp(lam) / bb(lam)
                param_info[0]["amps"][i] = amp_guess

            elif fix is False:
                fmax_lam = 2898.0 / temp
                bb = BlackBody1D(1, temp)
                if (fmax_lam >= min(obs_x)) & (fmax_lam <= max(obs_x)):
                    lam = fmax_lam
                    amp_guess = sp(lam) / bb(lam) * 0.2
                elif fmax_lam > max(obs_x):
                    lam = max(obs_x)
                    amp_guess = obs_y[np.argmax(obs_x)] / bb(lam) * 0.2
                else:
                    lam = min(obs_x)
                    amp_guess = obs_y[np.argmin(obs_x)] / bb(lam) * 0.2
                param_info[0]["amps"][i] = amp_guess
            else:
                pass

        # guess starting point of dust features and lines
        # set to half of the median (non-negative) intensity of the entire input spectrum

        # dust (1), h2 (2), and ion (3)
        for j in range(1, 4):
            if param_info[j] is not None:
                for i, fix in enumerate(param_info[j]["amps_fixed"]):
                    if fix is False:
                        amp_guess = 0.5 * np.median(obs_y)
                        param_info[j]["amps"][i] = amp_guess

        return param_info
예제 #2
0
    def __init__(self, bb_info, dust_features, h2_features, ion_features):
        """
        Setup a variant based on inputs.  Generates an astropy.modeling
        compound model.

        Notes
        -----
        Would be great to rename the parameters such that they uniquely
        identify the component (dust, gas, specific line, etc.).  This is
        possible - say a discussion on the stsci slack channel - James Davies?
        """
        model_comps = []
        self.bb_info = bb_info
        if bb_info is not None:
            amps = bb_info['amps']
            temps = bb_info['temps']
            amps_limits = bb_info['amps_limits']
            n_bb = len(amps)
            cont_model = BlackBody1D(temperature=temps[0],
                                     amplitude=amps[0],
                                     fixed={'temperature': True})
            cont_model.amplitude.bounds = amps_limits[0]
            for k in range(1, n_bb):
                new_model = BlackBody1D(temperature=temps[k],
                                        amplitude=amps[k],
                                        fixed={'temperature': True})
                new_model.amplitude.bounds = amps_limits[k]
                cont_model = cont_model + new_model

            self.cont_model = cont_model
            model_comps.append(cont_model)

        # dust features should be a Drude profile
        self.dust_features = dust_features
        if dust_features is not None:
            amps = dust_features['amps']
            x_0 = dust_features['x_0']
            fwhms = dust_features['fwhms']
            amps_limits = dust_features['amps_limits']
            x_0_limits = dust_features['x_0_limits']
            fwhms_limits = dust_features['fwhms_limits']
            n_df = len(amps)
            df_model = Drude1D(amplitude=amps[0],
                               x_0=x_0[0],
                               fwhm=fwhms[0],
                               bounds={
                                   'amplitude': amps_limits[0],
                                   'x_0': x_0_limits[0],
                                   'fwhm': fwhms_limits[0]
                               })
            for k in range(1, n_df):
                df_model = df_model + Drude1D(amplitude=amps[k],
                                              x_0=x_0[k],
                                              fwhm=fwhms[k],
                                              bounds={
                                                  'amplitude': amps_limits[k],
                                                  'x_0': x_0_limits[k],
                                                  'fwhm': fwhms_limits[k]
                                              })

            self.df_model = df_model
            model_comps.append(df_model)

        self.h2_features = h2_features
        if h2_features is not None:
            amps = h2_features['amps']
            x_0 = h2_features['x_0']
            fwhms = h2_features['fwhms']
            amps_limits = h2_features['amps_limits']
            x_0_limits = h2_features['x_0_limits']
            fwhms_limits = h2_features['fwhms_limits']
            names = h2_features['names']
            n_h2 = len(amps)
            h2_model = Gaussian1D(name=names[0],
                                  amplitude=amps[0],
                                  mean=x_0[0],
                                  stddev=fwhms[0] / 2.355,
                                  bounds={
                                      'amplitude':
                                      amps_limits[0],
                                      'x_0':
                                      x_0_limits[0],
                                      'stddev': (fwhms_limits[0][0] / 2.355,
                                                 fwhms_limits[0][1] / 2.355)
                                  })
            for k in range(1, n_h2):
                h2_model = h2_model + Gaussian1D(
                    name=names[k],
                    amplitude=amps[k],
                    mean=x_0[k],
                    stddev=fwhms[k] / 2.355,
                    bounds={
                        'amplitude':
                        amps_limits[k],
                        'x_0':
                        x_0_limits[k],
                        'stddev': (fwhms_limits[k][0] / 2.355,
                                   fwhms_limits[k][1] / 2.355)
                    })

            self.h2_model = h2_model
            model_comps.append(h2_model)

        self.ion_features = ion_features
        if ion_features is not None:
            amps = ion_features['amps']
            x_0 = ion_features['x_0']
            fwhms = ion_features['fwhms']
            amps_limits = ion_features['amps_limits']
            x_0_limits = ion_features['x_0_limits']
            fwhms_limits = ion_features['fwhms_limits']
            names = ion_features['names']
            n_ion = len(amps)
            ion_model = Gaussian1D(name=names[0],
                                   amplitude=amps[0],
                                   mean=x_0[0],
                                   stddev=fwhms[0] / 2.355,
                                   bounds={
                                       'amplitude':
                                       amps_limits[0],
                                       'x_0':
                                       x_0_limits[0],
                                       'stddev': (fwhms_limits[0][0] / 2.355,
                                                  fwhms_limits[0][1] / 2.355)
                                   })
            for k in range(1, n_ion):
                ion_model = ion_model + Gaussian1D(
                    name=names[k],
                    amplitude=amps[k],
                    mean=x_0[k],
                    stddev=fwhms[k] / 2.355,
                    bounds={
                        'amplitude':
                        amps_limits[k],
                        'x_0':
                        x_0_limits[k],
                        'stddev': (fwhms_limits[k][0] / 2.355,
                                   fwhms_limits[k][1] / 2.355)
                    })
            self.ion_model = ion_model
            model_comps.append(ion_model)

        self.model = model_comps[0]
        for cmodel in model_comps[1:]:
            self.model += cmodel

        # need to make the type of attenuation model a passed variable
        self.model *= S07_attenuation()
예제 #3
0
파일: base.py 프로젝트: kxxdhdn/pahfit
    def __init__(self, param_info=None, filename=None, tformat=None):
        """
        Setup a variant based on inputs.  Generates an astropy.modeling
        compound model.
        """
        # check that param_info or filename is set
        if filename is None and param_info is None:
            raise ValueError('Either param_info or filename need to be set \
                             when initializing a PAHFITBase object')

        # read in the parameter info from a file
        if filename is not None:
            param_info = self.read(filename, tformat=tformat)

        bb_info = param_info[0]
        dust_features = param_info[1]
        h2_features = param_info[2]
        ion_features = param_info[3]
        att_info = param_info[4]

        # setup the model
        self.bb_info = bb_info
        if bb_info is not None:
            # 1st component defines the overall model variable
            self.model = BlackBody1D(name=bb_info['names'][0],
                                     temperature=bb_info['temps'][0],
                                     amplitude=bb_info['amps'][0],
                                     bounds={
                                         'temperature':
                                         bb_info['temps_limits'][0],
                                         'amplitude': bb_info['amps_limits'][0]
                                     },
                                     fixed={
                                         'temperature':
                                         bb_info['temps_fixed'][0],
                                         'amplitude': bb_info['amps_fixed'][0]
                                     })
            for k in range(1, len(bb_info['names'])):
                self.model += BlackBody1D(name=bb_info['names'][k],
                                          temperature=bb_info['temps'][k],
                                          amplitude=bb_info['amps'][k],
                                          bounds={
                                              'temperature':
                                              bb_info['temps_limits'][k],
                                              'amplitude':
                                              bb_info['amps_limits'][k]
                                          },
                                          fixed={
                                              'temperature':
                                              bb_info['temps_fixed'][k],
                                              'amplitude':
                                              bb_info['amps_fixed'][k]
                                          })

        self.dust_features = dust_features
        if dust_features is not None:
            for k in range(len(dust_features['names'])):
                self.model += Drude1D(name=dust_features['names'][k],
                                      amplitude=dust_features['amps'][k],
                                      x_0=dust_features['x_0'][k],
                                      fwhm=dust_features['fwhms'][k],
                                      bounds={
                                          'amplitude':
                                          dust_features['amps_limits'][k],
                                          'x_0':
                                          dust_features['x_0_limits'][k],
                                          'fwhm':
                                          dust_features['fwhms_limits'][k]
                                      },
                                      fixed={
                                          'amplitude':
                                          dust_features['amps_fixed'][k],
                                          'x_0':
                                          dust_features['x_0_fixed'][k],
                                          'stddev':
                                          dust_features['fwhms_fixed'][k]
                                      })

        self.h2_features = h2_features
        if h2_features is not None:
            for k in range(len(h2_features['names'])):
                self.model += Gaussian1D(
                    name=h2_features['names'][k],
                    amplitude=h2_features['amps'][k],
                    mean=h2_features['x_0'][k],
                    stddev=h2_features['fwhms'][k] / 2.355,
                    bounds={
                        'amplitude':
                        h2_features['amps_limits'][k],
                        'mean':
                        h2_features['x_0_limits'][k],
                        'stddev': (h2_features['fwhms_limits'][k][0] / 2.355,
                                   h2_features['fwhms_limits'][k][1] / 2.355)
                    },
                    fixed={
                        'amplitude': h2_features['amps_fixed'][k],
                        'mean': h2_features['x_0_fixed'][k],
                        'stddev': h2_features['fwhms_fixed'][k]
                    })

        self.ion_features = ion_features
        if ion_features is not None:
            for k in range(len(ion_features['names'])):
                self.model += Gaussian1D(
                    name=ion_features['names'][k],
                    amplitude=ion_features['amps'][k],
                    mean=ion_features['x_0'][k],
                    stddev=ion_features['fwhms'][k] / 2.355,
                    bounds={
                        'amplitude':
                        ion_features['amps_limits'][k],
                        'mean':
                        ion_features['x_0_limits'][k],
                        'stddev': (ion_features['fwhms_limits'][k][0] / 2.355,
                                   ion_features['fwhms_limits'][k][1] / 2.355)
                    },
                    fixed={
                        'amplitude': ion_features['amps_fixed'][k],
                        'mean': ion_features['x_0_fixed'][k],
                        'stddev': ion_features['fwhms_fixed'][k]
                    })

        # apply the attenuation to *all* the components
        self.model *= S07_attenuation(
            name=att_info['names'][0],
            tau_sil=att_info['amps'][0],
            bounds={'tau_sil': att_info['amps_limits'][0]},
            fixed={'tau_sil': att_info['amps_fixed'][0]})
예제 #4
0
파일: base.py 프로젝트: qianqian0426/pahfit
    def __init__(self,
                 obs_x,
                 obs_y,
                 estimate_start=False,
                 param_info=None,
                 filename=None,
                 tformat=None):
        """
        Setup a variant based on inputs.  Generates an astropy.modeling
        compound model.
        """
        # check that param_info or filename is set
        if filename is None and param_info is None:
            raise ValueError("Either param_info or filename need to be set \
                             when initializing a PAHFITBase object")

        # read in the parameter info from a file
        if filename is not None:
            param_info = self.read(filename, tformat=tformat)

        if estimate_start:
            # guess values and update starting point (if not set fixed) based on the input spectrum
            param_info = self.estimate_init(obs_x, obs_y, param_info)

        bb_info = param_info[0]
        dust_features = param_info[1]
        h2_features = param_info[2]
        ion_features = param_info[3]
        att_info = param_info[4]

        # setup the model
        self.bb_info = bb_info
        if bb_info is not None:
            # 1st component defines the overall model variable
            self.model = BlackBody1D(
                name=bb_info["names"][0],
                temperature=bb_info["temps"][0],
                amplitude=bb_info["amps"][0],
                bounds={
                    "temperature": bb_info["temps_limits"][0],
                    "amplitude": bb_info["amps_limits"][0],
                },
                fixed={
                    "temperature": bb_info["temps_fixed"][0],
                    "amplitude": bb_info["amps_fixed"][0],
                },
            )
            for k in range(1, len(bb_info["names"])):
                self.model += BlackBody1D(
                    name=bb_info["names"][k],
                    temperature=bb_info["temps"][k],
                    amplitude=bb_info["amps"][k],
                    bounds={
                        "temperature": bb_info["temps_limits"][k],
                        "amplitude": bb_info["amps_limits"][k],
                    },
                    fixed={
                        "temperature": bb_info["temps_fixed"][k],
                        "amplitude": bb_info["amps_fixed"][k],
                    },
                )

        self.dust_features = dust_features
        if dust_features is not None:
            for k in range(len(dust_features["names"])):
                self.model += Drude1D(
                    name=dust_features["names"][k],
                    amplitude=dust_features["amps"][k],
                    x_0=dust_features["x_0"][k],
                    fwhm=dust_features["fwhms"][k],
                    bounds={
                        "amplitude": dust_features["amps_limits"][k],
                        "x_0": dust_features["x_0_limits"][k],
                        "fwhm": dust_features["fwhms_limits"][k],
                    },
                    fixed={
                        "amplitude": dust_features["amps_fixed"][k],
                        "x_0": dust_features["x_0_fixed"][k],
                        "fwhm": dust_features["fwhms_fixed"][k],
                    },
                )

        self.h2_features = h2_features
        if h2_features is not None:
            for k in range(len(h2_features["names"])):
                self.model += Gaussian1D(
                    name=h2_features["names"][k],
                    amplitude=h2_features["amps"][k],
                    mean=h2_features["x_0"][k],
                    stddev=h2_features["fwhms"][k] / 2.355,
                    bounds={
                        "amplitude":
                        h2_features["amps_limits"][k],
                        "mean":
                        h2_features["x_0_limits"][k],
                        "stddev": (
                            h2_features["fwhms_limits"][k][0] / 2.355,
                            h2_features["fwhms_limits"][k][1] / 2.355,
                        ),
                    },
                    fixed={
                        "amplitude": h2_features["amps_fixed"][k],
                        "mean": h2_features["x_0_fixed"][k],
                        "stddev": h2_features["fwhms_fixed"][k],
                    },
                )

        self.ion_features = ion_features
        if ion_features is not None:
            for k in range(len(ion_features["names"])):
                self.model += Gaussian1D(
                    name=ion_features["names"][k],
                    amplitude=ion_features["amps"][k],
                    mean=ion_features["x_0"][k],
                    stddev=ion_features["fwhms"][k] / 2.355,
                    bounds={
                        "amplitude":
                        ion_features["amps_limits"][k],
                        "mean":
                        ion_features["x_0_limits"][k],
                        "stddev": (
                            ion_features["fwhms_limits"][k][0] / 2.355,
                            ion_features["fwhms_limits"][k][1] / 2.355,
                        ),
                    },
                    fixed={
                        "amplitude": ion_features["amps_fixed"][k],
                        "mean": ion_features["x_0_fixed"][k],
                        "stddev": ion_features["fwhms_fixed"][k],
                    },
                )

        # apply the attenuation to *all* the components
        self.model *= S07_attenuation(
            name=att_info["names"][0],
            tau_sil=att_info["amps"][0],
            bounds={"tau_sil": att_info["amps_limits"][0]},
            fixed={"tau_sil": att_info["amps_fixed"][0]},
        )