parser = optparse.OptionParser(usage = "%prog [options]") parser.add_option("-b", "--brick", type=str, help="input brickname") parser.add_option("-n", "--nspec", type=int, help="number of spectra to fit [default: all]") parser.add_option("-o", "--outfile", type=str, help="output file name") parser.add_option("--zspec", help="also include spectra in output file", action="store_true") opts, args = parser.parse_args() log = get_logger() #- Read brick files for each channel log.info("Reading bricks") brick = dict() for channel in ('b', 'r', 'z'): filename = io.findfile('brick', band=channel, brickid=opts.brick) brick[channel] = io.Brick(filename) #- Assume all channels have the same number of targets #- TODO: generalize this to allow missing channels if opts.nspec is None: opts.nspec = brick['b'].get_num_targets() log.info("Fitting {} targets".format(opts.nspec)) else: log.info("Fitting {} of {} targets".format(opts.nspec, brick['b'].get_num_targets())) nspec = opts.nspec #- Coadd individual exposures and combine channels #- Full coadd code is a bit slow, so try something quick and dirty for #- now to get something going for redshifting log.info("Combining individual channels and exposures")
def main(args, comm=None): log = get_logger() if args.npoly < 0: log.warning("Need npoly>=0, changing this %d -> 1" % args.npoly) args.npoly = 0 if args.nproc < 1: log.warning("Need nproc>=1, changing this %d -> 1" % args.nproc) args.nproc = 1 if comm is not None: if args.nproc != 1: if comm.rank == 0: log.warning("Using MPI, forcing multiprocessing nproc -> 1") args.nproc = 1 if args.objtype is not None: args.objtype = args.objtype.split(',') #- Read brick files for each channel if (comm is None) or (comm.rank == 0): log.info("Reading bricks") brick = dict() if args.brick is not None: if len(args.brickfiles) != 0: raise RuntimeError( 'Give -b/--brick or input brickfiles but not both') for channel in ('b', 'r', 'z'): filename = None if (comm is None) or (comm.rank == 0): filename = io.findfile('brick', band=channel, brickname=args.brick, specprod_dir=args.specprod_dir) if comm is not None: filename = comm.bcast(filename, root=0) brick[channel] = io.Brick(filename) else: for filename in args.brickfiles: bx = io.Brick(filename) if bx.channel not in brick: brick[bx.channel] = bx else: if (comm is None) or (comm.rank == 0): log.error('Channel {} in multiple input files'.format( bx.channel)) sys.exit(2) filters = brick.keys() for fil in filters: if (comm is None) or (comm.rank == 0): log.info("Filter found: " + fil) #- Assume all channels have the same number of targets #- TODO: generalize this to allow missing channels #if args.nspec is None: # args.nspec = brick['b'].get_num_targets() # log.info("Fitting {} targets".format(args.nspec)) #else: # log.info("Fitting {} of {} targets".format(args.nspec, brick['b'].get_num_targets())) #- Coadd individual exposures and combine channels #- Full coadd code is a bit slow, so try something quick and dirty for #- now to get something going for redshifting if (comm is None) or (comm.rank == 0): log.info("Combining individual channels and exposures") wave = [] for fil in filters: wave = np.concatenate([wave, brick[fil].get_wavelength_grid()]) np.ndarray.sort(wave) nwave = len(wave) #- flux and ivar arrays to fill for all targets #flux = np.zeros((nspec, nwave)) #ivar = np.zeros((nspec, nwave)) flux = [] ivar = [] good_targetids = [] targetids = brick['b'].get_target_ids() fpinfo = None if args.print_info is not None: if (comm is None) or (comm.rank == 0): fpinfo = open(args.print_info, "w") for i, targetid in enumerate(targetids): #- wave, flux, and ivar for this target; concatenate xwave = list() xflux = list() xivar = list() good = True for channel in filters: exp_flux, exp_ivar, resolution, info = brick[channel].get_target( targetid) weights = np.sum(exp_ivar, axis=0) ii, = np.where(weights > 0) if len(ii) == 0: good = False break xwave.extend(brick[channel].get_wavelength_grid()[ii]) #- Average multiple exposures on the same wavelength grid for each channel xflux.extend( np.average(exp_flux[:, ii], weights=exp_ivar[:, ii], axis=0)) xivar.extend(weights[ii]) if not good: continue xwave = np.array(xwave) xivar = np.array(xivar) xflux = np.array(xflux) ii = np.argsort(xwave) #flux[i], ivar[i] = resample_flux(wave, xwave[ii], xflux[ii], xivar[ii]) fl, iv = resample_flux(wave, xwave[ii], xflux[ii], xivar[ii]) flux.append(fl) ivar.append(iv) good_targetids.append(targetid) if not args.print_info is None: s2n = np.median(fl[:-1] * np.sqrt(iv[:-1]) / np.sqrt(wave[1:] - wave[:-1])) if (comm is None) or (comm.rank == 0): print targetid, s2n fpinfo.write(str(targetid) + " " + str(s2n) + "\n") if not args.print_info is None: if (comm is None) or (comm.rank == 0): fpinfo.close() sys.exit() good_targetids = good_targetids[args.first_spec:] flux = np.array(flux[args.first_spec:]) ivar = np.array(ivar[args.first_spec:]) nspec = len(good_targetids) if (comm is None) or (comm.rank == 0): log.info("number of good targets = %d" % nspec) if (args.nspec is not None) and (args.nspec < nspec): if (comm is None) or (comm.rank == 0): log.info("Fitting {} of {} targets".format(args.nspec, nspec)) nspec = args.nspec good_targetids = good_targetids[:nspec] flux = flux[:nspec] ivar = ivar[:nspec] else: if (comm is None) or (comm.rank == 0): log.info("Fitting {} targets".format(nspec)) if (comm is None) or (comm.rank == 0): log.debug("flux.shape={}".format(flux.shape)) zf = None if comm is None: # Use multiprocessing built in to RedMonster. zf = RedMonsterZfind(wave=wave, flux=flux, ivar=ivar, objtype=args.objtype, zrange_galaxy=args.zrange_galaxy, zrange_qso=args.zrange_qso, zrange_star=args.zrange_star, nproc=args.nproc, npoly=args.npoly) else: # Use MPI # distribute the spectra among processes my_firstspec, my_nspec = dist_uniform(nspec, comm.size, comm.rank) my_specs = slice(my_firstspec, my_firstspec + my_nspec) for p in range(comm.size): if p == comm.rank: if my_nspec > 0: log.info("process {} fitting spectra {} - {}".format( p, my_firstspec, my_firstspec + my_nspec - 1)) else: log.info("process {} idle".format(p)) sys.stdout.flush() comm.barrier() # do redshift fitting on each process myzf = None if my_nspec > 0: savelevel = os.environ["DESI_LOGLEVEL"] os.environ["DESI_LOGLEVEL"] = "WARNING" myzf = RedMonsterZfind(wave=wave, flux=flux[my_specs, :], ivar=ivar[my_specs, :], objtype=args.objtype, zrange_galaxy=args.zrange_galaxy, zrange_qso=args.zrange_qso, zrange_star=args.zrange_star, nproc=args.nproc, npoly=args.npoly) os.environ["DESI_LOGLEVEL"] = savelevel # Combine results into a single ZFindBase object on the root process. # We could do this with a gather, but we are using a small number of # processes, and point-to-point communication is easier for people to # understand. if comm.rank == 0: zf = ZfindBase(myzf.wave, np.zeros((nspec, myzf.nwave)), np.zeros((nspec, myzf.nwave)), R=None, results=None) for p in range(comm.size): if comm.rank == 0: if p == 0: # root process copies its own data into output zf.flux[my_specs] = myzf.flux zf.ivar[my_specs] = myzf.ivar zf.model[my_specs] = myzf.model zf.z[my_specs] = myzf.z zf.zerr[my_specs] = myzf.zerr zf.zwarn[my_specs] = myzf.zwarn zf.spectype[my_specs] = myzf.spectype zf.subtype[my_specs] = myzf.subtype else: # root process receives from process p and copies # it into the output. p_nspec = comm.recv(source=p, tag=0) # only proceed if the sending process actually # has some spectra assigned to it. if p_nspec > 0: p_firstspec = comm.recv(source=p, tag=1) p_slice = slice(p_firstspec, p_firstspec + p_nspec) p_flux = comm.recv(source=p, tag=2) zf.flux[p_slice] = p_flux p_ivar = comm.recv(source=p, tag=3) zf.ivar[p_slice] = p_ivar p_model = comm.recv(source=p, tag=4) zf.model[p_slice] = p_model p_z = comm.recv(source=p, tag=5) zf.z[p_slice] = p_z p_zerr = comm.recv(source=p, tag=6) zf.zerr[p_slice] = p_zerr p_zwarn = comm.recv(source=p, tag=7) zf.zwarn[p_slice] = p_zwarn p_type = comm.recv(source=p, tag=8) zf.spectype[p_slice] = p_type p_subtype = comm.recv(source=p, tag=9) zf.subtype[p_slice] = p_subtype else: if p == comm.rank: # process p sends to root comm.send(my_nspec, dest=0, tag=0) if my_nspec > 0: comm.send(my_firstspec, dest=0, tag=1) comm.send(myzf.flux, dest=0, tag=2) comm.send(myzf.ivar, dest=0, tag=3) comm.send(myzf.model, dest=0, tag=4) comm.send(myzf.z, dest=0, tag=5) comm.send(myzf.zerr, dest=0, tag=6) comm.send(myzf.zwarn, dest=0, tag=7) comm.send(myzf.spectype, dest=0, tag=8) comm.send(myzf.subtype, dest=0, tag=9) comm.barrier() if (comm is None) or (comm.rank == 0): # The full results exist only on the rank zero process. # reformat results dtype = list() dtype = [ ('Z', zf.z.dtype), ('ZERR', zf.zerr.dtype), ('ZWARN', zf.zwarn.dtype), ('SPECTYPE', zf.spectype.dtype), ('SUBTYPE', zf.subtype.dtype), ] formatted_data = np.empty(nspec, dtype=dtype) formatted_data['Z'] = zf.z formatted_data['ZERR'] = zf.zerr formatted_data['ZWARN'] = zf.zwarn formatted_data['SPECTYPE'] = zf.spectype formatted_data['SUBTYPE'] = zf.subtype # Create a ZfindBase object with formatted results zfi = ZfindBase(None, None, None, results=formatted_data) zfi.nspec = nspec # QA if (args.qafile is not None) or (args.qafig is not None): log.info("performing skysub QA") # Load qabrick = load_qa_brick(args.qafile) # Run qabrick.run_qa('ZBEST', (zfi, brick)) # Write if args.qafile is not None: write_qa_brick(args.qafile, qabrick) log.info("successfully wrote {:s}".format(args.qafile)) # Figure(s) if args.qafig is not None: raise IOError("Not yet implemented") qa_plots.brick_zbest(args.qafig, zfi, qabrick) #- Write some output if args.outfile is None: args.outfile = io.findfile('zbest', brickname=args.brick) log.info("Writing " + args.outfile) #io.write_zbest(args.outfile, args.brick, targetids, zfi, zspec=args.zspec) io.write_zbest(args.outfile, args.brick, good_targetids, zfi, zspec=args.zspec) return
def main(): log = get_logger() key = 'DESI_ROOT' if key not in os.environ: log.fatal('Required ${} environment variable not set'.format(key)) return 0 desidir = os.getenv(key) simsdir = os.path.join(desidir, 'spectro', 'sim', 'bgs-sims1.0') brickdir = os.path.join(simsdir, 'bricks') parser = argparse.ArgumentParser() parser.add_argument('--sim', type=int, default=None, help='Simulation number (see documentation)') parser.add_argument('--nproc', type=int, default=1, help='Number of processors to use.') parser.add_argument('--simsdir', default=simsdir, help='Top-level simulation directory') parser.add_argument('--bricks', action='store_true', help='Generate the brick files.') parser.add_argument('--zfind', action='store_true', help='Fit for the redshifts.') parser.add_argument('--results', action='store_true', help='Merge all the relevant results.') parser.add_argument('--qaplots', action='store_true', help='Generate QAplots.') args = parser.parse_args() if args.sim is None: parser.print_help() sys.exit(1) # -------------------------------------------------- # Initialize the parameters of each simulation here. if args.sim == 1: seed = 678245 brickname = 'sim01' nbrick = 50 nspec = 20 phase = 0.25 rmag = (19.5, 19.5) redshift = (0.1, 0.3) zenith = 30 exptime = 300 angle = (0, 150) simoptions = [ '--exptime-range', '{}'.format(exptime), '{}'.format(exptime), '--rmagrange-bgs', '{}'.format(rmag[0]), '{}'.format(rmag[1]), '--zrange-bgs', '{}'.format(redshift[0]), '{}'.format(redshift[1]), '--moon-zenith-range', '{}'.format(zenith), '{}'.format(zenith), '--moon-phase-range', '{}'.format(phase), '{}'.format(phase), '--moon-angle-range', '{}'.format(angle[0]), '{}'.format(angle[1]) ] elif args.sim == 2: seed = 991274 brickname = 'sim02' nbrick = 50 nspec = 20 phase = (0.0, 1.0) rmag = (19.5, 19.5) redshift = (0.1, 0.3) zenith = 30 exptime = 300 angle = 60 simoptions = [ '--exptime-range', '{}'.format(exptime), '{}'.format(exptime), '--rmagrange-bgs', '{}'.format(rmag[0]), '{}'.format(rmag[1]), '--zrange-bgs', '{}'.format(redshift[0]), '{}'.format(redshift[1]), '--moon-zenith-range', '{}'.format(zenith), '{}'.format(zenith), '--moon-phase-range', '{}'.format(phase[0]), '{}'.format(phase[1]), '--moon-angle-range', '{}'.format(angle), '{}'.format(angle) ] elif args.sim == 3: seed = 471934 brickname = 'sim03' nbrick = 50 nspec = 20 phase = (0.0, 1.0) rmag = (19.5, 19.5) redshift = (0.1, 0.3) zenith = 30 exptime = 300 angle = (0, 150) simoptions = [ '--exptime-range', '{}'.format(exptime), '{}'.format(exptime), '--rmagrange-bgs', '{}'.format(rmag[0]), '{}'.format(rmag[1]), '--zrange-bgs', '{}'.format(redshift[0]), '{}'.format(redshift[1]), '--moon-zenith-range', '{}'.format(zenith), '{}'.format(zenith), '--moon-phase-range', '{}'.format(phase[0]), '{}'.format(phase[1]), '--moon-angle-range', '{}'.format(angle[0]), '{}'.format(angle[1]) ] elif args.sim == 4: seed = 971234 brickname = 'sim04' nbrick = 100 nspec = 50 phase = (0.0, 1.0) rmag = (17.5, 20.0) redshift = (0.1, 0.3) zenith = 30 exptime = 300 angle = (0, 150) simoptions = [ '--exptime-range', '{}'.format(exptime), '{}'.format(exptime), '--rmagrange-bgs', '{}'.format(rmag[0]), '{}'.format(rmag[1]), '--zrange-bgs', '{}'.format(redshift[0]), '{}'.format(redshift[1]), '--moon-zenith-range', '{}'.format(zenith), '{}'.format(zenith), '--moon-phase-range', '{}'.format(phase[0]), '{}'.format(phase[1]), '--moon-angle-range', '{}'.format(angle[0]), '{}'.format(angle[1]) ] nobj = nbrick*nspec rand = np.random.RandomState(seed) # -------------------------------------------------- # Generate the brick and truth files. if args.bricks: brightoptions = [ '--brickname', '{}'.format(brickname), '--nbrick', '{}'.format(nbrick), '--nspec', '{}'.format(nspec), '--outdir', '{}'.format(simsdir), '--brickdir', '{}'.format(brickdir), '--seed', '{}'.format(seed), '--objtype', 'BGS'] brightargs = brightsims.parse(np.hstack((brightoptions, simoptions))) brightargs.verbose = True brightsims.main(brightargs) # -------------------------------------------------- # Fit the redshifts if args.zfind: inputfile = os.path.join(simsdir, brickname+'-input.fits') log.info('Reading {}'.format(inputfile)) cat = fits.getdata(inputfile, 1) log.info('Testing with just one brick!') #for ib in range(10, 11): for ib in range(nbrick): thisbrick = cat['BRICKNAME'][ib] brickfiles = [os.path.join(brickdir, 'brick-{}-{}.fits'.format(ch, thisbrick)) for ch in ['b', 'r', 'z']] redoptions = [ '--brick', thisbrick, '--nproc', '{}'.format(args.nproc), '--specprod_dir', simsdir, '--zrange-galaxy', '{}'.format(redshift[0]), '{}'.format(redshift[1]), '--outfile', os.path.join(brickdir, thisbrick, 'zbest-{}.fits'.format(thisbrick)), '--objtype', 'ELG,LRG'] redargs = zfind.parse(redoptions) zfind.main(redargs) # -------------------------------------------------- # Parse and write out the simulation inputs, brick spectra, and redshifts if args.results: inputfile = os.path.join(simsdir, brickname+'-input.fits') log.info('Reading {}'.format(inputfile)) cat = fits.getdata(inputfile, 1) # Build a results table. resultfile = makepath(os.path.join(simsdir, '{}-results.fits'.format(brickname))) resultcols = [ ('EXPTIME', 'f4'), ('AIRMASS', 'f4'), ('MOONPHASE', 'f4'), ('MOONANGLE', 'f4'), ('MOONZENITH', 'f4'), ('SNR_B', 'f4'), ('SNR_R', 'f4'), ('SNR_Z', 'f4'), ('TARGETID', 'i8'), ('RMAG', 'f4'), ('D4000', 'f4'), ('EWHBETA', 'f4'), ('ZTRUE', 'f4'), ('Z', 'f4'), ('ZERR', 'f4'), ('ZWARNING', 'f4')] result = Table(np.zeros(nobj, dtype=resultcols)) result['EXPTIME'].unit = 's' result['MOONANGLE'].unit = 'deg' result['MOONZENITH'].unit = 'deg' for ib in range(nbrick): # Copy over some data. thisbrick = cat['BRICKNAME'][ib] result['EXPTIME'][nspec*ib:nspec*(ib+1)] = cat['EXPTIME'][ib] result['AIRMASS'][nspec*ib:nspec*(ib+1)] = cat['AIRMASS'][ib] result['MOONPHASE'][nspec*ib:nspec*(ib+1)] = cat['MOONPHASE'][ib] result['MOONANGLE'][nspec*ib:nspec*(ib+1)] = cat['MOONANGLE'][ib] result['MOONZENITH'][nspec*ib:nspec*(ib+1)] = cat['MOONZENITH'][ib] # Read the truth file of the first channel to get the metadata. truthfile = os.path.join(brickdir, thisbrick, 'truth-brick-{}-{}.fits'.format('b', thisbrick)) log.info('Reading {}'.format(truthfile)) truth = io.Brick(truthfile).hdu_list[4].data result['TARGETID'][nspec*ib:nspec*(ib+1)] = truth['TARGETID'] result['RMAG'][nspec*ib:nspec*(ib+1)] = 22.5-2.5*np.log10(truth['DECAM_FLUX'][:,2]) result['D4000'][nspec*ib:nspec*(ib+1)] = truth['D4000'] result['EWHBETA'][nspec*ib:nspec*(ib+1)] = truth['EWHBETA'] result['ZTRUE'][nspec*ib:nspec*(ib+1)] = truth['TRUEZ'] # Finally read the zbest file. zbestfile = os.path.join(brickdir, thisbrick, 'zbest-{}.fits'.format(thisbrick)) if os.path.isfile(zbestfile): log.info('Reading {}'.format(zbestfile)) zbest = read_zbest(zbestfile) # There's gotta be a better way than looping here! for ii in range(nspec): this = np.where(zbest.targetid[ii] == result['TARGETID'])[0] result['Z'][this] = zbest.z[ii] result['ZERR'][this] = zbest.zerr[ii] result['ZWARNING'][this] = zbest.zwarn[ii] #pdb.set_trace() # Finally, read the spectra and truth tables, one per channel. for channel in ('b','r','z'): brickfile = os.path.join(brickdir, thisbrick, 'brick-{}-{}.fits'.format(channel, thisbrick)) log.info('Reading {}'.format(brickfile)) brick = io.Brick(brickfile) wave = brick.get_wavelength_grid() for iobj in range(nspec): flux = brick.hdu_list[0].data[iobj,:] ivar = brick.hdu_list[1].data[iobj,:] these = np.where((wave>np.mean(wave)-50)*(wave<np.mean(wave)+50)*(flux>0))[0] result['SNR_'+channel.upper()][nspec*ib+iobj] = \ np.median(np.sqrt(flux[these]*ivar[these])) log.info('Writing {}'.format(resultfile)) write_bintable(resultfile, result, extname='RESULTS', clobber=True) # -------------------------------------------------- # Build QAplots if args.qaplots: phaserange = (-0.05, 1.05) snrrange = (0, 3) rmagrange = (17.5, 20) anglerange = (-5, 155) d4000range = (0.9, 2.2) snrinterval = 1.0 cmap = mpl.colors.ListedColormap(sns.color_palette('muted')) resultfile = os.path.join(simsdir, '{}-results.fits'.format(brickname)) log.info('Reading {}'.format(resultfile)) res = fits.getdata(resultfile, 1) qafile = os.path.join(simsdir, 'qa-{}.pdf'.format(brickname)) log.info('Writing {}'.format(qafile)) # ------------------------------ # Simulation 1 if args.sim == 1: fig, ax0 = plt.subplots(1, 1, figsize=(6, 4.5)) ax0.scatter(res['MOONANGLE']+rand.normal(0, 0.2, nobj), res['SNR_B'], label='b channel', c=col[1]) ax0.scatter(res['MOONANGLE']+rand.normal(0, 0.2, nobj), res['SNR_R'], label='r channel', c=col[2]) ax0.scatter(res['MOONANGLE']+rand.normal(0, 0.2, nobj), res['SNR_Z'], label='z channel', c=col[0]) ax0.set_xlabel('Object-Moon Angle (deg)') ax0.set_ylabel(r'Signal-to-Noise Ratio (pixel$^{-1}$)') ax0.set_xlim(anglerange) ax0.set_ylim(snrrange) plt.legend(loc='upper left', labelspacing=0.25) plt.text(0.95, 0.7, 't = {:g} s\nr = {:g} mag\nRedshift = {:.2f}-{:.2f}'.format(exptime, rmag, redshift[0], redshift[1])+\ '\nLunar Zenith Angle = {:g} deg\nLunar Phase = {:g}'.format(zenith, phase), horizontalalignment='right', transform=ax0.transAxes, fontsize=11) plt.subplots_adjust(bottom=0.2, right=0.95, left=0.15) plt.savefig(qafile) plt.close() #pdb.set_trace() # ------------------------------ # Simulation 2 if args.sim == 2: fig, ax0 = plt.subplots(1, 1, figsize=(6, 4.5)) ax0.scatter(res['MOONPHASE']+rand.normal(0, 0.02, nobj), res['SNR_B'], label='b channel', c=col[1]) ax0.scatter(res['MOONPHASE']+rand.normal(0, 0.02, nobj), res['SNR_R'], label='r channel', c=col[2]) ax0.scatter(res['MOONPHASE']+rand.normal(0, 0.02, nobj), res['SNR_Z'], label='z channel', c=col[0]) ax0.set_xlabel('Lunar Phase (0=Full, 1=New)') ax0.set_ylabel(r'Signal-to-Noise Ratio (pixel$^{-1}$)') ax0.set_xlim(phaserange) ax0.set_ylim(snrrange) plt.legend(loc='upper left', labelspacing=0.25) plt.text(0.95, 0.7, 't = {:g} s\nr = {:g} mag\nRedshift = {:.2f}-{:.2f}'.format(exptime, rmag, redshift[0], redshift[1])+\ '\nLunar Zenith Angle = {:g} deg\nObject-Moon Angle = {:g} deg'.format(zenith, angle), horizontalalignment='right', transform=ax0.transAxes, fontsize=11) plt.subplots_adjust(bottom=0.2, right=0.95, left=0.15) plt.savefig(qafile) plt.close() # ------------------------------ # Simulation 3 if args.sim == 3: fig, ax0 = plt.subplots(1, 1, figsize=(6, 4)) im = ax0.scatter(res['MOONANGLE']+rand.normal(0, 0.3, nobj), res['SNR_R'], c=res['MOONPHASE'], vmin=phaserange, cmap=cmap) ax0.set_xlabel('Object-Moon Angle (deg)') ax0.set_ylabel(r'r channel Signal-to-Noise Ratio (pixel$^{-1}$)') ax0.set_xlim(anglerange) ax0.set_ylim(snrrange) ax0.yaxis.set_major_locator(mpl.ticker.MultipleLocator(snrinterval)) plt.text(0.95, 0.7, 't = {:g} s\nr = {:g} mag\nRedshift = {:.2f}-{:.2f}'.format(exptime, rmag, redshift[0], redshift[1])+\ '\nLunar Zenith Angle = {:g} deg'.format(zenith), horizontalalignment='right', transform=ax0.transAxes, fontsize=11) cbar = fig.colorbar(im) cbar.set_ticks([0, 0.5, 1]) cbar.ax.set_yticklabels(['Full','Quarter','New'], rotation=90) cbar.ax.set_ylabel('Lunar Phase') plt.subplots_adjust(bottom=0.2, right=1.0) plt.savefig(qafile) plt.close() # ------------------------------ # Simulation 4 if args.sim == 4: bins = 30 zgood = (np.abs(res['Z']-res['ZTRUE'])<5E-5)*(res['ZWARNING']==0)*1 H, xedges, yedges = np.histogram2d(res['RMAG'], res['MOONPHASE'], bins=bins, weights=zgood) H2, _, _ = np.histogram2d(res['RMAG'], res['MOONPHASE'], bins=bins) extent = np.array((rmagrange, phaserange)).flatten() #pdb.set_trace() fig, ax0 = plt.subplots(1, 1, figsize=(6, 4)) im = ax0.imshow(H/H2, extent=extent, interpolation='nearest')#, cmap=cmap) ax0.set_xlabel('r (AB mag)') ax0.set_ylabel('Lunar Phase (0=Full, 1=New)') ax0.set_xlim(rmagrange) ax0.set_ylim(phaserange) #plt.text(0.95, 0.7, 't = {:g} s\nr = {:g} mag\nRedshift = {:.2f}-{:.2f}'.format(exptime, rmag, # redshift[0], redshift[1])+\ # '\nLunar Zenith Angle = {:g} deg'.format(zenith), # horizontalalignment='right', transform=ax0.transAxes, # fontsize=11) cbar = fig.colorbar(im) #cbar.set_ticks([0, 0.5, 1]) #cbar.ax.set_yticklabels(['Full','Quarter','New'], rotation=90) #cbar.ax.set_ylabel('Lunar Phase') plt.subplots_adjust(bottom=0.2, right=1.0) plt.savefig(qafile) plt.close() # ------------------------------ # Simulation 10 if args.sim == 10: zgood = (np.abs(res['Z']-res['ZTRUE'])<0.001)*(res['ZWARNING']==0)*1 #pdb.set_trace() fig, (ax0, ax1, ax2) = plt.subplots(3, 1, figsize=(6,6)) # moon phase vs S/N(r) im = ax0.scatter(res['RMAG'], res['SNR_R'], c=res['MOONPHASE'], vmin=phaserange, cmap=cmap) ax0.set_xlabel('r (AB mag)') ax0.set_ylabel('S/N (r channel)') ax0.set_xlim(rmagrange) ax0.set_ylim(snrrange) ax0.yaxis.set_major_locator(mpl.ticker.MultipleLocator(snrinterval)) # object-moon angle vs S/N(r) im = ax1.scatter(res['MOONANGLE'], res['SNR_R'], c=res['MOONPHASE'], vmin=phaserange, cmap=cmap) ax1.set_xlabel('Object-Moon Angle (deg)') ax1.set_ylabel('S/N (r channel)') ax1.set_xlim(anglerange) ax1.set_ylim(snrrange) ax1.yaxis.set_major_locator(mpl.ticker.MultipleLocator(snrinterval)) # D(4000) vs S/N(r) im = ax2.scatter(res['D4000'], res['SNR_R'], c=res['MOONPHASE'], vmin=phaserange, cmap=cmap) ax2.set_xlabel('$D_{n}(4000)$') ax2.set_ylabel('S/N (r channel)') ax2.set_xlim(d4000range) ax2.set_ylim(snrrange) ax2.yaxis.set_major_locator(mpl.ticker.MultipleLocator(snrinterval)) # Shared colorbar cbarax = fig.add_axes([0.83, 0.15, 0.03, 0.8]) cbar = fig.colorbar(im, cax=cbarax) ticks = ['Full','Quarter','New'] cbar.set_ticks([0, 0.5, 1]) cbar.ax.set_yticklabels(ticks, rotation=-45) plt.tight_layout(pad=0.5)#, h_pad=0.2, w_pad=0.3) plt.subplots_adjust(right=0.78) plt.savefig(qafile) plt.close()