Beispiel #1
0
def set_arrays(filename, args, fields=None, ascii=True, clobber=False):

    if os.path.isfile(filename) and not clobber:
        raise IOErr("filefound", filename)

    if not numpy.iterable(args) or len(args) == 0:
        raise IOErr('noarrayswrite')

    if not numpy.iterable(args[0]):
        raise IOErr('noarrayswrite')

    size = len(args[0])
    for arg in args:
        if not numpy.iterable(arg):
            raise IOErr('noarrayswrite')
        elif len(arg) != size:
            raise IOErr('arraysnoteq')

    if ascii and '[' not in filename and ']' not in filename:
        filename += "[opt kernel=text/simple]"

    tbl = pycrates.TABLECrate()

    if fields is None:
        fields = ['col%i' % (ii + 1) for ii in range(len(args))]

    if len(args) != len(fields):
        raise IOErr('toomanycols', str(len(fields)), str(len(args)))

    for val, name in izip(args, fields):
        _set_column(tbl, name, val)

    pycrates.write_file(tbl, filename, clobber=True)
    close_crate_dataset(tbl.get_dataset())
Beispiel #2
0
def set_table_data(filename,
                   data,
                   col_names,
                   hdr=None,
                   hdrnames=None,
                   ascii=False,
                   clobber=False,
                   packup=False):

    if not packup and os.path.isfile(filename) and not clobber:
        raise IOErr("filefound", filename)

    tbl = pycrates.TABLECrate()

    col_names = [name for name in col_names if data[name] is not None]
    col_names.remove('name')
    try:
        for name in col_names:
            if data[name] is None:
                continue
            _set_column(tbl, name, data[name])

    finally:
        if packup:
            return tbl

        if ascii and '[' not in filename and ']' not in filename:
            filename += "[opt kernel=text/simple]"

        # pycrates.write_file(tbl, filename)
        tbl.write(filename, clobber=True)
        close_crate_dataset(tbl.get_dataset())
Beispiel #3
0
def _arrays_to_crate(arrays, colnames=None):
    """Create a TABLECrate that contains the contents of the
    columns in arrays (each element is a column).

    If colnames is not None then they are used as the column names,
    otherwise values of col1 to colN are used.

    The data arrays used in the crate are references of the
    input values (i.e. they are not copied, unlike _sarray_to_crate).

    Not all data types are necessarily supported.
    """

    na = len(arrays)
    if colnames is None:
        colnames = ["col{}".format(i) for i in range(1, na + 1)]

    else:
        nc = len(colnames)
        if nc != na:
            raise ValueError("Number of columns ({}) and column names ({}) does not match.".format(nc, na))

    cr = pycrates.TABLECrate()
    cr.name = "TABLE"
    for (col, name) in zip(arrays, colnames):
        add_colvals(cr, name, col)

    return cr
def set_table_data(filename,
                   data,
                   col_names,
                   hdr=None,
                   hdrnames=None,
                   ascii=False,
                   clobber=False,
                   packup=False):

    if not packup and not clobber and os.path.isfile(filename):
        raise IOErr("filefound", filename)

    tbl = pycrates.TABLECrate()

    try:
        for name in col_names:
            _set_column(tbl, name, data[name])

    finally:
        if packup:
            return tbl

        if ascii and '[' not in filename and ']' not in filename:
            filename += "[opt kernel=text/simple]"

        # pycrates.write_file(tbl, filename)
        tbl.write(filename, clobber=True)
Beispiel #5
0
    def __init__(self, fov, pixsize=1):
        """Read in the data from the file or crate
        fov.

        An IOError is thrown if the input does not contain
        the necessary information.

        pixsize is the pixelsize to use for the axis grids;
        it must be > 0
        """

        if isinstance(fov, pycrates.TABLECrate):
            cr = fov

            # Unfortunately we lose any filter applied to the
            # filename by the caller using this approach.
            #
            fname = cr.get_filename()

        else:
            cr = pycrates.TABLECrate(fov, mode="r")
            fname = fov

        if pixsize <= 0:
            raise ValueError("pixsize must be > 0, not {}".format(pixsize))

        self.filename = os.path.abspath(fname)
        self.pixsize = pixsize
        self._read_input(cr)
