Instruction:
Can you tell what is the following Python 3 function doing
def make_hpx_to_wcs_mapping(hpx, wcs):
    npix = (int(wcs.wcs.crpix[0] * 2), int(wcs.wcs.crpix[1] * 2))
    pix_crds = np.dstack(np.meshgrid(np.arange(npix[0]),
                                     np.arange(npix[1]))).swapaxes(0, 1).reshape((npix[0] * npix[1], 2))
    if wcs.wcs.naxis == 2:
        sky_crds = wcs.wcs_pix2world(pix_crds, 0)
    else:
        use_wcs = wcs.dropaxis(2)
        sky_crds = use_wcs.wcs_pix2world(pix_crds, 0)

    sky_crds *= np.radians(1.)
    sky_crds[0:, 1] = (np.pi / 2) - sky_crds[0:, 1]

    fullmask = np.isnan(sky_crds)
    mask = (fullmask[0:, 0] + fullmask[0:, 1]) == 0
    ipixs = -1 * np.ones(npix, int).T.flatten()
    ipixs[mask] = hp.pixelfunc.ang2pix(hpx.nside, sky_crds[0:, 1][mask],
                                       sky_crds[0:, 0][mask], hpx.nest)

    # Here we are counting the number of HEALPix pixels each WCS pixel points to;
    # this could probably be vectorized by filling a histogram.
    d_count = {}
    for ipix in ipixs:
        if ipix in d_count:
            d_count[ipix] += 1
        else:
            d_count[ipix] = 1

    # Here we are getting a multiplicative factor that tells use how to split up
    # the counts in each HEALPix pixel (by dividing the corresponding WCS pixels
    # by the number of associated HEALPix pixels).
    # This could also likely be vectorized.
    mult_val = np.ones(ipixs.shape)
    for i, ipix in enumerate(ipixs):
        mult_val[i] /= d_count[ipix]

    ipixs = ipixs.reshape(npix).flatten()
    mult_val = mult_val.reshape(npix).flatten()
    return ipixs, mult_val, npix

Response: Make the mapping data needed to from HPX pixelization to WCS - based array.


Instruction:
Write a Python 3 function for
parsing the HPX_REG header keyword into a list of tokens.

Response:
def parse_hpxregion(region):
    """Parse the HPX_REG header keyword into a list of tokens."""

    m = re.match(r'([A-Za-z\_]*?)\((.*?)\)', region)
    if m is None:
        raise Exception('Failed to parse hpx region string.')

    if not m.group(1):
        return re.split(',', m.group(2))
    else:
        return [m.group(1)] + re.split(',', m.group(2))


Instruction:
Given the following Python 3 function, write the documentation
def upix_to_pix(upix):
    nside = np.power(2, np.floor(np.log2(upix / 4)) / 2).astype(int)
    pix = upix - 4 * np.power(nside, 2)
    return pix, nside

Response: Get the nside from a unique pixel number.


Instruction:
Can you generate the documentation for the following Python 3 function
def create_hpx(cls, nside, nest, coordsys='CEL', order=-1, ebins=None,
                   region=None, conv=HPX_Conv('FGST_CCUBE'), pixels=None):
        """Create a HPX object.

        Parameters
        ----------
        nside    : int
           HEALPix nside paramter

        nest     : bool
           True for HEALPix "NESTED" indexing scheme, False for "RING" scheme.

        coordsys : str
           "CEL" or "GAL"

        order    : int
           nside = 2**order

        ebins    : `~numpy.ndarray`
            Energy bin edges

        region   : str
            Allows for partial-sky mappings

        conv     : `HPX_Conv`
            Object defining the convention for column names and the like

        pixels   : `np.array` or `None`
            For use with 'EXPLICIT' region string
        """
        return cls(nside, nest, coordsys, order, ebins,
                   region=region, conv=conv, pixels=pixels)

Response: Create a HEALPix object with the specified nside nest and coordsys.


Instruction:
How would you code a function in Python 3 to
identify the convention used to write this file

Response:
def identify_HPX_convention(header):
        """ Identify the convention used to write this file """
        # Hopefully the file contains the HPX_CONV keyword specifying
        # the convention used
        try:
            return header['HPX_CONV']
        except KeyError:
            pass

        indxschm = header.get('INDXSCHM', None)

        # Try based on the EXTNAME keyword
        extname = header.get('EXTNAME', None)
        if extname == 'HPXEXPOSURES':
            return 'FGST_BEXPCUBE'
        elif extname == 'SKYMAP2':
            if 'COORDTYPE' in header.keys():
                return 'GALPROP'
            else:
                return 'GALPROP2'

        # Check for the INDXSCHM keyword
        if indxschm == 'SPARSE':
            return 'FGST_SRCMAP_SPARSE'

        # Check the name of the first column
        colname = header['TTYPE1']
        if colname == 'PIX':
            colname = header['TTYPE2']

        if colname == 'KEY':
            return 'FGST_SRCMAP_SPARSE'
        elif colname == 'ENERGY1':
            return 'FGST_TEMPLATE'
        elif colname == 'COSBINS':
            return 'FGST_LTCUBE'
        elif colname == 'Bin0':
            return 'GALPROP'
        elif colname in ['CHANNEL1', 'Bin 0']:
            if extname == 'SKYMAP':
                return 'FGST_CCUBE'
            else:
                return 'FGST_SRCMAP'
        else:
            raise ValueError("Could not identify HEALPix convention")


Instruction:
Can you generate a brief explanation for the following Python 3 code
def create_from_header(cls, header, ebins=None, pixels=None):
        convname = HPX.identify_HPX_convention(header)
        conv = HPX_FITS_CONVENTIONS[convname]

        if conv.convname not in ['GALPROP', 'GALPROP2']:
            if header["PIXTYPE"] != "HEALPIX":
                raise Exception("PIXTYPE != HEALPIX")
        if header["PIXTYPE"] != "HEALPIX":
            raise Exception("PIXTYPE != HEALPIX")
        if header["ORDERING"] == "RING":
            nest = False
        elif header["ORDERING"] == "NESTED":
            nest = True
        else:
            raise Exception("ORDERING != RING | NESTED")

        try:
            order = header["ORDER"]
        except KeyError:
            order = -1

        if order < 0:
            nside = header["NSIDE"]
        else:
            nside = -1

        try:
            coordsys = header[conv.coordsys]
        except KeyError:
            coordsys = header['COORDSYS']

        try:
            region = header["HPX_REG"]
        except KeyError:
            try:
                region = header["HPXREGION"]
            except KeyError:
                region = None

        try:
            if header['INDXSCHM'] in ['EXPLICIT', 'PARTIAL']:
                use_pixels = pixels
            else:
                use_pixels = None
        except KeyError:
            use_pixels = None

        return cls(nside, nest, coordsys, order, ebins, region=region, conv=conv, pixels=use_pixels)

Response: Creates an HPX object from a header.


Instruction:
Here you have a function in Python 3, explain what it does
def create_from_hdu(cls, hdu, ebins=None):
        convname = HPX.identify_HPX_convention(hdu.header)
        conv = HPX_FITS_CONVENTIONS[convname]
        try:
            pixels = hdu.data[conv.idxstring]
        except KeyError:
            pixels = None
        return cls.create_from_header(hdu.header, ebins, pixels)

Response: Creates an HPX object from a FITS header.


Instruction:
Can you generate the documentation for the following Python 3 function
def make_header(self):
        cards = [fits.Card("TELESCOP", "GLAST"),
                 fits.Card("INSTRUME", "LAT"),
                 fits.Card(self._conv.coordsys, self._coordsys),
                 fits.Card("PIXTYPE", "HEALPIX"),
                 fits.Card("ORDERING", self.ordering),
                 fits.Card("ORDER", self._order),
                 fits.Card("NSIDE", self._nside),
                 fits.Card("FIRSTPIX", 0),
                 fits.Card("LASTPIX", self._maxpix - 1),
                 fits.Card("HPX_CONV", self._conv.convname)]

        if self._coordsys == "CEL":
            cards.append(fits.Card("EQUINOX", 2000.0,
                                   "Equinox of RA & DEC specifications"))

        if self._region is not None:
            cards.append(fits.Card("HPX_REG", self._region))
            cards.append(fits.Card("INDXSCHM", "PARTIAL"))
        elif self._ipix is not None:
            cards.append(fits.Card("INDXSCHM", "EXPLICIT"))
        else:
            if self._conv.convname in ['FGST_SRCMAP_SPARSE']:
                cards.append(fits.Card("INDXSCHM", "SPARSE"))
            else:
                cards.append(fits.Card("INDXSCHM", "IMPLICIT"))

        header = fits.Header(cards)
        return header

Response: Builds and returns a FITS header for this HEALPix map.


Instruction:
Create a Python 3 function to
build and returns a FITs HDU with input data

Response:
def make_hdu(self, data, **kwargs):
        """ Builds and returns a FITs HDU with input data

        data      : The data begin stored

        Keyword arguments
        -------------------
        extname   : The HDU extension name
        colbase   : The prefix for column names
        """
        shape = data.shape
        extname = kwargs.get('extname', self.conv.extname)

        if shape[-1] != self._npix:
            raise Exception(
                "Size of data array does not match number of pixels")
        cols = []

        if self._ipix is not None:
            cols.append(fits.Column(self.conv.idxstring, "J", array=self._ipix))

        if self.conv.convname == 'FGST_SRCMAP_SPARSE':
            nonzero = data.nonzero()
            nfilled = len(nonzero[0])
            if len(shape) == 1:
                cols.append(fits.Column("PIX", "J", array=nonzero[0].astype(int)))
                cols.append(fits.Column("VALUE", "E", array=data.flat[nonzero].astype(float).reshape(nfilled)))
            elif len(shape) == 2:
                keys = self._npix * nonzero[0] + nonzero[1]
                cols.append(fits.Column("PIX", "J", array=nonzero[1].reshape(nfilled)))
                cols.append(fits.Column("CHANNEL", "I", array=nonzero[0].reshape(nfilled)))
                cols.append(fits.Column("VALUE", "E",
                                        array=data.flat[keys].astype(float).reshape(nfilled)))
            else:
                raise Exception("HPX.write_fits only handles 1D and 2D maps")

        else:
            if len(shape) == 1:
                cols.append(fits.Column(self.conv.colname(
                    indx=self.conv.firstcol), "E", array=data.astype(float)))
            elif len(shape) == 2:
                for i in range(shape[0]):
                    cols.append(fits.Column(self.conv.colname(
                        indx=i + self.conv.firstcol), "E", array=data[i].astype(float)))
            else:
                raise Exception("HPX.write_fits only handles 1D and 2D maps")

        header = self.make_header()
        hdu = fits.BinTableHDU.from_columns(cols, header=header, name=extname)

        return hdu


Instruction:
Can you generate the documentation for the following Python 3 function
def make_energy_bounds_hdu(self, extname="EBOUNDS"):
        if self._ebins is None:
            return None
        cols = [fits.Column("CHANNEL", "I", array=np.arange(1, len(self._ebins + 1))),
                fits.Column("E_MIN", "1E", unit='keV',
                            array=1000 * self._ebins[0:-1]),
                fits.Column("E_MAX", "1E", unit='keV', array=1000 * self._ebins[1:])]
        hdu = fits.BinTableHDU.from_columns(
            cols, self.make_header(), name=extname)
        return hdu

Response:
Builds and returns a FITs HDU with the energy bin boundries
 ArcGIS.


Instruction:
Implement a function in Python 3 to
build and returns a FITs HDU with the energy bin boundries .

Response:
def make_energies_hdu(self, extname="ENERGIES"):
        """ Builds and returns a FITs HDU with the energy bin boundries

        extname   : The HDU extension name
        """
        if self._evals is None:
            return None
        cols = [fits.Column("ENERGY", "1E", unit='MeV',
                            array=self._evals)]
        hdu = fits.BinTableHDU.from_columns(
            cols, self.make_header(), name=extname)
        return hdu


