Esempio n. 1
0
def process_Rfwhm(Rfwhm, wa, model, models):
    """ Convolve the input models using the Rfwhm option

    Return the new models.

    wa:  wavelength array, shape (N,)
    model: model flux array, shape (N,)
    models: list of model flux arrays each with shape (N,)

    Rfwhm is one of:

      'convolve_with_COS_FOS'
      a float
      an array floats with shape (N,)

    Returns
    -------
    new_model, new_models
    """

    model_out = None
    models_out = []

    #import pdb; pdb.set_trace()
    if Rfwhm is None:
        return model, models

    elif Rfwhm == 'convolve_with_COS_FOS':
        #print 'convolving with COS/FOS instrument profile'
        #import pdb; pdb.set_trace()
        model_out = convolve_with_COS_FOS(model, wa, use_COS_nuv=True)
        for m in models:
            #if m.min() < (1 - 1e-2):
            m = convolve_with_COS_FOS(m, wa, use_COS_nuv=True)
            models_out.append(m)

    elif isinstance(Rfwhm, float):
        #print 'Convolving with fwhm %.2f km/s' % Rfwhm
        # use a pixel velocity width 4 times smaller than the FWHM
        ndiv = 4.
        try:
            wa_dv = make_constant_dv_wa_scale(wa[0], wa[-1], Rfwhm / ndiv)
        except:
            import pdb
            pdb.set_trace()
        model_out = convolve_constant_dv(wa, model, wa_dv, ndiv)
        # do the same to every model if there's more than one
        for m in models:
            #if m.min() < (1 - 1e-2):
            m = convolve_constant_dv(wa, m, wa_dv, ndiv)
            models_out.append(m)
    else:
        raise ValueError('Unknown value for Rfwhm option')

    return model_out, models_out
