Exemplo n.º 1
0
def test_name_from_coord():
    coord = SkyCoord(ra=15.4, dec=-23.1, unit='deg')
    name = ltu.name_from_coord(coord)
    assert name == 'J010136.00-230600.0'
    # Name 2
    name2 = ltu.name_from_coord(coord, precision=(0, 0))
    assert name2 == 'J010136-230600'
Exemplo n.º 2
0
def test_name_from_coord():
    coord = SkyCoord(ra=15.4, dec=-23.1, unit='deg')
    name = ltu.name_from_coord(coord)
    assert name == 'J010136.00-230600.0'
    # Name 2
    name2 = ltu.name_from_coord(coord, precision=(0, 0))
    assert name2 == 'J010136-230600'
Exemplo n.º 3
0
def main(pargs):
    """ Run
    """
    import json

    from linetools import utils as ltu

    from frb import frb

    # Load
    frb_name = pargs.frb_name if pargs.frb_name[:3].upper() == 'FRB' else 'FRB'+pargs.frb_name
    try:
        FRB = frb.FRB.by_name(frb_name.upper())
    except FileNotFoundError:
        print("Your desired FRB is not in this Repo.  Sorry..")
        return

    def pjson(obj):
        return json.dumps(obj, sort_keys=True, indent=4,
                         separators=(',', ': '))

    # Coords
    print("=========================================================\n")
    print(frb_name)
    print(ltu.name_from_coord(FRB.coord, precision=(4,4)), '\n     ra,dec = {:0.7f},{:0.7f} deg'.format(FRB.coord.ra.value,
                                                                           FRB.coord.dec.value))
    print('sig_a = {:0.3f} arcsec'.format(FRB.sig_a))
    print('sig_b = {:0.3f} arcsec'.format(FRB.sig_b))
    print('PA = {:0.1f} deg'.format(FRB.eellipse['theta']))
    print('')
    print('DM={}'.format(FRB.DM))

    print('Repeater={}'.format(FRB.repeater))

    if pargs.verbose:
        print('ee={}'.format(pjson(FRB.eellipse)))
        print('DM_ISM(ne2001)={:0.1f}'.format(FRB.DMISM))


    # Host
    hg = FRB.grab_host()
    if hg is not None:
        print("")
        print("=========================================================\n")
        print("Host\n")
        print(ltu.name_from_coord(hg.coord))
        print('z: \n {}'.format(pjson(hg.redshift)))
        if pargs.verbose:
            # photometry
            print('photom: \n {}'.format(pjson(hg.photom)))
            print('derived: \n {}'.format(pjson(hg.derived)))
            print('morphology: \n {}'.format(pjson(hg.morphology)))
            print('neb_lines: \n {}'.format(pjson(hg.neb_lines)))
Exemplo n.º 4
0
    def __init__(self, radec, sl_type=None, em_type=None, comment=None, name=None, **kwargs):
        """  Initiator

        Parameters
        ----------
        radec : tuple or SkyCoord
            (RA,DEC) in deg or astropy.coordinate.SkyCoord
        sl_type : str, optional
          Sightline type, e.g. IGM
        em_type : str, optional
          Type of emission source for absorption sightline, e.g. QSO
        comment : str, optional
          A comment, default is ``
        name : str, optional
            Name of the sightline, e.g. '3C273'
        """
        # Required
        self.coord = ltu.radec_to_coord(radec)

        # Lists
        self._components = []

        # Name
        if name is None:
            self.name = ltu.name_from_coord(self.coord)
        else:
            self.name = name

        # Others
        self.em_type = em_type
        self.sl_type = sl_type
        self._abssystems = None  # Saving the namespace for future usage
Exemplo n.º 5
0
    def __init__(self, radec, sl_type='', em_type='', comment=None, name=None, **kwargs):
        """  Initiator

        Parameters
        ----------
        radec : tuple or SkyCoord
            (RA,DEC) in deg or astropy.coordinate.SkyCoord
        sl_type : str, optional
          Sightline type, e.g. IGM
        em_type : str, optional
          Type of emission source for absorption sightline, e.g. QSO
        comment : str, optional
          A comment, default is ``
        name : str, optional
            Name of the sightline, e.g. '3C273'
        """
        # Required
        self.coord = ltu.radec_to_coord(radec)

        # Lists
        self._components = []

        # Name
        if name is None:
            self.name = ltu.name_from_coord(self.coord)
        else:
            self.name = name

        # Others
        self.em_type = em_type
        self.sl_type = sl_type
        self._abssystems = []  # Saving the namespace for future usage