Instruction:
Can you write a function in Python 3 where it
writes input data to a FITS file.

Response:
def write_fits(self, data, outfile, extname="SKYMAP", clobber=True):
        """ Write input data to a FITS file

        data      : The data begin stored
        outfile   : The name of the output file
        extname   : The HDU extension name
        clobber   : True -> overwrite existing files
        """
        hdu_prim = fits.PrimaryHDU()
        hdu_hpx = self.make_hdu(data, extname=extname)
        hl = [hdu_prim, hdu_hpx]
        if self.conv.energy_hdu == 'EBOUNDS':
            hdu_energy = self.make_energy_bounds_hdu()
        elif self.conv.energy_hdu == 'ENERGIES':
            hdu_energy = self.make_energies_hdu()
        if hdu_energy is not None:
            hl.append(hdu_energy)
        hdulist = fits.HDUList(hl)
        hdulist.writeto(outfile, overwrite=clobber)


Instruction:
Create a Python 3 function for
returning the list of pixels indices for all the pixels in a HEALPix nest.

Response:
def get_index_list(nside, nest, region):
        """ Returns the list of pixels indices for all the pixels in a region

        nside    : HEALPix nside parameter
        nest     : True for 'NESTED', False = 'RING'
        region   : HEALPix region string
        """

        tokens = parse_hpxregion(region)
        if tokens[0] == 'DISK':
            vec = coords_to_vec(float(tokens[1]), float(tokens[2]))
            ilist = hp.query_disc(nside, vec[0], np.radians(float(tokens[3])),
                                  inclusive=False, nest=nest)
        elif tokens[0] == 'DISK_INC':
            vec = coords_to_vec(float(tokens[1]), float(tokens[2]))
            ilist = hp.query_disc(nside, vec[0], np.radians(float(tokens[3])),
                                  inclusive=True, fact=int(tokens[4]),
                                  nest=nest)
        elif tokens[0] == 'HPX_PIXEL':
            nside_pix = int(tokens[2])
            if tokens[1] == 'NESTED':
                ipix_ring = hp.nest2ring(nside_pix, int(tokens[3]))
            elif tokens[1] == 'RING':
                ipix_ring = int(tokens[3])
            else:
                raise Exception(
                    "Did not recognize ordering scheme %s" % tokens[1])
            ilist = match_hpx_pixel(nside, nest, nside_pix, ipix_ring)
        else:
            raise Exception(
                "HPX.get_index_list did not recognize region type %s" % tokens[0])
        return ilist


Instruction:
Can you tell what is the following Python 3 function doing
def get_ref_dir(region, coordsys):
        if region is None:
            if coordsys == "GAL":
                c = SkyCoord(0., 0., frame=Galactic, unit="deg")
            elif coordsys == "CEL":
                c = SkyCoord(0., 0., frame=ICRS, unit="deg")
            return c

        tokens = parse_hpxregion(region)
        if tokens[0] in ['DISK', 'DISK_INC']:
            if coordsys == "GAL":
                c = SkyCoord(float(tokens[1]), float(
                    tokens[2]), frame=Galactic, unit="deg")
            elif coordsys == "CEL":
                c = SkyCoord(float(tokens[1]), float(
                    tokens[2]), frame=ICRS, unit="deg")
            return c
        elif tokens[0] == 'HPX_PIXEL':
            nside_pix = int(tokens[2])
            ipix_pix = int(tokens[3])
            if tokens[1] == 'NESTED':
                nest_pix = True
            elif tokens[1] == 'RING':
                nest_pix = False
            else:
                raise Exception(
                    "Did not recognize ordering scheme %s" % tokens[1])
            theta, phi = hp.pix2ang(nside_pix, ipix_pix, nest_pix)
            lat = np.degrees((np.pi / 2) - theta)
            lon = np.degrees(phi)
            if coordsys == "GAL":
                c = SkyCoord(lon, lat, frame=Galactic, unit="deg")
            elif coordsys == "CEL":
                c = SkyCoord(lon, lat, frame=ICRS, unit="deg")
            return c
        else:
            raise Exception(
                "HPX.get_ref_dir did not recognize region type %s" % tokens[0])
        return None

Response: Finds and returns the reference direction for a given HEALPix region string.


Instruction:
Implement a function in Python 3 to
find and returns the approximate size of a HEALPix region string.

Response:
def get_region_size(region):
        """ Finds and returns the approximate size of region (in degrees)
        from a HEALPix region string.
        """
        if region is None:
            return 180.
        tokens = parse_hpxregion(region)
        if tokens[0] in ['DISK', 'DISK_INC']:
            return float(tokens[3])
        elif tokens[0] == 'HPX_PIXEL':
            pixel_size = get_pixel_size_from_nside(int(tokens[2]))
            return 2. * pixel_size
        else:
            raise Exception(
                "HPX.get_region_size did not recognize region type %s" % tokens[0])
        return None


Instruction:
Here you have a function in Python 3, explain what it does
def make_wcs(self, naxis=2, proj='CAR', energies=None, oversample=2):
        w = WCS(naxis=naxis)
        skydir = self.get_ref_dir(self._region, self.coordsys)

        if self.coordsys == 'CEL':
            w.wcs.ctype[0] = 'RA---%s' % (proj)
            w.wcs.ctype[1] = 'DEC--%s' % (proj)
            w.wcs.crval[0] = skydir.ra.deg
            w.wcs.crval[1] = skydir.dec.deg
        elif self.coordsys == 'GAL':
            w.wcs.ctype[0] = 'GLON-%s' % (proj)
            w.wcs.ctype[1] = 'GLAT-%s' % (proj)
            w.wcs.crval[0] = skydir.galactic.l.deg
            w.wcs.crval[1] = skydir.galactic.b.deg
        else:
            raise Exception('Unrecognized coordinate system.')

        pixsize = get_pixel_size_from_nside(self.nside)
        roisize = self.get_region_size(self._region)
        allsky = False
        if roisize > 45:
            roisize = 90
            allsky = True

        npixels = int(2. * roisize / pixsize) * oversample
        crpix = npixels / 2.

        if allsky:
            w.wcs.crpix[0] = 2 * crpix
            npix = (2 * npixels, npixels)
        else:
            w.wcs.crpix[0] = crpix
            npix = (npixels, npixels)

        w.wcs.crpix[1] = crpix
        w.wcs.cdelt[0] = -pixsize / oversample
        w.wcs.cdelt[1] = pixsize / oversample

        if naxis == 3:
            w.wcs.crpix[2] = 1
            w.wcs.ctype[2] = 'Energy'
            if energies is not None:
                w.wcs.crval[2] = 10 ** energies[0]
                w.wcs.cdelt[2] = 10 ** energies[1] - 10 ** energies[0]

        w = WCS(w.to_header())
        wcs_proj = WCSProj(w, npix)
        return wcs_proj

Response: Make a WCS object for this HPX pixelization.


Instruction:
Can you implement a function in Python 3 that
gets the sky coordinates of all the pixels in this pixelization

Response:
def get_sky_coords(self):
        """ Get the sky coordinates of all the pixels in this pixelization """
        if self._ipix is None:
            theta, phi = hp.pix2ang(
                self._nside, list(range(self._npix)), self._nest)
        else:
            theta, phi = hp.pix2ang(self._nside, self._ipix, self._nest)

        lat = np.degrees((np.pi / 2) - theta)
        lon = np.degrees(phi)
        return np.vstack([lon, lat]).T


Instruction:
Implement a function in Python 3 to
return the indices in the flat array corresponding to a set of coordinates

Response:
def get_pixel_indices(self, lats, lons):
        """ "Return the indices in the flat array corresponding to a set of coordinates """
        theta = np.radians(90. - lats)
        phi = np.radians(lons)
        return hp.ang2pix(self.nside, theta, phi, self.nest)


Instruction:
Create a Python 3 function for
returning the pixel index of a SkyCoord object.

Response:
def skydir_to_pixel(self, skydir):
        """Return the pixel index of a SkyCoord object."""
        if self.coordsys in ['CEL', 'EQU']:
            skydir = skydir.transform_to('icrs')
            lon = skydir.ra.deg
            lat = skydir.dec.deg
        else:
            skydir = skydir.transform_to('galactic')
            lon = skydir.l.deg
            lat = skydir.b.deg

        return self.get_pixel_indices(lat, lon)


Instruction:
Explain what the following Python 3 code does
def write_to_fitsfile(self, fitsfile, clobber=True):
        from fermipy.skymap import Map
        hpx_header = self._hpx.make_header()
        index_map = Map(self.ipixs, self.wcs)
        mult_map = Map(self.mult_val, self.wcs)
        prim_hdu = index_map.create_primary_hdu()
        mult_hdu = index_map.create_image_hdu()
        for key in ['COORDSYS', 'ORDERING', 'PIXTYPE',
                    'ORDERING', 'ORDER', 'NSIDE',
                    'FIRSTPIX', 'LASTPIX']:
            prim_hdu.header[key] = hpx_header[key]
            mult_hdu.header[key] = hpx_header[key]

        hdulist = fits.HDUList([prim_hdu, mult_hdu])
        hdulist.writeto(fitsfile, overwrite=clobber)

Response: Write this mapping to a FITS file.


Instruction:
Explain what the following Python 3 code does
def create_from_fitsfile(cls, fitsfile):
        from fermipy.skymap import Map
        index_map = Map.create_from_fits(fitsfile)
        mult_map = Map.create_from_fits(fitsfile, hdu=1)
        ff = fits.open(fitsfile)
        hpx = HPX.create_from_hdu(ff[0])
        mapping_data = dict(ipixs=index_map.counts,
                            mult_val=mult_map.counts,
                            npix=mult_map.counts.shape)
        return cls(hpx, index_map.wcs, mapping_data)

Response: Read a FITS file and use it to make a mapping


Instruction:
Can you implement a function in Python 3 that
fills the wcs map from the input HEALPix data using the pre - calculated mappings from the input HEALPix data.

Response:
def fill_wcs_map_from_hpx_data(self, hpx_data, wcs_data, normalize=True):
        """Fills the wcs map from the hpx data using the pre-calculated
        mappings

        hpx_data  : the input HEALPix data
        wcs_data  : the data array being filled
        normalize : True -> perserve integral by splitting HEALPix values between bins

        """
        # FIXME, there really ought to be a better way to do this

        hpx_naxis = len(hpx_data.shape)
        wcs_naxis = len(wcs_data.shape)

        if hpx_naxis + 1 != wcs_naxis:
            raise ValueError("HPX.fill_wcs_map_from_hpx_data: HPX naxis should be 1 less that WCS naxis: %i, %i"%(hpx_naxis, wcs_naxis))
        if hpx_naxis == 2:
            if hpx_data.shape[1] != wcs_data.shape[2]:
                raise ValueError("HPX.fill_wcs_map_from_hpx_data: size of energy axes don't match: %i, %i"%(hpx_naxis[1], wcs_naxis[2]))

        lmap_valid = self._lmap[self._valid]
        wcs_layer_shape = wcs_data.shape[0]*wcs_data.shape[1]
        if hpx_naxis == 2:
            for i in range(hpx_data.shape[1]):
                wcs_data_layer = np.zeros(wcs_layer_shape)
                wcs_data_layer[self._valid] = hpx_data[:,i][lmap_valid]
                orig_value = wcs_data_layer.sum()
                if normalize:
                    wcs_data_layer *= self._mult_val
                wcs_data[:,:,i].flat = wcs_data_layer
        else:
            wcs_data_flat = np.zeros(wcs_layer_shape)
            wcs_data_flat[self._valid] = hpx_data[lmap_valid]
            if normalize:
                wcs_data_flat *= self._mult_val
            wcs_data.flat = wcs_data_flat


Instruction:
Write a Python 3 script to
create a WCS map from the HEALPix data