Beispiel #6
0
def _dict_to_crate(d, colnames=None):
    """Create a TABLECrate that contains the contents of the
    dictionary. If colnames is not None then it it an array of names
    that determines the order to add the columns to the crate (and can
    be used to filter out columns). Use of collections.OrderedDict
    rather than a normal dictionary can also be used to determine
    the order of the columns.

    The data arrays used in the crate are references of the
    input values (i.e. they are not copied, unlike _sarray_to_crate).

    Not all data types are necessarily supported.
    """

    cr = pycrates.TABLECrate()
    cr.name = "TABLE"

    if colnames is None:
        names = d.keys()
    else:
        names = colnames

    for cname in names:
        add_colvals(cr, cname, d[cname])

    return cr
Beispiel #7
0
def _sarray_to_crate(sa, colnames=None):
    """Create a TABLECrate that contains the contents
    of the supplied structured/rec array. If colnames is
    not None then it it an array of names that determines
    the order to add the columns to the crate (and can
    be used to filter out columns in sa).

    The arrays in the structured array are explicitly
    copied into the crate to avoid some memory issues
    seen in CIAO 4.4 testing. However, this may not
    resolve all issues so it is suggested that this
    routine is not used at this time.

    Not all data types are necessarily supported.
    """

    cr = pycrates.TABLECrate()
    cr.name = "TABLE"

    if colnames is None:
        names = sa.dtype.names
    else:
        names = colnames

    for cname in names:
        # We copy the values to avoid an issue on writing out the
        # crate; not sure if this is a Crates or NumPy problem
        # and whether this has been fixed since CIAO 4.4 when it
        # was seen
        #
        add_colvals(cr, cname, sa[cname].copy())

    return cr
Beispiel #8
0
def set_pha_data(filename,
                 data,
                 col_names,
                 header=None,
                 ascii=False,
                 clobber=False,
                 packup=False):

    if not packup and os.path.isfile(filename) and not clobber:
        raise IOErr("filefound", filename)

    phadataset = pycrates.phacratedataset.PHACrateDataset()

    # FIXME: Placeholder for pycrates2 bug
    phadataset.set_rw_mode('rw')

    pha = pycrates.TABLECrate()
    pha.name = "SPECTRUM"
    try:

        # Write header values using CrateKey objects
        for key in header.keys():
            if header[key] is None:
                continue
            _set_key(pha, key, header[key])

        # Write column values using CrateData objects
        for name in col_names:
            if data[name] is None:
                continue
            _set_column(pha, name, data[name])

    finally:
        phadataset.add_crate(pha)

        if packup:
            return phadataset

        if ascii and '[' not in filename and ']' not in filename:
            filename += "[opt kernel=text/simple]"

        # pycrates.write_pha(phadataset, filename)
        phadataset.write(filename, clobber=True)
        close_crate_dataset(phadataset)
Beispiel #9
0
def get_caldb_installed(caldb=None):
    """What CIAO CALDB is installed (version and release date)?

    Parameters
    ----------
    caldb : str, optional
        If set, the directory to search in, otherwise the
        CALDB environment variable is used.

    Returns
    -------
    version, date
        The CIAO CALDB version, as a string, and the release date
        of the version (as a date object) of the installed
        CIAO CALDB.

    See Also
    --------
    get_caldb_installed_date, get_caldb_installed_version

    """

    if caldb is None:
        caldb = get_caldb_dir()
    fname = os.path.join(caldb,
                         "docs/chandra/caldb_version/caldb_version.fits")
    cr = pycrates.TABLECrate(fname, mode='r')

    for cname in ["CALDB_VER", "CALDB_DATE"]:
        if not cr.column_exists(cname):
            raise IOError(
                "Unable to find the {} column in the CALDB version file.".
                format(cname))

    cversion = pycrates.copy_colvals(cr, "CALDB_VER")[-1]
    cdate = pycrates.copy_colvals(cr, "CALDB_DATE")[-1]

    cversion = cversion.strip()
    cdate = cdate.strip()

    return (cversion, todate(cdate))
