def main(args): if args.file is not None: spectrograph_name, config_lines, spec2d_files = io.read_spec2d_file( args.file, filetype="coadd3d") else: msgs.error('You must input a coadd3d file') # Coadd the files coadd_cube(spec2d_files, det=args.det, overwrite=args.overwrite)
def main(args): if args.file is None: msgs.error('You must input a coadd3d file') else: spectrograph_name, config_lines, spec2d_files = io.read_spec2d_file(args.file, filetype="coadd3d") spectrograph = load_spectrograph(spectrograph_name) # Parameters spectrograph_def_par = spectrograph.default_pypeit_par() parset = par.PypeItPar.from_cfg_lines(cfg_lines=spectrograph_def_par.to_config(), merge_with=config_lines) # If detector was passed as an argument override whatever was in the coadd3d file if args.det is not None: msgs.info("Restricting to detector={}".format(args.det)) parset['rdx']['detnum'] = int(args.det) # Coadd the files coadd_cube(spec2d_files, parset, overwrite=args.overwrite)
def main(args): """ Executes 2d coadding """ msgs.info('PATH =' + os.getcwd()) # Load the file if args.file is not None: spectrograph_name, config_lines, spec2d_files \ = io.read_spec2d_file(args.file, filetype="coadd2d") spectrograph = load_spectrograph(spectrograph_name) # Parameters # TODO: Shouldn't this reinstantiate the same parameters used in # the PypeIt run that extracted the objects? Why are we not # just passing the pypeit file? # JFH: The reason is that the coadd2dfile may want different reduction parameters # DP: I think config_specific_par() is more appropriate here. default_pypeit_par() # is included in config_specific_par() # NOTE `config_specific_par` works with the spec2d files because we construct the header # of those files to include all the relevant keywords from the raw file. spectrograph_cfg_lines = spectrograph.config_specific_par( spec2d_files[0]).to_config() parset = par.PypeItPar.from_cfg_lines( cfg_lines=spectrograph_cfg_lines, merge_with=config_lines) elif args.obj is not None: # TODO: We should probably be reading the pypeit file and using # those parameters here rather than using the default parset. # TODO: This needs to define the science path spec2d_files = glob.glob('./Science/spec2d_*' + args.obj + '*') head0 = fits.getheader(spec2d_files[0]) spectrograph_name = head0['PYP_SPEC'] spectrograph = load_spectrograph(spectrograph_name) # NOTE `config_specific_par` works with the spec2d files because we construct the header # of those files to include all the relevant keywords from the raw file. spectrograph_cfg_lines = spectrograph.config_specific_par( spec2d_files[0]).to_config() parset = par.PypeItPar.from_cfg_lines( cfg_lines=spectrograph_cfg_lines) else: return msgs.error( 'You must provide either a coadd2d file (--file) or an object name (--obj)' ) # If detector was passed as an argument override whatever was in the coadd2d_file if args.det is not None: msgs.info("Restricting reductions to detector={}".format(args.det)) # parset['rdx']['detnum'] = par.util.eval_tuple(args.det.split(',')) # TODO this needs to be adjusted if we want to pass (as inline command) mosaic detectors parset['rdx']['detnum'] = [int(d) for d in args.det.split(',')] # Get headers (if possible) and base names spec1d_files = [ files.replace('spec2d', 'spec1d') for files in spec2d_files ] head1d = None for spec1d_file in spec1d_files: if os.path.isfile(spec1d_file): head1d = fits.getheader(spec1d_file) break if head1d is None: msgs.warn( "No 1D spectra so am generating a dummy header for output") head1d = io.initialize_header() head2d = fits.getheader(spec2d_files[0]) if args.basename is None: #TODO Fix this, currently does not work if target names have - or _ filename_first = os.path.basename(spec2d_files[0]) filename_last = os.path.basename(spec2d_files[-1]) prefix_first = (filename_first.split('_')[1]).split('-')[0] prefix_last = (filename_last.split('_')[1]).split('-')[0] objname = (filename_first.split('-')[1]).split('_')[0] basename = '{:s}-{:s}-{:s}'.format(prefix_first, prefix_last, objname) else: basename = args.basename # TODO Heliocentric for coadd2d needs to be thought through. Currently turning it off. parset['calibrations']['wavelengths']['refframe'] = 'observed' # TODO Flexure correction for coadd2d needs to be thought through. Currently turning it off. parset['flexure']['spec_method'] = 'skip' # Write the par to disk par_outfile = basename + '_coadd2d.par' print("Writing the parameters to {}".format(par_outfile)) parset.to_config(par_outfile, exclude_defaults=True, include_descr=False) # Now run the coadds skysub_mode = head2d['SKYSUB'] findobj_mode = head2d['FINDOBJ'] bkg_redux = True if 'DIFF' in skysub_mode else False find_negative = True if 'NEG' in findobj_mode else False # Print status message msgs_string = 'Reducing target {:s}'.format(basename) + msgs.newline() msgs_string += 'Coadding frame sky-subtraced with {:s}'.format( skysub_mode) msgs_string += 'Searching for objects that are {:s}'.format( findobj_mode) msgs_string += msgs.newline( ) + 'Combining frames in 2d coadd:' + msgs.newline() for f, file in enumerate(spec2d_files): msgs_string += 'Exp {0}: {1:s}'.format( f, os.path.basename(file)) + msgs.newline() msgs.info(msgs_string) # TODO: This needs to be added to the parameter list for rdx redux_path = os.getcwd() master_dirname = os.path.basename(head2d['PYPMFDIR']) + '_coadd' master_dir = os.path.join(redux_path, master_dirname) # Make the new Master dir if not os.path.isdir(master_dir): msgs.info( 'Creating directory for Master output: {0}'.format(master_dir)) os.makedirs(master_dir) # Instantiate the sci_dict sci_dict = OrderedDict() # This needs to be ordered sci_dict['meta'] = {} sci_dict['meta']['vel_corr'] = 0. sci_dict['meta']['bkg_redux'] = bkg_redux sci_dict['meta']['find_negative'] = find_negative # Make QA coadd directory parset['rdx']['qadir'] += '_coadd' qa_path = os.path.join(parset['rdx']['redux_path'], parset['rdx']['qadir'], 'PNGs') if not os.path.isdir(qa_path): os.makedirs(qa_path) # Find the detectors to reduce # detectors = PypeIt.select_detectors(detnum=parset['rdx']['detnum'], ndet=spectrograph.ndet) detectors = spectrograph.select_detectors( subset=parset['rdx']['detnum']) # if len(detectors) != spectrograph.ndet: # msgs.warn('Not reducing detectors: {0}'.format(' '.join([str(d) for d in # set(np.arange(spectrograph.ndet) + 1) - set(detectors)]))) msgs.info(f'Detectors to work on: {detectors}') # Only_slits? if args.only_slits: parset['coadd2d']['only_slits'] = [ int(item) for item in args.only_slits.split(',') ] # container for specobjs all_specobjs = specobjs.SpecObjs() # container for spec2dobj all_spec2d = spec2dobj.AllSpec2DObj() # set some meta all_spec2d['meta']['bkg_redux'] = bkg_redux all_spec2d['meta']['find_negative'] = find_negative # Loop on detectors for det in detectors: msgs.info("Working on detector {0}".format(det)) # Instantiate Coadd2d coadd = coadd2d.CoAdd2D.get_instance( spec2d_files, spectrograph, parset, det=det, offsets=parset['coadd2d']['offsets'], weights=parset['coadd2d']['weights'], spec_samp_fact=args.spec_samp_fact, spat_samp_fact=args.spat_samp_fact, bkg_redux=bkg_redux, find_negative=find_negative, debug_offsets=args.debug_offsets, debug=args.debug) # TODO Add this stuff to a run method in coadd2d # Coadd the slits coadd_dict_list = coadd.coadd( only_slits=parset['coadd2d']['only_slits']) # Create the pseudo images pseudo_dict = coadd.create_pseudo_image(coadd_dict_list) # Reduce msgs.info('Running the extraction') # TODO -- This should mirror what is in pypeit.extract_one # TODO -- JFH :: This ought to return a Spec2DObj and SpecObjs which # would be slurped into AllSpec2DObj and all_specobsj, as below. # TODO -- JFH -- Check that the slits we are using are correct sci_dict[coadd.detname] = {} sci_dict[coadd.detname]['sciimg'], sci_dict[coadd.detname]['sciivar'], \ sci_dict[coadd.detname]['skymodel'], sci_dict[coadd.detname]['objmodel'], \ sci_dict[coadd.detname]['ivarmodel'], sci_dict[coadd.detname]['outmask'], \ sci_dict[coadd.detname]['specobjs'], sci_dict[coadd.detname]['detector'], \ sci_dict[coadd.detname]['slits'], sci_dict[coadd.detname]['tilts'], \ sci_dict[coadd.detname]['waveimg'] \ = coadd.reduce(pseudo_dict, show=args.show, show_peaks=args.peaks, basename=basename) # Tack on detector (similarly to pypeit.extract_one) for sobj in sci_dict[coadd.detname]['specobjs']: sobj.DETECTOR = sci_dict[coadd.detname]['detector'] # fill the specobjs container all_specobjs.add_sobj(sci_dict[coadd.detname]['specobjs']) # fill the spec2dobj container but first ... # pull out maskdef_designtab from sci_dict[det]['slits'] maskdef_designtab = sci_dict[ coadd.detname]['slits'].maskdef_designtab slits = copy.deepcopy(sci_dict[coadd.detname]['slits']) slits.maskdef_designtab = None # fill up all_spec2d[coadd.detname] = spec2dobj.Spec2DObj( sciimg=sci_dict[coadd.detname]['sciimg'], ivarraw=sci_dict[coadd.detname]['sciivar'], skymodel=sci_dict[coadd.detname]['skymodel'], objmodel=sci_dict[coadd.detname]['objmodel'], ivarmodel=sci_dict[coadd.detname]['ivarmodel'], scaleimg=np.array([1.0], dtype=np.float), bpmmask=sci_dict[coadd.detname]['outmask'], detector=sci_dict[coadd.detname]['detector'], slits=slits, waveimg=sci_dict[coadd.detname]['waveimg'], tilts=sci_dict[coadd.detname]['tilts'], sci_spat_flexure=None, sci_spec_flexure=None, vel_corr=None, vel_type=None, maskdef_designtab=maskdef_designtab) # Save pseudo image master files #coadd.save_masters() # SAVE TO DISK # Make the new Science dir # TODO: This needs to be defined by the user scipath = os.path.join(redux_path, 'Science_coadd') if not os.path.isdir(scipath): msgs.info( 'Creating directory for Science output: {0}'.format(scipath)) os.makedirs(scipath) # THE FOLLOWING MIMICS THE CODE IN pypeit.save_exposure() subheader = spectrograph.subheader_for_spec(head2d, head2d) # Write spec1D if all_specobjs.nobj > 0: outfile1d = os.path.join(scipath, 'spec1d_{:s}.fits'.format(basename)) all_specobjs.write_to_fits(subheader, outfile1d) # Info outfiletxt = os.path.join(scipath, 'spec1d_{:s}.txt'.format(basename)) sobjs = specobjs.SpecObjs.from_fitsfile(outfile1d, chk_version=False) sobjs.write_info(outfiletxt, spectrograph.pypeline) # Build header for spec2d outfile2d = os.path.join(scipath, 'spec2d_{:s}.fits'.format(basename)) pri_hdr = all_spec2d.build_primary_hdr( head2d, spectrograph, subheader=subheader, # TODO -- JFH :: Decide if we need any of these redux_path=None, master_key_dict=None, master_dir=None) # Write spec2d all_spec2d.write_to_fits(outfile2d, pri_hdr=pri_hdr)
def main(args): """ Executes 2d coadding """ msgs.warn('PATH =' + os.getcwd()) # Load the file if args.file is not None: spectrograph_name, config_lines, spec2d_files = io.read_spec2d_file( args.file, filetype="coadd2d") spectrograph = load_spectrograph(spectrograph_name) # Parameters # TODO: Shouldn't this reinstantiate the same parameters used in # the PypeIt run that extracted the objects? Why are we not # just passing the pypeit file? # JFH: The reason is that the coadd2dfile may want different reduction parameters spectrograph_def_par = spectrograph.default_pypeit_par() parset = par.PypeItPar.from_cfg_lines( cfg_lines=spectrograph_def_par.to_config(), merge_with=config_lines) elif args.obj is not None: # TODO: We should probably be reading the pypeit file and using those parameters here rather than using the # default parset. # TODO: This needs to define the science path spec2d_files = glob.glob('./Science/spec2d_*' + args.obj + '*') head0 = fits.getheader(spec2d_files[0]) spectrograph_name = head0['PYP_SPEC'] spectrograph = load_spectrograph(spectrograph_name) parset = spectrograph.default_pypeit_par() else: msgs.error( 'You must either input a coadd2d file with --file or an object name with --obj' ) # Update with configuration specific parameters (which requires science file) and initialize spectrograph spectrograph_cfg_lines = spectrograph.config_specific_par( spec2d_files[0]).to_config() parset = par.PypeItPar.from_cfg_lines(cfg_lines=spectrograph_cfg_lines, merge_with=parset.to_config()) # If detector was passed as an argument override whatever was in the coadd2d_file if args.det is not None: msgs.info("Restricting reductions to detector={}".format(args.det)) parset['rdx']['detnum'] = int(args.det) # Get headers (if possible) and base names spec1d_files = [ files.replace('spec2d', 'spec1d') for files in spec2d_files ] head1d = None for spec1d_file in spec1d_files: if os.path.isfile(spec1d_file): head1d = fits.getheader(spec1d_file) break if head1d is None: msgs.warn("No 1D spectra so am generating a dummy header for output") head1d = io.initialize_header() head2d = fits.getheader(spec2d_files[0]) if args.basename is None: filename = os.path.basename(spec2d_files[0]) basename = filename.split('_')[2] else: basename = args.basename # Write the par to disk par_outfile = basename + '_coadd2d.par' print("Writing the parameters to {}".format(par_outfile)) parset.to_config(par_outfile) # Now run the coadds skysub_mode = head2d['SKYSUB'] ir_redux = True if 'DIFF' in skysub_mode else False # Print status message msgs_string = 'Reducing target {:s}'.format(basename) + msgs.newline() msgs_string += 'Performing coadd of frames reduce with {:s} imaging'.format( skysub_mode) msgs_string += msgs.newline( ) + 'Combining frames in 2d coadd:' + msgs.newline() for file in spec2d_files: msgs_string += '{0:s}'.format(os.path.basename(file)) + msgs.newline() msgs.info(msgs_string) # TODO: This needs to be added to the parameter list for rdx redux_path = os.getcwd() master_dirname = os.path.basename(head2d['PYPMFDIR']) + '_coadd' master_dir = os.path.join(redux_path, master_dirname) # Make the new Master dir if not os.path.isdir(master_dir): msgs.info( 'Creating directory for Master output: {0}'.format(master_dir)) os.makedirs(master_dir) # Instantiate the sci_dict sci_dict = OrderedDict() # This needs to be ordered sci_dict['meta'] = {} sci_dict['meta']['vel_corr'] = 0. sci_dict['meta']['ir_redux'] = ir_redux # Find the detectors to reduce detectors = PypeIt.select_detectors(detnum=parset['rdx']['detnum'], ndet=spectrograph.ndet) if len(detectors) != spectrograph.ndet: msgs.warn('Not reducing detectors: {0}'.format(' '.join([ str(d) for d in set(np.arange(spectrograph.ndet) + 1) - set(detectors) ]))) # Loop on detectors for det in detectors: msgs.info("Working on detector {0}".format(det)) sci_dict[det] = {} # Instantiate Coadd2d coadd = coadd2d.CoAdd2D.get_instance( spec2d_files, spectrograph, parset, det=det, offsets=parset['coadd2d']['offsets'], weights=parset['coadd2d']['weights'], ir_redux=ir_redux, debug_offsets=args.debug_offsets, debug=args.debug, samp_fact=args.samp_fact) # Coadd the slits coadd_dict_list = coadd.coadd( only_slits=None) # TODO implement only_slits later # Create the pseudo images pseudo_dict = coadd.create_pseudo_image(coadd_dict_list) # Reduce msgs.info('Running the extraction') # TODO -- This should mirror what is in pypeit.extract_one # TODO -- JFH :: This ought to return a Spec2DObj and SpecObjs which would be slurped into # AllSpec2DObj and all_specobsj, as below. # TODO -- JFH -- Check that the slits we are using are correct sci_dict[det]['sciimg'], sci_dict[det]['sciivar'], sci_dict[det]['skymodel'], sci_dict[det]['objmodel'], \ sci_dict[det]['ivarmodel'], sci_dict[det]['outmask'], sci_dict[det]['specobjs'], sci_dict[det]['detector'], \ sci_dict[det]['slits'], sci_dict[det]['tilts'], sci_dict[det]['waveimg'] = coadd.reduce( pseudo_dict, show = args.show, show_peaks = args.peaks) # Save pseudo image master files #coadd.save_masters() # Make the new Science dir # TODO: This needs to be defined by the user scipath = os.path.join(redux_path, 'Science_coadd') if not os.path.isdir(scipath): msgs.info('Creating directory for Science output: {0}'.format(scipath)) os.makedirs(scipath) # THE FOLLOWING MIMICS THE CODE IN pypeit.save_exposure() # TODO -- These lines should be above once reduce() passes back something sensible all_specobjs = specobjs.SpecObjs() for det in detectors: all_specobjs.add_sobj(sci_dict[det]['specobjs']) # Write outfile1d = os.path.join(scipath, 'spec1d_{:s}.fits'.format(basename)) subheader = spectrograph.subheader_for_spec(head2d, head2d) all_specobjs.write_to_fits(subheader, outfile1d) # 2D spectra # TODO -- These lines should be above once reduce() passes back something sensible all_spec2d = spec2dobj.AllSpec2DObj() all_spec2d['meta']['ir_redux'] = ir_redux for det in detectors: all_spec2d[det] = spec2dobj.Spec2DObj( det=det, sciimg=sci_dict[det]['sciimg'], ivarraw=sci_dict[det]['sciivar'], skymodel=sci_dict[det]['skymodel'], objmodel=sci_dict[det]['objmodel'], ivarmodel=sci_dict[det]['ivarmodel'], scaleimg=np.array([1.0], dtype=np.float), bpmmask=sci_dict[det]['outmask'], detector=sci_dict[det]['detector'], slits=sci_dict[det]['slits'], waveimg=sci_dict[det]['waveimg'], tilts=sci_dict[det]['tilts'], sci_spat_flexure=None, sci_spec_flexure=None, vel_corr=None, vel_type=None) # Build header outfile2d = os.path.join(scipath, 'spec2d_{:s}.fits'.format(basename)) pri_hdr = all_spec2d.build_primary_hdr( head2d, spectrograph, subheader=subheader, # TODO -- JFH :: Decide if we need any of these redux_path=None, master_key_dict=None, master_dir=None) # Write all_spec2d.write_to_fits(outfile2d, pri_hdr=pri_hdr)