Response:
def make_wcs_data_from_hpx_data(self, hpx_data, wcs, normalize=True):
        """ Creates and fills a wcs map from the hpx data using the pre-calculated
        mappings

        hpx_data  : the input HEALPix data
        wcs       : the WCS object
        normalize : True -> perserve integral by splitting HEALPix values between bins
        """
        wcs_data = np.zeros(wcs.npix)
        self.fill_wcs_map_from_hpx_data(hpx_data, wcs_data, normalize)
        return wcs_data


Instruction:
Can you write a function in Python 3 where it
gets the number of energy bins in the SED

Response:
def _get_enum_bins(configfile):
    """Get the number of energy bin in the SED

    Parameters
    ----------

    configfile : str
        Fermipy configuration file.

    Returns
    -------

    nbins : int
        The number of energy bins

    """
    config = yaml.safe_load(open(configfile))

    emin = config['selection']['emin']
    emax = config['selection']['emax']
    log_emin = np.log10(emin)
    log_emax = np.log10(emax)
    ndec = log_emax - log_emin
    binsperdec = config['binning']['binsperdec']
    nebins = int(np.round(binsperdec * ndec))

    return nebins


Instruction:
Create a Python 3 function for
filling the arrays from the files in filelist collist

Response:
def fill_output_table(filelist, hdu, collist, nbins):
    """Fill the arrays from the files in filelist

    Parameters
    ----------

    filelist : list
        List of the files to get data from.

    hdu : str
        Name of the HDU containing the table with the input data.

    colllist : list
        List of the column names

    nbins : int
        Number of bins in the input data arrays

    Returns
    -------

    table : astropy.table.Table
        A table with all the requested data extracted.

    """
    nfiles = len(filelist)
    shape = (nbins, nfiles)
    outdict = {}
    for c in collist:
        outdict[c['name']] = np.ndarray(shape)

    sys.stdout.write('Working on %i files: ' % nfiles)
    sys.stdout.flush()
    for i, f in enumerate(filelist):
        sys.stdout.write('.')
        sys.stdout.flush()
        tab = Table.read(f, hdu)
        for c in collist:
            cname = c['name']
            outdict[cname][:, i] = tab[cname].data
    sys.stdout.write('!\n')
    outcols = []
    for c in collist:
        cname = c['name']
        if 'unit' in c:
            col = Column(data=outdict[cname], name=cname,
                         dtype=np.float, shape=nfiles, unit=c['unit'])
        else:
            col = Column(data=outdict[cname], name=cname,
                         dtype=np.float, shape=nfiles)
        outcols.append(col)
    tab = Table(data=outcols)
    return tab


Instruction:
Write a Python 3 script for
collecting summary statisitics from an array of summary data

Response:
def collect_summary_stats(data):
    """Collect summary statisitics from an array

    This creates a dictionry of output arrays of summary
    statistics, with the input array dimension reducted by one.

    Parameters
    ----------

    data : `numpy.ndarray`
        Array with the collected input data

    Returns
    -------

    output : dict
        Dictionary of `np.ndarray` with the summary data.
        These include mean, std, median, and 4 quantiles (0.025, 0.16, 0.86, 0.975).

    """
    mean = np.mean(data, axis=0)
    std = np.std(data, axis=0)
    median = np.median(data, axis=0)
    q02, q16, q84, q97 = np.percentile(data, [2.5, 16, 84, 97.5], axis=0)

    o = dict(mean=mean,
             std=std,
             median=median,
             q02=q02,
             q16=q16,
             q84=q84,
             q97=q97)

    return o


Instruction:
Explain what the following Python 3 code does
def add_summary_stats_to_table(table_in, table_out, colnames):
    for col in colnames:
        col_in = table_in[col]
        stats = collect_summary_stats(col_in.data)
        for k, v in stats.items():
            out_name = "%s_%s" % (col, k)
            col_out = Column(data=np.vstack(
                [v]), name=out_name, dtype=col_in.dtype, shape=v.shape, unit=col_in.unit)
            table_out.add_column(col_out)

Response: Collect summary statisitics from an input table and add them to an output table.


Instruction:
Can you implement a function in Python 3 that
builds a stats summary table for a table that has all the SED results

Response:
def summarize_sed_results(sed_table):
    """Build a stats summary table for a table that has all the SED results """
    del_cols = ['dnde', 'dnde_err', 'dnde_errp', 'dnde_errn', 'dnde_ul',
                'e2dnde', 'e2dnde_err', 'e2dnde_errp', 'e2dnde_errn', 'e2dnde_ul',
                'norm', 'norm_err', 'norm_errp', 'norm_errn', 'norm_ul',
                'ts']
    stats_cols = ['dnde', 'dnde_ul',
                  'e2dnde', 'e2dnde_ul',
                  'norm', 'norm_ul']

    table_out = Table(sed_table[0])
    table_out.remove_columns(del_cols)
    add_summary_stats_to_table(sed_table, table_out, stats_cols)
    return table_out


Instruction:
Here you have a function in Python 3, explain what it does
def build_job_configs(self, args):
        job_configs = {}

        ttype = args['ttype']
        (targets_yaml, sim) = NAME_FACTORY.resolve_targetfile(
            args, require_sim_name=True)
        if targets_yaml is None:
            return job_configs

        write_full = args['write_full']

        targets = load_yaml(targets_yaml)

        base_config = dict(config=args['config'],
                           nsims=args['nsims'],
                           seed=args['seed'])

        first = args['seed']
        last = first + args['nsims'] - 1

        for target_name, profile_list in targets.items():
            for profile in profile_list:
                full_key = "%s:%s:%s" % (target_name, profile, sim)
                name_keys = dict(target_type=ttype,
                                 target_name=target_name,
                                 sim_name=sim,
                                 profile=profile,
                                 fullpath=True)
                sed_file = NAME_FACTORY.sim_sedfile(**name_keys)
                outfile = sed_file.replace(
                    '_SEED.fits', '_collected_%06i_%06i.fits' % (first, last))
                logfile = make_nfs_path(outfile.replace('.fits', '.log'))
                if not write_full:
                    outfile = None
                summaryfile = sed_file.replace(
                    '_SEED.fits', '_summary_%06i_%06i.fits' % (first, last))
                job_config = base_config.copy()
                job_config.update(dict(sed_file=sed_file,
                                       outfile=outfile,
                                       summaryfile=summaryfile,
                                       logfile=logfile))
                job_configs[full_key] = job_config

        return job_configs

Response: Hook to build job configurations from the given arguments


Instruction:
Implement a function in Python 3 to
update the base dictionary with the values from a YAML file.

Response:
def update_base_dict(self, yamlfile):
        """Update the values in baseline dictionary used to resolve names
        """
        self.base_dict.update(**yaml.safe_load(open(yamlfile)))


Instruction:
Can you generate a brief explanation for the following Python 3 code
def _format_from_dict(self, format_string, **kwargs):
        kwargs_copy = self.base_dict.copy()
        kwargs_copy.update(**kwargs)
        localpath = format_string.format(**kwargs_copy)
        if kwargs.get('fullpath', False):
            return self.fullpath(localpath=localpath)
        return localpath

Response: Return a formatted file name dictionary components


Instruction:
Can you generate a brief explanation for the following Python 3 code
def sim_sedfile(self, **kwargs):
        if 'seed' not in kwargs:
            kwargs['seed'] = 'SEED'
        return self._format_from_dict(NameFactory.sim_sedfile_format, **kwargs)

Response: Return the name for the simulated SED file for a particular targetCOOKIE


Instruction:
Create a Python 3 function for
returning the path for a stamp file for a scatter gather job

Response:
def stamp(self, **kwargs):
        """Return the path for a stamp file for a scatter gather job"""
        kwargs_copy = self.base_dict.copy()
        kwargs_copy.update(**kwargs)
        return NameFactory.stamp_format.format(**kwargs_copy)


Instruction:
Can you implement a function in Python 3 that
gets the name of the targetfile based on the job arguments

Response:
def resolve_targetfile(self, args, require_sim_name=False):  # x
        """Get the name of the targetfile based on the job arguments"""
        ttype = args.get('ttype')
        if is_null(ttype):
            sys.stderr.write('Target type must be specified')
            return (None, None)

        sim = args.get('sim')
        if is_null(sim):
            if require_sim_name:
                sys.stderr.write('Simulation scenario must be specified')
                return (None, None)
            else:
                sim = None

        name_keys = dict(target_type=ttype,
                         targetlist='target_list.yaml',
                         sim_name=sim,
                         fullpath=True)
        if sim is None:
            targetfile = self.targetfile(**name_keys)
        else:
            targetfile = self.sim_targetfile(**name_keys)

        targets_override = args.get('targetfile')
        if is_not_null(targets_override):
            targetfile = targets_override

        return (targetfile, sim)


Instruction:
How would you implement a function in Python 3 that
resolves the name of the specturm file based on the job arguments

Response:
def resolve_randconfig(self, args):
        """Get the name of the specturm file based on the job arguments"""
        ttype = args.get('ttype')
        if is_null(ttype):
            sys.stderr.write('Target type must be specified')
            return None
        name_keys = dict(target_type=ttype,
                         fullpath=True)
        randconfig = self.randconfig(**name_keys)
        rand_override = args.get('rand_config')
        if is_not_null(rand_override):
            randconfig = rand_override
        return randconfig


Instruction:
Write a Python 3 function for
noting that gtmktime will be skipped if no FT2 file is provided.

Response:
def main():

    usage = "usage: %(prog)s [options] "
    description = "Run gtselect and gtmktime on one or more FT1 files.  "
    "Note that gtmktime will be skipped if no FT2 file is provided."
    parser = argparse.ArgumentParser(usage=usage, description=description)

    add_lsf_args(parser)
    parser.add_argument('--zmax', default=100., type=float, help='')
    parser.add_argument('--dcostheta', default=0.025, type=float, help='')
    parser.add_argument('--binsz', default=1.0, type=float, help='')
    parser.add_argument('--outdir', default=None, type=str,
                        help='Path to output directory used when merge=False.')
    parser.add_argument('--outfile', default=None, type=str,
                        help='Path to output file used when merge=True.')
    parser.add_argument('--scfile', default=None, type=str, help='',
                        required=True)

    parser.add_argument('--dry_run', default=False, action='store_true')
    parser.add_argument('--overwrite', default=False, action='store_true')
    parser.add_argument('--merge', default=False, action='store_true',
                        help='Merge input FT1 files into a single file.')

    parser.add_argument('files', nargs='+', default=None,
                        help='List of directories in which the analysis will '
                             'be run.')

    args = parser.parse_args()

    args.outdir = os.path.abspath(args.outdir)
    args.scfile = os.path.abspath(args.scfile)
    mkdir(args.outdir)
    input_files = [[os.path.abspath(x)] for x in args.files]
    output_files = [os.path.join(args.outdir, os.path.basename(x))
                    for x in args.files]

    if args.batch:
        opts = copy.deepcopy(args.__dict__)
        opts.pop('files')
        opts.pop('batch')
        submit_jobs('python ' + os.path.abspath(__file__.rstrip('cd')),
                    input_files, output_files, {k: v for k, v in opts.items()})
        sys.exit(0)

    logger = Logger.get(os.path.basename(__file__), None, logging.INFO)
    logger.info('Starting.')
    cwd = os.getcwd()
    user = os.environ['USER']
    tmpdir = tempfile.mkdtemp(prefix=user + '.', dir='/scratch')
    os.chdir(tmpdir)

    logger.info('tmpdir %s', tmpdir)
    logger.info('outdir %s', args.outdir)
    logger.info('outfile %s', args.outfile)

    for infiles, outfile in zip(input_files, output_files):

        logger.info('infiles %s', pprint.pformat(infiles))
        logger.info('outfile %s', outfile)

        kw = dict(evfile='list.txt',
                  scfile=args.scfile,
                  outfile='ltcube.fits',
                  binsz=args.binsz,
                  dcostheta=args.dcostheta,
                  zmax=args.zmax)

        create_filelist(infiles, 'list.txt')
        staged_outfile = kw['outfile']
        run_gtapp('gtltcube', logger, kw)
        logger.info('cp %s %s', staged_outfile, outfile)
        shutil.copy(staged_outfile, outfile)

    os.chdir(cwd)
    logger.info('Deleting %s', tmpdir)
    shutil.rmtree(tmpdir)
    logger.info('Done.')