Exemplo n.º 6
0
def plot_spec(specDB, meta, frb=None):
    import numpy as np
    from astropy.coordinates import SkyCoord
    from linetools import utils as ltu
    """ Plot galaxy spectra """
    # Grab spectra
    spec = specDB.spectra_from_meta(meta)
    # Add labels
    lbls = ['None'] * len(meta)
    ugroups = np.unique(meta['GROUP'])
    for ugroup in ugroups:
        rows = np.where(meta['GROUP'] == ugroup)[0]
        coords = SkyCoord(ra=meta['RA_GROUP'][rows],
                          dec=meta['DEC_GROUP'][rows],
                          unit='deg')
        if frb is None:
            for kk, row, imeta in zip(range(len(rows)), rows, meta):
                # JNAME
                jname = ltu.name_from_coord(coords[kk])
                lbls[row] = '{:s}_{:s}'.format(jname, meta['INSTR'][row])
        else:
            seps = frb.coord.separation(coords).to('arcsec')
            pas = frb.coord.position_angle(coords).to('deg')
            for row, sep, pa, imeta in zip(rows, seps, pas, meta):
                # Separation and PA
                lbls[row] = '{:s}_{:s}_{:d}_{:d}'.format(
                    frb.frb_name, meta['INSTR'][row], int(pa.value),
                    int(sep.value))
    spec.labels = lbls
    # Add object type
    spec.stypes = ['Galaxy'] * len(lbls)
    # Add redshift
    spec.z = meta['zem_GROUP']
    # Plot
    spec.plot(xspec=True)  #, scale=1.5)
Exemplo n.º 7
0
    def __init__(self, radec, igal_rand=10, iabs_rand=100, proper=False, field_name='',
                 wrapped=True, cosmo=None, **kwargs):

        IgmGalaxyField.__init__(self, radec, **kwargs)

        self.igal_rand = igal_rand
        self.iabs_rand = iabs_rand

        self.absreal = None # absreal  # np rec array with absorber properties (single ion)
        self.absrand = None

        # Cosmology
        if cosmo is None:
            cosmo = Planck15
        self.cosmo = cosmo

        # Central coordiantes
        self.CRA = self.coord.ra.value #np.mean(self.absreal.RA)
        self.CDEC = self.coord.dec.value # np.mean(self.absreal.DEC)

        if len(field_name) == 0:
            self.name = ltu.name_from_coord(self.coord)
        else:
            self.name = field_name
        self.proper = proper
        self.wrapped = wrapped

        self.galreal = None # Filled with addGal
        self.absreal = None # Filled with addAbs
        self.ion = None
Exemplo n.º 8
0
def plot_spec(specDB, meta, frb, dust_correct=False):
    import numpy as np
    from astropy.coordinates import SkyCoord
    from linetools import utils as ltu
    from frb.galaxies import nebular

    """ Plot galaxy spectra """
    # Grab spectra
    spec = specDB.spectra_from_meta(meta)

    # Dust?
    if dust_correct:
        import extinction
        EBV = nebular.get_ebv(frb.coord)['meanValue']  #
        AV = EBV * 3.1  # RV

        for kk in range(spec.nspec):
            spec.select = kk
            Al = extinction.fm07(spec.wavelength.value, AV)#, 3.1)
            spec.flux = spec.flux * 10 ** (Al / 2.5)
            spec.sig = spec.sig * 10 ** (Al / 2.5)

    # Add labels
    lbls = ['None']*len(meta)
    ugroups = np.unique(meta['GROUP'])
    for ugroup in ugroups:
        rows = np.where(meta['GROUP'] == ugroup)[0]
        coords = SkyCoord(ra=meta['RA_GROUP'][rows], dec=meta['DEC_GROUP'][rows], unit='deg')
        if frb is None:
            for kk, row, imeta in zip(range(len(rows)), rows, meta):
                # JNAME
                jname = ltu.name_from_coord(coords[kk])
                lbls[row]='{:s}_{:s}'.format(jname, meta['INSTR'][row])
        else:
            seps = frb.coord.separation(coords).to('arcsec')
            pas = frb.coord.position_angle(coords).to('deg')
            for row, sep, pa, imeta in zip(rows, seps, pas, meta):
                # Separation and PA
                lbls[row]='{:s}_{:s}_{:d}_{:d}'.format(frb.frb_name, meta['INSTR'][row],
                                                   int(pa.value), int(sep.value))
    spec.labels = lbls
    # Add object type
    spec.stypes = ['Galaxy']*len(lbls)
    # Add redshift
    spec.z = meta['zem_GROUP']

    # Plot
    spec.plot(xspec=True)#, scale=1.5)