Esempio n. 2
0
File: model.py Progetto: nhmc/H2
def ymodel(wa, pars):
    """Generate the model normalised flux array for every region.

    Note this needs the global variables `lines_vary` and `regions` to
    be defined.
    """
    linepars = pars
    dz = 0
    if options['wa_vary']:
        linepars, regpars = pars[:-len(regions)], pars[-len(regions):]
    lines = copy_par_to_lines(linepars, lines_vary)
    fl = []
    for ireg, (wa, tau0, sp, (i, j),tname) in enumerate(regions):
        tau = tau0.copy()
        for l in lines:
            if options['wa_vary']:
                dz = regpars[ireg] / wa[len(wa)//2] * (l.z + 1)

            trans = atom[l.name.strip()]
            tau += calc_iontau(wa, trans, l.z+1 + dz, l.logN, l.b)

        dwpix = wa[1] - wa[0]
        flmodel0 = convolve_with_COS_FOS(np.exp(-tau), wa, dwpix)
        flmodel = np.interp(sp.wa[i:j], wa, flmodel0)
        fl.extend(flmodel)
        
    return fl
Esempio n. 3
0
File: velplot.py Progetto: nhmc/H2
def process_Rfwhm(Rfwhm, wa, model, models):
    """ Convolve the input models using the Rfwhm option

    Return the new models.

    wa:  wavelength array, shape (N,)
    model: model flux array, shape (N,)
    models: list of model flux arrays each with shape (N,)

    Rfwm is one of:

      'convolve_with_COS_FOS'
      a float

    Returns
    -------
    new_model, new_models
    """

    model_out = None
    models_out = []

    if Rfwhm is None:
        return model, models

    elif Rfwhm == 'convolve_with_COS_FOS':
        print 'convolving with COS/FOS instrument profile'
        model_out = convolve_with_COS_FOS(model, wa, wa[1] - wa[0])
        models_out = [convolve_with_COS_FOS(m, wa, wa[1] - wa[0]) for m
                      in models]

    elif isinstance(Rfwhm, float):
        print 'Convolving with fwhm %.2f km/s' % Rfwhm
        # use a pixel velocity width 4 times smaller than the FWHM
        ndiv = 4.
        wa_dv = make_constant_dv_wa_scale(wa[0], wa[-1], Rfwhm / ndiv)
        model_out = convolve_constant_dv(wa, model, wa_dv, ndiv)
        # do the same to every model if there's more than one
        for m in models:
            models_out.append(convolve_constant_dv(wa, m, wa_dv, ndiv))
    else:
        raise ValueError('Unknown value for Rfwhm option')

    return model_out, models_out
Esempio n. 4
0
File: model.py Progetto: nhmc/H2
def plot_model(pars):
    """
    `regions`, `x` must be defined in the model.py module namespace
    """
    from run_emcee.plot_mcmc import get_fig_axes, get_nrows_ncols

    linepars = pars
    dz = 0
    if options['wa_vary']:
        linepars, regpars = pars[:-len(regions)], pars[-len(regions):]
    lines = copy_par_to_lines(linepars, lines_vary)
    
    nrows, ncols = get_nrows_ncols(len(regions))
    fig, axes = get_fig_axes(nrows, ncols, len(regions), width=8.2)
    fig.subplots_adjust(wspace=1e-6, hspace=1e-6, right=1, top=1,
                        left=0.07, bottom=0.06)
    z0 = lines.z[1]
    zp1 = lines.z.mean()
    colours = dict(J0='purple',J1='g',J2='r',J3='b')

    for ind, (wa, tau0, sp, (i, j), tname) in enumerate(regions):

        tau = tau0.copy()
        for l in lines:
            if options['wa_vary']:
                #import pdb; pdb.set_trace()
                dz = regpars[ind] / wa[len(wa)//2] * (l.z + 1)
                #print l.z, dz, l.logN
            
            trans = atom[l.name.strip()]
            tau += calc_iontau(wa, trans, l.z+1 + dz, l.logN, l.b)

        dwpix = wa[1] - wa[0]
        flmodel0 = convolve_with_COS_FOS(np.exp(-tau), wa, dwpix)
        ymod = np.interp(sp.wa[i:j], wa, flmodel0)


        ax = axes[ind]
        i1 = max(i-50, 0)
        j1 = min(j+50, len(sp.wa)-1)
        nfl = sp.fl[i1:j1] / sp.co[i1:j1]
        ner = sp.er[i1:j1] / sp.co[i1:j1]

        tstr, t = findtrans(tname, atom)
        obswa = t.wa * (1 + z0)
        dv = c_kms * (sp.wa[i:j] / obswa - 1)
        dv1 = c_kms * (sp.wa[i1:j1] / obswa - 1)

        tstr = tstr[2:]
        
        ax.axhline(0, color='0.5',lw=0.5)
        ax.axhline(1, color='k', lw=0.5, ls='--')
        ax.fill_between([-150, 150], -0.35, -0.15, color='0.9')
        ax.axhline(-0.25, color='k', lw=0.25)
        ax.plot(dv1, nfl, color='0.7', lw=0.5, drawstyle='steps-mid')
        ax.plot(dv, sp.fl[i:j]/sp.co[i:j], 'k', lw=0.5, drawstyle='steps-mid')
        ax.plot(dv, ymod, color='0.3')
        #ax.axvline(0, color='0.5', lw=0.5)

        ax.plot([-23]*2, [1.1, 1.4], '0.5')
        ax.plot([0]*2, [1.1, 1.4], '0.5')
        
        puttext(0.95, 0.95, tstr, ax, fontsize=9, va='top', ha='right',
                color=colours[tstr[:2]])

        resid = (sp.fl[i:j]/sp.co[i:j] - ymod) / sp.er[i:j] * sp.co[i:j]

        ax.plot(dv, -0.25 + resid*0.1, '.', color='0.3', ms=2)
        ax.set_ylim(-0.5, 1.9)
        ax.set_xlim(-120, 120)
        ax.set_yticks([0, 0.5, 1, 1.5])
        ax.set_yticklabels(['0.0', '0.5', '1.0', '1.5'])
        ax.set_xticks([-100, -50, 0, 50, 100])
        ax.set_xticklabels(['', '-50', '0', '50', ''])
        if ind+1 < (ncols*(nrows-1)):
            ax.set_xticklabels([])
        if ind % ncols:
            ax.set_yticklabels([])

    fig.text(0.5, 0.00, 'Velocity offset (km/s)', fontsize=12, ha='center',va='bottom')
    fig.text(0.015, 0.5, 'Transmission', fontsize=12, rotation=90,va='center')
    ndf = len(ydata) - len(pars)
    print (((ydata - ymodel(x, pars))/ ysigma) **2).sum() / ndf
    pl.savefig('fig/model.pdf')
    pl.savefig('fig/model.png',dpi=300)

    return fig
Esempio n. 5
0
    def _get_models(self, absorbers, system_width, resolution,
                    convolve_with_cos_fuv, convolve_with_cos_nuv, oversample,
                    plot_components):

        # Subdivide wavelength array if we are oversampling:
        if oversample > 1:
            dw = ((self.wavelength[1] - self.wavelength[0]) /
                  oversample)
            self.model_wavelength = np.arange(
                self.wavelength[0], self.wavelength[-1], dw)
        else:
            self.model_wavelength = self.wavelength

        # Gaussian kernel with a pixel velocity width 4 times smaller than
        # the FWHM:
        ndiv = 4
        kernel = Gaussian1DKernel(ndiv / 2.354820046)

        # Calculate quantities for Gaussian convolution if they are required:
        if not convolve_with_cos_fuv and not convolve_with_cos_nuv:

            if isinstance(resolution, dict):
                scales = []
                low = 0
                wmax = resolution.keys().sort()

                for w in wmax:
                    high = self.model_wavelength.searchsorted(w)
                    dlogw = np.log10(1 + resolution[w] / (ndiv * c_kms))
                    npts = int(np.log10(self.model_wavelength[high] /
                               self.model_wavelength[low]) / dlogw)
                    scales.append(self.model_wavelength[low] *
                                  10 ** (np.arange(npts) * dlogw))
                    low = high

                scale = np.concatenate(scales)

            else:
                dlogw = np.log10(1 + resolution / (ndiv * c_kms))
                npts = int(np.log10(self.model_wavelength[-1] /
                           self.model_wavelength[0]) / dlogw)
                scale = (self.model_wavelength[0] *
                         10 ** (np.arange(npts) * dlogw))

        self.system_components, self.blend_components = [], []
        self.ticks = defaultdict(list)

        # We want to create models for absorbers with different covering
        # fractions separately, so we'll store them with key access in a
        # dictionary. We'll take the product of all models with the same
        # covering fractions in the loop below, then apply zero offsets
        # (for covering fractions < 1) to those models at the end, before
        # combining them into a single model:
        models = dict()

        # Loop over absorbers:
        for absorber in absorbers:

            # Calculate the optical depth profile:
            tau = absorber.optical_depth(
                self.model_wavelength).astype('float64')

            # Add this to the total model appropriate for the covering
            # fraction of this absorber. Don't apply any zero offsets yet -
            # we'll do this at the end:
            if absorber.covering_fraction not in models.keys():
                models[absorber.covering_fraction] = np.exp(-tau)
            else:
                models[absorber.covering_fraction] *= np.exp(-tau)

            # Log wavelengths of transitions that contribute to the model if
            # the optical depth at the line centre is > 0.001:
            for transition in absorber.transitions:
                if tau_peak(transition, absorber.logn, absorber.b) > 0.001:
                    self.ticks['wavelength'].append(
                        transition.wavelength.value * (1 + absorber.redshift))
                    self.ticks['transition'].append(transition.name)

            # Only calculate the individual model components if we are
            # plotting them (expensive otherwise):
            if plot_components:

                # Ensure zero offsets are applied (for covering fractions < 1):
                component = (np.exp(-tau) * absorber.covering_fraction + 1 -
                             absorber.covering_fraction)

                # Convolve with the instrument LSF:
                if convolve_with_cos_fuv or convolve_with_cos_nuv:
                    try:
                        from COS import convolve_with_COS_FOS

                    except:
                        raise ImportError('COS module not installed')

                    if convolve_with_cos_nuv:

                        if self.model_wavelength[0] > 1600:
                            component = convolve_with_COS_FOS(
                                component, self.model_wavelength,
                                use_cos_nuv=True, cos_nuv_only=True)

                        else:
                            component = convolve_with_COS_FOS(
                                component, self.model_wavelength,
                                use_cos_nuv=True)

                    else:
                        component = convolve_with_COS_FOS(
                            component, self.model_wavelength)

                else:
                    # Interpolate onto constant velocity scale:
                    component0 = np.interp(
                        scale, self.model_wavelength, component)

                    # Do the convolution:
                    component = np.interp(
                        self.model_wavelength, scale,
                        convolve(component0, kernel))

                dz = system_width * (1 + self.redshift) / c_kms

                # Add components to the appropriate lists, depending on the
                # adopted system width:
                if ((absorber.redshift > self.redshift - dz / 2) &
                        (absorber.redshift < self.redshift + dz / 2)):
                    self.system_components.append(component)
                else:
                    self.blend_components.append(component)

        # Ensure that zero offsets are applied (for covering fractions < 1):
        for key in models.keys():
            covering_fraction = key
            models[key] = (models[key] * covering_fraction +
                           1 - covering_fraction)

        # Combine the models:
        model = np.product([models[key] for key in models.keys()], axis=0)

        # Cast line lists as NumPy arrays:
        self.ticks['wavelength'] = np.array(self.ticks['wavelength'])
        self.ticks['transition'] = np.array(self.ticks['transition'])

        # Convolve the models with the instrument LSF:
        if convolve_with_cos_fuv or convolve_with_cos_nuv:
            try:
                from COS import convolve_with_COS_FOS

            except:
                raise ImportError('convolve_with_COS_FOS not available')

            if convolve_with_cos_nuv:

                if self.model_wavelength[0] > 1600:
                    self.model = convolve_with_COS_FOS(
                        model, self.model_wavelength, use_cos_nuv=True,
                        cos_nuv_only=True)

                else:
                    self.model = convolve_with_COS_FOS(
                        model, self.model_wavelength, use_cos_nuv=True)

            else:
                self.model = convolve_with_COS_FOS(
                    model, self.model_wavelength)

        else:
            # Interpolate onto a constant velocity scale:
            model0 = np.interp(scale, self.model_wavelength, model)

            # Do the convolution:
            self.model = np.interp(
                self.model_wavelength, scale, convolve(model0, kernel))

        # Combined model on coarse wavelength grid
        # (same as `model` if `oversample` = 1):
        if oversample == 1:
            self.coarse_model = self.model
        else:
            self.coarse_model = np.interp(
                self.wavelength, self.model_wavelength, self.model)