Instruction:
Can you tell what is the following Python 3 function doing
def convert_sed_cols(tab):
    # Update Column names
    for colname in list(tab.columns.keys()):

        newname = colname.lower()
        newname = newname.replace('dfde', 'dnde')

        if tab.columns[colname].name == newname:
            continue

        tab.columns[colname].name = newname

    return tab

Response: Cast SED column names to lowercase.


Instruction:
Write a Python 3 function for
returning the derivative a an array of input values

Response:
def derivative(self, x, der=1):
        """ return the derivative a an array of input values

        x   : the inputs
        der : the order of derivative
        """
        from scipy.interpolate import splev
        return splev(x, self._sp, der=der)


Instruction:
Given the following Python 3 function, write the documentation
def _compute_mle(self):
        min_y = np.min(self._interp.y)
        if self._interp.y[0] == min_y:
            self._mle = self._interp.x[0]
        elif self._interp.y[-1] == min_y:
            self._mle = self._interp.x[-1]
        else:
            argmin_y = np.argmin(self._interp.y)
            ix0 = max(argmin_y - 4, 0)
            ix1 = min(argmin_y + 4, len(self._interp.x) - 1)

            while np.sign(self._interp.derivative(self._interp.x[ix0])) == \
                    np.sign(self._interp.derivative(self._interp.x[ix1])):
                ix0 += 1

            self._mle = scipy.optimize.brentq(self._interp.derivative,
                                              self._interp.x[ix0],
                                              self._interp.x[ix1],
                                              xtol=1e-10 *
                                              np.median(self._interp.x))

Response: Compute the maximum likelihood estimate.


Instruction:
Can you create a Python 3 function that
finds the point at which the log - likelihood changes by a given value with respect to its value at the MLE.

Response:
def getDeltaLogLike(self, dlnl, upper=True):
        """Find the point at which the log-likelihood changes by a
        given value with respect to its value at the MLE."""
        mle_val = self.mle()
        # A little bit of paranoia to avoid zeros
        if mle_val <= 0.:
            mle_val = self._interp.xmin
        if mle_val <= 0.:
            mle_val = self._interp.x[1]
        log_mle = np.log10(mle_val)
        lnl_max = self.fn_mle()

        # This ultra-safe code to find an absolute maximum
        # fmax = self.fn_mle()
        # m = (fmax-self.interp.y > 0.1+dlnl) & (self.interp.x>self._mle)

        # if sum(m) == 0:
        #    xmax = self.interp.x[-1]*10
        # else:
        #    xmax = self.interp.x[m][0]

        # Matt has found that it is faster to use an interpolator
        # than an actual root-finder to find the root,
        # probably b/c of python overhead.
        # That would be something like this:
        # rf = lambda x: self._interp(x)+dlnl-lnl_max
        # return opt.brentq(rf,self._mle,self._interp.xmax,
        #                   xtol=1e-10*np.abs(self._mle))
        if upper:
            x = np.logspace(log_mle, np.log10(self._interp.xmax), 100)
            retVal = np.interp(dlnl, self.interp(x) - lnl_max, x)
        else:
            x = np.linspace(self._interp.xmin, self._mle, 100)
            retVal = np.interp(dlnl, self.interp(x)[::-1] - lnl_max, x[::-1])

        return retVal


Instruction:
Implement a Python 3 function for
evaluating the limits corresponding to a C. L. of alpha%.

Response:
def getLimit(self, alpha, upper=True):
        """ Evaluate the limits corresponding to a C.L. of (1-alpha)%.

        Parameters
        ----------
        alpha :  limit confidence level.
        upper :  upper or lower limits.
        """
        dlnl = onesided_cl_to_dlnl(1.0 - alpha)
        return self.getDeltaLogLike(dlnl, upper=upper)


Instruction:
Implement a Python 3 function for
evaluating the interval corresponding to a C. L of alpha%.

Response:
def getInterval(self, alpha):
        """ Evaluate the interval corresponding to a C.L. of (1-alpha)%.

        Parameters
        ----------
        alpha : limit confidence level.
        """
        dlnl = twosided_cl_to_dlnl(1.0 - alpha)
        lo_lim = self.getDeltaLogLike(dlnl, upper=False)
        hi_lim = self.getDeltaLogLike(dlnl, upper=True)
        return (lo_lim, hi_lim)


Instruction:
Can you implement a function in Python 3 that
creates a new object from a table.

Response:
def create_from_table(cls, tab_e):
        """
        Parameters
        ----------
        tab_e : `~astropy.table.Table`
            EBOUNDS table.
        """

        convert_sed_cols(tab_e)
        try:
            emin = np.array(tab_e['e_min'].to(u.MeV))
            emax = np.array(tab_e['e_max'].to(u.MeV))
        except:
            emin = np.array(tab_e['e_min'])
            emax = np.array(tab_e['e_max'])

        ne = len(emin)
        try:
            ref_dnde = np.array(tab_e['ref_dnde'])
        except:
            ref_dnde = np.ones((ne))

        try:
            ref_flux = np.array(tab_e['ref_flux'])
        except:
            ref_flux = np.ones((ne))

        try:
            ref_eflux = np.array(tab_e['ref_eflux'])
        except:
            ref_eflux = np.ones((ne))

        try:
            ref_npred = np.array(tab_e['ref_npred'])
        except:
            ref_npred = np.ones((ne))

        return cls(emin, emax, ref_dnde, ref_flux, ref_eflux, ref_npred)


Instruction:
How would you explain what the following Python 3 function does
def build_ebound_table(self):
        cols = [
            Column(name="E_MIN", dtype=float, data=self._emin, unit='MeV'),
            Column(name="E_MAX", dtype=float, data=self._emax, unit='MeV'),
            Column(name="E_REF", dtype=float, data=self._eref, unit='MeV'),
            Column(name="REF_DNDE", dtype=float, data=self._ref_dnde,
                   unit='ph / (MeV cm2 s)'),
            Column(name="REF_FLUX", dtype=float, data=self._ref_flux,
                   unit='ph / (cm2 s)'),
            Column(name="REF_EFLUX", dtype=float, data=self._ref_eflux,
                   unit='MeV / (cm2 s)'),
            Column(name="REF_NPRED", dtype=float, data=self._ref_npred,
                   unit='ph')
        ]
        tab = Table(data=cols)
        return tab

Response: Build and return an EBOUNDS table with the encapsulated data.


Instruction:
Can you create a Python 3 function that
returns the derivate of the log - like summed over the energy bins.

Response:
def derivative(self, x, der=1):
        """Return the derivate of the log-like summed over the energy
        bins

        Parameters
        ----------
        x   : `~numpy.ndarray`
           Array of N x M values

        der : int
           Order of the derivate

        Returns
        -------
        der_val : `~numpy.ndarray`
           Array of negative log-likelihood values.
        """
        if len(x.shape) == 1:
            der_val = np.zeros((1))
        else:
            der_val = np.zeros((x.shape[1:]))

        for i, xv in enumerate(x):
            der_val += self._loglikes[i].interp.derivative(xv, der=der)
        return der_val


Instruction:
How would you explain what the following Python 3 function does
def mles(self):
        mle_vals = np.ndarray((self._nx))
        for i in range(self._nx):
            mle_vals[i] = self._loglikes[i].mle()
        return mle_vals

Response: return the maximum likelihood estimates for each of the energy bins


Instruction:
Write a Python 3 function that can
return test statistic values for each energy bin

Response:
def ts_vals(self):
        """ returns test statistic values for each energy bin
        """
        ts_vals = np.ndarray((self._nx))
        for i in range(self._nx):
            ts_vals[i] = self._loglikes[i].TS()

        return ts_vals


Instruction:
Given the following Python 3 function, write the documentation
def chi2_vals(self, x):

        chi2_vals = np.ndarray((self._nx))
        for i in range(self._nx):

            mle = self._loglikes[i].mle()
            nll0 = self._loglikes[i].interp(mle)
            nll1 = self._loglikes[i].interp(x[i])
            chi2_vals[i] = 2.0 * np.abs(nll0 - nll1)

        return chi2_vals

Response: Compute the difference in the log - likelihood between the MLE in each energy bin and the normalization predicted by the global best - fit model.


Instruction:
Can you generate the documentation for the following Python 3 function
def getLimits(self, alpha, upper=True):
        limit_vals = np.ndarray((self._nx))

        for i in range(self._nx):
            limit_vals[i] = self._loglikes[i].getLimit(alpha, upper)

        return limit_vals

Response: Evaluate the limits corresponding to a C. L of alpha%.


Instruction:
Write a Python 3 script for
evaluating the two - sided intervals corresponding to a C. L. of alpha%.

Response:
def getIntervals(self, alpha):
        """ Evaluate the two-sided intervals corresponding to a C.L. of
        (1-alpha)%.

        Parameters
        ----------
        alpha :  float
           limit confidence level.

        Returns
        -------
        limit_vals_hi : `~numpy.ndarray`
            An array of lower limit values.

        limit_vals_lo : `~numpy.ndarray`
            An array of upper limit values.
        """
        limit_vals_lo = np.ndarray((self._nx))
        limit_vals_hi = np.ndarray((self._nx))

        for i in range(self._nx):
            lo_lim, hi_lim = self._loglikes[i].getInterval(alpha)
            limit_vals_lo[i] = lo_lim
            limit_vals_hi[i] = hi_lim

        return limit_vals_lo, limit_vals_hi


Instruction:
Can you write a function in Python 3 where it
fits the normalization given a set of spectral values that define a spectral shape and limits of the derivatvie.

Response:
def fitNormalization(self, specVals, xlims):
        """Fit the normalization given a set of spectral values that
        define a spectral shape

        This version is faster, and solves for the root of the derivatvie

        Parameters
        ----------
        specVals :  an array of (nebin values that define a spectral shape
        xlims    :  fit limits

        returns the best-fit normalization value
        """
        from scipy.optimize import brentq

        def fDeriv(x): return self.norm_derivative(specVals, x)
        try:
            result = brentq(fDeriv, xlims[0], xlims[1])
        except:
            check_underflow = self.__call__(specVals * xlims[0]) < \
                self.__call__(specVals * xlims[1])
            if check_underflow.any():
                return xlims[0]
            else:
                return xlims[1]
        return result


Instruction:
Can you generate the documentation for the following Python 3 function
def fitNorm_v2(self, specVals):
        from scipy.optimize import fmin

        def fToMin(x): return self.__call__(specVals * x)
        result = fmin(fToMin, 0., disp=False, xtol=1e-6)
        return result

Response:
Fit the normalization given a set of spectral values
        that define a spectral shape. This version uses scipy. optimize. fmin.


Instruction:
How would you implement a function in Python 3 that
fits a spectral function to a set of parameters.