Exemplo n.º 9
0
def generate(image,
             wcs,
             title,
             flip_ra=False,
             flip_dec=False,
             log_stretch=False,
             cutout=None,
             primary_coord=None,
             secondary_coord=None,
             third_coord=None,
             slit=None,
             vmnx=None,
             extra_text=None,
             outfile=None):
    """
    Basic method to generate a Finder chart figure

    Args:
        image (np.ndarray):
          Image for the finder
        wcs (astropy.wcs.WCS):
          WCS solution
        title (str):
          Title; typically the name of the primary source
        flip_ra (bool, default False):
            Flip the RA (x-axis). Useful for southern hemisphere finders.
        flip_dec (bool, default False):
            Flip the Dec (y-axis). Useful for southern hemisphere finders.
        log_stretch (bool, optional):
            Use a log stretch for the image display
        cutout (tuple, optional):
            SkyCoord (center coordinate) and Quantity (image angular size)
            for a cutout from the input image.
        primary_coord (astropy.coordinates.SkyCoord, optional):
          If provided, place a mark in red at this coordinate
        secondary_coord (astropy.coordinates.SkyCoord, optional):
          If provided, place a mark in cyan at this coordinate
          Assume it is an offset star (i.e. calculate offsets)
        third_coord (astropy.coordinates.SkyCoord, optional):
          If provided, place a mark in yellow at this coordinate
        slit (tuple, optional):
          If provided, places a rectangular slit with specified
          coordinates, width, length, and position angle on image (from North to East)
          [SkyCoords('21h44m25.255s',-40d54m00.1s', frame='icrs'), 1*u.arcsec, 10*u.arcsec, 20*u.deg]
        vmnx (tuple, optional):
          Used for scaling the image.  Otherwise, the image
          is analyzed for these values.
        extra_text : str
          Extra text to be added at the bottom of the Figure.
          e.g. `DSS r-filter`
        outfile (str, optional):
          Filename for the figure.  File type will be according
          to the extension

    Returns:
        matplotlib.pyplot.figure, matplotlib.pyplot.Axis

    """

    utils.set_mplrc()

    plt.clf()
    fig = plt.figure(figsize=(7, 8.5))
    # fig.set_size_inches(7.5,10.5)

    # Cutout?
    if cutout is not None:
        cutout_img = Cutout2D(image, cutout[0], cutout[1], wcs=wcs)
        # Overwrite
        wcs = cutout_img.wcs
        image = cutout_img.data

    # Axis
    ax = fig.add_axes([0.10, 0.20, 0.75, 0.5], projection=wcs)

    # Show
    if log_stretch:
        norm = mplnorm.ImageNormalize(stretch=LogStretch())
    else:
        norm = None
    cimg = ax.imshow(image, cmap='Greys', norm=norm)

    # Flip so RA increases to the left
    if flip_ra is True:
        ax.invert_xaxis()
    if flip_dec is True:
        ax.invert_yaxis()

    # N/E
    overlay = ax.get_coords_overlay('icrs')

    overlay['ra'].set_ticks(color='white')
    overlay['dec'].set_ticks(color='white')

    overlay['ra'].set_axislabel('Right Ascension')
    overlay['dec'].set_axislabel('Declination')

    overlay.grid(color='green', linestyle='solid', alpha=0.5)

    # Contrast
    if vmnx is None:
        mean, median, stddev = sigma_clipped_stats(
            image
        )  # Also set clipping level and number of iterations here if necessary
        #
        vmnx = (median - stddev, median + 2 * stddev
                )  # sky level - 1 sigma and +2 sigma above sky level
        print("Using vmnx = {} based on the image stats".format(vmnx))
    cimg.set_clim(vmnx[0], vmnx[1])

    # Add Primary
    if primary_coord is not None:
        c = SphericalCircle((primary_coord.ra, primary_coord.dec),
                            2 * units.arcsec,
                            transform=ax.get_transform('icrs'),
                            edgecolor='red',
                            facecolor='none')
        ax.add_patch(c)
        # Text
        jname = ltu.name_from_coord(primary_coord)
        ax.text(0.5,
                1.34,
                jname,
                fontsize=28,
                horizontalalignment='center',
                transform=ax.transAxes)

    # Secondary
    if secondary_coord is not None:
        c_S1 = SphericalCircle((secondary_coord.ra, secondary_coord.dec),
                               2 * units.arcsec,
                               transform=ax.get_transform('icrs'),
                               edgecolor='cyan',
                               facecolor='none')
        ax.add_patch(c_S1)
        # Text
        jname = ltu.name_from_coord(secondary_coord)
        ax.text(0.5,
                1.24,
                jname,
                fontsize=22,
                color='blue',
                horizontalalignment='center',
                transform=ax.transAxes)
        # Print offsets
        if primary_coord is not None:
            sep = primary_coord.separation(secondary_coord).to('arcsec')
            PA = primary_coord.position_angle(secondary_coord)
            # RA/DEC
            dec_off = np.cos(PA) * sep  # arcsec
            ra_off = np.sin(PA) * sep  # arcsec (East is *higher* RA)
            ax.text(
                0.5,
                1.22,
                'Offset from Ref. Star (cyan) to Target (red):\nRA(to targ) = {:.2f}  DEC(to targ) = {:.2f}'
                .format(-1 * ra_off.to('arcsec'), -1 * dec_off.to('arcsec')),
                fontsize=15,
                horizontalalignment='center',
                transform=ax.transAxes,
                color='blue',
                va='top')
    # Add tertiary
    if third_coord is not None:
        c = SphericalCircle((third_coord.ra, third_coord.dec),
                            2 * units.arcsec,
                            transform=ax.get_transform('icrs'),
                            edgecolor='yellow',
                            facecolor='none')
        ax.add_patch(c)

    # Slit
    if ((slit is not None) and (flag_photu is True)):
        # List of values - [coodinates, width, length, PA],
        # e.g. [SkyCoords('21h44m25.255s',-40d54m00.1s', frame='icrs'), 1*u.arcsec, 10*u.arcsec, 20*u.deg]
        slit_coords, width, length, pa = slit

        pa_deg = pa.to('deg').value

        aper = SkyRectangularAperture(
            positions=slit_coords, w=length, h=width, theta=pa
        )  # For theta=0, width goes North-South, which is slit length

        apermap = aper.to_pixel(wcs)

        apermap.plot(color='purple', lw=1)

        plt.text(0.5,
                 -0.1,
                 'Slit PA={} deg'.format(pa_deg),
                 color='purple',
                 fontsize=15,
                 ha='center',
                 va='top',
                 transform=ax.transAxes)

    if ((slit is not None) and (flag_photu is False)):
        raise IOError('Slit cannot be placed without photutils package')

    # Title
    ax.text(0.5,
            1.44,
            title,
            fontsize=32,
            horizontalalignment='center',
            transform=ax.transAxes)

    # Extra text
    if extra_text is not None:
        ax.text(-0.1,
                -0.25,
                extra_text,
                fontsize=20,
                horizontalalignment='left',
                transform=ax.transAxes)
    # Sources

    # Labels
    #ax.set_xlabel(r'\textbf{DEC (EAST direction)}')
    #ax.set_ylabel(r'\textbf{RA (SOUTH direction)}')

    if outfile is not None:
        plt.savefig(outfile)
        plt.close()
    else:
        plt.show()

    # Return
    return fig, ax
