def get_rmf_data(arg, make_copy=True): """ get_rmf_data( filename [, make_copy=True ]) get_rmf_data( RMFCrate [, make_copy=True ]) """ filename = '' close_dataset = False if type(arg) == str: rmfdataset = open_crate_dataset(arg, pycrates.rmfcratedataset.RMFCrateDataset) #if (isinstance(rmfdataset, (pycrates.TABLECrate, pycrates.IMAGECrate)) or # pycrates.is_pha(rmfdataset) == 1): # raise IOErr('badfile', arg, "RMFCrateDataset obj") if pycrates.is_rmf(rmfdataset) != 1: raise IOErr('badfile', arg, "RMFCrateDataset obj") filename = arg close_dataset = True elif pycrates.is_rmf(arg) == 1: rmfdataset = arg filename = arg.get_filename() make_copy = False else: raise IOErr('badfile', arg, "RMFCrateDataset obj") # Open the response matrix by extension name, and try using # some of the many, many ways people break the OGIP definition # of the extension name for the response matrix. rmf = _get_crate_by_blockname(rmfdataset, 'MATRIX') if rmf is None: rmf = _get_crate_by_blockname(rmfdataset, 'SPECRESP MATRIX') if rmf is None: rmf = _get_crate_by_blockname(rmfdataset, 'AXAF_RMF') if rmf is None: rmf = _get_crate_by_blockname(rmfdataset, 'RSP_MATRIX') if rmf is None: try: rmf = rmfdataset.get_crate(2) except IndexError: rmf = None if rmf is None or rmf.get_colnames() is None: raise IOErr('filenotfound', arg) data = {} if not rmf.column_exists('ENERG_LO'): raise IOErr('reqcol', 'ENERG_LO', filename) if not rmf.column_exists('ENERG_HI'): raise IOErr('reqcol', 'ENERG_HI', filename) # FIXME: this will be a problem now that we have # to pass the name of the matrix column if not rmf.column_exists('MATRIX'): raise IOErr('reqcol', 'MATRIX', filename) if not rmf.column_exists('N_GRP'): raise IOErr('reqcol', 'N_GRP', filename) if not rmf.column_exists('F_CHAN'): raise IOErr('reqcol', 'F_CHAN', filename) if not rmf.column_exists('N_CHAN'): raise IOErr('reqcol', 'N_CHAN', filename) data['detchans'] = _require_hdr_key(rmf, 'DETCHANS', SherpaInt) data['energ_lo'] = _require_col(rmf, 'ENERG_LO', make_copy, fix_type=True) data['energ_hi'] = _require_col(rmf, 'ENERG_HI', make_copy, fix_type=True) data['n_grp'] = _require_col(rmf, 'N_GRP', make_copy, dtype=SherpaUInt, fix_type=True) f_chan = rmf.get_column('F_CHAN') offset = f_chan.get_tlmin() fcbuf = _require_col(rmf, 'F_CHAN', make_copy) ncbuf = _require_col(rmf, 'N_CHAN', make_copy) respbuf = _require_col_list(rmf, 'MATRIX', 1, make_copy) #ebounds = None #if rmfdataset.get_current_crate() < rmfdataset.get_ncrates(): # ebounds = rmfdataset.get_crate(rmfdataset.get_current_crate() + 1) ebounds = _get_crate_by_blockname(rmfdataset, 'EBOUNDS') if ebounds is None: ebounds = rmfdataset.get_crate(3) data['header'] = _get_meta_data(rmf) data['header'].pop('DETCHANS') channel = None if ebounds is not None: data['e_min'] = _try_col(ebounds, 'E_MIN', make_copy, fix_type=True) data['e_max'] = _try_col(ebounds, 'E_MAX', make_copy, fix_type=True) if ebounds.column_exists('CHANNEL'): channel = ebounds.get_column('CHANNEL') # FIXME: do I include the header keywords from ebounds # data['header'].update(_get_meta_data(ebounds)) if offset < 0: error("Failed to locate TLMIN keyword for F_CHAN" + " column in RMF file '%s'; " % filename + 'Update the offset value in the RMF data set to' + ' appropriate TLMIN value prior to fitting') if offset < 0 and channel is not None: offset = channel.get_tlmin() # If response is non-OGIP, tlmin is -(max of type), so resort to default if not (offset < 0): data['offset'] = offset # # FIXME: # # Currently, CRATES does something screwy: If n_grp is zero in a bin, # it appends a zero to f_chan, n_chan, and matrix. I have no idea what # the logic behind this is -- why would you add data that you know you # don't need? Although it's easy enough to filter the zeros out of # f_chan and n_chan, it's harder for matrix, since zero is a legitimate # value there. # # I think this crazy behavior of CRATES should be changed, but for the # moment we'll just punt in this case. (If we don't, the calculation # in rmf_fold() will be trashed.) # CRATES does not support variable length arrays, so here we condense # the array of tuples into the proper length array chan_width = data['n_grp'].max() resp_width = 0 if len(respbuf.shape) > 1: resp_width = respbuf.shape[1] (data['f_chan'], data['n_chan'], data['matrix'] ) = resp_init( data['n_grp'], fcbuf, ncbuf, chan_width, respbuf.ravel(), resp_width ) if close_dataset: close_crate_dataset(rmfdataset) return data, filename
def get_rmf_data(arg, make_copy=True): """ get_rmf_data( filename [, make_copy=True ]) get_rmf_data( RMFCrate [, make_copy=True ]) """ filename = '' close_dataset = False if type(arg) == str: rmfdataset = open_crate_dataset( arg, pycrates.rmfcratedataset.RMFCrateDataset) # if (isinstance(rmfdataset, (pycrates.TABLECrate, pycrates.IMAGECrate)) or # pycrates.is_pha(rmfdataset) == 1): # raise IOErr('badfile', arg, "RMFCrateDataset obj") if pycrates.is_rmf(rmfdataset) != 1: raise IOErr('badfile', arg, "RMFCrateDataset obj") filename = arg close_dataset = True elif pycrates.is_rmf(arg) == 1: rmfdataset = arg filename = arg.get_filename() make_copy = False else: raise IOErr('badfile', arg, "RMFCrateDataset obj") # Open the response matrix by extension name, and try using # some of the many, many ways people break the OGIP definition # of the extension name for the response matrix. rmf = _get_crate_by_blockname(rmfdataset, 'MATRIX') if rmf is None: rmf = _get_crate_by_blockname(rmfdataset, 'SPECRESP MATRIX') if rmf is None: rmf = _get_crate_by_blockname(rmfdataset, 'AXAF_RMF') if rmf is None: rmf = _get_crate_by_blockname(rmfdataset, 'RSP_MATRIX') if rmf is None: try: rmf = rmfdataset.get_crate(2) except IndexError: rmf = None if rmf is None or rmf.get_colnames() is None: raise IOErr('filenotfound', arg) data = {} if not rmf.column_exists('ENERG_LO'): raise IOErr('reqcol', 'ENERG_LO', filename) if not rmf.column_exists('ENERG_HI'): raise IOErr('reqcol', 'ENERG_HI', filename) # FIXME: this will be a problem now that we have # to pass the name of the matrix column if not rmf.column_exists('MATRIX'): raise IOErr('reqcol', 'MATRIX', filename) if not rmf.column_exists('N_GRP'): raise IOErr('reqcol', 'N_GRP', filename) if not rmf.column_exists('F_CHAN'): raise IOErr('reqcol', 'F_CHAN', filename) if not rmf.column_exists('N_CHAN'): raise IOErr('reqcol', 'N_CHAN', filename) data['detchans'] = _require_hdr_key(rmf, 'DETCHANS', SherpaInt) data['energ_lo'] = _require_col(rmf, 'ENERG_LO', make_copy, fix_type=True) data['energ_hi'] = _require_col(rmf, 'ENERG_HI', make_copy, fix_type=True) data['n_grp'] = _require_col(rmf, 'N_GRP', make_copy, dtype=SherpaUInt, fix_type=True) f_chan = rmf.get_column('F_CHAN') offset = f_chan.get_tlmin() fcbuf = _require_col(rmf, 'F_CHAN', make_copy) ncbuf = _require_col(rmf, 'N_CHAN', make_copy) respbuf = _require_col_list(rmf, 'MATRIX', 1, make_copy) # ebounds = None # if rmfdataset.get_current_crate() < rmfdataset.get_ncrates(): # ebounds = rmfdataset.get_crate(rmfdataset.get_current_crate() + 1) ebounds = _get_crate_by_blockname(rmfdataset, 'EBOUNDS') if ebounds is None: ebounds = rmfdataset.get_crate(3) data['header'] = _get_meta_data(rmf) data['header'].pop('DETCHANS') channel = None if ebounds is not None: data['e_min'] = _try_col(ebounds, 'E_MIN', make_copy, fix_type=True) data['e_max'] = _try_col(ebounds, 'E_MAX', make_copy, fix_type=True) if ebounds.column_exists('CHANNEL'): channel = ebounds.get_column('CHANNEL') # FIXME: do I include the header keywords from ebounds # data['header'].update(_get_meta_data(ebounds)) if offset < 0: error("Failed to locate TLMIN keyword for F_CHAN" + " column in RMF file '%s'; " % filename + 'Update the offset value in the RMF data set to' + ' appropriate TLMIN value prior to fitting') if offset < 0 and channel is not None: offset = channel.get_tlmin() # If response is non-OGIP, tlmin is -(max of type), so resort to default if not (offset < 0): data['offset'] = offset # # FIXME: # # Currently, CRATES does something screwy: If n_grp is zero in a bin, # it appends a zero to f_chan, n_chan, and matrix. I have no idea what # the logic behind this is -- why would you add data that you know you # don't need? Although it's easy enough to filter the zeros out of # f_chan and n_chan, it's harder for matrix, since zero is a legitimate # value there. # # I think this crazy behavior of CRATES should be changed, but for the # moment we'll just punt in this case. (If we don't, the calculation # in rmf_fold() will be trashed.) # CRATES does not support variable length arrays, so here we condense # the array of tuples into the proper length array chan_width = data['n_grp'].max() resp_width = 0 if len(respbuf.shape) > 1: resp_width = respbuf.shape[1] (data['f_chan'], data['n_chan'], data['matrix']) = resp_init(data['n_grp'], fcbuf, ncbuf, chan_width, respbuf.ravel(), resp_width) if close_dataset: close_crate_dataset(rmfdataset) return data, filename
def get_rmf_data(arg, make_copy=True): """ get_rmf_data( filename [, make_copy=True ]) get_rmf_data( RMFCrate [, make_copy=True ]) """ filename = '' if type(arg) == str: #rmf = pycrates.read_rmf(arg) rmf = _open_crate(pycrates.RMFCrate, [arg]) filename = arg # Make a copy of the data, since we don't know that pycrates will # do something sensible wrt reference counting elif pycrates.is_rmf(arg) == pycrates.dmSUCCESS: rmf = arg filename = arg.get_filename() make_copy = False else: raise IOErr('badfile', arg, "RMFCrate obj") if rmf is None or rmf.get_colnames() is None: raise IOErr('filenotfound', arg) data = {} if rmf.energ_lo is None: raise IOErr('reqcol', 'ENERG_LO', filename) if rmf.energ_hi is None: raise IOErr('reqcol', 'ENERG_HI', filename) if rmf.matrix is None: raise IOErr('reqcol', 'MATRIX', filename) if rmf.n_grp is None: raise IOErr('reqcol', 'N_GRP', filename) if rmf.f_chan is None: raise IOErr('reqcol', 'F_CHAN', filename) if rmf.n_chan is None: raise IOErr('reqcol', 'N_CHAN', filename) data['detchans'] = _require_hdr_key(rmf, 'DETCHANS', SherpaInt) data['energ_lo'] = _require_col(rmf.energ_lo, make_copy, fix_type=True) data['energ_hi'] = _require_col(rmf.energ_hi, make_copy, fix_type=True) data['n_grp'] = _require_col(rmf.n_grp, make_copy, dtype=SherpaUInt, fix_type=True) fcbuf = _require_col(rmf.f_chan, make_copy) ncbuf = _require_col(rmf.n_chan, make_copy) respbuf = _require_col_list(rmf.matrix, 1, make_copy) data['e_min'] = _try_col(rmf.e_min, make_copy, fix_type=True) data['e_max'] = _try_col(rmf.e_max, make_copy, fix_type=True) data['header'] = _get_meta_data(rmf) data['header'].pop('DETCHANS') offset = rmf.f_chan.get_tlmin() if offset < 0: error("Failed to locate TLMIN keyword for F_CHAN" + " column in RMF file '%s'; " % filename + 'Update the offset value in the RMF data set to' + ' appropriate TLMIN value prior to fitting') if offset < 0 and rmf.channel is not None: offset = rmf.channel.get_tlmin() # If response is non-OGIP, tlmin is -(max of type), so resort to default if not (offset < 0): data['offset'] = offset # # FIXME: # # Currently, CRATES does something screwy: If n_grp is zero in a bin, # it appends a zero to f_chan, n_chan, and matrix. I have no idea what # the logic behind this is -- why would you add data that you know you # don't need? Although it's easy enough to filter the zeros out of # f_chan and n_chan, it's harder for matrix, since zero is a legitimate # value there. # # I think this crazy behavior of CRATES should be changed, but for the # moment we'll just punt in this case. (If we don't, the calculation # in rmf_fold() will be trashed.) # CRATES does not support variable length arrays, so here we condense # the array of tuples into the proper length array chan_width = data['n_grp'].max() resp_width = 0 if len(respbuf.shape) > 1: resp_width = respbuf.shape[1] (data['f_chan'], data['n_chan'], data['matrix'] ) = resp_init( data['n_grp'], fcbuf, ncbuf, chan_width, respbuf.ravel(), resp_width ) return data, filename