Beispiel #10
0
def write_draws(draws, outfile, params=None, format="ascii"):
    """Writes the draws (except for iteration number 0) to the file outfile.

    Over-writes the file if it exists. If params is given then it
    should be the output of get_parameter_info and is used to
    add extra information to the output file (well, it will do,
    for now it does not).

    The output format is determined by the format parameter; it
    can be one of
      "fits"  - FITS binary table
      "ascii" - simple ASCII table (two comment lines then data)
      "dtf"   - ASCII file in CIAO TEXT/DTF format (CIAO tools can
                treat it similarly to a FITS table)
      None    - let Crates determine, probably because you have
                specified an option within the outfile name
                (specialised use only)
    """

    formats = {"ascii": "text/simple", "dtf": "text/dtf", "fits": "fits"}
    if format != None and not formats.has_key(format.lower()):
        raise RuntimeError, "Unknown output format '%s'" % format

    # Use crates to create the output file.
    #
    cr = crates.TABLECrate()

    # We need to store the crate data objects so that they are not
    # garbage collected until after the write_file() call.
    #
    store = {}

    def create_col(cname, cval):
        store[cname] = crates.CrateData()
        store[cname].name = cname
        if 1 != store[cname].load(cval, 1):
            raise RuntimeError, "Unable to add column %s to the Crate Data object." % cname
        if 1 != crates.add_col(cr, store[cname]):
            raise RuntimeError, "Unable to add column %s to the Crates." % cname

    def create_key(kname, kval, desc=None):
        store[kname] = crates.CrateKey()
        store[kname].name = kname
        if desc != None:
            store[kname].desc = desc
        if 1 != store[kname].load(kval):
            raise RuntimeError, "Unable to set key %s to %g" % (name, kval)
        if 1 != crates.add_key(cr, store[kname]):
            raise RuntimeError, "Unable to add key %s to Crates." % kname

    # Column data, and then keywords.
    # Note that we do not write out any iteration numbered 0 as this is
    # assumed to be the "best-fit" position.
    #
    idx = draws["iteration"] > 0
    for cname in ["iteration", "accept", "statistic", "alphas"]:
        create_col(cname, draws[cname][idx])
    for cname in draws["parnames"]:
        create_col(cname, draws[cname][idx])

    if params == None:
        create_key("statmin", draws["statistic"][0],
                   "statistic at best-fit location")
        for k in draws["parnames"]:
            create_key("P_%s" % k, draws[k][0], "best-fit value")
    else:
        create_key("statmin", params["statval"],
                   "statistic at best-fit location")
        create_key("sigma", params["sigma"],
                   "sigma value for lower/upper limits")
        for (k, v, l, h) in zip(params["parnames"], params["parvals"],
                                params["parmins"], params["parmaxes"]):
            create_key("p_%s" % k, v, "best-fit value")
            create_key("dl_%s" % k, l, "best-fit lower limit")
            create_key("dh_%s" % k, h, "best-fit upper limit")

    # Write out the file
    #
    if format == None:
        outname = outfile
    else:
        outname = outfile + "[opt kernel=%s]" % formats[format.lower()]
    if 1 != crates.write_file(cr, outname):
        raise IOError, "Unable to write data out to '%s'" % outname
    print "Created: %s" % outfile
Beispiel #11
0
    def _estimate_expmap(self, *args):
        """Estimate the exposure map given an ARF.

        Although the arguments are listed with parameter names
        below, the function **does not** accept named arguments.
        It uses positional arguments and type checks to determine
        the parameters.

        Parameters
        ----------
        crate
            A TABLECrate, containing ``energ_lo``, ``energ_hi``,
            and ``specresp`` columns.
        filename : string
            The name of an ARF file
        xlo, xhi, y : arrays of numbers
            The arrays taken to be the ``energ_lo``, ``energ_hi``, and
            ``specresp`` columns

        Return
        ------
        expmap : number
            An estimate of the exposure map at the position
            of the source, and has units of cm^2 count / self.fluxtype

        Notes
        -----
        The ARF is linearly interpolated onto the energy grid
        of the dataset and the weighted sum calculated. The
        ARF is assumed to have units of cm^2 count / photon, and
        be defined on a grid given in keV.

        The ``estimate_instmap()`` method should be called in
        preference to this routine.
        """

        nargs = len(args)
        if nargs == 3:
            elo = args[0]
            ehi = args[1]
            specresp = args[2]

            if len(elo) == 1 or len(ehi) == 1 or len(specresp) == 1:
                emsg = "Expected three arrays of the same " + \
                    "length, with more than one element in"
                raise TypeError(emsg)
            if len(elo) != len(ehi) or len(elo) != len(specresp):
                emsg = "Expected three arrays of the same length"
                raise ValueError(emsg)

        elif nargs != 1:
            emsg = "_estimate_expmap() takes 2 or 4 arguments " + \
                "({} given)".format(nargs + 1)
            raise TypeError(emsg)

        else:
            if isinstance(args[0], pycrates.TABLECrate):
                cr = args[0]
            else:
                cr = pycrates.TABLECrate(args[0], mode="r")

            try:
                elo = cr.get_column("ENERG_LO").values.copy()
                ehi = cr.get_column("ENERG_HI").values.copy()
                specresp = cr.get_column("SPECRESP").values.copy()
            except ValueError as e:
                fname = cr.get_filename()
                raise ValueError("Crate {} - {}".format(fname, e))

        # Interpolate using the mid-point of the ARF
        # onto the mid-point of the grid if necessary.
        #
        emid = 0.5 * (elo + ehi)
        if emid.shape == self.xmid.shape and \
                np.all(emid == self.xmid):
            arf = specresp
        else:
            arf = su.interpolate(self.xmid, emid, specresp)
            arf = np.asarray(arf, dtype=self.weight.dtype)
            arf[arf < 0] = 0.0

        return np.sum(self.weight * arf)