Exemplo n.º 10
0
def generate(image,
             wcs,
             title,
             log_stretch=False,
             cutout=None,
             primary_coord=None,
             secondary_coord=None,
             third_coord=None,
             vmnx=None,
             outfile=None):
    """
    Basic method to generate a Finder chart figure

    Args:
        image (np.ndarray):
          Image for the finder
        wcs (astropy.wcs.WCS):
          WCS solution
        title (str):
          TItle; typically the name of the primry source
        log_stretch (bool, optional):
            Use a log stretch for the image display
        cutout (tuple, optional):
            SkyCoord (center coordinate) and Quantity (image angular size)
            for a cutout from the input image.
        primary_coord (astropy.coordinates.SkyCoord, optional):
          If provided, place a mark in red at this coordinate
        secondary_coord (astropy.coordinates.SkyCoord, optional):
          If provided, place a mark in cyan at this coordinate
          Assume it is an offset star (i.e. calculate offsets)
        third_coord (astropy.coordinates.SkyCoord, optional):
          If provided, place a mark in yellow at this coordinate
        vmnx (tuple, optional):
          Used for scaling the image.  Otherwise, the image
          is analyzed for these values.
        outfile (str, optional):
          Filename for the figure.  File type will be according
          to the extension

    Returns:
        matplotlib.pyplot.figure, matplotlib.pyplot.Axis

    """

    utils.set_mplrc()

    plt.clf()
    fig = plt.figure(dpi=600)
    fig.set_size_inches(7.5, 10.5)

    # Cutout?
    if cutout is not None:
        cutout_img = Cutout2D(image, cutout[0], cutout[1], wcs=wcs)
        # Overwrite
        wcs = cutout_img.wcs
        image = cutout_img.data

    # Axis
    ax = fig.add_axes([0.10, 0.20, 0.80, 0.5], projection=wcs)

    # Show
    if log_stretch:
        norm = mplnorm.ImageNormalize(stretch=LogStretch())
    else:
        norm = None
    cimg = ax.imshow(image, cmap='Greys', norm=norm)

    # Flip so RA increases to the left
    ax.invert_xaxis()

    # N/E
    overlay = ax.get_coords_overlay('icrs')

    overlay['ra'].set_ticks(color='white')
    overlay['dec'].set_ticks(color='white')

    overlay['ra'].set_axislabel('Right Ascension')
    overlay['dec'].set_axislabel('Declination')

    overlay.grid(color='green', linestyle='solid', alpha=0.5)

    # Contrast
    if vmnx is None:
        mean, median, stddev = sigma_clipped_stats(
            image
        )  # Also set clipping level and number of iterations here if necessary
        #
        vmnx = (median - stddev, median + 2 * stddev
                )  # sky level - 1 sigma and +2 sigma above sky level
        print("Using vmnx = {} based on the image stats".format(vmnx))
    cimg.set_clim(vmnx[0], vmnx[1])

    # Add Primary
    if primary_coord is not None:
        c = SphericalCircle((primary_coord.ra, primary_coord.dec),
                            2 * units.arcsec,
                            transform=ax.get_transform('icrs'),
                            edgecolor='red',
                            facecolor='none')
        ax.add_patch(c)
        # Text
        jname = ltu.name_from_coord(primary_coord)
        ax.text(0.5,
                1.34,
                jname,
                fontsize=28,
                horizontalalignment='center',
                transform=ax.transAxes)

    # Secondary
    if secondary_coord is not None:
        c_S1 = SphericalCircle((secondary_coord.ra, secondary_coord.dec),
                               2 * units.arcsec,
                               transform=ax.get_transform('icrs'),
                               edgecolor='cyan',
                               facecolor='none')
        ax.add_patch(c_S1)
        # Text
        jname = ltu.name_from_coord(secondary_coord)
        ax.text(0.5,
                1.24,
                jname,
                fontsize=22,
                color='blue',
                horizontalalignment='center',
                transform=ax.transAxes)
        # Print offsets
        if primary_coord is not None:
            sep = primary_coord.separation(secondary_coord).to('arcsec')
            PA = primary_coord.position_angle(secondary_coord)
            # RA/DEC
            dec_off = np.cos(PA) * sep  # arcsec
            ra_off = np.sin(PA) * sep  # arcsec (East is *higher* RA)
            ax.text(0.5,
                    1.14,
                    'RA(to targ) = {:.2f}  DEC(to targ) = {:.2f}'.format(
                        -1 * ra_off.to('arcsec'), -1 * dec_off.to('arcsec')),
                    fontsize=18,
                    horizontalalignment='center',
                    transform=ax.transAxes)
    # Add tertiary
    if third_coord is not None:
        c = SphericalCircle((third_coord.ra, third_coord.dec),
                            2 * units.arcsec,
                            transform=ax.get_transform('icrs'),
                            edgecolor='yellow',
                            facecolor='none')
        ax.add_patch(c)
    # Slit?
    '''
    if slit is not None:
        r = Rectangle((primary_coord.ra.value, primary_coord.dec.value),
                      slit[0]/3600., slit[1]/3600., angle=360-slit[2],
                      transform=ax.get_transform('icrs'),
                      facecolor='none', edgecolor='red')
        ax.add_patch(r)
    '''
    # Title
    ax.text(0.5,
            1.44,
            title,
            fontsize=32,
            horizontalalignment='center',
            transform=ax.transAxes)

    # Sources
    # Labels
    #ax.set_xlabel(r'\textbf{DEC (EAST direction)}')
    #ax.set_ylabel(r'\textbf{RA (SOUTH direction)}')

    if outfile is not None:
        plt.savefig(outfile)
        plt.close()
    else:
        plt.show()

    # Return
    return fig, ax