Response:
def fit_spectrum(self, specFunc, initPars, freePars=None):
        """ Fit for the free parameters of a spectral function

        Parameters
        ----------
        specFunc : `~fermipy.spectrum.SpectralFunction`
            The Spectral Function

        initPars : `~numpy.ndarray`
            The initial values of the parameters

        freePars : `~numpy.ndarray`
            Boolean array indicating which parameters should be free in
            the fit.

        Returns
        -------
        params : `~numpy.ndarray`
            Best-fit parameters.

        spec_vals : `~numpy.ndarray`
            The values of the best-fit spectral model in each energy bin.

        ts_spec : float
            The TS of the best-fit spectrum

        chi2_vals : `~numpy.ndarray`
            Array of chi-squared values for each energy bin.

        chi2_spec : float
            Global chi-squared value for the sum of all energy bins.

        pval_spec : float
            p-value of chi-squared for the best-fit spectrum.
        """
        if not isinstance(specFunc, SEDFunctor):
            specFunc = self.create_functor(specFunc, initPars,
                                           scale=specFunc.scale)

        if freePars is None:
            freePars = np.empty(len(initPars), dtype=bool)
            freePars.fill(True)

        initPars = np.array(initPars)
        freePars = np.array(freePars)

        def fToMin(x):

            xp = np.array(specFunc.params)
            xp[freePars] = x
            return self.__call__(specFunc(xp))

        result = fmin(fToMin, initPars[freePars], disp=False, xtol=1e-6)

        out_pars = specFunc.params
        out_pars[freePars] = np.array(result)

        spec_vals = specFunc(out_pars)
        spec_npred = np.zeros(len(spec_vals))

        if isinstance(specFunc, spectrum.SEDFluxFunctor):
            spec_npred = spec_vals * self.refSpec.ref_npred / self.refSpec.ref_flux
        elif isinstance(specFunc, spectrum.SEDEFluxFunctor):
            spec_npred = spec_vals * self.refSpec.ref_npred / self.refSpec.ref_eflux

        ts_spec = self.TS_spectrum(spec_vals)
        chi2_vals = self.chi2_vals(spec_vals)
        chi2_spec = np.sum(chi2_vals)
        pval_spec = stats.distributions.chi2.sf(chi2_spec, len(spec_vals))
        return dict(params=out_pars, spec_vals=spec_vals,
                    spec_npred=spec_npred,
                    ts_spec=ts_spec, chi2_spec=chi2_spec,
                    chi2_vals=chi2_vals, pval_spec=pval_spec)


Instruction:
Can you generate the documentation for the following Python 3 function
def build_scandata_table(self):
        shape = self._norm_vals.shape
        col_norm = Column(name="norm", dtype=float)
        col_normv = Column(name="norm_scan", dtype=float,
                           shape=shape)
        col_dll = Column(name="dloglike_scan", dtype=float,
                         shape=shape)
        tab = Table(data=[col_norm, col_normv, col_dll])
        tab.add_row({"norm": 1.,
                     "norm_scan": self._norm_vals,
                     "dloglike_scan": -1 * self._nll_vals})
        return tab

Response: Build an astropy. table. Table object from these data.


Instruction:
Can you implement a function in Python 3 that
combines the log - likelihoods from a number of components.

Response:
def stack_nll(shape, components, ylims, weights=None):
        """Combine the log-likelihoods from a number of components.

        Parameters
        ----------
        shape    :  tuple
           The shape of the return array

        components : `~fermipy.castro.CastroData_Base`
           The components to be stacked

        weights : array-like

        Returns
        -------
        norm_vals : `numpy.ndarray`
           N X M array of Normalization values

        nll_vals  : `numpy.ndarray`
           N X M array of log-likelihood values

        nll_offsets :  `numpy.ndarray`
           N array of maximum log-likelihood values in each bin

        """
        n_bins = shape[0]
        n_vals = shape[1]

        if weights is None:
            weights = np.ones((len(components)))

        norm_vals = np.zeros(shape)
        nll_vals = np.zeros(shape)
        nll_offsets = np.zeros((n_bins))
        for i in range(n_bins):
            log_min = np.log10(ylims[0])
            log_max = np.log10(ylims[1])
            norm_vals[i, 1:] = np.logspace(log_min, log_max, n_vals - 1)
            for c, w in zip(components, weights):
                nll_vals[i] += w * c[i].interp(norm_vals[i]) - c.nll_offsets[i]

            # Reset the offsets
            nll_obj = LnLFn(norm_vals[i], nll_vals[i])
            ll_offset = nll_obj.fn_mle()
            nll_vals[i] -= ll_offset
            nll_offsets[i] = -ll_offset
            pass

        return norm_vals, nll_vals, nll_offsets


Instruction:
Can you generate the documentation for the following Python 3 function
def create_from_yamlfile(cls, yamlfile):
        data = load_yaml(yamlfile)
        nebins = len(data)
        emin = np.array([data[i]['emin'] for i in range(nebins)])
        emax = np.array([data[i]['emax'] for i in range(nebins)])
        ref_flux = np.array([data[i]['flux'][1] for i in range(nebins)])
        ref_eflux = np.array([data[i]['eflux'][1] for i in range(nebins)])
        conv = np.array([data[i]['eflux2npred'] for i in range(nebins)])
        ref_npred = conv*ref_eflux
        ones = np.ones(ref_flux.shape)
        ref_spec = ReferenceSpec(emin, emax, ones, ref_flux, ref_eflux, ref_npred)
        norm_data = np.array([data[i]['eflux'] for i in range(nebins)])
        ll_data =  np.array([data[i]['logLike'] for i in range(nebins)])
        max_ll = ll_data.max(1)
        nll_data = (max_ll - ll_data.T).T
        return cls(norm_data, nll_data, ref_spec, 'eflux')

Response:
Create a Castro data object from a yaml file contains
        the likelihood data.


Instruction:
Write a Python 3 function for
creating a Castro data object from a text file containing differential flux points.

Response:
def create_from_flux_points(cls, txtfile):
        """Create a Castro data object from a text file containing a
        sequence of differential flux points."""

        tab = Table.read(txtfile, format='ascii.ecsv')
        dnde_unit = u.ph / (u.MeV * u.cm ** 2 * u.s)
        loge = np.log10(np.array(tab['e_ref'].to(u.MeV)))
        norm = np.array(tab['norm'].to(dnde_unit))
        norm_errp = np.array(tab['norm_errp'].to(dnde_unit))
        norm_errn = np.array(tab['norm_errn'].to(dnde_unit))
        norm_err = 0.5 * (norm_errp + norm_errn)
        dloge = loge[1:] - loge[:-1]
        dloge = np.insert(dloge, 0, dloge[0])
        emin = 10 ** (loge - dloge * 0.5)
        emax = 10 ** (loge + dloge * 0.5)
        ectr = 10 ** loge
        deltae = emax - emin
        flux = norm * deltae
        eflux = norm * deltae * ectr

        ones = np.ones(flux.shape)
        ref_spec = ReferenceSpec(emin, emax, ones, ones, ones, ones)

        spec_data = SpecData(ref_spec, norm, flux, eflux, norm_err)

        stephi = np.linspace(0, 1, 11)
        steplo = -np.linspace(0, 1, 11)[1:][::-1]

        loscale = 3 * norm_err
        hiscale = 3 * norm_err
        loscale[loscale > norm] = norm[loscale > norm]

        norm_vals_hi = norm[:, np.newaxis] + \
            stephi[np.newaxis, :] * hiscale[:, np.newaxis]
        norm_vals_lo = norm[:, np.newaxis] + \
            steplo[np.newaxis, :] * loscale[:, np.newaxis]

        norm_vals = np.hstack((norm_vals_lo, norm_vals_hi))
        nll_vals = 0.5 * \
            (norm_vals - norm[:, np.newaxis]) ** 2 / \
            norm_err[:, np.newaxis] ** 2

        norm_vals *= flux[:, np.newaxis] / norm[:, np.newaxis]

        return cls(norm_vals, nll_vals, spec_data, 'flux')


Instruction:
Given the following Python 3 function, write the documentation
def create_from_tables(cls, norm_type='eflux',
                           tab_s="SCANDATA",
                           tab_e="EBOUNDS"):
        """Create a CastroData object from two tables

        Parameters
        ----------
        norm_type : str
            Type of normalization to use.  Valid options are:

            * norm : Normalization w.r.t. to test source
            * flux : Flux of the test source ( ph cm^-2 s^-1 )
            * eflux: Energy Flux of the test source ( MeV cm^-2 s^-1 )
            * npred: Number of predicted photons (Not implemented)
            * dnde : Differential flux of the test source ( ph cm^-2 s^-1
              MeV^-1 )

        tab_s : str
           table scan data

        tab_e : str
           table energy binning and normalization data

        Returns
        -------
        castro : `~fermipy.castro.CastroData`
        """
        if norm_type in ['flux', 'eflux', 'dnde']:
            norm_vals = np.array(tab_s['norm_scan'] *
                                 tab_e['ref_%s' % norm_type][:, np.newaxis])
        elif norm_type == "norm":
            norm_vals = np.array(tab_s['norm_scan'])
        else:
            raise Exception('Unrecognized normalization type: %s' % norm_type)

        nll_vals = -np.array(tab_s['dloglike_scan'])

        rs = ReferenceSpec.create_from_table(tab_e)
        return cls(norm_vals, nll_vals, rs, norm_type)

Response: Create a CastroData object from two tables.


Instruction:
Here you have a function in Python 3, explain what it does
def create_from_fits(cls, fitsfile, norm_type='eflux',
                         hdu_scan="SCANDATA",
                         hdu_energies="EBOUNDS",
                         irow=None):
        """Create a CastroData object from a tscube FITS file.

        Parameters
        ----------
        fitsfile  : str
            Name of the fits file

        norm_type : str
            Type of normalization to use.  Valid options are:

            * norm : Normalization w.r.t. to test source
            * flux : Flux of the test source ( ph cm^-2 s^-1 )
            * eflux: Energy Flux of the test source ( MeV cm^-2 s^-1 )
            * npred: Number of predicted photons (Not implemented)
            * dnde : Differential flux of the test source ( ph cm^-2 s^-1
              MeV^-1 )

        hdu_scan : str
            Name of the FITS HDU with the scan data

        hdu_energies : str
            Name of the FITS HDU with the energy binning and
            normalization data

        irow : int or None
            If none, then this assumes that there is a single row in
            the scan data table Otherwise, this specifies which row of
            the table to use

        Returns
        -------
        castro : `~fermipy.castro.CastroData`

        """
        if irow is not None:
            tab_s = Table.read(fitsfile, hdu=hdu_scan)[irow]
        else:
            tab_s = Table.read(fitsfile, hdu=hdu_scan)
        tab_e = Table.read(fitsfile, hdu=hdu_energies)

        tab_s = convert_sed_cols(tab_s)
        tab_e = convert_sed_cols(tab_e)

        return cls.create_from_tables(norm_type, tab_s, tab_e)

Response: Create a CastroData object from a tscube FITS file.


Instruction:
Write a Python 3 function for
creating a CastroData object from an SED fits file.

Response:
def create_from_sedfile(cls, fitsfile, norm_type='eflux'):
        """Create a CastroData object from an SED fits file

        Parameters
        ----------
        fitsfile  : str
            Name of the fits file

        norm_type : str
            Type of normalization to use, options are:

            * norm : Normalization w.r.t. to test source
            * flux : Flux of the test source ( ph cm^-2 s^-1 )
            * eflux: Energy Flux of the test source ( MeV cm^-2 s^-1 )
            * npred: Number of predicted photons (Not implemented)
            * dnde : Differential flux of the test source ( ph cm^-2 s^-1
              MeV^-1 )

        Returns
        -------
        castro : `~fermipy.castro.CastroData`
        """
        tab_s = Table.read(fitsfile, hdu=1)
        tab_s = convert_sed_cols(tab_s)

        if norm_type in ['flux', 'eflux', 'dnde']:
            ref_colname = 'ref_%s' % norm_type
            norm_vals = np.array(tab_s['norm_scan'] *
                                 tab_s[ref_colname][:, np.newaxis])
        elif norm_type == "norm":
            norm_vals = np.array(tab_s['norm_scan'])
        else:
            raise ValueError('Unrecognized normalization type: %s' % norm_type)

        nll_vals = -np.array(tab_s['dloglike_scan'])
        ref_spec = ReferenceSpec.create_from_table(tab_s)
        spec_data = SpecData(ref_spec, tab_s['norm'], tab_s['norm_err'])
        return cls(norm_vals, nll_vals, spec_data, norm_type)


