def qproc_boxcar_extraction(xytraceset, image, fibers=None, width=7, fibermap=None, save_sigma=True) : """ Fast boxcar extraction of spectra from a preprocessed image and a trace set Args: xytraceset : DESI XYTraceSet object image : DESI preprocessed Image object Optional: fibers : 1D np.array of int (default is all fibers, the first fiber is always = 0) width : extraction boxcar width, default is 7 fibermap : table Returns: QFrame object """ log=get_logger() log.info("Starting...") t0=time.time() wavemin = xytraceset.wavemin wavemax = xytraceset.wavemax xcoef = xytraceset.x_vs_wave_traceset._coeff ycoef = xytraceset.y_vs_wave_traceset._coeff spectrograph = 0 if "CAMERA" in image.meta : camera=image.meta["CAMERA"].strip() spectrograph = int(camera[-1]) log.info("camera='{}' -> spectrograph={}. I AM USING THIS TO DEFINE THE FIBER NUMBER (ASSUMING 500 FIBERS PER SPECTRO).".format(camera,spectrograph)) allfibers = np.arange(xcoef.shape[0])+500*spectrograph if fibers is None : fibers = allfibers #log.info("wavelength range : [%f,%f]"%(wavemin,wavemax)) if image.mask is not None : image.ivar *= (image.mask==0) # Applying a mask that keeps positive value to get the Variance by inversing the inverse variance. var=np.zeros(image.ivar.size) ok=image.ivar.ravel()>0 var[ok] = 1./image.ivar.ravel()[ok] var=var.reshape(image.ivar.shape) badimage=(image.ivar==0) n0 = image.pix.shape[0] n1 = image.pix.shape[1] frame_flux = np.zeros((fibers.size,n0)) frame_ivar = np.zeros((fibers.size,n0)) frame_wave = np.zeros((fibers.size,n0)) frame_sigma = None ysigcoef = None if save_sigma : if xytraceset.ysig_vs_wave_traceset is None : log.warning("will not save sigma in qframe because missing in traceset") else : frame_sigma = np.zeros((fibers.size,n0)) ysigcoef = xytraceset.ysig_vs_wave_traceset._coeff xx = np.tile(np.arange(n1),(n0,1)) hw = width//2 twave=np.linspace(wavemin, wavemax, n0//4) # this number of bins n0//p is calibrated to give a negligible difference of wavelength precision rwave=(twave-wavemin)/(wavemax-wavemin)*2-1. y=np.arange(n0).astype(float) dwave = np.zeros(n0) for f,fiber in enumerate(fibers) : log.debug("extracting fiber #%03d"%fiber) ty = legval(rwave, ycoef[f]) tx = legval(rwave, xcoef[f]) frame_wave[f] = np.interp(y,ty,twave) x_of_y = np.interp(y,ty,tx) i=np.where(y<ty[0])[0] if i.size>0 : # need extrapolation frame_wave[f,i] = twave[0]+(twave[1]-twave[0])/(ty[1]-ty[0])*(y[i]-ty[0]) i=np.where(y>ty[-1])[0] if i.size>0 : # need extrapolation frame_wave[f,i] = twave[-1]+(twave[-2]-twave[-1])/(ty[-2]-ty[-1])*(y[i]-ty[-1]) dwave[1:] = frame_wave[f,1:]-frame_wave[f,:-1] dwave[0] = 2*dwave[1]-dwave[2] if np.any(dwave<=0) : log.error("neg. or null dwave") raise ValueError("neg. or null dwave") frame_flux[f],frame_ivar[f] = numba_extract(image.pix,var,x_of_y,hw) # flux density frame_flux[f] /= dwave frame_ivar[f] *= dwave**2 if frame_sigma is not None : ts = legval(rwave, ysigcoef[f]) frame_sigma[f] = np.interp(y,ty,ts) t1=time.time() log.info(" done {} fibers in {:3.1f} sec".format(len(fibers),t1-t0)) if fibermap is None: log.warning("setting up a fibermap to save the FIBER identifiers") fibermap = empty_fibermap(fibers.size) fibermap["FIBER"] = fibers else : indices = np.arange(fibermap["FIBER"].size)[np.in1d(fibermap["FIBER"],fibers)] fibermap = fibermap[:][indices] return QFrame(frame_wave, frame_flux, frame_ivar, mask=None, sigma=frame_sigma , fibers=fibers, meta=image.meta, fibermap=fibermap)
def get_targets(nspec, program, tileid=None, seed=None, specify_targets=dict(), specmin=0): """ Generates a set of targets for the requested program Args: nspec: (int) number of targets to generate program: (str) program name DARK, BRIGHT, GRAY, MWS, BGS, LRG, ELG, ... Options: * tileid: (int) tileid, used for setting RA,dec * seed: (int) random number seed * specify_targets: (dict of dicts) Define target properties like magnitude and redshift for each target class. Each objtype has its own key,value pair see simspec.templates.specify_galparams_dict() or simsepc.templates.specify_starparams_dict() * specmin: (int) first spectrum number (0-indexed) Returns: * fibermap * targets as tuple of (flux, wave, meta) """ if tileid is None: tile_ra, tile_dec = 0.0, 0.0 else: tile_ra, tile_dec = io.get_tile_radec(tileid) program = program.upper() log.debug('Using random seed {}'.format(seed)) np.random.seed(seed) #- Get distribution of target types true_objtype, target_objtype = sample_objtype(nspec, program) #- Get DESI wavelength coverage try: params = desimodel.io.load_desiparams() wavemin = params['ccd']['b']['wavemin'] wavemax = params['ccd']['z']['wavemax'] except KeyError: wavemin = desimodel.io.load_throughput('b').wavemin wavemax = desimodel.io.load_throughput('z').wavemax dw = 0.2 wave = np.arange(round(wavemin, 1), wavemax, dw) nwave = len(wave) flux = np.zeros( (nspec, len(wave)) ) meta, _ = empty_metatable(nmodel=nspec, objtype='SKY') objmeta = dict() fibermap = empty_fibermap(nspec) targetid = np.random.randint(sys.maxsize, size=nspec).astype(np.int64) meta['TARGETID'] = targetid fibermap['TARGETID'] = targetid for objtype in set(true_objtype): ii = np.where(true_objtype == objtype)[0] nobj = len(ii) fibermap['OBJTYPE'][ii] = target_objtype[ii] if objtype in specify_targets.keys(): obj_kwargs = specify_targets[objtype] else: obj_kwargs = dict() # Simulate spectra if objtype == 'SKY': fibermap['DESI_TARGET'][ii] = desi_mask.SKY continue elif objtype == 'ELG': from desisim.templates import ELG elg = ELG(wave=wave) simflux, wave1, meta1, objmeta1 = elg.make_templates(nmodel=nobj, seed=seed, **obj_kwargs) fibermap['DESI_TARGET'][ii] = desi_mask.ELG elif objtype == 'LRG': from desisim.templates import LRG lrg = LRG(wave=wave) simflux, wave1, meta1, objmeta1 = lrg.make_templates(nmodel=nobj, seed=seed, **obj_kwargs) fibermap['DESI_TARGET'][ii] = desi_mask.LRG elif objtype == 'BGS': from desisim.templates import BGS bgs = BGS(wave=wave) simflux, wave1, meta1, objmeta1 = bgs.make_templates(nmodel=nobj, seed=seed, **obj_kwargs) fibermap['DESI_TARGET'][ii] = desi_mask.BGS_ANY fibermap['BGS_TARGET'][ii] = bgs_mask.BGS_BRIGHT elif objtype == 'QSO': from desisim.templates import QSO qso = QSO(wave=wave) simflux, wave1, meta1, objmeta1 = qso.make_templates(nmodel=nobj, seed=seed, lyaforest=False, **obj_kwargs) fibermap['DESI_TARGET'][ii] = desi_mask.QSO # For a "bad" QSO simulate a normal star without color cuts, which isn't # right. We need to apply the QSO color-cuts to the normal stars to pull # out the correct population of contaminating stars. # Note by @moustakas: we can now do this using desisim/#150, but we are # going to need 'noisy' photometry (because the QSO color-cuts # explicitly avoid the stellar locus). elif objtype == 'QSO_BAD': from desisim.templates import STAR #from desitarget.cuts import isQSO #star = STAR(wave=wave, colorcuts_function=isQSO) star = STAR(wave=wave) simflux, wave1, meta1, objmeta1 = star.make_templates(nmodel=nobj, seed=seed, **obj_kwargs) fibermap['DESI_TARGET'][ii] = desi_mask.QSO elif objtype == 'STD': from desisim.templates import STD std = STD(wave=wave) simflux, wave1, meta1, objmeta1 = std.make_templates(nmodel=nobj, seed=seed, **obj_kwargs) #- Loop options for forwards/backwards compatibility for name in ['STD_FAINT', 'STD_FSTAR', 'STD']: if name in desi_mask.names(): fibermap['DESI_TARGET'][ii] |= desi_mask[name] break elif objtype == 'MWS_STAR': from desisim.templates import MWS_STAR mwsstar = MWS_STAR(wave=wave) # TODO: mag ranges for different programs of STAR targets should be in desimodel if 'magrange' not in obj_kwargs.keys(): obj_kwargs['magrange'] = (15.0,20.0) simflux, wave1, meta1, objmeta1 = mwsstar.make_templates(nmodel=nobj, seed=seed, **obj_kwargs) fibermap['DESI_TARGET'][ii] |= desi_mask.MWS_ANY #- MWS bit names changed after desitarget 0.6.0 so use number #- instead of name for now (bit 0 = mask 1 = MWS_MAIN currently) fibermap['MWS_TARGET'][ii] = 1 else: raise ValueError('Unable to simulate OBJTYPE={}'.format(objtype)) # Assign targetid meta1['TARGETID'] = targetid[ii] if hasattr(objmeta1, 'data'): # simqso.sqgrids.QsoSimPoints object objmeta1.data['TARGETID'] = targetid[ii] else: if len(objmeta1) > 0: objmeta1['TARGETID'] = targetid[ii] # We want the dict key tied to the "true" object type (e.g., STAR), # not, e.g., QSO_BAD. objmeta[meta1['OBJTYPE'][0]] = objmeta1 flux[ii] = simflux meta[ii] = meta1 for band in ['G', 'R', 'Z', 'W1', 'W2']: key = 'FLUX_'+band fibermap[key][ii] = meta[key][ii] #- TODO: FLUX_IVAR #- Load fiber -> positioner mapping and tile information fiberpos = desimodel.io.load_fiberpos() #- Where are these targets? Centered on positioners for now. x = fiberpos['X'][specmin:specmin+nspec] y = fiberpos['Y'][specmin:specmin+nspec] fp = FocalPlane(tile_ra, tile_dec) ra = np.zeros(nspec) dec = np.zeros(nspec) for i in range(nspec): ra[i], dec[i] = fp.xy2radec(x[i], y[i]) #- Fill in the rest of the fibermap structure fibermap['FIBER'] = np.arange(nspec, dtype='i4') fibermap['POSITIONER'] = fiberpos['POSITIONER'][specmin:specmin+nspec] fibermap['SPECTROID'] = fiberpos['SPECTROGRAPH'][specmin:specmin+nspec] fibermap['TARGETCAT'] = np.zeros(nspec, dtype=(str, 20)) fibermap['LAMBDA_REF'] = np.ones(nspec, dtype=np.float32)*5400 fibermap['TARGET_RA'] = ra fibermap['TARGET_DEC'] = dec fibermap['FIBERASSIGN_X'] = x fibermap['FIBERASSIGN_Y'] = y fibermap['FIBER_RA'] = fibermap['TARGET_RA'] fibermap['FIBER_DEC'] = fibermap['TARGET_DEC'] fibermap['BRICKNAME'] = brick.brickname(ra, dec) return fibermap, (flux, wave, meta, objmeta)
def get_targets(nspec, tileid=None): """ Returns: fibermap truth table TODO (@moustakas): Deal with the random seed correctly. TODO: document this better """ if tileid is None: tile_ra, tile_dec = 0.0, 0.0 else: tile_ra, tile_dec = io.get_tile_radec(tileid) #- Get distribution of target types true_objtype, target_objtype = sample_objtype(nspec) #- Get DESI wavelength coverage wavemin = desimodel.io.load_throughput('b').wavemin wavemax = desimodel.io.load_throughput('z').wavemax dw = 0.2 wave = np.arange(round(wavemin, 1), wavemax, dw) nwave = len(wave) truth = dict() truth['FLUX'] = np.zeros((nspec, len(wave))) truth['REDSHIFT'] = np.zeros(nspec, dtype='f4') truth['TEMPLATEID'] = np.zeros(nspec, dtype='i4') truth['OIIFLUX'] = np.zeros(nspec, dtype='f4') truth['D4000'] = np.zeros(nspec, dtype='f4') truth['VDISP'] = np.zeros(nspec, dtype='f4') truth['OBJTYPE'] = np.zeros(nspec, dtype='S10') #- Note: unlike other elements, first index of WAVE isn't spectrum index truth['WAVE'] = wave fibermap = empty_fibermap(nspec) for objtype in set(true_objtype): ii = np.where(true_objtype == objtype)[0] nobj = len(ii) fibermap['OBJTYPE'][ii] = target_objtype[ii] truth['OBJTYPE'][ii] = true_objtype[ii] # Simulate spectra if objtype == 'SKY': continue elif objtype == 'ELG': from desisim.templates import ELG elg = ELG(wave=wave) simflux, wave1, meta = elg.make_templates(nmodel=nobj) elif objtype == 'LRG': from desisim.templates import LRG lrg = LRG(wave=wave) simflux, wave1, meta = lrg.make_templates(nmodel=nobj) elif objtype == 'QSO': from desisim.templates import QSO qso = QSO(wave=wave) simflux, wave1, meta = qso.make_templates(nmodel=nobj) # For a "bad" QSO simulate a normal star without color cuts, which isn't # right. We need to apply the QSO color-cuts to the normal stars to pull # out the correct population of contaminating stars. elif objtype == 'QSO_BAD': from desisim.templates import STAR star = STAR(wave=wave) simflux, wave1, meta = star.make_templates(nmodel=nobj) elif objtype == 'STD': from desisim.templates import STAR star = STAR(wave=wave, FSTD=True) simflux, wave1, meta = star.make_templates(nmodel=nobj) truth['FLUX'][ii] = 1e17 * simflux truth['UNITS'] = '1e-17 erg/s/cm2/A' truth['TEMPLATEID'][ii] = meta['TEMPLATEID'] truth['REDSHIFT'][ii] = meta['REDSHIFT'] # Pack in the photometry. TODO: Include WISE. magg = meta['GMAG'] magr = meta['RMAG'] magz = meta['ZMAG'] fibermap['MAG'][ii, 0:3] = np.vstack([magg, magr, magz]).T fibermap['FILTER'][ii, 0:3] = ['DECAM_G', 'DECAM_R', 'DECAM_Z'] if objtype == 'ELG': truth['OIIFLUX'][ii] = meta['OIIFLUX'] truth['D4000'][ii] = meta['D4000'] truth['VDISP'][ii] = meta['VDISP'] if objtype == 'LRG': truth['D4000'][ii] = meta['D4000'] truth['VDISP'][ii] = meta['VDISP'] #- Load fiber -> positioner mapping and tile information fiberpos = desimodel.io.load_fiberpos() #- Where are these targets? Centered on positioners for now. x = fiberpos['X'][0:nspec] y = fiberpos['Y'][0:nspec] fp = FocalPlane(tile_ra, tile_dec) ra = np.zeros(nspec) dec = np.zeros(nspec) for i in range(nspec): ra[i], dec[i] = fp.xy2radec(x[i], y[i]) #- Fill in the rest of the fibermap structure fibermap['FIBER'] = np.arange(nspec, dtype='i4') fibermap['POSITIONER'] = fiberpos['POSITIONER'][0:nspec] fibermap['SPECTROID'] = fiberpos['SPECTROGRAPH'][0:nspec] fibermap['TARGETID'] = np.random.randint(sys.maxint, size=nspec) fibermap['TARGETCAT'] = np.zeros(nspec, dtype='|S20') fibermap['LAMBDAREF'] = np.ones(nspec, dtype=np.float32) * 5400 fibermap['TARGET_MASK0'] = np.zeros(nspec, dtype='i8') fibermap['RA_TARGET'] = ra fibermap['DEC_TARGET'] = dec fibermap['X_TARGET'] = x fibermap['Y_TARGET'] = y fibermap['X_FVCOBS'] = fibermap['X_TARGET'] fibermap['Y_FVCOBS'] = fibermap['Y_TARGET'] fibermap['X_FVCERR'] = np.zeros(nspec, dtype=np.float32) fibermap['Y_FVCERR'] = np.zeros(nspec, dtype=np.float32) fibermap['RA_OBS'] = fibermap['RA_TARGET'] fibermap['DEC_OBS'] = fibermap['DEC_TARGET'] fibermap['BRICKNAME'] = brick.brickname(ra, dec) return fibermap, truth
def get_targets(nspec, tileid=None): """ Returns: fibermap truth table TODO: document this better """ if tileid is None: tile_ra, tile_dec = 0.0, 0.0 else: tile_ra, tile_dec = io.get_tile_radec(tileid) #- Get distribution of target types true_objtype, target_objtype = sample_objtype(nspec) #- Get DESI wavelength coverage wavemin = desimodel.io.load_throughput('b').wavemin wavemax = desimodel.io.load_throughput('z').wavemax dw = 0.2 wave = np.arange(round(wavemin, 1), wavemax, dw) nwave = len(wave) truth = dict() truth['FLUX'] = np.zeros( (nspec, len(wave)) ) truth['REDSHIFT'] = np.zeros(nspec, dtype='f4') truth['TEMPLATEID'] = np.zeros(nspec, dtype='i4') truth['O2FLUX'] = np.zeros(nspec, dtype='f4') truth['OBJTYPE'] = np.zeros(nspec, dtype='S10') #- Note: unlike other elements, first index of WAVE isn't spectrum index truth['WAVE'] = wave fibermap = empty_fibermap(nspec) for objtype in set(true_objtype): ii = np.where(true_objtype == objtype)[0] fibermap['OBJTYPE'][ii] = target_objtype[ii] truth['OBJTYPE'][ii] = true_objtype[ii] if objtype == 'SKY': continue try: simflux, meta = io.read_templates(wave, objtype, len(ii)) except ValueError, err: print err continue truth['FLUX'][ii] = simflux #- STD don't have redshift Z; others do #- In principle we should also have redshifts (radial velocities) #- for standards as well. if 'Z' in meta.dtype.names: truth['REDSHIFT'][ii] = meta['Z'] elif objtype != 'STD': print "No redshifts for", objtype, len(ii) #- Only ELGs have [OII] flux if objtype == 'ELG': truth['O2FLUX'][ii] = meta['OII_3727'] #- Everyone had a templateid truth['TEMPLATEID'][ii] = meta['TEMPLATEID'] #- Extract magnitudes from colors #- TODO: make this more consistent at the input level #- Standard Stars have SDSS magnitudes if objtype == 'STD': magr = meta['SDSS_R'] magi = magr - meta['SDSS_RI'] magz = magi - meta['SDSS_IZ'] magg = magr - meta['SDSS_GR'] #- R-G, not G-R ? magu = magg - meta['SDSS_UG'] mags = np.vstack( [magu, magg, magr, magi, magz] ).T filters = ['SDSS_U', 'SDSS_G', 'SDSS_R', 'SDSS_I', 'SDSS_Z'] fibermap['MAG'][ii] = mags fibermap['FILTER'][ii] = filters #- LRGs elif objtype == 'LRG': magz = meta['DECAM_Z'] magr = magz - meta['DECAM_RZ'] magw = magr - meta['DECAM_RW1'] fibermap['MAG'][ii, 0:3] = np.vstack( [magr, magz, magw] ).T fibermap['FILTER'][ii, 0:3] = ['DECAM_R', 'DECAM_Z', 'WISE_W1'] #- ELGs elif objtype == 'ELG': magr = meta['DECAM_R'] magg = magr - meta['DECAM_GR'] magz = magr - meta['DECAM_RZ'] fibermap['MAG'][ii, 0:3] = np.vstack( [magg, magr, magz] ).T fibermap['FILTER'][ii, 0:3] = ['DECAM_G', 'DECAM_R', 'DECAM_Z'] elif objtype == 'QSO': #- QSO templates don't have magnitudes yet pass
def get_targets(nspec, tileid=None): """ Returns: fibermap truth table TODO (@moustakas): Deal with the random seed correctly. TODO: document this better """ if tileid is None: tile_ra, tile_dec = 0.0, 0.0 else: tile_ra, tile_dec = io.get_tile_radec(tileid) # - Get distribution of target types true_objtype, target_objtype = sample_objtype(nspec) # - Get DESI wavelength coverage wavemin = desimodel.io.load_throughput("b").wavemin wavemax = desimodel.io.load_throughput("z").wavemax dw = 0.2 wave = np.arange(round(wavemin, 1), wavemax, dw) nwave = len(wave) truth = dict() truth["FLUX"] = np.zeros((nspec, len(wave))) truth["REDSHIFT"] = np.zeros(nspec, dtype="f4") truth["TEMPLATEID"] = np.zeros(nspec, dtype="i4") truth["OIIFLUX"] = np.zeros(nspec, dtype="f4") truth["D4000"] = np.zeros(nspec, dtype="f4") truth["OBJTYPE"] = np.zeros(nspec, dtype="S10") # - Note: unlike other elements, first index of WAVE isn't spectrum index truth["WAVE"] = wave fibermap = empty_fibermap(nspec) for objtype in set(true_objtype): ii = np.where(true_objtype == objtype)[0] nobj = len(ii) fibermap["OBJTYPE"][ii] = target_objtype[ii] truth["OBJTYPE"][ii] = true_objtype[ii] # Simulate spectra if objtype == "SKY": continue elif objtype == "ELG": from desisim.templates import ELG elg = ELG(nmodel=nobj, wave=wave) simflux, wave1, meta = elg.make_templates() elif objtype == "LRG": from desisim.templates import LRG lrg = LRG(nmodel=nobj, wave=wave) simflux, wave1, meta = lrg.make_templates() elif objtype == "QSO": from desisim.templates import QSO qso = QSO(nmodel=nobj, wave=wave) simflux, wave1, meta = qso.make_templates() # For a "bad" QSO simulate a normal star without color cuts, which isn't # right. We need to apply the QSO color-cuts to the normal stars to pull # out the correct population of contaminating stars. elif objtype == "QSO_BAD": from desisim.templates import STAR star = STAR(nmodel=nobj, wave=wave) simflux, wave1, meta = star.make_templates() elif objtype == "STD": from desisim.templates import STAR star = STAR(nmodel=nobj, wave=wave, FSTD=True) simflux, wave1, meta = star.make_templates() truth["FLUX"][ii] = simflux truth["TEMPLATEID"][ii] = meta["TEMPLATEID"] truth["REDSHIFT"][ii] = meta["REDSHIFT"] # Pack in the photometry. TODO: Include WISE. magg = meta["GMAG"] magr = meta["RMAG"] magz = meta["ZMAG"] fibermap["MAG"][ii, 0:3] = np.vstack([magg, magr, magz]).T fibermap["FILTER"][ii, 0:3] = ["DECAM_G", "DECAM_R", "DECAM_Z"] if objtype == "ELG": truth["OIIFLUX"][ii] = meta["OIIFLUX"] truth["D4000"][ii] = meta["D4000"] if objtype == "LRG": truth["D4000"][ii] = meta["D4000"] # - Load fiber -> positioner mapping and tile information fiberpos = desimodel.io.load_fiberpos() # - Where are these targets? Centered on positioners for now. x = fiberpos["X"][0:nspec] y = fiberpos["Y"][0:nspec] fp = FocalPlane(tile_ra, tile_dec) ra = np.zeros(nspec) dec = np.zeros(nspec) for i in range(nspec): ra[i], dec[i] = fp.xy2radec(x[i], y[i]) # - Fill in the rest of the fibermap structure fibermap["FIBER"] = np.arange(nspec, dtype="i4") fibermap["POSITIONER"] = fiberpos["POSITIONER"][0:nspec] fibermap["SPECTROID"] = fiberpos["SPECTROGRAPH"][0:nspec] fibermap["TARGETID"] = np.random.randint(sys.maxint, size=nspec) fibermap["TARGETCAT"] = np.zeros(nspec, dtype="|S20") fibermap["LAMBDAREF"] = np.ones(nspec, dtype=np.float32) * 5400 fibermap["TARGET_MASK0"] = np.zeros(nspec, dtype="i8") fibermap["RA_TARGET"] = ra fibermap["DEC_TARGET"] = dec fibermap["X_TARGET"] = x fibermap["Y_TARGET"] = y fibermap["X_FVCOBS"] = fibermap["X_TARGET"] fibermap["Y_FVCOBS"] = fibermap["Y_TARGET"] fibermap["X_FVCERR"] = np.zeros(nspec, dtype=np.float32) fibermap["Y_FVCERR"] = np.zeros(nspec, dtype=np.float32) fibermap["RA_OBS"] = fibermap["RA_TARGET"] fibermap["DEC_OBS"] = fibermap["DEC_TARGET"] fibermap["BRICKNAME"] = brick.brickname(ra, dec) return fibermap, truth
#!/usr/bin/env python import sys,string import argparse import numpy as np from desispec.io.fibermap import empty_fibermap,write_fibermap parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument('-o','--out', type = str, default = None, required = True, help = 'path to output fibermap') parser.add_argument('--nspec', type = int, default = 0, required = True, help = 'number of spectra') parser.add_argument('--flavor', type = str, default = "bla", required = False, help = 'flavor') parser.add_argument('--night', type = str, default = "19751016", required = False, help = 'night') parser.add_argument('--expid', type = str, default = 0, required = False, help = 'exposure id') parser.add_argument('--spectro', type = int, default = 1, required = False, help = 'spectro') args = parser.parse_args() fmap = empty_fibermap(args.nspec*(args.spectro+1)) fmap.meta["FLAVOR"]=args.flavor fmap.meta["NIGHT"]=args.night fmap.meta["EXPID"]=args.expid write_fibermap(args.out,fmap)
def get_targets(nspec, program, tileid=None, seed=None, specify_targets=dict(), specmin=0): """ Generates a set of targets for the requested program Args: nspec: (int) number of targets to generate program: (str) program name DARK, BRIGHT, GRAY, MWS, BGS, LRG, ELG, ... Options: * tileid: (int) tileid, used for setting RA,dec * seed: (int) random number seed * specify_targets: (dict of dicts) Define target properties like magnitude and redshift for each target class. Each objtype has its own key,value pair see simspec.templates.specify_galparams_dict() or simsepc.templates.specify_starparams_dict() * specmin: (int) first spectrum number (0-indexed) Returns: * fibermap * targets as tuple of (flux, wave, meta) """ if tileid is None: tile_ra, tile_dec = 0.0, 0.0 else: tile_ra, tile_dec = io.get_tile_radec(tileid) program = program.upper() log.debug('Using random seed {}'.format(seed)) np.random.seed(seed) #- Get distribution of target types true_objtype, target_objtype = sample_objtype(nspec, program) #- Get DESI wavelength coverage wavemin = desimodel.io.load_throughput('b').wavemin wavemax = desimodel.io.load_throughput('z').wavemax dw = 0.2 wave = np.arange(round(wavemin, 1), wavemax, dw) nwave = len(wave) flux = np.zeros((nspec, len(wave))) meta = empty_metatable(nmodel=nspec, objtype='SKY') fibermap = empty_fibermap(nspec) for objtype in set(true_objtype): ii = np.where(true_objtype == objtype)[0] nobj = len(ii) fibermap['OBJTYPE'][ii] = target_objtype[ii] if objtype in specify_targets.keys(): obj_kwargs = specify_targets[objtype] else: obj_kwargs = dict() # Simulate spectra if objtype == 'SKY': fibermap['DESI_TARGET'][ii] = desi_mask.SKY continue elif objtype == 'ELG': from desisim.templates import ELG elg = ELG(wave=wave) simflux, wave1, meta1 = elg.make_templates(nmodel=nobj, seed=seed, **obj_kwargs) fibermap['DESI_TARGET'][ii] = desi_mask.ELG elif objtype == 'LRG': from desisim.templates import LRG lrg = LRG(wave=wave) simflux, wave1, meta1 = lrg.make_templates(nmodel=nobj, seed=seed, **obj_kwargs) fibermap['DESI_TARGET'][ii] = desi_mask.LRG elif objtype == 'BGS': from desisim.templates import BGS bgs = BGS(wave=wave) simflux, wave1, meta1 = bgs.make_templates(nmodel=nobj, seed=seed, **obj_kwargs) fibermap['DESI_TARGET'][ii] = desi_mask.BGS_ANY fibermap['BGS_TARGET'][ii] = bgs_mask.BGS_BRIGHT elif objtype == 'QSO': from desisim.templates import QSO qso = QSO(wave=wave) simflux, wave1, meta1 = qso.make_templates(nmodel=nobj, seed=seed, lyaforest=False, **obj_kwargs) fibermap['DESI_TARGET'][ii] = desi_mask.QSO # For a "bad" QSO simulate a normal star without color cuts, which isn't # right. We need to apply the QSO color-cuts to the normal stars to pull # out the correct population of contaminating stars. # Note by @moustakas: we can now do this using desisim/#150, but we are # going to need 'noisy' photometry (because the QSO color-cuts # explicitly avoid the stellar locus). elif objtype == 'QSO_BAD': from desisim.templates import STAR #from desitarget.cuts import isQSO #star = STAR(wave=wave, colorcuts_function=isQSO) star = STAR(wave=wave) simflux, wave1, meta1 = star.make_templates(nmodel=nobj, seed=seed, **obj_kwargs) fibermap['DESI_TARGET'][ii] = desi_mask.QSO elif objtype == 'STD': from desisim.templates import FSTD fstd = FSTD(wave=wave) simflux, wave1, meta1 = fstd.make_templates(nmodel=nobj, seed=seed, **obj_kwargs) fibermap['DESI_TARGET'][ii] = desi_mask.STD_FSTAR elif objtype == 'MWS_STAR': from desisim.templates import MWS_STAR mwsstar = MWS_STAR(wave=wave) # todo: mag ranges for different programs of STAR targets should be in desimodel if 'rmagrange' not in obj_kwargs.keys(): obj_kwargs['rmagrange'] = (15.0, 20.0) simflux, wave1, meta1 = mwsstar.make_templates(nmodel=nobj, seed=seed, **obj_kwargs) fibermap['DESI_TARGET'][ii] = desi_mask.MWS_ANY #- MWS bit names changed after desitarget 0.6.0 so use number #- instead of name for now (bit 0 = mask 1 = MWS_MAIN currently) fibermap['MWS_TARGET'][ii] = 1 else: raise ValueError('Unable to simulate OBJTYPE={}'.format(objtype)) flux[ii] = simflux meta[ii] = meta1 fibermap['FILTER'][ii, :6] = [ 'DECAM_G', 'DECAM_R', 'DECAM_Z', 'WISE_W1', 'WISE_W2' ] fibermap['MAG'][ii, 0] = 22.5 - 2.5 * np.log10(meta['FLUX_G'][ii]) fibermap['MAG'][ii, 1] = 22.5 - 2.5 * np.log10(meta['FLUX_R'][ii]) fibermap['MAG'][ii, 2] = 22.5 - 2.5 * np.log10(meta['FLUX_Z'][ii]) fibermap['MAG'][ii, 3] = 22.5 - 2.5 * np.log10(meta['FLUX_W1'][ii]) fibermap['MAG'][ii, 4] = 22.5 - 2.5 * np.log10(meta['FLUX_W2'][ii]) #- Load fiber -> positioner mapping and tile information fiberpos = desimodel.io.load_fiberpos() #- Where are these targets? Centered on positioners for now. x = fiberpos['X'][specmin:specmin + nspec] y = fiberpos['Y'][specmin:specmin + nspec] fp = FocalPlane(tile_ra, tile_dec) ra = np.zeros(nspec) dec = np.zeros(nspec) for i in range(nspec): ra[i], dec[i] = fp.xy2radec(x[i], y[i]) #- Fill in the rest of the fibermap structure fibermap['FIBER'] = np.arange(nspec, dtype='i4') fibermap['POSITIONER'] = fiberpos['POSITIONER'][specmin:specmin + nspec] fibermap['SPECTROID'] = fiberpos['SPECTROGRAPH'][specmin:specmin + nspec] fibermap['TARGETID'] = np.random.randint(sys.maxsize, size=nspec) fibermap['TARGETCAT'] = np.zeros(nspec, dtype=(str, 20)) fibermap['LAMBDAREF'] = np.ones(nspec, dtype=np.float32) * 5400 fibermap['RA_TARGET'] = ra fibermap['DEC_TARGET'] = dec fibermap['X_TARGET'] = x fibermap['Y_TARGET'] = y fibermap['X_FVCOBS'] = fibermap['X_TARGET'] fibermap['Y_FVCOBS'] = fibermap['Y_TARGET'] fibermap['X_FVCERR'] = np.zeros(nspec, dtype=np.float32) fibermap['Y_FVCERR'] = np.zeros(nspec, dtype=np.float32) fibermap['RA_OBS'] = fibermap['RA_TARGET'] fibermap['DEC_OBS'] = fibermap['DEC_TARGET'] fibermap['BRICKNAME'] = brick.brickname(ra, dec) return fibermap, (flux, wave, meta)
def get_targets(nspec, tileid=None): """ Returns: fibermap truth table TODO: document this better """ if tileid is None: tile_ra, tile_dec = 0.0, 0.0 else: tile_ra, tile_dec = io.get_tile_radec(tileid) #- Get distribution of target types true_objtype, target_objtype = sample_objtype(nspec) #- Get DESI wavelength coverage wavemin = desimodel.io.load_throughput('b').wavemin wavemax = desimodel.io.load_throughput('z').wavemax dw = 0.2 wave = np.arange(round(wavemin, 1), wavemax, dw) nwave = len(wave) truth = dict() truth['FLUX'] = np.zeros((nspec, len(wave))) truth['REDSHIFT'] = np.zeros(nspec, dtype='f4') truth['TEMPLATEID'] = np.zeros(nspec, dtype='i4') truth['O2FLUX'] = np.zeros(nspec, dtype='f4') truth['OBJTYPE'] = np.zeros(nspec, dtype='S10') #- Note: unlike other elements, first index of WAVE isn't spectrum index truth['WAVE'] = wave fibermap = empty_fibermap(nspec) for objtype in set(true_objtype): ii = np.where(true_objtype == objtype)[0] fibermap['OBJTYPE'][ii] = target_objtype[ii] truth['OBJTYPE'][ii] = true_objtype[ii] if objtype == 'SKY': continue try: simflux, meta = io.read_templates(wave, objtype, len(ii)) except ValueError, err: print err continue truth['FLUX'][ii] = simflux #- STD don't have redshift Z; others do #- In principle we should also have redshifts (radial velocities) #- for standards as well. if 'Z' in meta.dtype.names: truth['REDSHIFT'][ii] = meta['Z'] elif objtype != 'STD': print "No redshifts for", objtype, len(ii) #- Only ELGs have [OII] flux if objtype == 'ELG': truth['O2FLUX'][ii] = meta['OII_3727'] #- Everyone had a templateid truth['TEMPLATEID'][ii] = meta['TEMPLATEID'] #- Extract magnitudes from colors #- TODO: make this more consistent at the input level #- Standard Stars have SDSS magnitudes if objtype == 'STD': magr = meta['SDSS_R'] magi = magr - meta['SDSS_RI'] magz = magi - meta['SDSS_IZ'] magg = magr - meta['SDSS_GR'] #- R-G, not G-R ? magu = magg - meta['SDSS_UG'] mags = np.vstack([magu, magg, magr, magi, magz]).T filters = ['SDSS_U', 'SDSS_G', 'SDSS_R', 'SDSS_I', 'SDSS_Z'] fibermap['MAG'][ii] = mags fibermap['FILTER'][ii] = filters #- LRGs elif objtype == 'LRG': magz = meta['DECAM_Z'] magr = magz - meta['DECAM_RZ'] magw = magr - meta['DECAM_RW1'] fibermap['MAG'][ii, 0:3] = np.vstack([magr, magz, magw]).T fibermap['FILTER'][ii, 0:3] = ['DECAM_R', 'DECAM_Z', 'WISE_W1'] #- ELGs elif objtype == 'ELG': magr = meta['DECAM_R'] magg = magr - meta['DECAM_GR'] magz = magr - meta['DECAM_RZ'] fibermap['MAG'][ii, 0:3] = np.vstack([magg, magr, magz]).T fibermap['FILTER'][ii, 0:3] = ['DECAM_G', 'DECAM_R', 'DECAM_Z'] elif objtype == 'QSO': #- QSO templates don't have magnitudes yet pass
def get_targets(nspec, program, tileid=None, seed=None, specify_targets=dict(), specmin=0): """ Generates a set of targets for the requested program Args: nspec: (int) number of targets to generate program: (str) program name DARK, BRIGHT, GRAY, MWS, BGS, LRG, ELG, ... Options: * tileid: (int) tileid, used for setting RA,dec * seed: (int) random number seed * specify_targets: (dict of dicts) Define target properties like magnitude and redshift for each target class. Each objtype has its own key,value pair see simspec.templates.specify_galparams_dict() or simsepc.templates.specify_starparams_dict() * specmin: (int) first spectrum number (0-indexed) Returns: * fibermap * targets as tuple of (flux, wave, meta) """ if tileid is None: tile_ra, tile_dec = 0.0, 0.0 else: tile_ra, tile_dec = io.get_tile_radec(tileid) program = program.upper() log.debug('Using random seed {}'.format(seed)) np.random.seed(seed) #- Get distribution of target types true_objtype, target_objtype = sample_objtype(nspec, program) #- Get DESI wavelength coverage try: params = desimodel.io.load_desiparams() wavemin = params['ccd']['b']['wavemin'] wavemax = params['ccd']['z']['wavemax'] except KeyError: wavemin = desimodel.io.load_throughput('b').wavemin wavemax = desimodel.io.load_throughput('z').wavemax dw = 0.2 wave = np.arange(round(wavemin, 1), wavemax, dw) nwave = len(wave) flux = np.zeros( (nspec, len(wave)) ) meta, _ = empty_metatable(nmodel=nspec, objtype='SKY') objmeta = dict() fibermap = empty_fibermap(nspec) targetid = np.random.randint(sys.maxsize, size=nspec).astype(np.int64) meta['TARGETID'] = targetid fibermap['TARGETID'] = targetid for objtype in set(true_objtype): ii = np.where(true_objtype == objtype)[0] nobj = len(ii) fibermap['OBJTYPE'][ii] = target_objtype[ii] if objtype in specify_targets.keys(): obj_kwargs = specify_targets[objtype] else: obj_kwargs = dict() # Simulate spectra if objtype == 'SKY': fibermap['DESI_TARGET'][ii] = desi_mask.SKY continue elif objtype == 'ELG': from desisim.templates import ELG elg = ELG(wave=wave) simflux, wave1, meta1, objmeta1 = elg.make_templates(nmodel=nobj, seed=seed, **obj_kwargs) fibermap['DESI_TARGET'][ii] = desi_mask.ELG elif objtype == 'LRG': from desisim.templates import LRG lrg = LRG(wave=wave) simflux, wave1, meta1, objmeta1 = lrg.make_templates(nmodel=nobj, seed=seed, **obj_kwargs) fibermap['DESI_TARGET'][ii] = desi_mask.LRG elif objtype == 'BGS': from desisim.templates import BGS bgs = BGS(wave=wave) simflux, wave1, meta1, objmeta1 = bgs.make_templates(nmodel=nobj, seed=seed, **obj_kwargs) fibermap['DESI_TARGET'][ii] = desi_mask.BGS_ANY fibermap['BGS_TARGET'][ii] = bgs_mask.BGS_BRIGHT elif objtype == 'QSO': from desisim.templates import QSO qso = QSO(wave=wave) simflux, wave1, meta1, objmeta1 = qso.make_templates(nmodel=nobj, seed=seed, lyaforest=False, **obj_kwargs) fibermap['DESI_TARGET'][ii] = desi_mask.QSO # For a "bad" QSO simulate a normal star without color cuts, which isn't # right. We need to apply the QSO color-cuts to the normal stars to pull # out the correct population of contaminating stars. # Note by @moustakas: we can now do this using desisim/#150, but we are # going to need 'noisy' photometry (because the QSO color-cuts # explicitly avoid the stellar locus). elif objtype == 'QSO_BAD': from desisim.templates import STAR #from desitarget.cuts import isQSO #star = STAR(wave=wave, colorcuts_function=isQSO) star = STAR(wave=wave) simflux, wave1, meta1, objmeta1 = star.make_templates(nmodel=nobj, seed=seed, **obj_kwargs) fibermap['DESI_TARGET'][ii] = desi_mask.QSO elif objtype == 'STD': from desisim.templates import STD std = STD(wave=wave) simflux, wave1, meta1, objmeta1 = std.make_templates(nmodel=nobj, seed=seed, **obj_kwargs) #- Loop options for forwards/backwards compatibility for name in ['STD_FAINT', 'STD_FSTAR', 'STD']: if name in desi_mask.names(): fibermap['DESI_TARGET'][ii] |= desi_mask[name] break elif objtype == 'MWS_STAR': from desisim.templates import MWS_STAR mwsstar = MWS_STAR(wave=wave) # TODO: mag ranges for different programs of STAR targets should be in desimodel if 'magrange' not in obj_kwargs.keys(): obj_kwargs['magrange'] = (15.0,20.0) simflux, wave1, meta1, objmeta1 = mwsstar.make_templates(nmodel=nobj, seed=seed, **obj_kwargs) fibermap['DESI_TARGET'][ii] |= desi_mask.MWS_ANY #- MWS bit names changed after desitarget 0.6.0 so use number #- instead of name for now (bit 0 = mask 1 = MWS_MAIN currently) fibermap['MWS_TARGET'][ii] = 1 else: raise ValueError('Unable to simulate OBJTYPE={}'.format(objtype)) # Assign targetid meta1['TARGETID'] = targetid[ii] if hasattr(objmeta1, 'data'): # simqso.sqgrids.QsoSimPoints object objmeta1.data['TARGETID'] = targetid[ii] else: if len(objmeta1) > 0: objmeta1['TARGETID'] = targetid[ii] # We want the dict key tied to the "true" object type (e.g., STAR), # not, e.g., QSO_BAD. objmeta[meta1['OBJTYPE'][0]] = objmeta1 flux[ii] = simflux meta[ii] = meta1 for band in ['G', 'R', 'Z', 'W1', 'W2']: key = 'FLUX_'+band fibermap[key][ii] = meta[key][ii] #- TODO: FLUX_IVAR #- Load fiber -> positioner mapping and tile information fiberpos = desimodel.io.load_fiberpos() #- Where are these targets? Centered on positioners for now. x = fiberpos['X'][specmin:specmin+nspec] y = fiberpos['Y'][specmin:specmin+nspec] fp = FocalPlane(tile_ra, tile_dec) ra = np.zeros(nspec) dec = np.zeros(nspec) for i in range(nspec): ra[i], dec[i] = fp.xy2radec(x[i], y[i]) #- Fill in the rest of the fibermap structure fibermap['FIBER'] = np.arange(nspec, dtype='i4') fibermap['POSITIONER'] = fiberpos['POSITIONER'][specmin:specmin+nspec] fibermap['SPECTROID'] = fiberpos['SPECTROGRAPH'][specmin:specmin+nspec] fibermap['TARGETCAT'] = np.zeros(nspec, dtype=(str, 20)) fibermap['LAMBDA_REF'] = np.ones(nspec, dtype=np.float32)*5400 fibermap['TARGET_RA'] = ra fibermap['TARGET_DEC'] = dec fibermap['DESIGN_X'] = x fibermap['DESIGN_Y'] = y fibermap['FIBER_RA'] = fibermap['TARGET_RA'] fibermap['FIBER_DEC'] = fibermap['TARGET_DEC'] fibermap['BRICKNAME'] = brick.brickname(ra, dec) return fibermap, (flux, wave, meta, objmeta)