Exemplo n.º 11
0
    def write_to_igmguesses(self,
                            outfile,
                            fwhm=3.,
                            specfilename=None,
                            creator=None,
                            instrument='unknown',
                            altname='unknown',
                            date=None,
                            overwrite=False):
        import json
        """
        Writes an IGMGuesses formatted JSON file

        Parameters
        ----------
        outfile : str
            Name of the IGMGuesses JSON file to write to.
        fwhm : int
            FWHM for IGMguesses
        specfilename : str
            Name of the spectrum file these guesses are associated to.
        altname : str
            Alternative name for the sightline. e.g. 3C273
        creator : str
            Name of the person who is creating the file. Important for tracking.
        instrument : str
            String indicating the instrument and its configuration associated to the specfilename.
            e.g. HST/COS/G130M+G160M/LP2
        overwrite : bool
            Wthether to overwrite output


        Returns
        -------

        """
        import datetime
        # Slurp IGMGuesses component attributes
        from pyigm.guis.igmguesses import comp_init_attrib
        from linetools.isgm.abscomponent import AbsComponent
        tmp = AbsComponent((10.0 * u.deg, 45 * u.deg), (14, 2), 1.0,
                           [-300, 300] * u.km / u.s)
        comp_init_attrib(tmp)
        igmg_akeys = list(tmp.attrib.keys())
        # components
        comp_list = self._components
        coord_ref = comp_list[0].coord
        if date is None:
            date = str(datetime.date.today().strftime('%Y-%b-%d'))

        # spec_file, meta
        if hasattr(self, 'igmg_dict'):
            spec_file = self.igmg_dict['spec_file']
            meta = self.igmg_dict['meta']
            # Updates
            meta['Date'] = date
            if creator is not None:
                meta['Creator'] = creator
            #
            fwhm = self.igmg_dict['fwhm']
        else:
            spec_file = specfilename
            # coordinates and meta
            RA = coord_ref.ra.to('deg').value
            DEC = coord_ref.dec.to('deg').value
            jname = ltu.name_from_coord(coord_ref, precision=(2, 1))
            if self.zem is None:
                zem = 0.  # IGMGuesses rules
            else:
                zem = self.zem
            if creator is None:
                creator = 'unknown'
            meta = {
                'RA': RA,
                'DEC': DEC,
                'ALTNAME': altname,
                'zem': zem,
                'Creator': creator,
                'Instrument': instrument,
                'Date': date,
                'JNAME': jname
            }

        # Create dict of the components
        out_dict = dict(cmps={},
                        spec_file=spec_file,
                        fwhm=fwhm,
                        bad_pixels=[],
                        meta=meta)

        for comp in comp_list:
            key = comp.name
            out_dict['cmps'][key] = comp.to_dict()
            # import pdb; pdb.set_trace()
            # check coordinate
            if comp.coord != coord_ref:
                raise ValueError(
                    "All AbsComponent objects must have the same coordinates!")
            out_dict['cmps'][key]['zcomp'] = comp.zcomp
            # IGMGuesses specific component attr
            for igm_key in [
                    'zfit', 'Nfit', 'bfit', 'wrest', 'mask_abslines', 'vlim'
            ]:
                out_dict['cmps'][key][igm_key] = comp.igmg_attrib['top_level'][
                    igm_key]
            # IGMGuesses attribute dict
            out_dict['cmps'][key]['attrib'] = {}
            for igm_key in igmg_akeys:
                try:
                    out_dict['cmps'][key]['attrib'][
                        igm_key] = comp.igmg_attrib[igm_key]
                except KeyError:
                    out_dict['cmps'][key]['attrib'][igm_key] = comp.attrib[
                        igm_key]
            #out_dict['cmps'][key]['vlim'] = list(comp.vlim.value)
            out_dict['cmps'][key]['reliability'] = str(comp.reliability)
            out_dict['cmps'][key]['comment'] = str(comp.comment)
            # Compatability on sig_logN
            out_dict['cmps'][key]['attrib']['sig_logN'] = comp.attrib[
                'sig_logN'][0]

        # JSONify
        gd_dict = ltu.jsonify(out_dict)

        # Write file
        ltu.savejson(outfile,
                     gd_dict,
                     overwrite=overwrite,
                     sort_keys=True,
                     indent=4,
                     separators=(',', ': '))
        print('Wrote: {:s}'.format(outfile))