def main(args=None): from linetools.scripts.utils import coord_arg_to_coord from linetools import utils as ltu from astropy.io import fits, ascii from astropy.coordinates import SkyCoord import astropy.units as u from pyntejos.catalogs import add_radec_deg_columns pargs = parser(options=args) # RA,DEC icoord = coord_arg_to_coord(pargs.radec) coord = ltu.radec_to_coord(icoord) # define catalog print('Reading {} catalog'.format(pargs.catalog)) if pargs.catalog == 'QSO': # read qsos from MILLIQUAS catalog col_names = [ 'ra_d', 'dec_d', 'name', 'description', 'rmag', 'bmag', 'comment', 'psf_r', 'psf_b', 'z', 'cite', 'zcite', 'qso_prob', 'Xname', 'Rname', 'Lobe1', 'Lobe2' ] cat = ascii.read( '/media/ntejos/disk1/catalogs/qsos/milliquas/milliquas.txt', format='fixed_width', names=col_names) elif pargs.catalog == 'GC': # read MW globular cluster catalog cat = ascii.read( '/media/ntejos/disk1/catalogs/globular_clusters/mwgc10_1.dat', format='fixed_width') # add ra_d, dec_d columns cat = add_radec_deg_columns(cat) else: print(' Not implemented for such catalog.') return # cross-match print('Cross-matching...') cat_coords = SkyCoord(cat['ra_d'], cat['dec_d'], unit='deg') seplim = pargs.angsep * u.arcmin sep2d = coord.separation(cat_coords) cond = sep2d <= seplim cat = cat[cond] if len(cat) < 1: print("No matches found.") else: cat['sep2d'] = sep2d[cond] if pargs.redshift is not None: from astropy.cosmology import Planck15 as cosmo import pdb pdb.set_trace() sep = (cosmo.kpc_comoving_per_arcmin(float(pargs.redshift)) * cat['sep2d']).to('Mpc') cat['sep_mpc'] = sep.value cat.sort('sep2d') print(cat)
def query_Simbad_NED(objname, z=np.nan): ''' Make use to astroquery to extract basic coordiantes/redshift information z: redshift. Normally NED query would give an answer. Provide z if NED answer is not satifying return: astropy SkyCoord object ''' import numpy as np from astroquery.simbad import Simbad from astroquery.ned import Ned from astropy.coordinates import SkyCoord import astropy.units as u from astropy.cosmology import Planck15 as cosmo sim = Simbad.query_object(objname) try: test1 = sim['RA'] except: print('Danger: %s cannot be recognized by Simbad, try other names.' % (objname)) return False try: ned = Ned.query_object(objname) except: print('Danger: %s cannot be recognized by NED, try other names.' % (objname)) return False galcoord = SkyCoord(ra=sim['RA'], dec=sim['DEC'], unit=(u.hour, u.deg), frame='icrs') if np.isfinite(z): gz = z else: gz = ned['Redshift'][0] scale_kpc_arcmin = cosmo.kpc_comoving_per_arcmin(gz) scale_pc_arcsec = scale_kpc_arcmin.to(u.pc / u.arcsec) print('Simbad: RA = %.4f deg ' % (galcoord.icrs.ra.deg), galcoord.icrs.ra) print('Simbad: DEC = %.4f deg ' % (galcoord.icrs.dec.deg), galcoord.icrs.dec) print('Simbad: l = %.4f deg, b = %.4f deg' % (galcoord.galactic.l.deg, galcoord.galactic.b.deg)) print('NED: z = %.4f; Input z = %.4f' % (ned['Redshift'], z)) print('Scale at z = %.4f: %.1f kpc/arcmin, %.1f pc/arcsec' % (gz, abs(scale_kpc_arcmin.value), abs(scale_pc_arcsec.value))) print('Returning astropy SkyCoord object...') return galcoord
def main(args=None): from linetools.scripts.utils import coord_arg_to_coord from linetools import utils as ltu from astropy.io import fits, ascii from astropy.coordinates import SkyCoord import astropy.units as u from pyntejos.catalogs import add_radec_deg_columns pargs = parser(options=args) # RA,DEC icoord = coord_arg_to_coord(pargs.radec) coord = ltu.radec_to_coord(icoord) # define catalog print('Reading {} catalog'.format(pargs.catalog)) if pargs.catalog == 'QSO': # read qsos from MILLIQUAS catalog col_names = ['ra_d', 'dec_d', 'name', 'description', 'rmag', 'bmag', 'comment', 'psf_r', 'psf_b', 'z', 'cite', 'zcite', 'qso_prob', 'Xname', 'Rname', 'Lobe1', 'Lobe2'] cat = ascii.read('/media/ntejos/disk1/catalogs/qsos/milliquas/milliquas.txt', format='fixed_width', names=col_names) elif pargs.catalog == 'GC': # read MW globular cluster catalog cat = ascii.read('/media/ntejos/disk1/catalogs/globular_clusters/mwgc10_1.dat', format='fixed_width') # add ra_d, dec_d columns cat = add_radec_deg_columns(cat) else: print(' Not implemented for such catalog.') return # cross-match print('Cross-matching...') cat_coords = SkyCoord(cat['ra_d'], cat['dec_d'], unit='deg') seplim = pargs.angsep * u.arcmin sep2d = coord.separation(cat_coords) cond = sep2d <= seplim cat = cat[cond] if len(cat) < 1: print("No matches found.") else: cat['sep2d'] = sep2d[cond] if pargs.redshift is not None: from astropy.cosmology import Planck15 as cosmo import pdb; pdb.set_trace() sep = (cosmo.kpc_comoving_per_arcmin(float(pargs.redshift)) * cat['sep2d']).to('Mpc') cat['sep_mpc'] = sep.value cat.sort('sep2d') print(cat)
def stack_spec(spec_file, dv=100 * u.km / u.s, cut_on_rho=4.): # Load xspec, tpe, spec_tbl = load_spec(spec_file) # Cut on separation (should do this much earlier in the process) if cut_on_rho is not None: warnings.warn("Cutting on rho in stack. Should do this earlier") b_coords = SkyCoord(ra=tpe['BG_RA'], dec=tpe['BG_DEC'], unit='deg') f_coords = SkyCoord(ra=tpe['FG_RA'], dec=tpe['FG_DEC'], unit='deg') kpc_amin = cosmo.kpc_comoving_per_arcmin(tpe['FG_Z']) # kpc per arcmin ang_seps = b_coords.separation(f_coords) rho = ang_seps.to('arcmin') * kpc_amin / (1 + tpe['FG_Z']) cut_rho = rho.to('Mpc').value < cut_on_rho print("We have {:d} spectra after the cut.".format(np.sum(cut_rho))) xspec = xspec[cut_rho] tpe = tpe[cut_rho] spec_tbl = spec_tbl[cut_rho] # Remove those without continua has_co = spec_tbl['HAS_CO'].data co_spec = xspec[has_co] co_spec.normed = True # Apply continuum # May also wish to isolate in wavelength to avoid rejected pixels for ii in range(co_spec.nspec): co_spec.select = ii co = co_spec.co.value sig = co_spec.sig.value bad_pix = np.any([(co == 0.), (co == 1.), (sig <= 0.)], axis=0) co_spec.add_to_mask(bad_pix, compressed=True) # Rebin to rest zarr = tpe['FG_Z'][has_co] rebin_spec = lspu.rebin_to_rest(co_spec, zarr, dv) # Stack stack = lspu.smash_spectra(rebin_spec) # Plot tpep.plot_stack(stack, 'all_stack.pdf') tpep.plot_spec_img(rebin_spec, 'spec_img.pdf') pdb.set_trace() # Return return
def grab_sdss_spectra(radec, radius=0.1 * u.deg, outfil=None, debug=False, maxsep=None, timeout=600., zmin=None): """ Grab SDSS spectra Parameters ---------- radec : tuple RA, DEC in deg radius : float, optional (0.1*u.deg) Search radius -- Astroquery actually makes a box, not a circle timeout : float, optional Timeout limit for connection with SDSS outfil : str ('tmp.fits') Name of output file for FITS table maxsep : float (None) :: Mpc Maximum separation to include zmin : float (None) Minimum redshift to include Returns ------- tbl : Table """ cC = coords.SkyCoord(ra=radec[0], dec=radec[1]) # Query photoobj_fs = ['ra', 'dec', 'objid', 'run', 'rerun', 'camcol', 'field'] mags = [ 'petroMag_u', 'petroMag_g', 'petroMag_r', 'petroMag_i', 'petroMag_z' ] magsErr = [ 'petroMagErr_u', 'petroMagErr_g', 'petroMagErr_r', 'petroMagErr_i', 'petroMagErr_z' ] phot_catalog = SDSS.query_region(cC, spectro=True, radius=radius, timeout=timeout, photoobj_fields=photoobj_fs + mags + magsErr) # Unique spec_catalog = SDSS.query_region(cC, spectro=True, radius=radius, timeout=timeout) # Duplicates exist nobj = len(phot_catalog) # print('grab_sdss_spectra: Found {:d} sources in the search box.'.format( nobj)) # Coordinates cgal = SkyCoord(ra=phot_catalog['ra'] * u.degree, dec=phot_catalog['dec'] * u.degree) sgal = SkyCoord(ra=spec_catalog['ra'] * u.degree, dec=spec_catalog['dec'] * u.degree) sepgal = cgal.separation(cC) #in degrees # Check for problems and parse z zobj = np.zeros(nobj) idx, d2d, d3d = coords.match_coordinates_sky(cgal, sgal, nthneighbor=1) if np.max(d2d) > 1. * u.arcsec: print('No spectral match!') xdb.set_trace() else: zobj = spec_catalog['z'][idx] idx, d2d, d3d = coords.match_coordinates_sky(cgal, cgal, nthneighbor=2) if np.min(d2d.to('arcsec')) < 1. * u.arcsec: print('Two photometric sources with same RA/DEC') xdb.set_trace() #xdb.set_trace() # Cut on Separation if not maxsep is None: print('grab_sdss_spectra: Restricting to {:g} Mpc separation.'.format( maxsep)) sepgal_kpc = cosmo.kpc_comoving_per_arcmin(zobj) * sepgal.to('arcmin') sepgal_mpc = sepgal_kpc.to('Mpc') gdg = np.where(sepgal_mpc < (maxsep * u.Unit('Mpc')))[0] phot_catalog = phot_catalog[gdg] #xdb.set_trace() nobj = len(phot_catalog) print('grab_sdss_spectra: Grabbing data for {:d} sources.'.format(nobj)) # Grab Spectra from SDSS # Generate output table attribs = galaxy_attrib() npix = 5000 #len( spec_hdus[0][1].data.flux ) spec_attrib = [(str('FLUX'), np.float32, (npix, )), (str('SIG'), np.float32, (npix, )), (str('WAVE'), np.float64, (npix, ))] tbl = np.recarray((nobj, ), dtype=attribs + spec_attrib) tbl['RA'] = phot_catalog['ra'] tbl['DEC'] = phot_catalog['dec'] tbl['TELESCOPE'] = str('SDSS 2.5-M') # Deal with spectra separately (for now) npix = 5000 #len( spec_hdus[0][1].data.flux ) for idx, obj in enumerate(phot_catalog): #print('idx = {:d}'.format(idx)) # Grab spectra (there may be duplicates) mt = np.where( sgal.separation(cgal[idx]).to('arcsec') < 1. * u.Unit('arcsec'))[0] if len(mt) > 1: # Use BOSS if you have it mmt = np.where(spec_catalog[mt]['instrument'] == 'BOSS')[0] if len(mmt) > 0: mt = mt[mmt[0]] else: mt = mt[0] elif len(mt) == 0: xdb.set_trace() else: mt = mt[0] # Grab spectra spec_hdus = SDSS.get_spectra(matches=Table(spec_catalog[mt])) tbl[idx]['INSTRUMENT'] = spec_catalog[mt]['instrument'] spec = spec_hdus[0][1].data npp = len(spec.flux) tbl[idx]['FLUX'][0:npp] = spec.flux sig = np.zeros(npp) gdi = np.where(spec.ivar > 0.)[0] if len(gdi) > 0: sig[gdi] = np.sqrt(1. / spec.ivar[gdi]) tbl[idx]['SIG'][0:npp] = sig tbl[idx]['WAVE'][0:npp] = 10.**spec.loglam # Redshifts meta = spec_hdus[0][2].data for attrib in ['Z', 'Z_ERR']: tbl[idx][attrib] = meta[attrib] if debug: sep_to_qso = cgal[idx].separation(cC).to('arcmin') print('z = {:g}, Separation = {:g}'.format(tbl[idx].Z, sep_to_qso)) xdb.set_trace() # Fill in rest tbl[idx].SDSS_MAG = np.array([obj[phot] for phot in mags]) tbl[idx].SDSS_MAGERR = np.array([obj[phot] for phot in magsErr]) # Clip on redshift to excise stars/quasars if zmin is not None: gd = np.where(tbl['Z'] > zmin)[0] tbl = tbl[gd] # Write to FITS file if outfil is not None: prihdr = fits.Header() prihdr['COMMENT'] = 'SDSS Spectra' prihdu = fits.PrimaryHDU(header=prihdr) tbhdu = fits.BinTableHDU(tbl) thdulist = fits.HDUList([prihdu, tbhdu]) thdulist.writeto(outfil, clobber=True) print('Wrote SDSS table to {:s}'.format(outfil)) return tbl
def grab_sdss_spectra(radec, radius=0.1*u.deg, outfil=None, debug=False, maxsep=None, timeout=600., zmin=None): """ Grab SDSS spectra Parameters ---------- radec : tuple RA, DEC in deg radius : float, optional (0.1*u.deg) Search radius -- Astroquery actually makes a box, not a circle timeout : float, optional Timeout limit for connection with SDSS outfil : str ('tmp.fits') Name of output file for FITS table maxsep : float (None) :: Mpc Maximum separation to include zmin : float (None) Minimum redshift to include Returns ------- tbl : Table """ cC = coords.SkyCoord(ra=radec[0], dec=radec[1]) # Query photoobj_fs = ['ra', 'dec', 'objid', 'run', 'rerun', 'camcol', 'field'] mags = ['petroMag_u', 'petroMag_g', 'petroMag_r', 'petroMag_i', 'petroMag_z'] magsErr = ['petroMagErr_u', 'petroMagErr_g', 'petroMagErr_r', 'petroMagErr_i', 'petroMagErr_z'] phot_catalog = SDSS.query_region(cC,spectro=True,radius=radius, timeout=timeout, photoobj_fields=photoobj_fs+mags+magsErr) # Unique spec_catalog = SDSS.query_region(cC,spectro=True, radius=radius, timeout=timeout) # Duplicates exist nobj = len(phot_catalog) # print('grab_sdss_spectra: Found {:d} sources in the search box.'.format(nobj)) # Coordinates cgal = SkyCoord(ra=phot_catalog['ra']*u.degree, dec=phot_catalog['dec']*u.degree) sgal = SkyCoord(ra=spec_catalog['ra']*u.degree, dec=spec_catalog['dec']*u.degree) sepgal = cgal.separation(cC) #in degrees # Check for problems and parse z zobj = np.zeros(nobj) idx, d2d, d3d = coords.match_coordinates_sky(cgal, sgal, nthneighbor=1) if np.max(d2d) > 1.*u.arcsec: print('No spectral match!') xdb.set_trace() else: zobj = spec_catalog['z'][idx] idx, d2d, d3d = coords.match_coordinates_sky(cgal, cgal, nthneighbor=2) if np.min(d2d.to('arcsec')) < 1.*u.arcsec: print('Two photometric sources with same RA/DEC') xdb.set_trace() #xdb.set_trace() # Cut on Separation if not maxsep is None: print('grab_sdss_spectra: Restricting to {:g} Mpc separation.'.format(maxsep)) sepgal_kpc = cosmo.kpc_comoving_per_arcmin(zobj) * sepgal.to('arcmin') sepgal_mpc = sepgal_kpc.to('Mpc') gdg = np.where( sepgal_mpc < (maxsep * u.Unit('Mpc')))[0] phot_catalog = phot_catalog[gdg] #xdb.set_trace() nobj = len(phot_catalog) print('grab_sdss_spectra: Grabbing data for {:d} sources.'.format(nobj)) # Grab Spectra from SDSS # Generate output table attribs = galaxy_attrib() npix = 5000 #len( spec_hdus[0][1].data.flux ) spec_attrib = [(str('FLUX'), np.float32, (npix,)), (str('SIG'), np.float32, (npix,)), (str('WAVE'), np.float64, (npix,))] tbl = np.recarray( (nobj,), dtype=attribs+spec_attrib) tbl['RA'] = phot_catalog['ra'] tbl['DEC'] = phot_catalog['dec'] tbl['TELESCOPE'] = str('SDSS 2.5-M') # Deal with spectra separately (for now) npix = 5000 #len( spec_hdus[0][1].data.flux ) for idx,obj in enumerate(phot_catalog): #print('idx = {:d}'.format(idx)) # Grab spectra (there may be duplicates) mt = np.where( sgal.separation(cgal[idx]).to('arcsec') < 1.*u.Unit('arcsec'))[0] if len(mt) > 1: # Use BOSS if you have it mmt = np.where( spec_catalog[mt]['instrument'] == 'BOSS')[0] if len(mmt) > 0: mt = mt[mmt[0]] else: mt = mt[0] elif len(mt) == 0: xdb.set_trace() else: mt = mt[0] # Grab spectra spec_hdus = SDSS.get_spectra(matches=Table(spec_catalog[mt])) tbl[idx]['INSTRUMENT'] = spec_catalog[mt]['instrument'] spec = spec_hdus[0][1].data npp = len(spec.flux) tbl[idx]['FLUX'][0:npp] = spec.flux sig = np.zeros(npp) gdi = np.where(spec.ivar > 0.)[0] if len(gdi) > 0: sig[gdi] = np.sqrt( 1./spec.ivar[gdi] ) tbl[idx]['SIG'][0:npp] = sig tbl[idx]['WAVE'][0:npp] = 10.**spec.loglam # Redshifts meta = spec_hdus[0][2].data for attrib in ['Z','Z_ERR']: tbl[idx][attrib] = meta[attrib] if debug: sep_to_qso = cgal[idx].separation(cC).to('arcmin') print('z = {:g}, Separation = {:g}'.format(tbl[idx].Z, sep_to_qso)) xdb.set_trace() # Fill in rest tbl[idx].SDSS_MAG = np.array( [obj[phot] for phot in mags]) tbl[idx].SDSS_MAGERR = np.array( [obj[phot] for phot in magsErr]) # Clip on redshift to excise stars/quasars if zmin is not None: gd = np.where(tbl['Z'] > zmin)[0] tbl = tbl[gd] # Write to FITS file if outfil is not None: prihdr = fits.Header() prihdr['COMMENT'] = 'SDSS Spectra' prihdu = fits.PrimaryHDU(header=prihdr) tbhdu = fits.BinTableHDU(tbl) thdulist = fits.HDUList([prihdu, tbhdu]) thdulist.writeto(outfil,clobber=True) print('Wrote SDSS table to {:s}'.format(outfil)) return tbl
def tpe_stack_lris(dv=100 * u.km / u.s): """ Testing stacks with LRIS """ # Load sample ipos = this_file.rfind('/') if ipos == -1: path = './' else: path = this_file[0:ipos] tpe = Table.read(path + '/../TPE_DR12_31.2_spec.fits') # Load spectra # Coordiantes b_coords = SkyCoord(ra=tpe['BG_RA'], dec=tpe['BG_DEC'], unit='deg') f_coords = SkyCoord(ra=tpe['FG_RA'], dec=tpe['FG_DEC'], unit='deg') # Cut on impact parameter and BOSS kpc_amin = cosmo.kpc_comoving_per_arcmin(tpe['FG_Z']) # kpc per arcmin ang_seps = b_coords.separation(f_coords) rho = ang_seps.to('arcmin') * kpc_amin / (1 + tpe['FG_Z']) cut_Rlris = (rho.to('Mpc').value < 4) & (tpe['BG_LYA_INSTRUMENT'] == 'LRIS' ) # & ( #tpe['FG_Z'] > 2.) # Some of these have too low z (just barely) # Cut gd_b_coords = b_coords[cut_Rlris] gd_tpe = tpe[cut_Rlris] # Grab these spectra from QPQ # For boss, we are ok taking the first entry of each # The returned set is aligned with the input coords qpq = IgmSpec(db_file=qpq_file, skip_test=True) IDs = qpq.qcat.match_coord(gd_b_coords, group='LRIS') meta = qpq['LRIS'].meta gcut = meta['GRATING'] == '1200/3400' # There is one with B400 B1200 = np.in1d(IDs, meta['PRIV_ID'][gcut]) print("There are {:d} sources without B1200".format(np.sum(~B1200))) # Cut again gd_b_coords = gd_b_coords[B1200] gd_tpe = gd_tpe[B1200] gd_IDs = IDs[B1200] # Find the rows idx = cat_utils.match_ids(gd_IDs, meta['PRIV_ID']) rows = meta['GROUP_ID'][idx] pdb.set_trace() spec, meta = qpq.coords_to_spectra(gd_b_coords, 'LRIS', all_spec=False) # Check for continua has_co = np.array([True] * spec.nspec) for ii in range(spec.nspec): # Select spec.select = ii # Match to lya lya = (1 + gd_tpe['FG_Z'][ii]) * 1215.67 * u.AA iwave = np.argmin(np.abs(spec.wavelength - lya)) # Check for co #coval = spec.co[iwave] #print('spec: {:d} with co={:g}'.format(ii, coval)) if np.isclose(spec.co[iwave], 0.) or np.isclose(spec.co[iwave], 1.): has_co[ii] = False # Slice to good co print("{:d} BOSS spectra with a continuum".format(np.sum(has_co))) co_spec = spec[has_co] co_spec.normed = True # Apply continuum # NEED TO ZERO OUT REGIONS WITHOUT CONTINUUM # May also wish to isolate in wavelength to avoid rejected pixels for ii in range(co_spec.nspec): co_spec.select = ii co = co_spec.co.value bad_pix = np.any([(co == 0.), (co == 1.)], axis=0) co_spec.add_to_mask(bad_pix, compressed=True) # Rebin to rest zarr = gd_tpe['FG_Z'][has_co] rebin_spec = lspu.rebin_to_rest(co_spec, zarr, dv) # Stack stack = lspu.smash_spectra(rebin_spec) # Plot plot_stack(stack, 'LRIS_stack.pdf') return stack
def tpe_stack_boss(dv=100 * u.km / u.s): """ Testing stacks with BOSS """ # Load sample ipos = this_file.rfind('/') if ipos == -1: path = './' else: path = this_file[0:ipos] tpe = Table.read(path + '/../TPE_DR12_31.2_spec.fits') # Load spectra igmsp = IgmSpec() # Coordiantes b_coords = SkyCoord(ra=tpe['BG_RA'], dec=tpe['BG_DEC'], unit='deg') f_coords = SkyCoord(ra=tpe['FG_RA'], dec=tpe['FG_DEC'], unit='deg') # Cut on impact parameter and BOSS kpc_amin = cosmo.kpc_comoving_per_arcmin(tpe['FG_Z']) # kpc per arcmin ang_seps = b_coords.separation(f_coords) rho = ang_seps.to('arcmin') * kpc_amin / (1 + tpe['FG_Z']) cut_Rboss = (rho.to('Mpc').value < 4) & ( tpe['BG_LYA_INSTRUMENT'] == 'BOSS') & ( tpe['FG_Z'] > 2.) # Some of these have too low z (just barely) # Cut gd_b_coords = b_coords[cut_Rboss] gd_f_coords = f_coords[cut_Rboss] gd_tpe = tpe[cut_Rboss] # Grab these spectra from igmsp # For boss, we are ok taking the first entry of each # The returned set is aligned with the input coords spec, meta = igmsp.coords_to_spectra(gd_b_coords, 'BOSS_DR12', all_spec=False) # Check for continua has_co = np.array([True] * spec.nspec) for ii in range(spec.nspec): # Select spec.select = ii # Match to lya lya = (1 + gd_tpe['FG_Z'][ii]) * 1215.67 * u.AA iwave = np.argmin(np.abs(spec.wavelength - lya)) # Check for co #coval = spec.co[iwave] #print('spec: {:d} with co={:g}'.format(ii, coval)) if np.isclose(spec.co[iwave], 0.) or np.isclose(spec.co[iwave], 1.): has_co[ii] = False # Slice to good co print("{:d} BOSS spectra with a continuum".format(np.sum(has_co))) co_spec = spec[has_co] co_spec.normed = True # Apply continuum # NEED TO ZERO OUT REGIONS WITHOUT CONTINUUM # May also wish to isolate in wavelength to avoid rejected pixels for ii in range(co_spec.nspec): co_spec.select = ii co = co_spec.co.value bad_pix = np.any([(co == 0.), (co == 1.)], axis=0) co_spec.add_to_mask(bad_pix, compressed=True) # Rebin to rest zarr = gd_tpe['FG_Z'][has_co] rebin_spec = lspu.rebin_to_rest(co_spec, zarr, dv) # Check 2D check_td = True if check_td: fx = rebin_spec.data['flux'] sig = rebin_spec.data['sig'] gds = sig > 0. fx[~gds] = 0. xdb.set_trace() # xdb.ximshow(fx) # Stack stack = lspu.smash_spectra(rebin_spec) # Plot plot_stack(stack, 'BOSS_stack.pdf') print('Wrote') return stack