Instruction:
Here you have a function in Python 3, explain what it does
def create_from_stack(cls, shape, components, ylims, weights=None):
        if len(components) == 0:
            return None
        norm_vals, nll_vals, nll_offsets = CastroData_Base.stack_nll(shape,
                                                                     components,
                                                                     ylims,
                                                                     weights)
        return cls(norm_vals, nll_vals,
                   components[0].refSpec,
                   components[0].norm_type)

Response: Creates a new instance of the class from a stack of log - likelihoods.


Instruction:
Write a Python 3 function that can
return the log - likelihood for a particular spectrum

Response:
def spectrum_loglike(self, specType, params, scale=1E3):
        """ return the log-likelihood for a particular spectrum

        Parameters
        ----------
        specTypes  : str
            The type of spectrum to try

        params : array-like
            The spectral parameters

        scale : float
            The energy scale or 'pivot' energy
        """
        sfn = self.create_functor(specType, scale)[0]
        return self.__call__(sfn(params))


Instruction:
Here you have a function in Python 3, explain what it does
def create_functor(self, specType, initPars=None, scale=1E3):

        emin = self._refSpec.emin
        emax = self._refSpec.emax

        fn = SpectralFunction.create_functor(specType,
                                             self.norm_type,
                                             emin,
                                             emax,
                                             scale=scale)

        if initPars is None:
            if specType == 'PowerLaw':
                initPars = np.array([5e-13, -2.0])
            elif specType == 'LogParabola':
                initPars = np.array([5e-13, -2.0, 0.0])
            elif specType == 'PLExpCutoff':
                initPars = np.array([5e-13, -1.0, 1E4])

        fn.params = initPars
        return fn

Response: Create a functor object that computes normalizations in the given spectral model class.


Instruction:
Make a summary of the following Python 3 code
def create_from_fits(cls, fitsfile, norm_type='flux'):
        tsmap = WcsNDMap.read(fitsfile)

        tab_e = Table.read(fitsfile, 'EBOUNDS')
        tab_s = Table.read(fitsfile, 'SCANDATA')
        tab_f = Table.read(fitsfile, 'FITDATA')

        tab_e = convert_sed_cols(tab_e)
        tab_s = convert_sed_cols(tab_s)
        tab_f = convert_sed_cols(tab_f)

        emin = np.array(tab_e['e_min'])
        emax = np.array(tab_e['e_max'])
        try:
            if str(tab_e['e_min'].unit) == 'keV':
                emin /= 1000.
        except:
            pass
        try:
            if str(tab_e['e_max'].unit) == 'keV':
                emax /= 1000.
        except:
            pass

        nebins = len(tab_e)
        npred = tab_e['ref_npred']

        ndim = len(tsmap.data.shape)

        if ndim == 2:
            cube_shape = (tsmap.data.shape[0],
                          tsmap.data.shape[1], nebins)
        elif ndim == 1:
            cube_shape = (tsmap.data.shape[0], nebins)
        else:
            raise RuntimeError("Counts map has dimension %i" % (ndim))

        refSpec = ReferenceSpec.create_from_table(tab_e)
        nll_vals = -np.array(tab_s["dloglike_scan"])
        norm_vals = np.array(tab_s["norm_scan"])

        axis = MapAxis.from_edges(np.concatenate((emin, emax[-1:])),
                                  interp='log')
        geom_3d = tsmap.geom.to_cube([axis])
        tscube = WcsNDMap(geom_3d,
                          np.rollaxis(tab_s["ts"].reshape(cube_shape), 2, 0))

        ncube = WcsNDMap(geom_3d,
                         np.rollaxis(tab_s["norm"].reshape(cube_shape), 2, 0))
        nmap = WcsNDMap(tsmap.geom,
                        tab_f['fit_norm'].reshape(tsmap.data.shape))

        ref_colname = 'ref_%s' % norm_type
        norm_vals *= tab_e[ref_colname][np.newaxis, :, np.newaxis]

        return cls(tsmap, nmap, tscube, ncube,
                   norm_vals, nll_vals, refSpec,
                   norm_type)

Response: Create a TSCube object from a FITS file created by gttscubeFITS.


Instruction:
Given the following Python 3 function, write the documentation
def castroData_from_ipix(self, ipix, colwise=False):
        # pix = utils.skydir_to_pix
        if colwise:
            ipix = self._tsmap.ipix_swap_axes(ipix, colwise)
        norm_d = self._norm_vals[ipix]
        nll_d = self._nll_vals[ipix]
        return CastroData(norm_d, nll_d, self._refSpec, self._norm_type)

Response: Build a CastroData object for a particular pixel


Instruction:
Write a Python 3 script for
building a CastroData object for a particular pixel

Response:
def castroData_from_pix_xy(self, xy, colwise=False):
        """ Build a CastroData object for a particular pixel """
        ipix = self._tsmap.xy_pix_to_ipix(xy, colwise)
        return self.castroData_from_ipix(ipix)


Instruction:
Here you have a function in Python 3, explain what it does
def find_and_refine_peaks(self, threshold, min_separation=1.0,
                              use_cumul=False):
        """Run a simple peak-finding algorithm, and fit the peaks to
        paraboloids to extract their positions and error ellipses.

        Parameters
        ----------
        threshold : float
            Peak threshold in TS.

        min_separation : float
            Radius of region size in degrees.  Sets the minimum allowable
            separation between peaks.

        use_cumul : bool
            If true, used the cumulative TS map (i.e., the TS summed
            over the energy bins) instead of the TS Map from the fit
            to and index=2 powerlaw.

        Returns
        -------
        peaks    : list
            List of dictionaries containing the location and amplitude of
            each peak.  Output of `~fermipy.sourcefind.find_peaks`

        """
        if use_cumul:
            theMap = self._ts_cumul
        else:
            theMap = self._tsmap

        peaks = find_peaks(theMap, threshold, min_separation)
        for peak in peaks:
            o, skydir = fit_error_ellipse(theMap, (peak['ix'], peak['iy']),
                                          dpix=2)
            peak['fit_loc'] = o
            peak['fit_skydir'] = skydir
            if o['fit_success']:
                skydir = peak['fit_skydir']
            else:
                skydir = peak['skydir']

        return peaks

Response: Run a simple peak - finding algorithm and extract the positions and error ellipses of the peaks to the TS map.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def make_lat_lons(cvects):
    lats = np.degrees(np.arcsin(cvects[2]))
    lons = np.degrees(np.arctan2(cvects[0], cvects[1]))
    return np.hstack([lats, lons])

Response: Convert from directional cosines to latitidue and longitude


Instruction:
Can you generate the documentation for the following Python 3 function
def make_cos_vects(lon_vect, lat_vect):
    lon_rad = np.radians(lon_vect)
    lat_rad = np.radians(lat_vect)
    cvals = np.cos(lat_rad)
    xvals = cvals * np.sin(lon_rad)
    yvals = cvals * np.cos(lon_rad)
    zvals = np.sin(lat_rad)
    cvects = np.vstack([xvals, yvals, zvals])
    return cvects

Response: Convert from longitude and latitude values to directional cosines.


Instruction:
How would you explain what the following Python 3 function does
def find_matches_by_distance(cos_vects, cut_dist):
    dist_rad = np.radians(cut_dist)
    cos_t_cut = np.cos(dist_rad)
    nsrc = cos_vects.shape[1]
    match_dict = {}
    for i, v1 in enumerate(cos_vects.T):
        cos_t_vect = (v1 * cos_vects.T).sum(1)
        cos_t_vect[cos_t_vect < -1.0] = -1.0
        cos_t_vect[cos_t_vect > 1.0] = 1.0
        mask = cos_t_vect > cos_t_cut
        acos_t_vect = np.ndarray(nsrc)
        # The 1e-6 is here b/c we use 0.0 for sources that failed the cut elsewhere.
        # We should maybe do this better, but it works for now.
        acos_t_vect[mask] = np.degrees(np.arccos(cos_t_vect[mask])) + 1e-6
        for j in np.where(mask[:i])[0]:
            match_dict[(j, i)] = acos_t_vect[j]

    return match_dict

Response: Find all the pairs of sources within a given distance of each other.


Instruction:
Make a summary of the following Python 3 code
def find_matches_by_sigma(cos_vects, unc_vect, cut_sigma):
    match_dict = {}
    sig_2_vect = unc_vect * unc_vect
    for i, v1 in enumerate(cos_vects.T):
        cos_t_vect = (v1 * cos_vects.T).sum(1)
        cos_t_vect[cos_t_vect < -1.0] = -1.0
        cos_t_vect[cos_t_vect > 1.0] = 1.0
        sig_2_i = sig_2_vect[i]
        acos_t_vect = np.degrees(np.arccos(cos_t_vect))
        total_unc = np.sqrt(sig_2_i + sig_2_vect)
        sigma_vect = acos_t_vect / total_unc
        mask = sigma_vect < cut_sigma
        for j in np.where(mask[:i])[0]:
            match_dict[(j, i)] = sigma_vect[j]

    return match_dict

Response: Find all the pairs of sources within a given distance of each other.


Instruction:
Here you have a function in Python 3, explain what it does
def fill_edge_matrix(nsrcs, match_dict):
    e_matrix = np.zeros((nsrcs, nsrcs))
    for k, v in match_dict.items():
        e_matrix[k[0], k[1]] = v
    return e_matrix

Response: Create and fill a matrix with the edges between sources.


Instruction:
Can you create a Python 3 function that
makes a reverse dictionary of the cluster list.

Response:
def make_rev_dict_unique(cdict):
    """ Make a reverse dictionary

    Parameters
    ----------
    in_dict : dict(int:dict(int:True))
       A dictionary of clusters.  Each cluster is a source index and
       the dictionary of other sources in the cluster.

    Returns
    -------
    rev_dict : dict(int:dict(int:True))
       A dictionary pointing from source index to the clusters it is
       included in.

    """
    rev_dict = {}
    for k, v in cdict.items():
        if k in rev_dict:
            rev_dict[k][k] = True
        else:
            rev_dict[k] = {k: True}
        for vv in v.keys():
            if vv in rev_dict:
                rev_dict[vv][k] = True
            else:
                rev_dict[vv] = {k: True}
    return rev_dict


