def slurp(self, make_frameqa=False, remove=True, **kwargs): """ Slurp all the individual QA files into one master QA file Args: make_frameqa: bool, optional Regenerate the individual QA files (at the frame level first) remove: bool, optional Remove Returns: """ from desispec.io import meta from desispec.qa import QA_Exposure from desispec.io import write_qa_prod import pdb # Remake? if make_frameqa: self.make_frameqa(**kwargs) # Loop on nights path_nights = glob.glob(self.specprod_dir+'/exposures/*') nights = [ipathn[ipathn.rfind('/')+1:] for ipathn in path_nights] # Reset log.info("Resetting qa_exps in qa_prod") self.qa_exps = [] # Loop for night in nights: # Loop on exposures for exposure in get_exposures(night, specprod_dir = self.specprod_dir): frames_dict = get_files(filetype = str('frame'), night = night, expid = exposure, specprod_dir = self.specprod_dir) if len(frames_dict.keys()) == 0: continue # Load any frame (for the type) key = frames_dict.keys()[0] frame_fil = frames_dict[key] frame = read_frame(frame_fil) qa_exp = QA_Exposure(exposure, night, frame.meta['FLAVOR'], specprod_dir=self.specprod_dir, remove=remove) # Append self.qa_exps.append(qa_exp) # Write outroot = self.specprod_dir+'/'+self.prod_name+'_qa' write_qa_prod(outroot, self)
def load_qa_data(self, remove=False): """ Load the QA data files for a given exposure (currently yaml) Args: remove: bool, optional Remove QA frame files """ from desispec import io as desiio qafiles = desiio.get_files(filetype='qa_'+self.type, night=self.night, expid=self.expid, specprod_dir=self.specprod_dir) #import pdb; pdb.set_trace() # Load into frames for camera,qadata_path in qafiles.iteritems(): qa_frame = desiio.load_qa_frame(qadata_path) # Remove? if remove: #import pdb; pdb.set_trace() os.remove(qadata_path) # Test for key in ['expid','night']: assert getattr(qa_frame,key) == getattr(self, key) # Save self.data['frames'][camera] = qa_frame.qa_data
def make_frameqa(self, make_plots=False, clobber=True): """ Work through the Production and make QA for all frames Parameters: make_plots: bool, optional Remake the plots too? clobber: bool, optional Returns: """ # imports from desispec.io import meta from desispec.io.qa import load_qa_frame, write_qa_frame from desispec.io.fiberflat import read_fiberflat from desispec.io.sky import read_sky from desispec.io.fluxcalibration import read_flux_calibration from desispec.qa import qa_plots from desispec.io.fluxcalibration import read_stdstar_models # Loop on nights path_nights = glob.glob(self.specprod_dir+'/exposures/*') nights = [ipathn[ipathn.rfind('/')+1:] for ipathn in path_nights] for night in nights: for exposure in get_exposures(night, specprod_dir = self.specprod_dir): # Object only?? frames_dict = get_files(filetype = str('frame'), night = night, expid = exposure, specprod_dir = self.specprod_dir) for camera,frame_fil in frames_dict.items(): # Load frame frame = read_frame(frame_fil) spectro = int(frame.meta['CAMERA'][-1]) if frame.meta['FLAVOR'] in ['flat','arc']: qatype = 'qa_calib' else: qatype = 'qa_data' qafile = meta.findfile(qatype, night=night, camera=camera, expid=exposure, specprod_dir=self.specprod_dir) if (not clobber) & os.path.isfile(qafile): log.info("qafile={:s} exists. Not over-writing. Consider clobber=True".format(qafile)) continue # Load qaframe = load_qa_frame(qafile, frame, flavor=frame.meta['FLAVOR']) # Flat QA if frame.meta['FLAVOR'] in ['flat']: fiberflat_fil = meta.findfile('fiberflat', night=night, camera=camera, expid=exposure, specprod_dir=self.specprod_dir) fiberflat = read_fiberflat(fiberflat_fil) qaframe.run_qa('FIBERFLAT', (frame, fiberflat), clobber=clobber) if make_plots: # Do it qafig = meta.findfile('qa_flat_fig', night=night, camera=camera, expid=exposure, specprod_dir=self.specprod_dir) qa_plots.frame_fiberflat(qafig, qaframe, frame, fiberflat) # SkySub QA if qatype == 'qa_data': sky_fil = meta.findfile('sky', night=night, camera=camera, expid=exposure, specprod_dir=self.specprod_dir) skymodel = read_sky(sky_fil) qaframe.run_qa('SKYSUB', (frame, skymodel)) if make_plots: qafig = meta.findfile('qa_sky_fig', night=night, camera=camera, expid=exposure, specprod_dir=self.specprod_dir) qa_plots.frame_skyres(qafig, frame, skymodel, qaframe) # FluxCalib QA if qatype == 'qa_data': # Standard stars stdstar_fil = meta.findfile('stdstars', night=night, camera=camera, expid=exposure, specprod_dir=self.specprod_dir, spectrograph=spectro) model_tuple=read_stdstar_models(stdstar_fil) flux_fil = meta.findfile('calib', night=night, camera=camera, expid=exposure, specprod_dir=self.specprod_dir) fluxcalib = read_flux_calibration(flux_fil) qaframe.run_qa('FLUXCALIB', (frame, fluxcalib, model_tuple))#, indiv_stars)) if make_plots: qafig = meta.findfile('qa_flux_fig', night=night, camera=camera, expid=exposure, specprod_dir=self.specprod_dir) qa_plots.frame_fluxcalib(qafig, qaframe, frame, fluxcalib, model_tuple) # Write write_qa_frame(qafile, qaframe)
def main(args) : # imports import glob from desispec.io import findfile from desispec.io import get_exposures from desispec.io import get_files from desispec.io import read_frame from desispec.io.sky import read_sky from desispec.qa.qa_plots import skysub_resid import copy import pdb # Log log=get_logger() log.info("starting") # Exposures? if args.expids is not None: expids = [int(iarg) for iarg in args.expids.split(',')] else: expids = 'all' # Nights? if args.nights is not None: gdnights = [iarg for iarg in args.nights.split(',')] else: gdnights = 'all' # Channels? if args.channels is not None: gdchannels = [iarg for iarg in args.channels.split(',')] else: gdchannels = 'all' # Sky dict sky_dict = dict(wave=[], skyflux=[], res=[], count=0) channel_dict = dict(b=copy.deepcopy(sky_dict), r=copy.deepcopy(sky_dict), z=copy.deepcopy(sky_dict), ) # Loop on nights path_nights = glob.glob(args.specprod_dir+'/exposures/*') nights = [ipathn[ipathn.rfind('/')+1:] for ipathn in path_nights] for night in nights: if gdnights == 'all': pass else: if night not in gdnights: continue # Get em for exposure in get_exposures(night, specprod_dir = args.specprod_dir): # Check against input expids if expids == 'all': pass else: if exposure not in expids: continue # Get em frames_dict = get_files(filetype=str('cframe'), night=night, expid=exposure, specprod_dir=args.specprod_dir) for camera, cframe_fil in frames_dict.items(): channel = camera[0] # Check against input if gdchannels == 'all': pass else: if channel not in gdchannels: continue # Load frame log.info('Loading {:s}'.format(cframe_fil)) cframe = read_frame(cframe_fil) if cframe.meta['FLAVOR'] in ['flat','arc']: # Probably can't happen continue # Sky sky_file = findfile(str('sky'), night=night, camera=camera, expid=exposure, specprod_dir=args.specprod_dir) skymodel = read_sky(sky_file) # Resid skyfibers = np.where(cframe.fibermap['OBJTYPE'] == 'SKY')[0] res = cframe.flux[skyfibers] flux = skymodel.flux[skyfibers] # Residuals tmp = np.outer(np.ones(flux.shape[0]), cframe.wave) # Append #from xastropy.xutils import xdebug as xdb #xdb.set_trace() channel_dict[channel]['wave'].append(tmp.flatten()) channel_dict[channel]['skyflux'].append( np.log10(np.maximum(flux.flatten(),1e-1))) channel_dict[channel]['res'].append(res.flatten()) channel_dict[channel]['count'] += 1 # Figure for channel in ['b', 'r', 'z']: if channel_dict[channel]['count'] > 0: sky_wave = np.concatenate(channel_dict[channel]['wave']) sky_flux = np.concatenate(channel_dict[channel]['skyflux']) sky_res = np.concatenate(channel_dict[channel]['res']) # Plot skysub_resid(sky_wave, sky_flux, sky_res, outfile='tmp{:s}.png'.format(channel))
def main(args) : # imports import glob from desispec.io import findfile, makepath from desispec.io import get_exposures from desispec.io import get_files, get_nights from desispec.io import get_reduced_frames from desispec.io import specprod_root from desispec.io import qaprod_root from desispec.qa import utils as qa_utils import copy import pdb # Init specprod_dir = specprod_root() # Log log=get_logger() log.info("starting") # Path if args.qaprod_dir is not None: qaprod_dir = args.qaprod_dir else: qaprod_dir = qaprod_root() # Channels if args.channels is not None: channels = [iarg for iarg in args.channels.split(',')] else: channels = ['b','r','z'] # Sky dict sky_dict = dict(wave=[], skyflux=[], res=[], count=0) channel_dict = dict(b=copy.deepcopy(sky_dict), r=copy.deepcopy(sky_dict), z=copy.deepcopy(sky_dict), ) # Nights if args.nights is not None: nights = [iarg for iarg in args.nights.split(',')] else: nights = None # Exposure plot? if args.expid is not None: # Nights if nights is None: nights = get_nights() nights.sort() # Find the exposure for night in nights: if args.expid in get_exposures(night, specprod_dir=specprod_dir): frames_dict = get_files(filetype=str('cframe'), night=night, expid=args.expid, specprod_dir=specprod_dir) # Loop on channel #for channel in ['b','r','z']: for channel in ['z']: channel_dict[channel]['cameras'] = [] for camera, cframe_fil in frames_dict.items(): if channel in camera: sky_file = findfile(str('sky'), night=night, camera=camera, expid=args.expid, specprod_dir=specprod_dir) wave, flux, res, _ = qa_utils.get_skyres(cframe_fil) # Append channel_dict[channel]['wave'].append(wave) channel_dict[channel]['skyflux'].append(np.log10(np.maximum(flux,1e-1))) channel_dict[channel]['res'].append(res) channel_dict[channel]['cameras'].append(camera) channel_dict[channel]['count'] += 1 if channel_dict[channel]['count'] > 0: from desispec.qa.qa_plots import skysub_resid_series # Hidden to help with debugging skysub_resid_series(channel_dict[channel], 'wave', outfile=qaprod_dir+'/QA_skyresid_wave_expid_{:d}{:s}.png'.format(args.expid, channel)) skysub_resid_series(channel_dict[channel], 'flux', outfile=qaprod_dir+'/QA_skyresid_flux_expid_{:d}{:s}.png'.format(args.expid, channel)) return # Skyline if args.skyline: from desispec.qa.qa_plots import skyline_resid # Loop on channel for channel in channels: cframes = get_reduced_frames(nights=nights, channels=[channel]) if len(cframes) > 0: log.info("Loading sky residuals for {:d} cframes".format(len(cframes))) if len(cframes) == 1: log.error('len(cframes)==1; starting debugging') pdb.set_trace() # Need to call differently else: sky_wave, sky_flux, sky_res, sky_ivar = qa_utils.get_skyres( cframes, flatten=False) # Plot outfile=args.outdir+'/skyline_{:s}.png'.format(channel) log.info("Plotting to {:s}".format(outfile)) skyline_resid(channel, sky_wave, sky_flux, sky_res, sky_ivar, outfile=outfile) return # Full Prod Plot? if args.prod: from desispec.qa.qa_plots import skysub_resid_dual # Loop on channel for channel in channels: cframes = get_reduced_frames(nights=nights, channels=[channel]) if len(cframes) > 0: log.info("Loading sky residuals for {:d} cframes".format(len(cframes))) sky_wave, sky_flux, sky_res, _ = qa_utils.get_skyres(cframes) # Plot outfile=qaprod_dir+'/skyresid_prod_dual_{:s}.png'.format(channel) makepath(outfile) log.info("Plotting to {:s}".format(outfile)) skysub_resid_dual(sky_wave, sky_flux, sky_res, outfile=outfile) return # Test sky noise for Gaussianity if args.gauss: from desispec.qa.qa_plots import skysub_gauss # Loop on channel for channel in channels: cframes = get_reduced_frames(nights=nights, channels=[channel]) if len(cframes) > 0: # Cut down for debugging #cframes = [cframes[ii] for ii in range(15)] # log.info("Loading sky residuals for {:d} cframes".format(len(cframes))) sky_wave, sky_flux, sky_res, sky_ivar = qa_utils.get_skyres(cframes) # Plot log.info("Plotting..") outfile=qaprod_dir+'/skyresid_prod_gauss_{:s}.png'.format(channel) makepath(outfile) skysub_gauss(sky_wave, sky_flux, sky_res, sky_ivar, outfile=outfile) return