def dump_qa(ensemble, outdir, ctr, outline,
            creator=None, revision=1, color='green'):
    """Dump the QA data to a region-like FITS file

    The output files are qa.<ctr>.v<version>.[fits|reg], where the
    integers are written as 3-character, zero-padded values.

    Parameters
    ----------
    ensemble : string
        The ensemble value, written to the header as the ENSEMBLE
        keyword.
    outdir : string
        This output directory
    ctr : int
        Used for the file name and added to the header as the
        HULLCPT keyword.
    outline : dict
        The hull data to write out.
    creator : None or str, optional
        The name to use for the CREATOR field in the header.
    revision : int
        The value to write out to the header as the CHSVER
        keyword.
    color : str
        The color for the DS9 region files.

    Notes
    ------
    I'd like to add a transform to POS but it is a little-bit involved
    and I don't have time to dig up the code, so just add an explicit
    column instead of a virtual one. It should be the case that the
    base stack is the same for each row, but leave as a column rather
    than move to a header keyword for now.

    """

    assert chs_status.is_qa(outline['status'])
    assert outline['eqpos'] is not None
    assert outline['pos'] is not None
    assert outline['base_stack'] is not None

    idx = outline['status'].find('-')
    if idx == -1:
        reason = "unknown"
    else:
        reason = outline['status'][idx + 1:]

    outfile = os.path.join(outdir,
                           'qa.{:03d}.v{:03d}.fits'.format(ctr,
                                                           revision))

    cr = pycrates.TABLECrate()
    cr.name = 'QACASE'

    utils.add_standard_header(cr, creator=creator, revision=revision)
    utils.add_header(cr, [('ENSEMBLE', ensemble,
                           'The ensemble'),
                          ('HULLCPT', ctr,
                           'The Master_Id of the hull'),
                          ('QREASON', reason,
                           'Why is this a QA case?')])

    eqpos = outline['eqpos']
    pos = outline['pos']
    assert len(pos) == len(eqpos)

    ncpts = len(pos)

    utils.add_col(cr, 'COMPONENT', np.arange(1, ncpts + 1))
    utils.add_col(cr, 'SHAPE', ['Polygon'] * ncpts)
    utils.add_col(cr, 'BASE_STK', [outline['base_stack']] * ncpts,
                  desc='The stack used for SKY coord system, or NONE')

    nvertex = []
    for poly in pos:
        x = poly[0]
        y = poly[1]
        xidx = np.isfinite(x)
        yidx = np.isfinite(y)
        assert (xidx == yidx).all()
        nvertex.append(xidx.sum())

    utils.add_col(cr, 'NVERTEX', nvertex,
                  desc='The number of vertexes in the closed hull')

    nmax = max(nvertex)
    pos_out = np.full((ncpts, 2, nmax), np.nan, dtype=np.float64)
    eqpos_out = np.full((ncpts, 2, nmax), np.nan, dtype=np.float64)

    for i, dvals in enumerate(zip(pos, eqpos)):

        npts = nvertex[i]
        phys, cel = dvals
        pos_out[i, :, :npts] = phys
        eqpos_out[i, :, :npts] = cel

    col = pycrates.create_vector_column('POS', ['X', 'Y'])
    col.desc = 'The master hull vertices'
    col.unit = 'pixel'
    col.values = pos_out
    cr.add_column(col)

    col = pycrates.create_vector_column('EQPOS', ['RA', 'DEC'])
    col.desc = 'The master hull vertices'
    col.unit = 'degree'
    col.values = eqpos_out
    cr.add_column(col)

    cr.write(outfile)
    print("Created: {}".format(outfile))

    outfile = os.path.join(outdir,
                           'qa.{:03d}.v{:03d}.reg'.format(ctr,
                                                          revision))
    with open(outfile, 'w') as ofh:
        ds9_header(ofh, color=color)

        for i, cel in enumerate(eqpos):

            npts = nvertex[i]
            ostr = ds9_shape(cel[:, :npts])
            ostr += ' # text={{Id={} {}}}\n'.format(ctr,
                                                    i + 1)
            ofh.write(ostr)

    print("Created: {}".format(outfile))