Instruction:
Create a Python 3 function for
finding clusters from the spanning tree Parameters ---------- span_tree : a sparse nsrcs x nsrcs array Filled with zeros except for the active edges, which are filled with the edge measures (either distances or sigmas cut_value : float Value used to cluster group. All links with measures above this calue will be cut. returns dict(int:[int,...]) A dictionary of clusters. Each cluster is a source index and the list of other sources in the cluster.

Response:
def make_clusters(span_tree, cut_value):
    """ Find clusters from the spanning tree

    Parameters
    ----------
    span_tree : a sparse nsrcs x nsrcs array
       Filled with zeros except for the active edges, which are filled with the
       edge measures (either distances or sigmas

    cut_value : float
       Value used to cluster group.  All links with measures above this calue will be cut.

    returns dict(int:[int,...])
       A dictionary of clusters.   Each cluster is a source index and the list of other sources in the cluster.
    """
    iv0, iv1 = span_tree.nonzero()

    # This is the dictionary of all the pairings for each source
    match_dict = {}

    for i0, i1 in zip(iv0, iv1):
        d = span_tree[i0, i1]
        # Cut on the link distance
        if d > cut_value:
            continue

        imin = int(min(i0, i1))
        imax = int(max(i0, i1))
        if imin in match_dict:
            match_dict[imin][imax] = True
        else:
            match_dict[imin] = {imax: True}

    working = True
    while working:

        working = False
        rev_dict = make_rev_dict_unique(match_dict)
        k_sort = rev_dict.keys()
        k_sort.sort()
        for k in k_sort:
            v = rev_dict[k]
            # Multiple mappings
            if len(v) > 1:
                working = True
                v_sort = v.keys()
                v_sort.sort()
                cluster_idx = v_sort[0]
                for vv in v_sort[1:]:
                    try:
                        to_merge = match_dict.pop(vv)
                    except:
                        continue
                    try:
                        match_dict[cluster_idx].update(to_merge)
                        match_dict[cluster_idx][vv] = True
                    except:
                        continue
                    # remove self references
                    try:
                        match_dict[cluster_idx].pop(cluster_idx)
                    except:
                        pass

    # Convert to a int:list dictionary
    cdict = {}
    for k, v in match_dict.items():
        cdict[k] = v.keys()

    # make the reverse dictionary
    rdict = make_reverse_dict(cdict)
    return cdict, rdict


Instruction:
Can you generate a brief explanation for the following Python 3 code
def select_from_cluster(idx_key, idx_list, measure_vect):
    best_idx = idx_key
    best_measure = measure_vect[idx_key]
    out_list = [idx_key] + idx_list
    for idx, measure in zip(idx_list, measure_vect[idx_list]):
        if measure < best_measure:
            best_idx = idx
            best_measure = measure
    out_list.remove(best_idx)
    return best_idx, out_list

Response: Select a single source from a cluster and make it the new cluster key


Instruction:
Given the following Python 3 function, write the documentation
def find_centroid(cvects, idx_list, weights=None):
    if weights is None:
        weighted = cvects.T[idx_list].sum(0)
        sum_weights = float(len(idx_list))
    else:
        weighted = ((cvects * weights).T[idx_list]).sum(0)
        sum_weights = weights.sum(0)
    weighted /= sum_weights
    # make sure it is normalized
    norm = np.sqrt((weighted * weighted).sum())
    weighted /= norm
    return weighted

Response: Find the centroid for a set of vectors


Instruction:
How would you implement a function in Python 3 that
returns a vector of sources in each cluster.

Response:
def count_sources_in_cluster(n_src, cdict, rev_dict):
    """ Make a vector  of sources in each cluster

    Parameters
    ----------
    n_src : number of sources

    cdict : dict(int:[int,])
        A dictionary of clusters.  Each cluster is a source index and
        the list of other source in the cluster.

    rev_dict : dict(int:int)
       A single valued dictionary pointing from source index to
       cluster key for each source in a cluster.  Note that the key
       does not point to itself.

    Returns
    ----------
    `np.ndarray((n_src),int)' with the number of in the cluster a given source
    belongs to.
    """
    ret_val = np.zeros((n_src), int)
    for i in range(n_src):
        try:
            key = rev_dict[i]
        except KeyError:
            key = i
        try:
            n = len(cdict[key])
        except:
            n = 0
        ret_val[i] = n
    return ret_val


Instruction:
Implement a Python 3 function for
finding the centroid for a set of vectors and return the distances to the centroid

Response:
def find_dist_to_centroid(cvects, idx_list, weights=None):
    """ Find the centroid for a set of vectors

    Parameters
    ----------
    cvects : ~numpy.ndarray(3,nsrc) with directional cosine (i.e., x,y,z component) values

    idx_list : [int,...]
      list of the source indices in the cluster

    weights : ~numpy.ndarray(nsrc) with the weights to use.  None for equal weighting

    returns (np.ndarray(nsrc)) distances to the centroid (in degrees)
    """
    centroid = find_centroid(cvects, idx_list, weights)
    dist_vals = np.degrees(np.arccos((centroid * cvects.T[idx_list]).sum(1)))
    return dist_vals, centroid


Instruction:
Given the following Python 3 function, write the documentation
def find_dist_to_centroids(cluster_dict, cvects, weights=None):
    distances = np.zeros((cvects.shape[1]))
    cent_dict = {}
    for k, v in cluster_dict.items():
        l = [k] + v
        distances[l], centroid = find_dist_to_centroid(cvects, l, weights)
        cent_dict[k] = make_lat_lons(centroid)
    return distances, cent_dict

Response: Find the centroids and the distances to the centroid for all sources in a set of clusters.


Instruction:
Can you generate the documentation for the following Python 3 function
def select_from_clusters(cluster_dict, measure_vect):
    out_dict = {}
    for idx_key, idx_list in cluster_dict.items():
        out_idx, out_list = select_from_cluster(
            idx_key, idx_list, measure_vect)
        out_dict[out_idx] = out_list
    return out_dict

Response: Select a single source from each cluster and make it the new cluster key


Instruction:
Make a summary of the following Python 3 code
def make_reverse_dict(in_dict, warn=True):
    out_dict = {}
    for k, v in in_dict.items():
        for vv in v:
            if vv in out_dict:
                if warn:
                    print("Dictionary collision %i" % vv)
            out_dict[vv] = k
    return out_dict

Response: Build a dictionary that contains the keys of each other source in a cluster.


Instruction:
Can you create a Python 3 function that
converts the cluster membership dictionary to an array containing the index of the seed of a cluster.

Response:
def make_cluster_vector(rev_dict, n_src):
    """ Converts the cluster membership dictionary to an array

    Parameters
    ----------
    rev_dict : dict(int:int)
       A single valued dictionary pointing from source index to
       cluster key for each source in a cluster.

    n_src    : int
       Number of source in the array

    Returns
    -------
    out_array : `numpy.ndarray'
       An array filled with the index of the seed of a cluster if a source belongs to a cluster,
       and with -1 if it does not.
    """
    out_array = -1 * np.ones((n_src), int)
    for k, v in rev_dict.items():
        out_array[k] = v
        # We need this to make sure the see source points at itself
        out_array[v] = v
    return out_array


Instruction:
Can you tell what is the following Python 3 function doing
def make_cluster_name_vector(cluster_vect, src_names):
    out_array = np.where(cluster_vect >= 0, src_names[cluster_vect], "")
    return out_array

Response: Converts the cluster membership dictionary to an array containing the cluster name.


Instruction:
Can you implement a function in Python 3 that
converts the cluster membership array stored in a fits file back to a dictionary.

Response:
def make_dict_from_vector(in_array):
    """ Converts the cluster membership array stored in a fits file back to a dictionary

    Parameters
    ----------
    in_array : `np.ndarray'
       An array filled with the index of the seed of a cluster if a source belongs to a cluster,
       and with -1 if it does not.

    Returns
    -------
    returns dict(int:[int,...])
       Dictionary of clusters keyed by the best source in each cluster
    """
    out_dict = {}
    for i, k in enumerate(in_array):
        if k < 0:
            continue
        try:
            out_dict[k].append(i)
        except KeyError:
            out_dict[k] = [i]
    return out_dict


Instruction:
How would you explain what the following Python 3 function does
def filter_and_copy_table(tab, to_remove):
    nsrcs = len(tab)
    mask = np.zeros((nsrcs), '?')
    mask[to_remove] = True
    inv_mask = np.invert(mask)
    out_tab = tab[inv_mask]
    return out_tab

Response: Filter and copy a FITS table.


Instruction:
How would you code a function in Python 3 to
perform baseline fitting for a target region of Interest.

Response:
def baseline_roi_fit(gta, make_plots=False, minmax_npred=[1e3, np.inf]):
    """Do baseline fitting for a target Region of Interest

    Parameters
    ----------

    gta : `fermipy.gtaanalysis.GTAnalysis`
        The analysis object

    make_plots : bool
        Flag to make standard analysis plots

    minmax_npred : tuple or list
        Range of number of predicted coutns for which to free sources in initial fitting.

    """
    gta.free_sources(False)
    gta.write_roi('base_roi', make_plots=make_plots)

    gta.free_sources(True, minmax_npred=[1e3, np.inf])
    gta.optimize()
    gta.free_sources(False)
    gta.print_roi()


Instruction:
Write a Python 3 function for
adding a source and get the set of correlated sources

Response:
def add_source_get_correlated(gta, name, src_dict, correl_thresh=0.25, non_null_src=False):
    """Add a source and get the set of correlated sources

    Parameters
    ----------

    gta : `fermipy.gtaanalysis.GTAnalysis`
        The analysis object

    name : str
        Name of the source we are adding

    src_dict : dict
        Dictionary of the source parameters

    correl_thresh : float
        Threshold for considering a source to be correlated

    non_null_src : bool
        If True, don't zero the source

    Returns
    -------

    cdict : dict
        Dictionary with names and correlation factors of correlated sources

    test_src_name : bool
        Name of the test source

    """
    if gta.roi.has_source(name):
        gta.zero_source(name)
        gta.update_source(name)
        test_src_name = "%s_test" % name
    else:
        test_src_name = name

    gta.add_source(test_src_name, src_dict)
    gta.free_norm(test_src_name)
    gta.free_shape(test_src_name, free=False)
    fit_result = gta.fit(covar=True)

    mask = fit_result['is_norm']
    src_names = np.array(fit_result['src_names'])[mask]
    idx = (src_names == test_src_name).argmax()
    correl_vals = fit_result['correlation'][idx][mask]

    cdict = {}
    for src_name, correl_val in zip(src_names, correl_vals):
        if src_name == name:
            continue
        if np.fabs(correl_val) > 0.25:
            cdict[src_name] = correl_val

    if not non_null_src:
        gta.zero_source(test_src_name)

    gta.fit(covar=True)

    return cdict, test_src_name


Instruction:
Can you tell what is the following Python 3 function doing
def build_profile_dict(basedir, profile_name):
    profile_path = os.path.join(basedir, "profile_%s.yaml" % profile_name)
    profile_config = load_yaml(profile_path)
    src_name = profile_config['name']
    profile_dict = profile_config['source_model']
    return profile_name, src_name, profile_dict

Response: Build the name and source dictionary for the test source.


Instruction:
Write a Python 3 function for
getting the correct set of arguments for a batch job.

Response:
def get_batch_job_args(job_time=1500):
    """ Get the correct set of batch jobs arguments.

    Parameters
    ----------

    job_time : int
        Expected max length of the job, in seconds.
        This is used to select the batch queue and set the
        job_check_sleep parameter that sets how often
        we check for job completion.

    Returns
    -------
    job_args : dict
        Dictionary of arguments used to submit a batch job

    """
    if DEFAULT_JOB_TYPE == 'slac':
        from fermipy.jobs.slac_impl import get_slac_default_args
        return get_slac_default_args(job_time)
    elif DEFAULT_JOB_TYPE == 'native':
        from fermipy.jobs.native_impl import get_native_default_args
        return get_native_default_args()
    return None


Instruction:
Can you generate a brief explanation for the following Python 3 code
def get_batch_job_interface(job_time=1500):
    batch_job_args = get_batch_job_args(job_time)

    if DEFAULT_JOB_TYPE == 'slac':
        from fermipy.jobs.slac_impl import SlacInterface
        return SlacInterface(**batch_job_args)
    elif DEFAULT_JOB_TYPE == 'native':
        from fermipy.jobs.native_impl import NativeInterface
        return NativeInterface(**batch_job_args)
    return None

Response: Create a batch job interface object.


Instruction:
Create a Python 3 function to
register these classes with the LinkFactory

Response:
def register_classes():
    """Register these classes with the `LinkFactory` """
    CopyBaseROI.register_class()
    CopyBaseROI_SG.register_class()
    SimulateROI.register_class()
    SimulateROI_SG.register_class()
    RandomDirGen.register_class()
    RandomDirGen_SG.register_class()


Instruction:
Implement a function in Python 3 to
copy a list of files from orig_dir to dest_dir

Response:
def copy_analysis_files(cls, orig_dir, dest_dir, copyfiles):
        """ Copy a list of files from orig_dir to dest_dir"""
        for pattern in copyfiles:
            glob_path = os.path.join(orig_dir, pattern)
            files = glob.glob(glob_path)
            for ff in files:
                f = os.path.basename(ff)
                orig_path = os.path.join(orig_dir, f)
                dest_path = os.path.join(dest_dir, f)
                try:
                    copyfile(orig_path, dest_path)
                except IOError:
                    sys.stderr.write("WARNING: failed to copy %s\n" % orig_path)


Instruction:
Can you tell what is the following Python 3 function doing
def copy_target_dir(cls, orig_dir, dest_dir, roi_baseline, extracopy):
        try:
            os.makedirs(dest_dir)
        except OSError:
            pass

        copyfiles = ['%s.fits' % roi_baseline,
                     '%s.npy' % roi_baseline,
                     '%s_*.xml' % roi_baseline] + cls.copyfiles
        if isinstance(extracopy, list):
            copyfiles += extracopy

        cls.copy_analysis_files(orig_dir, dest_dir, copyfiles)

Response: Copy the target directory to dest_dir.


Instruction:
Can you create a Python 3 function that
hooks to build job configurations based on arguments

Response:
def build_job_configs(self, args):
        """Hook to build job configurations
        """
        job_configs = {}

        ttype = args['ttype']
        (sim_targets_yaml, sim) = NAME_FACTORY.resolve_targetfile(args)
        targets = load_yaml(sim_targets_yaml)

        base_config = dict(ttype=ttype,
                           roi_baseline=args['roi_baseline'],
                           extracopy = args['extracopy'],
                           sim=sim)

        for target_name in targets.keys():
            targetdir = NAME_FACTORY.sim_targetdir(target_type=ttype,
                                                   target_name=target_name,
                                                   sim_name=sim)
            logfile = os.path.join(targetdir, 'copy_base_dir.log')
            job_config = base_config.copy()
            job_config.update(dict(target=target_name,
                                   logfile=logfile))
            job_configs[target_name] = job_config

        return job_configs


Instruction:
Implement a function in Python 3 to
build a WCS. Geom object from a fermipy coniguration file

Response:
def _make_wcsgeom_from_config(config):
        """Build a `WCS.Geom` object from a fermipy coniguration file"""

        binning = config['binning']
        binsz = binning['binsz']
        coordsys = binning.get('coordsys', 'GAL')
        roiwidth = binning['roiwidth']
        proj = binning.get('proj', 'AIT')
        ra = config['selection']['ra']
        dec = config['selection']['dec']
        npix = int(np.round(roiwidth / binsz))
        skydir = SkyCoord(ra * u.deg, dec * u.deg)

        wcsgeom = WcsGeom.create(npix=npix, binsz=binsz,
                                 proj=proj, coordsys=coordsys,
                                 skydir=skydir)
        return wcsgeom


Instruction:
Explain what the following Python 3 code does
def _build_skydir_dict(wcsgeom, rand_config):
        step_x = rand_config['step_x']
        step_y = rand_config['step_y']
        max_x = rand_config['max_x']
        max_y = rand_config['max_y']
        seed = rand_config['seed']
        nsims = rand_config['nsims']

        cdelt = wcsgeom.wcs.wcs.cdelt
        pixstep_x = step_x / cdelt[0]
        pixstep_y = -1. * step_y / cdelt[1]
        pixmax_x = max_x / cdelt[0]
        pixmax_y = max_y / cdelt[0]

        nstep_x = int(np.ceil(2. * pixmax_x / pixstep_x)) + 1
        nstep_y = int(np.ceil(2. * pixmax_y / pixstep_y)) + 1

        center = np.array(wcsgeom._center_pix)

        grid = np.meshgrid(np.linspace(-1 * pixmax_x, pixmax_x, nstep_x),
                           np.linspace(-1 * pixmax_y, pixmax_y, nstep_y))
        grid[0] += center[0]
        grid[1] += center[1]

        test_grid = wcsgeom.pix_to_coord(grid)
        glat_vals = test_grid[0].flat
        glon_vals = test_grid[1].flat
        conv_vals = SkyCoord(glat_vals * u.deg, glon_vals *
                             u.deg, frame=Galactic).transform_to(ICRS)

        ra_vals = conv_vals.ra.deg[seed:nsims]
        dec_vals = conv_vals.dec.deg[seed:nsims]

        o_dict = {}
        for i, (ra, dec) in enumerate(zip(ra_vals, dec_vals)):
            key = i + seed
            o_dict[key] = dict(ra=ra, dec=dec)
        return o_dict

Response: Build a dictionary of random directions for a set of sky locations.


Instruction:
Can you implement a function in Python 3 that
clones the configuration and srcmaps

Response:
def _clone_config_and_srcmaps(config_path, seed):
        """Clone the configuration"""
        workdir = os.path.dirname(config_path)
        new_config_path = config_path.replace('.yaml', '_%06i.yaml' % seed)
        config = load_yaml(config_path)
        comps = config.get('components', [config])
        for i, comp in enumerate(comps):
            comp_name = "%02i" % i
            if 'gtlike' not in comp:
                comp['gtlike'] = {}
            orig_srcmap = os.path.abspath(os.path.join(workdir, 'srcmap_%s.fits' % (comp_name)))
            new_srcmap = os.path.abspath(os.path.join(workdir, 'srcmap_%06i_%s.fits' % (seed, comp_name)))
            comp['gtlike']['srcmap'] = os.path.abspath(os.path.join(workdir, 'srcmap_%06i_%s.fits' % (seed, comp_name)))
            comp['gtlike']['use_external_srcmap'] = True
            copyfile(orig_srcmap, new_srcmap)

        write_yaml(config, new_config_path)
        return new_config_path


Instruction:
Create a Python 3 function to
simulate a realization of a test set.

Response:
def _run_simulation(gta, roi_baseline,
                        injected_name, test_sources, current_seed, seed, non_null_src):
        """Simulate a realization of this analysis"""
        gta.load_roi('sim_baseline_%06i.npy' % current_seed)
        gta.set_random_seed(seed)
        gta.simulate_roi()
        if injected_name:
            gta.zero_source(injected_name)

        gta.optimize()
        gta.find_sources(sqrt_ts_threshold=5.0, search_skydir=gta.roi.skydir,
                         search_minmax_radius=[1.0, np.nan])
        gta.optimize()
        gta.free_sources(skydir=gta.roi.skydir, distance=1.0, pars='norm')
        gta.fit(covar=True)
        gta.write_roi('sim_refit_%06i' % current_seed)

        for test_source in test_sources:
            test_source_name = test_source['name']
            sedfile = "sed_%s_%06i.fits" % (test_source_name, seed)
            correl_dict, test_src_name = add_source_get_correlated(gta, test_source_name,
                                                                   test_source['source_model'],
                                                                   correl_thresh=0.25,
                                                                   non_null_src=non_null_src)

            # Write the list of correlated sources
            correl_yaml = os.path.join(gta.workdir,
                                       "correl_%s_%06i.yaml" % (test_source_name, seed))
            write_yaml(correl_dict, correl_yaml)

            gta.free_sources(False)
            for src_name in correl_dict.keys():
                gta.free_source(src_name, pars='norm')

            gta.sed(test_source_name, prefix=pkey, outfile=sedfile)
            # Set things back to how they were
            gta.delete_source(test_source_name)
            gta.load_xml('sim_refit_%06i' % current_seed)


Instruction:
Given the following Python 3 function, write the documentation
def build_job_configs(self, args):
        job_configs = {}

        ttype = args['ttype']
        (targets_yaml, sim) = NAME_FACTORY.resolve_targetfile(args)
        if targets_yaml is None:
            return job_configs

        config_yaml = 'config.yaml'
        config_override = args.get('config')
        if is_not_null(config_override):
            config_yaml = config_override

        rand_yaml = NAME_FACTORY.resolve_randconfig(args)

        targets = load_yaml(targets_yaml)

        base_config = dict(rand_config=rand_yaml)

        for target_name in targets.keys():
            name_keys = dict(target_type=ttype,
                             target_name=target_name,
                             sim_name=sim,
                             fullpath=True)
            simdir = NAME_FACTORY.sim_targetdir(**name_keys)
            config_path = os.path.join(simdir, config_yaml)
            outfile = os.path.join(simdir, 'skydirs.yaml')
            logfile = make_nfs_path(outfile.replace('yaml', 'log'))
            job_config = base_config.copy()
            job_config.update(dict(config=config_path,
                                   outfile=outfile,
                                   logfile=logfile))
            job_configs[target_name] = job_config

        return job_configs

Response: Hook to build job configurations based on the input arguments.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def build_job_configs(self, args):
        job_configs = {}

        ttype = args['ttype']
        (targets_yaml, sim) = NAME_FACTORY.resolve_targetfile(args)
        if targets_yaml is None:
            return job_configs

        config_yaml = 'config.yaml'
        config_override = args.get('config')
        if is_not_null(config_override):
            config_yaml = config_override

        targets = load_yaml(targets_yaml)
        nsims_job = args['nsims_job']
        first_seed = args['seed']
        nsims = args['nsims']
        last_seed = first_seed + nsims

        base_config = dict(sim_profile=args['sim_profile'],
                           roi_baseline=args['roi_baseline'],
                           non_null_src=args['non_null_src'],
                           sim=sim)

        for target_name, target_list in targets.items():
            name_keys = dict(target_type=ttype,
                             target_name=target_name,
                             sim_name=sim,
                             fullpath=True)
            simdir = NAME_FACTORY.sim_targetdir(**name_keys)
            config_path = os.path.join(simdir, config_yaml)

            job_config = base_config.copy()
            job_config.update(dict(config=config_path,
                                   profiles=target_list))

            current_seed = first_seed
            while current_seed < last_seed:
                fullkey = "%s_%06i" % (target_name, current_seed)
                logfile = make_nfs_path(os.path.join(simdir, "%s_%s_%06i.log" % (self.linkname,
                                                                                target_name, current_seed)))
                if nsims_job <= 0 or current_seed + nsims_job >= last_seed:
                    nsims_current = last_seed - current_seed
                else:
                    nsims_current = nsims_job
                job_config.update(dict(seed=current_seed,
                                       nsims=nsims_current,
                                       logfile=logfile))
                job_configs[fullkey] = job_config.copy()
                current_seed += nsims_current

        return job_configs

Response: Build the job configurations for the given target file.


Instruction:
Can you tell what is the following Python 3 function doing
def get_branches(aliases):

    ignore = ['pow', 'log10', 'sqrt', 'max']
    branches = []
    for k, v in aliases.items():

        tokens = re.sub('[\(\)\+\*\/\,\=\<\>\&\!\-\|]', ' ', v).split()

        for t in tokens:

            if bool(re.search(r'^\d', t)) or len(t) <= 3:
                continue

            if bool(re.search(r'[a-zA-Z]', t)) and t not in ignore:
                branches += [t]

    return list(set(branches))

Response: Get unique branch names from an alias dictionary.


Instruction:
Make a summary of the following Python 3 code
def load_friend_chains(chain, friend_chains, txt, nfiles=None):

    if re.search('.root?', txt) is not None:
        c = ROOT.TChain(chain.GetName())
        c.SetDirectory(0)
        c.Add(txt)
        friend_chains.append(c)
        chain.AddFriend(c, rand_str())
        return

    files = np.loadtxt(txt, unpack=True, dtype='str')
    if files.ndim == 0:
        files = np.array([files])
    if nfiles is not None:
        files = files[:nfiles]
    print("Loading %i files..." % len(files))

    c = ROOT.TChain(chain.GetName())
    c.SetDirectory(0)
    for f in files:
        c.Add(f)
    friend_chains.append(c)

    chain.AddFriend(c, rand_str())
    return

Response:
Load a list of trees from a file and add them as friends to the
    chain.


Instruction:
Make a summary of the following Python 3 code
def find_and_read_ebins(hdulist):
    from fermipy import utils
    ebins = None
    if 'ENERGIES' in hdulist:
        hdu = hdulist['ENERGIES']
        ectr = hdu.data.field(hdu.columns[0].name)
        ebins = np.exp(utils.center_to_edge(np.log(ectr)))
    elif 'EBOUNDS' in hdulist:
        hdu = hdulist['EBOUNDS']
        emin = hdu.data.field('E_MIN') / 1E3
        emax = hdu.data.field('E_MAX') / 1E3
        ebins = np.append(emin, emax[-1])
    return ebins

Response: Reads and returns the energy bin edges of the current resource.