def test_abscomp_H2():
    Zion = (-1, -1)  # temporary code for molecules
    Ntuple = (1, 17, -1)  # initial guess for Ntuple (needs to be given for adding lines from linelist)
    coord = SkyCoord(0,0, unit='deg')
    z = 0.212
    vlim = [-100., 100.] * u.km/u.s
    comp = AbsComponent(coord, Zion, z, vlim, Ntup=Ntuple)
    comp.add_abslines_from_linelist(llist='H2', init_name="B19-0P(1)", wvlim=[1100, 5000]*u.AA)
    assert len(comp._abslines) == 7
Exemple #2
0
def test_abscomp_H2():
    Zion = (-1, -1)  # temporary code for molecules
    Ntuple = (
        1, 17, -1
    )  # initial guess for Ntuple (needs to be given for adding lines from linelist)
    coord = SkyCoord(0, 0, unit='deg')
    z = 0.212
    vlim = [-100., 100.] * u.km / u.s
    comp = AbsComponent(coord, Zion, z, vlim, Ntup=Ntuple)
    comp.add_abslines_from_linelist(llist='H2',
                                    init_name="B19-0P(1)",
                                    wvlim=[1100, 5000] * u.AA)
    assert len(comp._abslines) == 7
Exemple #3
0
    def stack_plot(self,
                   to_plot,
                   pvlim=None,
                   maxtrans=3,
                   return_fig=True,
                   add_missing_lines=False,
                   spec=None,
                   **kwargs):
        '''Show a stack plot of the CGM absorption system

        Parameters
        ----------
        to_plot : List of AbsLines, AbsComponents, tuples, or strs
           If AbsLines, pass list on to linetools.analysis.plots.stack_plot()
           If not Abslines, will plot up to maxtrans of strongest transitions
           covered by spectra for components of some species.
             If tuples or strs, should be Zion value or ion name: (8,6) or 'OVI'
        pvlim : Quantities, optional
           Override system vlim for plotting
        maxtrans : int, optional
           Maximum number of lines per transition to plot
        add_missing_lines : bool, optional
           If True, plot transitions that do not have associated AbsLine objects
        spec : XSpectrum1D, optional
           Spectrum to plot in regions of requested lines; required if assoc.
           AbsLine objects do not have their analy['specfile'] attributes set

        Returns
        -------
        fig : matplotlib Figure, optional
           Figure instance containing stack plot with subplots, axes, etc.
        '''

        from linetools.analysis import plots as ltap
        from linetools.spectralline import AbsLine
        from linetools.isgm.abscomponent import AbsComponent
        from linetools.spectra.io import readspec
        from linetools.lists.linelist import LineList
        from linetools.abund import ions as ltai
        from pyigm import utils as pu

        ilist = LineList('ISM')

        if not isinstance(to_plot[0], AbsLine):
            lines2plot = []  # Master list of lines to plot
            for i, tp in enumerate(to_plot):
                if isinstance(tp, AbsComponent):
                    comp = to_plot
                else:  # Pick components in system closest to z_cgm
                    thesecomps = pu.get_components(self, tp)
                    if len(thesecomps) == 0:
                        if add_missing_lines is True:
                            # Add components
                            if isinstance(tp, str):
                                tup = ltai.name_to_ion(tp)
                            else:
                                tup = tp
                            comp = AbsComponent(self.coord,
                                                tup,
                                                zcomp=self.z,
                                                vlim=[-100., 100.] * u.km /
                                                u.s)
                            comp.add_abslines_from_linelist()
                            if spec is not None:
                                for al in comp._abslines:
                                    al.analy['spec'] = spec
                            else:
                                raise ValueError('spec must be provided if '
                                                 'requesting species without'
                                                 ' existing components.')
                        else:
                            continue
                    else:
                        # Find component with redshift closest to systemic
                        compvels = np.array(
                            [np.median(tc.vlim.value) for tc in thesecomps])
                        comp = thesecomps[np.argmin(np.abs(compvels))]

                    ### Get strongest transitions covered
                    wmins = []
                    wmaxs = []
                    for j, al in enumerate(comp._abslines):
                        # Load spectrum if not already loaded
                        if al.analy['spec'] is None:
                            try:
                                if spec is not None:
                                    al.analy['spec'] = spec
                                else:
                                    al.analy['spec'] = readspec(
                                        al.analy['spec_file'])
                            except:
                                raise LookupError("spec must be defined or "
                                                  "analy['specfile'] must be "
                                                  "declared for AbsLines")
                        # Get wavelength limits to know where to look
                        wmins.append(al.analy['spec'].wvmin.value)
                        wmaxs.append(al.analy['spec'].wvmax.value)
                    wlims = (np.min(np.array(wmins)), np.max(
                        np.array(wmaxs))) * u.Angstrom
                    # ID the strong transitions
                    strong = ilist.strongest_transitions(tp,
                                                         wvlims=wlims /
                                                         (1. + comp.zcomp),
                                                         n_max=maxtrans)
                    if strong is None:  #  No lines covered in the spectra
                        warnings.warn(
                            'No lines for {} are covered by the spectra'
                            'provided.'.format(tp))
                        continue
                    # Grab the AbsLines from this AbsComponent and their names
                    complines = comp._abslines
                    complines = np.array(complines)  # For the indexing
                    compnames = np.array([ll.name for ll in complines])
                    ### Add the lines found to the master list
                    if isinstance(strong, dict):  # Only one line covered
                        lines2plot.append(
                            complines[compnames == strong['name']][0])
                    else:  # Multiple lines covered
                        for i, sn in enumerate(strong['name']):
                            # Handle case where relevant components are defined
                            if sn in compnames:
                                tokeep = [complines[compnames == sn][0]]
                                lines2plot.extend(tokeep)
                            # Now case where components were not attached to sys
                            elif add_missing_lines is True:
                                # Add line to the existing comp to preserve z, etc.
                                compcopy = comp.copy(
                                )  #Copy to add dummy lines
                                # Set up observed wavelength range
                                obswave = strong['wrest'][i] * (1. +
                                                                compcopy.zcomp)
                                wvrange = [obswave - 0.1, obswave + 0.1
                                           ] * u.Angstrom
                                # Add this line to the component
                                compcopy.add_abslines_from_linelist(
                                    wvlim=wvrange)
                                al = compcopy._abslines[-1]
                                # Set the spectrum
                                if spec is not None:
                                    al.analy['spec'] = spec
                                else:
                                    al.analy['spec'] = comp._abslines[0].analy[
                                        'spec']
                                # Add the line
                                lines2plot.append(al)
                            else:
                                warnings.warn(
                                    '{} covered by spectra but not in'
                                    'components list'.format(sn))
        else:
            lines2plot = to_plot

        # Deal with velocity limits
        if pvlim is not None:
            vlim = pvlim
        else:
            vlim = self.vlim
        ### Make the plot!
        fig = ltap.stack_plot(lines2plot,
                              vlim=vlim,
                              return_fig=return_fig,
                              zref=self.z,
                              **kwargs)
        fig.subplots_adjust(bottom=0.,
                            left=0.1,
                            right=0.95,
                            hspace=0.,
                            wspace=0.35)
        return fig