def median_spectrum(redshift, wave_grid, flux_rms, flux_std): medianSpec = spectrum() medianSpec.z = redshift medianSpec.npix = wave_grid.size medianSpec.wave = wave_grid medianSpec.flux = flux_rms['BOSS'] medianSpec.flux_error = flux_std['BOSS'] medianSpec.__fit_powerlaw__(type='BOSS') medianSpec.alpha_BOSS = medianSpec.alpha medianSpec.flux_corr = flux_rms['CORR'] medianSpec.flux_error = flux_std['CORR'] medianSpec.__fit_powerlaw__(type='CORR') medianSpec.alpha_CORR = medianSpec.alpha medianSpec.flux_corr = flux_rms['MARG'] medianSpec.flux_error = flux_std['MARG'] medianSpec.__fit_powerlaw__(type='CORR') medianSpec.alpha_MARG = medianSpec.alpha print '{0:>45s}'.format('SPECTRAL INDEX') print '{0:>33s} '.format('SI_medspec') print '{0:>20s} {1:15.12f}'.format('UNCORRECTED:', medianSpec.alpha_BOSS) print '{0:>20s} {1:15.12f}'.format('CORRECTED (Ours):', medianSpec.alpha_CORR) print '{0:>20s} {1:15.12f}'.format('CORRECTED (Margala):', medianSpec.alpha_MARG) return medianSpec
def main(): # ======================= SETTINGS ======================= settings = program_settings() settings.plot = True settings.smoothness = 5 settings.resample = True settings.z_min = 0 settings.z_max = 4 settings.z_delta = 0.1 # ======================= PARSER ======================= parser = argparse.ArgumentParser( formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument( '--spec-dir', type=str, default=None, help='full path to the directory containing the FITS files, required') args = parser.parse_args() # ======================= FILES ======================= # from the input argument, fetch file names if args.spec_dir: spectral_list = return_spectral_list(args.spec_dir) numspec = len(spectral_list[0]) uncorrected_files = spectral_list[0] corrected_files = spectral_list[1] corrected_files_m = spectral_list[2] # list that saves the number of files in each subfolder numfiles = [ len(uncorrected_files), len(corrected_files), len(corrected_files_m) ] labels = [] dir_basename = os.path.dirname(args.spec_dir) thingid = dir_basename.split('/')[7] # read the data from the uncorrected FITS files for fileList in spectral_list: ids = [] for file in fileList: spec_basename = os.path.basename(file).split('.fits')[0] plate, mjd, fiberid = [ int(field) for field in os.path.splitext(spec_basename) [0].split('-')[1:] ] ids.append('%04d-%5d-%04d' % (plate, mjd, fiberid)) labels.append(ids) #data, header = fitsio.read(file,ext=0,header=True) # ======================= ======================== ====================== flux_boss_list = [] flux_corr_list = [] flux_marg_list = [] # ======================= UNIVERSAL WAVELENGTH GRID ======================= loglam_grid = np.arange(start=3.55, stop=4.02, step=0.0001) wave_grid = np.power(10, loglam_grid) wave_npix = wave_grid.size wave_shape = wave_grid.shape row = np.dtype([('BOSS', 'd8', 1), ('CORR', 'd8', 1), ('MARG', 'd8', 1)]) si_data = np.zeros(shape=(max(numfiles)), dtype=row) pl_flux = np.zeros(shape=(max(numfiles), wave_npix), dtype=row) fl_data = np.zeros(shape=(max(numfiles), wave_npix), dtype=row) print pl_flux[0].size # ======================= CALCULATIONS ======================= for i in xrange(len(spectral_list)): for j, file in enumerate(spectral_list[i]): # ======================= READ SPECTRA ======================= spec = spectrum() spec_dirname = os.path.dirname(file) spec_basename = os.path.basename(file) if 'corr' not in spec_basename: spec.__read_BOSS__(file) elif 'corr' in spec_basename: spec.__read_CORR__(file) minwav = spec.wave.min() maxwav = spec.wave.max() index_start = np.argmin(abs(wave_grid - minwav)) index_stop = np.argmin(abs(wave_grid - maxwav)) newpix = index_stop - index_start # ======================= GET SPECTRAL INDEX ======================= if 'corr' not in spec_basename: spec.__fit_powerlaw__(type='BOSS') flux_old = spec.flux si_data[j]['BOSS'] = spec.alpha fl_data[j]['BOSS'][index_start:index_stop] = congrid.rebin_1d( spec.flux, newpix) pl_flux[j]['BOSS'][index_start:index_stop] = congrid.rebin_1d( spec.powerlaw, newpix) #10.0**(spec.delta + spec.beta*loglam_grid) if 'corr' in spec_basename: spec.__fit_powerlaw__(type='CORR') flux_old = spec.flux_corr if 'margala' not in spec_dirname: si_data[j]['CORR'] = spec.alpha fl_data[j]['CORR'][ index_start:index_stop] = congrid.rebin_1d( spec.flux_corr, newpix) pl_flux[j]['CORR'][ index_start:index_stop] = congrid.rebin_1d( spec.powerlaw, newpix) elif 'margala' in spec_dirname: si_data[j]['MARG'] = spec.alpha fl_data[j]['MARG'][ index_start:index_stop] = congrid.rebin_1d( spec.flux_corr, newpix) pl_flux[j]['MARG'][ index_start:index_stop] = congrid.rebin_1d( spec.powerlaw, newpix) ra = spec.ra dec = spec.dec z = spec.z del (spec) print np.median(si_data['BOSS']), np.std(si_data['BOSS']) print np.median(si_data['CORR']), np.std(si_data['CORR']) print np.median(si_data['MARG']), np.std(si_data['MARG'])
def main(): np.set_printoptions(threshold=6000) # PARSER parser = argparse.ArgumentParser( formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument( '--tpcorr', type=str, default= '/Volumes/T2TB/Isotropy/spectra/BOSScorrections/tpcorr-0.1/tpcorr.hdf5', help='Throughput correction filename, required') parser.add_argument( '--spec-dir', type=str, default=None, help='Path to directory containing individual spec files') parser.add_argument( '--all', action='store_true', help= 'Save corrected spectra for all available objects of the given data sample' ) parser.add_argument('--data', choices=['QSO', 'FQSO', 'STAR'], nargs=1, type=str, default='QSO', help='Object type of the chosen spectrum') parser.add_argument( '--nobalmer', action='store_true', default=True, help= 'Balmer corrections flag. If the flag is true, no Balmer corrections are applied.' ) args = parser.parse_args() # data sample name sample = args.data[0] # MARGALA CORRECTION FILE tpcorr = h5py.File(args.tpcorr, 'r') tpcorr_wave = tpcorr['wave'].value # BALMER CORRECTION FILE if args.nobalmer == True: resid_corr = None elif args.nobalmer == False: resid_corr = read_resid_corr( '/Volumes/T2TB/Isotropy/PySDSS/residcorr_v5_4_45.dat') print resid_corr # Parse arguments: extract plate, mjd, fiberid as integers and the spec filename ids = [] sid_tot = [] if args.spec_dir: spectral_list = return_spectral_list(args.spec_dir) uncorrected_files = spectral_list[0] total_files = uncorrected_files for file in uncorrected_files: spec_basename = os.path.basename(file).split('.fits')[0] plate, mjd, fiberid = [ int(field) for field in os.path.splitext(spec_basename)[0].split('-')[1:] ] ids.append((plate, mjd, fiberid)) sid_tot.append('%04d%5d%04d' % (plate, mjd, fiberid)) dtypedict = {'QSO': 'QUASARS', 'FQSO': 'FAILED QUASARS', 'STAR': 'STARS'} if args.all: print "CORRECTING ALL AVAILABLE SPECTRA OF {data}".format( data=dtypedict[sample]) PathToSpectra = os.path.join( "/Volumes/T2TB/Isotropy/spectra/SDSS_DR12", sample) total_files = glob(os.path.join(PathToSpectra, "*.fits")) print "Spectra available: {0:8d}".format(len(total_files)) for file in total_files: spec_basename = os.path.basename(file).split('.fits')[0] plate, mjd, fiberid = [ int(field) for field in os.path.splitext(spec_basename)[0].split('-')[1:] ] ids.append((plate, mjd, fiberid)) sid_tot.append('%04d%5d%04d' % (plate, mjd, fiberid)) #else: # parser.error('Must specify either a spec file using the --spec-file option or path to directory containing spec files and a target.') #sid_tot = np.array(sid_tot) sid_tot_array = np.array(sid_tot) sid_tot = set(sid_tot) if args.all: if args.nobalmer == False: dirpath = os.path.join( '/Volumes/T2TB/Isotropy/spectra/SDSS_DR12', '{data}_{name}'.format(data=sample, name='Margala')) elif args.nobalmer == True: dirpath = os.path.join( '/Volumes/T2TB/Isotropy/spectra/SDSS_DR12', '{data}_{name}_nobalmer'.format(data=sample, name='Margala')) else: dirpath = os.path.join(os.path.normpath(args.spec_dir), 'corrected', 'margala') # remove already corrected spectra from the list corrected_files = glob(os.path.join(dirpath, "*.fits")) print "Spectra previously corrected: {0:8d}".format(len(corrected_files)) sid_corr = [] for file in corrected_files: spec_basename = os.path.basename(file).split('.fits')[0] plate, mjd, fiberid = [ int(field) for field in os.path.splitext(spec_basename)[0].split('-')[1:] ] sid_corr.append('%04d%5d%04d' % (plate, mjd, fiberid)) sid_corr = set(sid_corr) sid_unc = sid_tot.difference(sid_corr) uncorrected_files = [] for i, file in enumerate(total_files): if sid_tot_array[i] in sid_unc: uncorrected_files.append(file) print "Spectra to be corrected: {0:8d}".format(len(uncorrected_files)) file_array = np.array(uncorrected_files) for file in uncorrected_files: print file HDU = fitsio.FITS(file) h = HDU[0].read_header() flux = HDU[1]['flux'][:] ivar = HDU[1]['ivar'][:] wavelength = np.power(10, HDU[1]['loglam'][:]) ra = HDU[2]['ra'][0][0] dec = HDU[2]['dec'][0][0] z = HDU[2]['z'][0][0] HDU.close() plate, mjd, fiberid = ids[np.argwhere(file_array == file)[0][0]] # Read the target's throughput correction vector tpcorr_key = '%s/%s/%s' % (plate, mjd, fiberid) try: correction = tpcorr[tpcorr_key].value except: print "No data on object found" continue # Create an interpolated correction function correction_interp = interp1d(tpcorr_wave, correction, kind='linear') # Sample the interpolated correction using the observation's wavelength grid resampled_correction = correction_interp(wavelength) # Apply the correction to the observed flux and ivar # Save the data into a fits file spec = spectrum() spec.plateid = plate spec.mjd = mjd spec.fiberid = fiberid spec.ra = ra spec.dec = dec spec.z = z spec.beginwl = h['COEFF0'] spec.npix = np.size(wavelength) spec.wave = wavelength spec.flux = flux spec.ivar = ivar spec.flux_error = np.sqrt(1. / ivar) apply_resid_corr(spec, resid_corr) corrected_flux = spec.flux * resampled_correction corrected_ivar = spec.ivar / resampled_correction**2 spec.flux_corr = corrected_flux spec.flux_error = np.sqrt(1. / corrected_ivar) spec.corr = resampled_correction spec.basename = os.path.basename(file) spec.dirname = os.path.dirname(file) spec.__save_fitsio__(dirpath=dirpath) del (spec) tpcorr.close()
def main(args): # files pathToFile = args.list # read Balmer corrections from SDSSmodules.SDSSfiles import read_resid_corr resid_corr = read_resid_corr( '/Volumes/T2TB/Isotropy/PySDSS/residcorr_v5_4_45.dat') objects = [] with open(pathToFile, 'r') as file: for line in file: plate, mjd, fiber = [ field for field in line.rstrip('\n').split(',') ] objects.append((plate, mjd, fiber)) k = 0 for object in objects: # define a spectrum instance: spec = spectrum() # read plate, mjd, fiber: plate, mjd, fiber = [int(value) for value in object] spec.plate = plate spec.MJD = mjd spec.fiberid = fiber spec.dirname = savedir spec.basename = 'spec-{plate:4d}-{mjd:5d}-{fiber:04d}.fits'.format( plate=plate, mjd=mjd, fiber=fiber) i = fiber - 1 #systematic offset # Pick your plate/mjd and read the data: spfile = '{top}{plate}/spPlate-{plate}-{mjd}.fits'.format(top=topdir, plate=plate, mjd=mjd) zbfile = '{top}{plate}/v5_7_0/spZbest-{plate}-{mjd}.fits'.format( top=topdir, plate=plate, mjd=mjd) zafile = '{top}{plate}/v5_7_0/spZall-{plate}-{mjd}.fits'.format( top=topdir, plate=plate, mjd=mjd) hdulist = pf.open(spfile) c0 = hdulist[0].header['coeff0'] c1 = hdulist[0].header['coeff1'] npix = hdulist[0].header['naxis1'] wave = 10.**(c0 + c1 * n.arange(npix)) spec.beginwl = c0 spec.npix = npix spec.wave = wave spec.lambda_eff = hdulist[5].data['LAMBDA_EFF'][i] # Following commented-out bit was needed for some of the early redux: #bzero = hdulist[0].header['bzero'] bunit = hdulist[0].header['bunit'] flux = hdulist[0].data ivar = hdulist[1].data # put Balmer _uncorrected_ flux and errors into the spectrum spec.flux = flux[i, :] * (ivar[i, :] > 0) spec.flux[spec.flux == 0] = n.nan spec.ivar = ivar[i, :] * (ivar[i, :] > 0) spec.ivar[spec.ivar == 0] = n.nan spec.flux_error = 1 / n.sqrt(spec.ivar) * (ivar[i, :] > 0) # apply Balmer corrections to the spectrum if args.balmer == True: apply_resid_corr(spec, resid_corr) elif args.balmer == False: pass hdulist.close() hdulist = 0 hdulist = pf.open(zbfile) metadata = hdulist[0].header synflux = hdulist[2].data zstruc = hdulist[1].data hdulist.close() hdulist = 0 k += 1 spec.alt = metadata['ALT'] spec.airtemp = metadata['AIRTEMP'] spec.seeing50 = metadata['SEEING50'] spec.humidity = metadata['HUMIDITY'] spec.pressure = metadata['PRESSURE'] spec.az = metadata['AZ'] spec.z = zstruc[i].field('z') spec.ra = zstruc[i].field('plug_ra') spec.dec = zstruc[i].field('plug_dec') #for key, val in vars(spec).items(): # print '{key} = {val}'.format(key=key, val=val) #p.figure() # Set starting fiber point (above), then copy and paste # the following repeatedly to loop over spectra: #i+=1 # Following commented-out bit was needed for some of the early redux: #p.plot(wave, (flux[i,:]-bzero) * (ivar[i,:] > 0), 'k', hold=False) #auxflx = flux[i,:] * (ivar[i,:] > 0) #p.plot(wave, spec.flux, 'k', hold=False) #p.plot(wave, synflux[i,:], 'g', hold=True) #p.xlabel('Angstroms') #p.ylabel(bunit) #p.title(zstruc[i].field('class') + ', z = ' + str(zstruc[i].field('z'))) #p.ylim(n.percentile(auxflx,1), 1.2*n.percentile(auxflx, 99)) #p.show() spec.__save_fitsio__(dirpath=savedir, filetype='valid')
def read_spec(filepath): """ Reads a FITS file containing the spectrum of a Quasar from the input path and returns a 'spectrum' class object into the main program. Parameters: ----------- filepath : Path to the FITS file Returns: -------- spectrum : A 'spectrum' class object """ spec_dirname = os.path.dirname(filepath) spec_basename = os.path.basename(filepath) #initialise spectrum spec = spectrum() spec.filename = spec_basename if 'corr' not in spec_basename: #print 'uncorrected' fits = fitsio.FITS(filepath) spec.ra = fits[2]['RA'][0] spec.dec = fits[2]['DEC'][0] spec.z = fits[2]['Z'][0] spec.loglam = fits[1]['LOGLAM'][:] spec.wav = np.power(10, spec.loglam) spec.flx = fits[1]['FLUX'][:] spec.err = fits[1]['IVAR'][:] spec.ivar = fits[1]['IVAR'][:] spec.npix = np.size(spec.loglam) spec.numexp = fits[-1].get_extnum( ) - 3 #(-4 because of the 4 standard HDUs + 1 because we start at index 0, i.e. fits[0]) spec.loglam_start = np.min(spec.loglam) spec.loglam_end = np.max(spec.loglam) else: #print 'corrected' fits = fitsio.FITS(filepath) header = fits[0].read_header() spec.ra = header['RA'] spec.dec = header['DEC'] spec.z = header['Z'] spec.npix = header['NPIX'] spec.wav = fits[1]['WAV'][:] spec.flx = fits[1]['FLUX'][:] spec.flx_corr = fits[1]['FLUX_CORR'][:] spec.err = fits[1]['FLUX_ERR'][:] if 'margala' not in spec_dirname: spec.corr5400 = fits[1]['CORR5400'][:] spec.corr4000 = fits[1]['CORR4000'][:] spec.corr = spec.corr5400 / spec.corr4000 spec.loglam_start = np.log10(spec.wav[0]) spec.loglam_end = np.log10(spec.wav[spec.npix - 1]) return spec
def read_spectra(path): np.set_printoptions(threshold=6000) outspec = spectrum() if os.path.isdir(path): filetype = 'dir' elif os.path.isfile(path): filetype = 'file' labels = [] if os.path.isdir(path): spectral_list = return_spectral_list(path) numspec = len(spectral_list[0]) uncorrected_files = spectral_list[0] corrected_files = spectral_list[1] corrected_files_m = spectral_list[2] # list that saves the number of files in each subfolder numfiles = [ len(uncorrected_files), len(corrected_files), len(corrected_files_m) ] dir_basename = os.path.dirname(path) thingid = dir_basename.split('/')[7] # read the data from the uncorrected FITS files for file in uncorrected_files: spec_basename = os.path.basename(file).split('.fits')[0] plate, mjd, fiberid = [ int(field) for field in os.path.splitext(spec_basename)[0].split('-')[1:] ] labels.append('%04d-%5d-%04d' % (plate, mjd, fiberid)) if os.path.isfile(path): spectral_list = [] spectral_list.append([path]) numspec = 1 dir_basename = os.path.dirname(path) thingid = dir_basename.split('/')[7] spec_basename = os.path.basename(path).split('.fits')[0] plate, mjd, fiberid = [ int(field) for field in os.path.splitext(spec_basename)[0].split('-')[1:] ] labels.append('%04d-%5d-%04d' % (plate, mjd, fiberid)) # ======================= UNIVERSAL WAVELENGTH GRID ======================= loglam_grid = np.arange(start=3.55, stop=4.02, step=0.0001) wave_grid = np.power(10, loglam_grid) wave_npix = wave_grid.size wave_shape = wave_grid.shape npix = wave_npix # ======================= ======================== ====================== keys = ['BOSS', 'CORR', 'MARG'] row_flux = np.dtype([('BOSS', np.float32, 1), ('CORR', np.float32, 1), ('MARG', np.float32, 1)]) row_data = np.dtype([('WAVE', np.float32, 1), ('FLUX', row_flux, 1), ('FLUX_ERR', row_flux, 1), ('POWERLAW', row_flux, 1), ('POWERLAW_ERR', row_flux, 1), ('CORR', row_flux, 1)]) row_si = np.dtype([('BOSS', np.float32, 3), ('CORR', np.float32, 3), ('MARG', np.float32, 3)]) data = np.zeros(shape=(numspec, wave_npix), dtype=row_data) data.fill(np.nan) data['WAVE'] = wave_grid si_data = np.ones(shape=(numspec, ), dtype=row_si) # ======================= ======================== ====================== outspec.keys = keys outspec.npix = wave_npix outspec.wave = wave_grid # ======================= READ DATA FROM FILES ======================= for i in xrange(len(spectral_list)): for j, file in enumerate(spectral_list[i]): # ======================= READ SPECTRA ======================= spec = spectrum() spec_dirname = os.path.dirname(file) spec_basename = os.path.basename(file) filetype, fileclass = check_filetype(file) if filetype == 'BOSS': spec.__read_BOSS__(file) flux_boss = np.zeros(shape=wave_shape) elif filetype == 'CORR': spec.__read_CORR__(file) flux_corr = np.zeros(shape=wave_shape) # __IMPORTANT__: use corrected flux as 'flux' spec.flux = spec.flux_corr # fit a powerlaw to the spectrum spec.__fit_powerlaw__(type=filetype) # ======================= REBINNING ======================= minwav = spec.wave.min() maxwav = spec.wave.max() # find where in the rebinned wavelength grid to put the rebinned flux values index_start = np.argmin(abs(wave_grid - minwav)) index_stop = np.argmin(abs(wave_grid - maxwav)) # the spectra is rebinned to 'newpix' pixels newpix = index_stop - index_start # put new flux values & the powerlaw into the data structure data[j]['FLUX'][fileclass][ index_start:index_stop] = congrid.rebin_1d(spec.flux, newpix) data[j]['FLUX_ERR'][fileclass][ index_start:index_stop] = congrid.rebin_1d( spec.flux_error, newpix) data[j]['POWERLAW'][fileclass][ index_start:index_stop] = congrid.rebin_1d( spec.powerlaw, newpix) data[j]['POWERLAW_ERR'][fileclass][ index_start:index_stop] = congrid.rebin_1d( spec.powerlaw_error, newpix) if len(spec.corr) > 0: data[j]['CORR'][fileclass][ index_start:index_stop] = congrid.rebin_1d( spec.corr, newpix) #for k in xrange(spec.npix): # print j, k, fileclass, spec.flux_error[k], data[j]['FLUX_ERR'][fileclass][k] # save the data on the spectral index & error into the si_data structure si_data[j][fileclass][0] = spec.alpha si_data[j][fileclass][1] = spec.alpha_error si_data[j][fileclass][2] = spec.delta outspec.ra = spec.ra outspec.dec = spec.dec outspec.z = spec.z del (spec) # ======================= ======================== ====================== # ======================= ======================== ====================== # calculate the RMS of flux for each spectrum class dataT = data.transpose() rmsFlux = np.zeros(shape=wave_shape, dtype=row_flux) rmsFlux.fill(np.nan) rmsR2 = np.zeros(shape=wave_shape, dtype=row_flux) rmsR2.fill(np.nan) rmsErr = np.zeros(shape=wave_shape, dtype=row_flux) rmsErr.fill(np.nan) rmsCorr = np.zeros(shape=wave_shape, dtype=row_si) rmsCorr.fill(np.nan) #rmsCorrE = np.zeros(shape=wave_shape, dtype=row_flux); rmsCorrE.fill(np.nan) rmsPL = np.zeros(shape=wave_shape, dtype=row_flux) rmsPL.fill(np.nan) rmsPLe = np.zeros(shape=wave_shape, dtype=row_flux) rmsPLe.fill(np.nan) for key in keys: for pix in xrange(npix): # calculate the variance weigthed mean and deviation from numspec values of flux rmsFlux[pix][key] = rms(dataT[pix]['FLUX'][key], variance=dataT[pix]['FLUX_ERR'][key]**2) rmsR2[pix][key] = np.sum( (dataT[pix]['FLUX'][key] - rmsFlux[pix][key])**2 / (np.nanstd(dataT[pix]['FLUX'][key]))**2) rmsErr[pix][key] = np.nanstd(dataT[pix]['FLUX'][key]) rmsCorr[pix][key][0] = np.nanpercentile(dataT[pix]['CORR'][key], 50) # MEDIAN rmsCorr[pix][key][1] = np.nanpercentile(dataT[pix]['CORR'][key], 36) # LOWER RANGE rmsCorr[pix][key][2] = np.nanpercentile(dataT[pix]['CORR'][key], 84) # UPPER RANGE rmsPL[pix][key] = rms(dataT[pix]['POWERLAW'][key], variance=dataT[pix]['POWERLAW_ERR'][key]**2) rmsPLe[pix][key] = np.nanstd(dataT[pix]['POWERLAW'][key]) outspec.flux = rmsFlux # has three keys: ['BOSS', 'CORR', 'MARG'] outspec.flux_error = rmsErr # has three keys: ['BOSS', 'CORR', 'MARG'] outspec.corr = rmsCorr # has three keys: ['BOSS', 'CORR', 'MARG'] outspec.R2 = rmsR2 # has three keys: ['BOSS', 'CORR', 'MARG'] outspec.powerlaw = rmsPL # has three keys: ['BOSS', 'CORR', 'MARG'] outspec.powerlaw_error = rmsPLe # has three keys: ['BOSS', 'CORR', 'MARG'] # ======================= ======================== ====================== auxspec = copy.deepcopy(outspec) rmsSIalpha = np.zeros(shape=(1, ), dtype=row_si) rmsSIdelta = np.zeros(shape=(1, ), dtype=row_si) for key in keys: auxspec.flux = rmsFlux[key] auxspec.flux_error = rmsErr[key] auxspec.__fit_powerlaw__(type='BOSS') rmsSIalpha[key][0][0] = auxspec.alpha rmsSIalpha[key][0][1] = auxspec.alpha_error rmsSIdelta[key][0][0] = auxspec.delta del auxspec outspec.alpha = np.array([rmsSIalpha[key][0][0] for key in keys]) outspec.alpha_error = np.array([rmsSIalpha[key][0][1] for key in keys]) outspec.delta = np.array([rmsSIdelta[key][0][0] for key in keys]) # spectrum metadata to return to the main program outspec.nspectra = numspec # spectral indices of _INDIVIDUAL_(!) spectra outspec.alpha_BOSS = si_data[ 'BOSS'] # has three values: [alpha, alpha_error, delta] outspec.alpha_CORR = si_data[ 'CORR'] # has three values: [alpha, alpha_error, delta] outspec.alpha_MARG = si_data[ 'MARG'] # has three values: [alpha, alpha_error, delta] outspec.labels = labels outspec.thingid = thingid #del(spec) return data, outspec
def main(): # ======================= PARSER ======================= parser = argparse.ArgumentParser( formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument( '--spec-dir', type=str, default=None, help='full path to the directory containing the FITS files, required') args = parser.parse_args() # ======================= FILES ======================= if args.spec_dir: specList = glob(os.path.join(args.spec_dir, '*.fits')) numfiles = len(specList) labels = [] dir_basename = os.path.dirname(args.spec_dir) thingid = dir_basename.split('/')[6] for file in specList: spec_basename = os.path.basename(file).split('.fits')[0] plate, mjd, fiberid = [ int(field) for field in os.path.splitext(spec_basename)[0].split('-')[1:] ] #spec_filename.append(os.path.join(args.dir, 'spec-%04d-%5d-%04d.fits' % (plate, mjd, fiberid))) labels.append('%04d-%5d-%04d' % (plate, mjd, fiberid)) #data, header = fitsio.read(file,ext=0,header=True) # ======================= UNIVERSAL WAVELENGTH GRID ======================= loglam_grid = np.arange(start=3.55, stop=4.02, step=0.0001) wave_grid = np.power(10, loglam_grid) wave_npix = wave_grid.size wave_shape = wave_grid.shape # ======================= ======================== ====================== flux_boss_list = [] flux_corr_list = [] flux_marg_list = [] keys = ['BOSS', 'CORR', 'MARG'] row = np.dtype([('WAVE', 'f8', 1), ('FLUX', 'f8', 1), ('FLUX_ERR', 'f8', 1)]) data = np.zeros(shape=(numfiles, wave_npix), dtype=row) # ======================= READ DATA FROM FILES ======================= for i, file in enumerate(specList): spec = spectrum() spec_dirname = os.path.dirname(file) spec_basename = os.path.basename(file) if 'corr' not in spec_basename: #print 'uncorrected' spec.__read_BOSS__(file) key = 'BOSS' outfile = '../paper/plots/' + thingid + '_spectrum.pdf' else: #print 'corrected' spec.__read_CORR__(file) if 'margala' not in spec_dirname: key = 'CORR' outfile = '../paper/plots/' + thingid + '_corr_spectrum.pdf' else: key = 'MARG' outfile = '../paper/plots/' + thingid + '_corr_spectrum_margala.pdf' # ======================= REBINNING ======================= minwav = spec.wave.min() maxwav = spec.wave.max() index_start = np.argmin(abs(wave_grid - minwav)) index_stop = np.argmin(abs(wave_grid - maxwav)) newpix = index_stop - index_start data[i]['WAVE'][index_start:index_stop] = congrid.rebin_1d( spec.wave, newpix) if key == 'BOSS': data[i]['FLUX'][index_start:index_stop] = congrid.rebin_1d( spec.flux, newpix) elif (key == 'CORR' or key == 'MARG'): data[i]['FLUX'][index_start:index_stop] = congrid.rebin_1d( spec.flux, newpix) ra = spec.ra dec = spec.dec z = spec.z majorLocator = MultipleLocator(500) majorFormatter = FormatStrFormatter('%d') minorLocator = MultipleLocator(100) # ======================= PLOT ======================= # PLOT xmin = wave_grid.min xmax = wave_grid.max xplotlim = (xmin, xmax) cmap = plt.get_cmap('Paired') line_colors = cmap(np.linspace(0, 1, numfiles)) # ======================= DEFINING THE CANVAS ======================= fsize = (20, 5) fig, axes = plt.subplots(2, 1, figsize=fsize, sharey=True) #plt.suptitle('PLATEID=%04d, MJD=%5d, FIBREID=%04d, RA = %10.6f, DEC = %10.6f , z = %5.3f' % (plate, mjd, fiberid, ra, dec, z)) fig.subplots_adjust(hspace=0.15) plt.suptitle('RA = %10.6f, DEC = %10.6f , z = %5.3f' % (ra, dec, z)) # ======================= LABELS ======================= #fig.text(0.5,0.0, r'Observed wavelength $[\AA]$', ha='center') fig.text(0.09, 0.5, r'Flux $[10^{-17} \rm{erg/s/cm^2/\AA}]$', va='center', rotation='vertical') ax1, ax2 = axes.flat xmins = [] xmaxs = [] ymins = [] ymaxs = [] j = 0 for i in xrange(0, numfiles): auxwav = wave_grid auxflx = data['FLUX'][i] # ======================= SMOOTHING ======================= box = 5 auxflx = smooth_array(auxflx, box) if np.size(auxflx) != np.size(auxwav): auxwav = auxwav[:np.size(auxflx)] #print np.size(auxwav), np.size(auxflx) # get the limits in y-axis xmin = np.min(auxwav) xmax = np.max(auxwav) xmins.append(xmin) xmaxs.append(xmax) ymin = np.percentile(auxflx, 0.5) ymins.append(ymin) ymax = 2.0 * np.percentile(auxflx, 99) ymaxs.append(ymax) ax1.plot(auxwav, auxflx, color=line_colors[j], label=labels[i]) ax2.plot(auxwav, auxflx, color=line_colors[j], label=labels[i]) j = j + 1 xplotlim = (min(xmins), max(xmaxs), 0.5 * (min(xmins) + max(xmaxs))) yplotlim = (min(ymins), max(ymaxs)) #print 'NEW GLOBAL MIN & MAX = ', yplotlim[0], yplotlim[1] ax1.set_xlim(xplotlim[0], xplotlim[2]) ax2.set_xlim(xplotlim[2], xplotlim[1]) ax1.set_ylim(yplotlim[0], yplotlim[1]) ax2.set_xlabel(r'Observed wavelength $[\AA]$') ax1.legend(loc='upper right', prop={'size': 10}) plt.savefig(outfile, format='pdf') plt.show()
def main(): # ======================= PARSER ======================= parser = argparse.ArgumentParser( formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument('--spec', type=str, default=None, help='full path to the corrected FITS file, required') args = parser.parse_args() specpath = args.spec save_dirname = os.path.dirname(os.path.dirname(specpath)) sdss_flag = os.path.isdir(os.path.join(save_dirname, 'sdss')) if sdss_flag: sdss_specpath = glob(os.path.join(save_dirname, 'sdss', '*.fits')) # spec_sdss = spectrum() # spec_sdss.__read_BOSS__(sdss_specpath[0]) # spec_sdss.__fit_powerlaw__('BOSS') # ======================= UNIVERSAL WAVELENGTH GRID ======================= loglam_grid = np.arange(start=3.55, stop=4.02, step=0.0001) wave_grid = np.power(10, loglam_grid) wave_npix = wave_grid.size wave_shape = wave_grid.shape npix = wave_npix # ======================= ======================== ====================== keys = ['SDSS', 'BOSS', 'CORR'] row_flux = np.dtype([('BOSS', 'f8', 1), ('CORR', 'f8', 1), ('SDSS', 'f8', 1)]) row_data = np.dtype([('WAVE', 'f8', 1), ('FLUX', row_flux, 1), ('FLUX_ERR', row_flux, 1), ('POWERLAW', row_flux, 1), ('CORR', row_flux, 1)]) row_si = np.dtype([('BOSS', 'f8', 3), ('CORR', 'f8', 3), ('SDSS', 'f8', 3)]) data = np.zeros(shape=(1, wave_npix), dtype=row_data) data.fill(np.nan) data['WAVE'] = wave_grid si_data = np.ones(shape=(1, ), dtype=row_si) for key in keys: spec = spectrum() if key == 'SDSS': spec.__read_BOSS__(sdss_specpath[0]) filetype = 'BOSS' else: spec.__read_CORR__(specpath) filetype = key if key == 'CORR': spec.flux = spec.flux_corr spec.__fit_powerlaw__(filetype) # ======================= REBINNING ======================= minwav = spec.wave.min() maxwav = spec.wave.max() # find where in the rebinned wavelength grid to put the rebinned flux values index_start = np.argmin(abs(wave_grid - minwav)) index_stop = np.argmin(abs(wave_grid - maxwav)) # the spectra is rebinned to 'newpix' pixels newpix = index_stop - index_start print key, data['FLUX'][key] # put new flux values & the powerlaw into the data structure data[0]['FLUX'][key][index_start:index_stop] = congrid.rebin_1d( spec.flux, newpix) si_data[0][key][0] = spec.alpha si_data[0][key][1] = spec.alpha_error si_data[0][key][2] = spec.chisq print save_dirname # READ SPECTRUM FROM FILE & FIT POWERLAWS TO THE UNCORRECTED AND CORRECTED SPECTRA # PRINT SI DATA print '{0:-^80s}'.format(' POWER-LAW FIT ') print '{0:>8}{1:^14s}{2:>10s}'.format('', 'SI', 'CHI2') for key in keys: print '{key} : {0:+6.4f}+-{1:6.4f}{2:>10.4f}'.format(key=key, *si_data[0][key]) # CALCULATE THE CHI SQUARE OF BOSS AND CORR DATA (USING SDSS DATA AS EXPECTED VALUES) if sdss_flag: print '{0:-^80s}'.format(' AGREEMENT WITH SDSS DATA ') print '{0:>7s}{1:>10s}'.format('', 'CHI2') for key in keys: if key != 'SDSS': chisq = np.nansum( (data[0]['FLUX'][key] - data[0]['FLUX']['SDSS'])**2 / data[0]['FLUX']['SDSS']) / npix print '{key} : {0:>10.4f}'.format(chisq, key=key) sys.exit() # ======================= BASTI'S SMOOTHING FUNCTION ======================= basti = True if basti: box = 5 flx = smooth_array(array=spec.flux, smooth_width=box) flx_sdss = smooth_array(array=spec_sdss.flux, smooth_width=box) flx_corr = smooth_array(array=spec.flux_corr, smooth_width=box) # ======================= DEFINING THE CANVAS ======================= fsize = (12, 5) fig = plt.figure(figsize=fsize) plt.suptitle( r'PLATE = %04d, MJD = %5d, FIBRE = %04d, RA = %6.3f, Dec = %6.3f , z = %5.3f' % (spec.plateid, spec.MJD, spec.fiberid, spec.ra, spec.dec, spec.z)) fig.subplots_adjust(hspace=0.15) # ======================= LABELS ======================= #fig.text(0.5,0.0, r'Observed wavelength $[\AA]$', ha='center') #fig.text(0.09, 0.5, r'Flux $[10^{-17} \rm{erg/s/cm^2/\AA}]$', va='center', rotation='vertical') # ======================= FIRST SUBPLOT ======================= majorLocator = MultipleLocator(500) majorFormatter = FormatStrFormatter('%d') minorLocator = MultipleLocator(250) #### PLOT ax2 = plt.subplot(223) ax3 = plt.subplot(224) ax1 = plt.subplot(211) ax1.plot(spec_sdss.wave, flx_sdss, color='orange', label='SDSS', linewidth=1.4) ax1.plot(spec.wave, flx, color='b', label='BOSS', linewidth=1.4) ax1.plot(spec.wave, flx_corr, color='g', label='Corrected BOSS', linewidth=1.4) #### SET LIMITS xmin = np.min(spec.wave) xmax = np.max(spec.wave) xhalf = (xmin + xmax) / 2 ymin = min(0, np.percentile(spec.flux, 1)) ymax = 1.1 * np.percentile(spec.flux, 99.7) xplotlim = (xmin, xmax) yplotlim = (ymin, ymax) ax1.set_xlim(xplotlim[0], xplotlim[1]) ax1.set_ylim(yplotlim[0], yplotlim[1]) ax1.xaxis.set_major_locator(majorLocator) ax1.xaxis.set_minor_locator(minorLocator) fig.text(0.5, 0.0, r'Observed wavelength $[\AA]$', ha='center', va='bottom', rotation='horizontal') ax1.set_ylabel(r'Flux $[10^{-17} \rm{erg/s/cm^2/\AA}]$') ax1.legend(loc='upper right', prop={'size': 10}) # ======================= SECOND SUBPLOT ======================= majorLocator = MultipleLocator(2000) majorFormatter = FormatStrFormatter('%d') minorLocator = MultipleLocator(1000) #### REDEFINE PLOTTING ARRAYS #flxarray = np.zeros(np.size(flx)) #flxcorrarray_margala = flx_corr_margala - flx #flxcorrarray = flx_corr - flx #### PLOT ax2.plot(spec.wave, spec.corr, color='r', label='Correction function', linewidth=2) ax2.set_ylabel(r'$C(\lambda)$') ax2.set_xlim(xplotlim[0], xplotlim[1]) #ax2.set_xlabel(r'Observed wavelength $[\AA]$') ax2.xaxis.set_major_locator(majorLocator) ax2.xaxis.set_minor_locator(minorLocator) #axes[1].legend(loc='lower right',prop={'size':12}) # ======================= THIRD SUBPLOT ======================= majorLocator = MultipleLocator(2000) majorFormatter = FormatStrFormatter('%d') minorLocator = MultipleLocator(1000) #### REDEFINE PLOTTING ARRAYS #flxarray = np.zeros(np.size(flx)) #flxcorrarray_margala = flx_corr_margala - flx #flxcorrarray = flx_corr - flx #### PLOT ax3.plot(spec_sdss.wave, spec_sdss.powerlaw, color='orange', linestyle='-', linewidth=2.) ax3.plot(spec.wave, spec.powerlaw_BOSS, color='b', linestyle='-', linewidth=2.) ax3.plot(spec.wave, spec.powerlaw_CORR, color='g', linestyle='-', linewidth=2.) colors = ['orange', 'blue', 'green'] alpha = [spec_sdss.alpha_BOSS, spec.alpha_BOSS, spec.alpha_CORR] alpha_err = [ spec_sdss.alpha_error_BOSS, spec.alpha_error_BOSS, spec.alpha_error_CORR ] ymin, ymax = ax3.get_ylim() dy = (ymax - ymin) / 10 for i in xrange(3): text = r'$\alpha_{{\nu}} = {0:=+{w}.{p}f}\pm{1:{w}.{p}f} $'.format( alpha[i], alpha_err[i], w=7, p=4) ax3.text(7700, 0.8 * ymax - dy * i, text, color=colors[i]) ax3.set_xlim(xplotlim[0], xplotlim[1]) #ax3.set_xlabel(r'Observed wavelength $[\AA]$') ax3.xaxis.set_major_locator(majorLocator) ax3.xaxis.set_minor_locator(minorLocator) ax3.set_ylabel(r'Flux $[10^{-17} \rm{erg/s/cm^2/\AA}]$') #ax3.legend(loc='upper right',prop={'size':9}) plt.savefig(os.path.join( save_dirname, '%04d-%05d-%04d-corrected_spectrum_2.pdf' % (spec.plateid, spec.MJD, spec.fiberid)), format='pdf') plt.show()
def main(): # ======================= SETTINGS ======================= settings = program_settings() settings.plot = True settings.smoothness = 5 settings.resample = True # ======================= PARSER ======================= parser = argparse.ArgumentParser( formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument( '--spec-dir', type=str, default=None, help='full path to the directory containing the FITS files, required') args = parser.parse_args() # ======================= FILES ======================= # from the input argument, fetch file names if args.spec_dir: spectral_list = return_spectral_list(args.spec_dir) uncorrected_files = spectral_list[0] corrected_files = spectral_list[1] corrected_files_m = spectral_list[2] # list that saves the number of files in each subfolder numfiles = [ len(uncorrected_files), len(corrected_files), len(corrected_files_m) ] labels = [] dir_basename = os.path.dirname(args.spec_dir) thingid = dir_basename.split('/')[7] # read the data from the uncorrected FITS files ids = [] for file in uncorrected_files: spec_basename = os.path.basename(file).split('.fits')[0] plate, mjd, fiberid = [ int(field) for field in os.path.splitext(spec_basename)[0].split('-')[1:] ] ids.append('%04d-%5d-%04d' % (plate, mjd, fiberid)) labels.append(ids) # read the data from the corrected FITS files ids = [] for file in corrected_files: spec_basename = os.path.basename(file).split('.fits')[0] plate, mjd, fiberid = [ int(field) for field in os.path.splitext(spec_basename)[0].split('-')[1:] ] ids.append('%04d-%5d-%04d' % (plate, mjd, fiberid)) labels.append(ids) # read the data from the corrected FITS files (Margala) ids = [] for file in corrected_files_m: spec_basename = os.path.basename(file).split('.fits')[0] plate, mjd, fiberid = [ int(field) for field in os.path.splitext(spec_basename)[0].split('-')[1:] ] ids.append('%04d-%5d-%04d' % (plate, mjd, fiberid)) labels.append(ids) #data, header = fitsio.read(file,ext=0,header=True) # ======================= ======================== ====================== wav_all = [] wav_ucorr = [] wav_corr = [] wav_corr_m = [] flx_all = [] flx_ucorr = [] flx_corr = [] flx_corr_m = [] npix_all = [] npix_ucorr = [] npix_corr = [] npix_corr_m = [] loglam_start_all = [] loglam_start_ucorr = [] loglam_start_corr = [] loglam_start_corr_m = [] loglam_end_all = [] loglam_end_ucorr = [] loglam_end_corr = [] loglam_end_corr_m = [] # ======================= READ DATA FROM FILES ======================= # uncorrected spectra npix = [] for file in uncorrected_files: spec = spectrum() spec.__read_BOSS__(file) wav_ucorr.append(spec.wave) flx_ucorr.append(spec.flux) npix_ucorr.append(spec.npix) loglam_start_ucorr.append(spec.beginwl) loglam_end_ucorr.append(spec.beginwl + (spec.npix * spec.deltawl)) ra = spec.ra dec = spec.dec z = spec.z wav_all.append(wav_ucorr) flx_all.append(flx_ucorr) npix_all.append(npix_ucorr) loglam_start_all.append(loglam_start_ucorr) loglam_end_all.append(loglam_end_ucorr) del spec # corrected spectra for file in corrected_files: spec = spectrum() spec.__read_CORR__(file) wav_corr.append(spec.wave) #flx_corr.append(spec.corr_flux) flx_corr.append(spec.flux_corr) npix_corr.append(spec.npix) loglam_start_corr.append(np.log10(np.min(spec.wave))) loglam_end_corr.append(np.log10(np.max(spec.wave))) del spec wav_all.append(wav_corr) flx_all.append(flx_corr) npix_all.append(npix_corr) loglam_start_all.append(loglam_start_corr) loglam_end_all.append(loglam_end_corr) # corrected margala spectra for file in corrected_files_m: spec = spectrum() spec.__read_CORR__(file) wav_corr_m.append(spec.wave) flx_corr_m.append(spec.flux_corr) npix_corr_m.append(spec.npix) loglam_start_corr_m.append(np.log10(np.min(spec.wave))) loglam_end_corr_m.append(np.log10(np.max(spec.wave))) del spec wav_all.append(wav_corr_m) flx_all.append(flx_corr_m) npix_all.append(npix_corr_m) loglam_start_all.append(loglam_start_corr_m) loglam_end_all.append(loglam_end_corr_m) # ======================= RESAMPLING THE FLUX ARRAYS ======================= # Each spectrum has a different number of pixels, 'starting' and 'end' wavelengths. We need to resample them a common pixel grid. if settings.resample == True: flx_all_resampled = [] # reshaped = transposed flx_all_resampled_reshaped = [] # create a resampled array in wavelengths: take minimum of 'starting' and maximum of 'end' wavelengths loglam_start = np.min(np.array(loglam_start_all)) loglam_end = np.max(np.array(loglam_end_all)) loglam_step = 0.0001 loglam_resampled = np.arange(loglam_start, loglam_end, loglam_step) wav_resampled = ma.power(10, loglam_resampled) ## # RESAMPLING THE FLUXES for i in xrange(np.size(numfiles)): # i goes over 3 indices: uncorrected, corrected, corrected_margala flx_kind = [] for j in xrange(numfiles[i]): # j goes over the spectra # locate the minimum and maximum of the wavelength array for this spectrum minwav = np.min(wav_all[i][j]) maxwav = np.max(wav_all[i][j]) # define auxiliarry arrays index = np.where((wav_resampled >= minwav) & (wav_resampled <= maxwav))[0] # find the interpolation function from data in the FITS file intfunc = interp1d(wav_all[i][j], flx_all[i][j]) # apply the interpolation (but only within the proper boundaries) # defining a masked array flx_resampled with the same mask as the wavelength array flx_resampled = ma.array(np.full(wav_resampled.size, np.nan)) #,mask = wav_mask) # changing the values of the flx_resampled array, but only for indices that are not masked flx_resampled[index] = intfunc(wav_resampled[index]) # define a mask in wavelengths not covered by the j-th spectrum wav_mask = ma.masked_outside(wav_resampled, minwav, maxwav).mask # define a mask of outliers (further than nsigma) nsigma = 8 outliers_boolean = is_outlier(flx_resampled, nsigma) outliers_mask = ma.make_mask(outliers_boolean) # combine the masks into a new mask and attach it to the flx_resampled mask = ma.mask_or(wav_mask, outliers_mask) flx_resampled.mask = mask #for k in xrange(np.size(wav_resampled)): # print i,j,k, wav_resampled[k], flx_resampled[k] flx_kind.append(flx_resampled) # append the arrays flx_kind = ma.array(flx_kind) flx_all_resampled.append(flx_kind) flx_kind = ma.array(flx_kind).T flx_all_resampled_reshaped.append(flx_kind) # ======================= CALCULATE THE VARIANCE ======================= flx_resampled_array = ma.array(flx_all_resampled_reshaped) print 'Calculating the variance' medFlux = [] devFlux = [] for i in xrange(np.size(numfiles)): # i goes over the uncorrected, corrected, corrected_margala median_i = [] dev_i = [] for j in xrange(np.size(flx_resampled_array[i]) / numfiles[i]): # j goes over the pixels fluxes = [] for k in xrange(numfiles[i]): # k goes over individual exposures (spectra) fluxes.append(flx_resampled_array[i][j][k]) median = np.nanmedian(fluxes) dev = np.nanstd(fluxes) median_i.append(median) dev_i.append(dev) medFlux.append(median_i) devFlux.append(dev_i) medFluxArray = np.array(medFlux) devFluxArray = np.array(devFlux) print '{0:>50s}'.format('STANDARD DEVIATION OF FLUX') print '{0:>31s} {1:>15s}'.format('MEDIAN', 'STD') print '{0:>20s} {1:15.12f} {2:15.12f}'.format( 'UNCORRECTED:', np.nanmedian(devFluxArray[0]), np.nanstd(devFluxArray[0])) print '{0:>20s} {1:15.12f} {2:15.12f}'.format( 'CORRECTED (Ours):', np.nanmedian(devFluxArray[1]), np.nanstd(devFluxArray[1])) print '{0:>20s} {1:15.12f} {2:15.12f}'.format( 'CORRECTED (Margala):', np.nanmedian(devFluxArray[2]), np.nanstd(devFluxArray[2])) # RMS IN THE LYMAN ALPHA FOREST index = np.where(wav_resampled <= 1215.67 * (1 + z))[0] medFluxArray_LyA = medFluxArray[:, index] devFluxArray_LyA = devFluxArray[:, index] if medFluxArray_LyA.size != 0: print '{0:>50s}'.format( 'STANDARD DEVIATION OF FLUX IN THE LYMAN ALPHA FOREST') print '{0:>31s} {1:>15s} {2:>15s} {3:>15s}'.format( 'MEDIAN', 'STD', 'MIN', 'MAX') print '{0:>20s} {1:15.12f} {2:15.12f} {3:15.12f} {4:15.12f}'.format( 'UNCORRECTED:', np.nanmedian(devFluxArray_LyA[0]), np.nanstd(devFluxArray_LyA[0]), np.nanmin(devFluxArray_LyA[0]), np.nanmax(devFluxArray_LyA[0])) print '{0:>20s} {1:15.12f} {2:15.12f} {3:15.12f} {4:15.12f}'.format( 'CORRECTED (Ours):', np.nanmedian(devFluxArray_LyA[1]), np.nanstd(devFluxArray_LyA[1]), np.nanmin(devFluxArray_LyA[1]), np.nanmax(devFluxArray_LyA[1])) print '{0:>20s} {1:15.12f} {2:15.12f} {3:15.12f} {4:15.12f}'.format( 'CORRECTED (Margala):', np.nanmedian(devFluxArray_LyA[2]), np.nanstd(devFluxArray_LyA[2]), np.nanmin(devFluxArray_LyA[2]), np.nanmax(devFluxArray_LyA[2])) settings.plot = True if settings.plot == True: # ======================= PLOT ======================= majorLocator = MultipleLocator(500) majorFormatter = FormatStrFormatter('%d') minorLocator = MultipleLocator(100) # PLOT NAME outfile = os.path.join(args.spec_dir, '%s_rms_triple_panel.pdf' % thingid) # PLOT PARAMETERS cmap = plt.cm.Spectral line_colors = cmap(np.linspace(0, 1, len(uncorrected_files))) #colors = ['Black','Crimson','Gold','Green','Navy','DarkMagenta','CornflowerBlue','Sienna','Green','Purple','Teal','MediumSpringGreen','Turquoise','FireBrick','Brown','Bisque','Yellow','Coral','Linen'] # ======================= DEFINING THE CANVAS ======================= # PLOT SIZE fsize = (12, 8) # MAKE SUBPLOTS fig, axes = plt.subplots(3, 1, figsize=fsize, sharey=True) fig.subplots_adjust(hspace=0.02) ax1, ax2, ax3 = axes.flat # SET TITLE plt.suptitle('THING ID = %9s' % (thingid)) # plt.suptitle('RA = %10.6f, DEC = %10.6f , z = %5.3f' %(ra,dec,z)) # ======================= AXES LABELS ======================= #fig.text(0.5,0.0, r'Observed wavelength $[\AA]$', ha='center') fig.text(0.08, 0.5, r'Flux $[10^{-17} \rm{erg/s/cm^2/\AA}]$', va='center', rotation='vertical') xmins = [] xmaxs = [] ymins = [] ymaxs = [] # PLOTTING DATA box = settings.smoothness for i in xrange(np.size(numfiles)): # i goes over the uncorrected, corrected, corrected_margala k = 0 auxmedian = smooth_array(np.array(medFlux[i]), box) auxdev = smooth_array(np.array(devFlux[i]), box) for j in xrange(numfiles[i]): # j goes over the spectra auxwav = ma.array(wav_resampled, mask=flx_all_resampled[i][j].mask) auxflx = flx_all_resampled[i][j] # ======================= SMOOTHING ======================= auxflx = smooth_array(auxflx, box) #if np.size(auxflx)!=np.size(auxwav): #auxwav = auxwav[:np.size(auxflx)] # get the limits in y-axis xmin = np.min(auxwav) xmax = np.max(auxwav) xmins.append(xmin) xmaxs.append(xmax) ymin = np.percentile(auxflx, 0.5) ymins.append(ymin) ymax = 1.2 * np.percentile(auxflx, 99) ymaxs.append(ymax) if i == 0: ax1.plot(auxwav, auxflx, color=line_colors[k], label=labels[i][j], linestyle=':', alpha=0.6) elif i == 1: ax2.plot(auxwav, auxflx, color=line_colors[k], label=labels[i][j], linestyle=':', alpha=0.6) elif i == 2: ax3.plot(auxwav, auxflx, color=line_colors[k], label=labels[i][j], linestyle=':', alpha=0.6) k = k + 1 if i == 0: sigma = ma.array(devFluxArray[0], mask=flx_all_resampled[i][j].mask) # PLOT MEDIAN FLUX AND RMS ax1.plot(auxwav, auxmedian, color='Green', linewidth=1.3) ax1.plot(auxwav, auxdev, color='Red', linewidth=1) # FILL AREA OF RMS ax1.fill_between(auxwav, auxmedian - sigma, auxmedian + sigma, color="PaleGreen") # FILL AREA OF LY A FOREST ax1.axvspan(10**loglam_start, 1215.67 * (1 + z), alpha=0.3, color="SkyBlue") print 10**loglam_start, 1215.67 * (1 + z) elif i == 1: sigma = ma.array(devFluxArray[1], mask=flx_all_resampled[i][j].mask) ax2.plot(auxwav, auxmedian, color='Green', linewidth=1.3) ax2.plot(auxwav, auxdev, color='Red', linewidth=1) ax2.fill_between(auxwav, auxmedian - sigma, auxmedian + sigma, color="PaleGreen") ax2.axvspan(10**loglam_start, 1215.67 * (1 + z), alpha=0.5, color="SkyBlue") elif i == 2: sigma = ma.array(devFluxArray[2], mask=flx_all_resampled[i][j].mask) ax3.plot(auxwav, auxmedian, color='Green', linewidth=1.3) ax3.plot(auxwav, auxdev, color='Red', linewidth=1) ax3.fill_between(auxwav, auxmedian - sigma, auxmedian + sigma, color="PaleGreen") ax3.axvspan(10**loglam_start, 1215.67 * (1 + z), alpha=0.5, color="SkyBlue") xplotlim = (min(xmins), max(xmaxs), 0.5 * (min(xmins) + max(xmaxs))) yplotlim = (min(ymins), max(ymaxs)) # AXES FINE TUNING ax1.text(6000, 0.85 * yplotlim[1], 'UNCORRECTED spectra') ax1.text(6000, 0.70 * yplotlim[1], 'RMS in the LyA forest') ax1.text( 6000, 0.55 * yplotlim[1], '{0:>5s} {1:5.2f} {2:2s} {3:5.2f}'.format( '$\sigma$ = ', np.nanmedian(devFluxArray_LyA[0]), '$\pm$', np.nanstd(devFluxArray_LyA[0]))) ax2.text(6000, 0.85 * yplotlim[1], 'CORRECTED spectra (this paper)') ax2.text(6000, 0.70 * yplotlim[1], 'RMS in the LyA forest') ax2.text( 6000, 0.55 * yplotlim[1], '{0:>5s} {1:5.2f} {2:2s} {3:5.2f}'.format( '$\sigma$ = ', np.nanmedian(devFluxArray_LyA[1]), '$\pm$', np.nanstd(devFluxArray_LyA[1]))) ax3.text(6000, 0.85 * yplotlim[1], 'CORRECTED spectra (Margala)') ax3.text(6000, 0.70 * yplotlim[1], 'RMS in the LyA forest') ax3.text( 6000, 0.55 * yplotlim[1], '{0:>5s} {1:5.2f} {2:2s} {3:5.2f}'.format( '$\sigma$ = ', np.nanmedian(devFluxArray_LyA[2]), '$\pm$', np.nanstd(devFluxArray_LyA[2]))) ax1.set_xlim(xplotlim[0], xplotlim[1]) ax2.set_xlim(xplotlim[0], xplotlim[1]) ax3.set_xlim(xplotlim[0], xplotlim[1]) ax1.set_ylim(yplotlim[0], yplotlim[1]) ax3.set_xlabel(r'Observed wavelength $[\AA]$') # LEGEND ax1.legend(loc='upper right', prop={'size': 9}) plt.savefig(outfile, format='pdf') plt.show()
def main(): # PARSER parser = argparse.ArgumentParser( formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument( '--tpcorr', type=str, default= '/Volumes/Transcend/Isotropy/spectra/BOSScorrections/tpcorr-0.1/tpcorr.hdf5', help='throughput correction filename, required') parser.add_argument('--all', action='store_true', help='save corrected spectra for all available QSOs') args = parser.parse_args() # MARGALA CORRECTION FILE tpcorr = h5py.File(args.tpcorr, 'r') tpcorr_wave = tpcorr['wave'].value # DIRECTORY TO SAVE THE CORRECTED SPECTRA TO, USER-DEFINED dirpath = os.path.normpath( '/Volumes/Transcend/Isotropy/spectra/SDSS_DR12/QSO_Margala') # ------------------------------------------------------------------------------------- # Parse arguments: extract plate, mjd, fiberid as integers and the spec filename # ids = list of tuples : (plate,mjd,fiberid) # sid = list of strings : string(plate+mjd+fiberid) ---> used to check already corrected spectra ids = [] sid_tot = [] if args.all: print "CORRECTING ALL AVAILABLE SPECTRA" # CREATE A LIST OF ALL FILES TO BE CORRECTED : total_files PathToSpectra = os.path.normpath( "/Volumes/Transcend/Isotropy/spectra/SDSS_DR12/QSO") total_files = glob(os.path.join(PathToSpectra, "*.fits")) print "Spectra available: {0:8d}".format(len(total_files)) for file in total_files: # APPEND THE UNIQUE IDENTIFIER TO sid_tot spec_basename = os.path.basename(file).split('.fits')[0] plate, mjd, fiberid = [ int(field) for field in os.path.splitext(spec_basename)[0].split('-')[1:] ] ids.append((plate, mjd, fiberid)) sid_tot.append('%04d%5d%04d' % (plate, mjd, fiberid)) # CREATE A PYTHON SET OBJECT FOR ALL SIDs (ALLOWS INTERSECTION, DIFERENCE) sid_tot_array = np.array(sid_tot) sid_tot = set(sid_tot) # CREATE A LIST OF ALL FILES ALREADY CORRECTED AND PRESENT IN THE OUTPUT DIRECTORY: corrected_files corrected_files = glob(os.path.join(dirpath, "*.fits")) print "Spectra corrected: {0:8d}".format(len(corrected_files)) sid_corr = [] for file in corrected_files: # APPEND THE UNIQUE IDENTIFIERS TO sid_corr spec_basename = os.path.basename(file).split('.fits')[0] plate, mjd, fiberid = [ int(field) for field in os.path.splitext(spec_basename)[0].split('-')[1:] ] sid_corr.append('%04d%5d%04d' % (plate, mjd, fiberid)) # CREATE A PYTHON SET OBJECT FOR CORRECTED SIDs sid_corr = set(sid_corr) sid_unc = sid_tot.difference(sid_corr) # FIND THE DIFFERENCE OF THE TWO SETS (sid_tot - sid_corr) # APPEND SIDs TO uncorrected_files ---> used later uncorrected_files = [] for i, file in enumerate(total_files): if sid_tot_array[i] in sid_unc: uncorrected_files.append(file) # ITERATE OVER FILES IN uncorrected_files AND APPLY THE CORRECTION print "To be corrected: {0:8d}".format(len(uncorrected_files)) file_array = np.array(uncorrected_files) for file in uncorrected_files: HDU = fitsio.FITS(file) flux = HDU[1]['flux'][:] ivar = HDU[1]['ivar'][:] wavelength = np.power(10, HDU[1]['loglam'][:]) ra = HDU[2]['ra'][0][0] dec = HDU[2]['dec'][0][0] z = HDU[2]['z'][0][0] HDU.close() plate, mjd, fiberid = ids[np.argwhere(file_array == file)[0][0]] # Read the target's throughput correction vector tpcorr_key = '%s/%s/%s' % (plate, mjd, fiberid) try: correction = tpcorr[tpcorr_key].value except: print "No data on object found" continue # Create an interpolated correction function correction_interp = interp1d(tpcorr_wave, correction, kind='linear') # Sample the interpolated correction using the observation's wavelength grid resampled_correction = correction_interp(wavelength) # Apply the correction to the observed flux and ivar corrected_flux = flux * resampled_correction corrected_ivar = ivar / resampled_correction**2 # Save the data into a fits file spec = spectrum() spec.plateid = plate spec.mjd = mjd spec.fiberid = fiberid spec.ra = ra spec.dec = dec spec.z = z spec.npix = np.size(wavelength) spec.wave = wavelength spec.flux = flux spec.ivar = ivar spec.flux_corr = corrected_flux spec.flux_error = np.sqrt(1. / corrected_ivar) spec.corr = resampled_correction spec.basename = os.path.basename(file) spec.dirname = os.path.dirname(file) spec.__save_fitsio__(dirpath=dirpath) del (spec) tpcorr.close()
def main(): # ======================= SETTINGS ======================= settings = program_settings() settings.plot = True settings.smoothness = 5 settings.resample = True # ======================= PARSER ======================= parser = argparse.ArgumentParser( formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument('--spec-dir', type=str, default=None, help='full path to the directory containing the FITS files, required') parser.add_argument('--panels', type=int, default=3, help='number of panels, default = 3') args = parser.parse_args() # ======================= FILES ======================= # from the input argument, fetch file names if args.spec_dir: spectral_list = return_spectral_list(args.spec_dir) numspec = len(spectral_list[0]) uncorrected_files = spectral_list[0] corrected_files = spectral_list[1] corrected_files_m = spectral_list[2] # list that saves the number of files in each subfolder numfiles = [len(uncorrected_files),len(corrected_files),len(corrected_files_m)] labels = [] dir_basename = os.path.dirname(args.spec_dir) thingid = dir_basename.split('/')[7] # read the data from the uncorrected FITS files ids = [] for file in uncorrected_files: spec_basename = os.path.basename(file).split('.fits')[0] plate, mjd, fiberid = [int(field) for field in os.path.splitext(spec_basename)[0].split('-')[1:]] ids.append('%04d-%5d-%04d' % (plate, mjd, fiberid)) labels.append(ids) # read the data from the corrected FITS files ids = [] for file in corrected_files: spec_basename = os.path.basename(file).split('.fits')[0] plate, mjd, fiberid = [int(field) for field in os.path.splitext(spec_basename)[0].split('-')[1:]] ids.append('%04d-%5d-%04d' % (plate, mjd, fiberid)) labels.append(ids) # read the data from the corrected FITS files (Margala) ids = [] for file in corrected_files_m: spec_basename = os.path.basename(file).split('.fits')[0] plate, mjd, fiberid = [int(field) for field in os.path.splitext(spec_basename)[0].split('-')[1:]] ids.append('%04d-%5d-%04d' % (plate, mjd, fiberid)) labels.append(ids) #data, header = fitsio.read(file,ext=0,header=True) # ======================= UNIVERSAL WAVELENGTH GRID ======================= loglam_grid = np.arange(start=3.55, stop = 4.02, step = 0.0001) wave_grid = np.power(10, loglam_grid) wave_npix = wave_grid.size wave_shape = wave_grid.shape # ======================= ======================== ====================== flux_boss_list = []; flux_corr_list = []; flux_marg_list = [] keys = ['BOSS','CORR','MARG'] row = np.dtype([('BOSS','f8',1),('CORR','f8',1),('MARG','f8',1)]) flux_data = np.zeros(shape = (max(numfiles),wave_npix), dtype=row) si_data = np.zeros(shape = (max(numfiles)), dtype=row) pwrlaw_data = np.zeros(shape = (max(numfiles),wave_npix), dtype=row) # ======================= READ DATA FROM FILES ======================= for i in xrange(len(spectral_list)): for j,file in enumerate(spectral_list[i]): # ======================= READ SPECTRA ======================= spec = spectrum() spec_dirname = os.path.dirname(file) spec_basename = os.path.basename(file) if 'corr' not in spec_basename: spec.__read_BOSS__(file) flux_boss = np.zeros(shape=wave_shape) elif 'corr' in spec_basename: spec.__read_CORR__(file) flux_corr = np.zeros(shape=wave_shape) # ======================= REBINNING ======================= minwav = spec.wave.min() ; maxwav = spec.wave.max() index_start = np.argmin(abs(wave_grid-minwav)) index_stop = np.argmin(abs(wave_grid-maxwav)) newpix = index_stop - index_start if 'corr' not in spec_basename: spec.__fit_powerlaw__(type='BOSS') si_data[j]['BOSS'] = spec.alpha flux_data[j]['BOSS'][index_start:index_stop] = congrid.rebin_1d(spec.flux, newpix) pwrlaw_data[j]['BOSS'][index_start:index_stop] = congrid.rebin_1d(spec.powerlaw, newpix) if 'corr' in spec_basename: spec.__fit_powerlaw__(type='CORR') if 'margala' not in spec_dirname: si_data[j]['CORR'] = spec.alpha flux_data[j]['CORR'][index_start:index_stop] = congrid.rebin_1d(spec.flux_corr, newpix) pwrlaw_data[j]['CORR'][index_start:index_stop] = congrid.rebin_1d(spec.powerlaw, newpix) elif 'margala' in spec_dirname: si_data[j]['MARG'] = spec.alpha flux_data[j]['MARG'][index_start:index_stop] = congrid.rebin_1d(spec.flux_corr, newpix) pwrlaw_data[j]['MARG'][index_start:index_stop] = congrid.rebin_1d(spec.powerlaw, newpix) ra = spec.ra ; dec = spec.dec; z = spec.z del(spec) # TRANSPOSE THE FLUXES TO CALCULATE RMS flux = np.transpose(flux_data) # ======================= CALCULATE THE VARIANCE ======================= print 'Calculating the variance' flux_rms = np.zeros(shape = wave_shape, dtype = row) flux_std = np.zeros(shape = wave_shape, dtype = row) for pix in xrange(wave_npix): flux_rms[pix]['BOSS'] = np.sqrt(np.mean(np.square(flux['BOSS'][pix]))); flux_std[pix]['BOSS'] = np.std(flux['BOSS'][pix]) flux_rms[pix]['CORR'] = np.sqrt(np.mean(np.square(flux['CORR'][pix]))); flux_std[pix]['CORR'] = np.std(flux['CORR'][pix]) flux_rms[pix]['MARG'] = np.sqrt(np.mean(np.square(flux['MARG'][pix]))); flux_std[pix]['MARG'] = np.std(flux['MARG'][pix]) medianSpec = median_spectrum(z, wave_grid, flux_rms, flux_std) print '{0:>50s}'.format('STANDARD DEVIATION OF FLUX') print '{0:>31s} {1:>15s}'.format('RMS','STD') print '{0:>20s} {1:15.12f} {2:15.12f}'.format('UNCORRECTED:', np.nanmedian(flux_rms['BOSS']), np.nanstd(flux_rms['BOSS'])) print '{0:>20s} {1:15.12f} {2:15.12f}'.format('CORRECTED (Ours):', np.nanmedian(flux_rms['CORR']), np.nanstd(flux_rms['CORR'])) print '{0:>20s} {1:15.12f} {2:15.12f}'.format('CORRECTED (Margala):', np.nanmedian(flux_rms['MARG']), np.nanstd(flux_rms['MARG'])) settings.plot=True if settings.plot==True: npanels = args.panels # ======================= PLOT ======================= majorLocator = MultipleLocator(500) majorFormatter = FormatStrFormatter('%d') minorLocator = MultipleLocator(100) # PLOT NAME if npanels == 1: outfile = os.path.join(args.spec_dir,'%s_rms_single_panel.pdf' %thingid) fsize = (12,3) elif npanels == 2: outfile = os.path.join(args.spec_dir,'%s_rms_double_panel.pdf' %thingid) fsize = (12,5) elif npanels == 3: outfile = os.path.join(args.spec_dir,'%s_rms_triple_panel.pdf' %thingid) fsize = (12,7) # PLOT PARAMETERS cmap = plt.get_cmap('Paired') line_colors = cmap(np.linspace(0,1,len(uncorrected_files))) # ======================= DEFINING THE CANVAS ======================= # PLOT SIZE fsize = (12,5) # MAKE SUBPLOTS fig, axs = plt.subplots(npanels,1,figsize=fsize,sharey=True) ax = np.array(axs) fig.subplots_adjust(hspace=0.02) # SET TITLE plt.suptitle('THING ID = %9s' %(thingid)) # plt.suptitle('RA = %10.6f, DEC = %10.6f , z = %5.3f' %(ra,dec,z)) # ======================= AXES LABELS ======================= #fig.text(0.5,0.0, r'Observed wavelength $[\AA]$', ha='center') fig.text(0.08, 0.5, r'Flux $[10^{-17} \rm{erg/s/cm^2/\AA}]$', va='center', rotation='vertical') xmins = [] xmaxs = [] ymins = [] ymaxs = [] # PLOTTING DATA box=settings.smoothness auxwav = wave_grid for i, key in zip(xrange(npanels),keys[0:npanels]): print 'PLOTTING {0:s}'.format(key) # i goes over the uncorrected, corrected, corrected_margala k = 0 # ======================= SMOOTHING ======================= auxmedian = smooth_array(flux_rms[key],box) auxdev = smooth_array(flux_std[key],box) for j in xrange(numfiles[i]): # j goes over the spectra auxflx = smooth_array(flux_data[j][key], box) if np.size(auxflx)!=np.size(auxwav): print 'error' print auxwav.shape print auxflx.shape sys.exit() #auxwav = auxwav[:np.size(auxflx)] # get the limits in y-axis ymin = np.percentile(auxflx, 0.5); ymins.append(ymin) ymax = 1.2*np.percentile(auxflx, 99.5); ymaxs.append(ymax) ax[i].plot(auxwav,auxflx,color=line_colors[k],label=labels[i][j],linestyle=':', alpha=0.6) k = k+1 # PLOT MEDIAN FLUX AND RMS sigma = flux_std[key] ax[i].plot(auxwav,auxmedian,color='Green',linewidth=1.3) ax[i].plot(auxwav,auxdev,color='Red',linewidth=1) # FILL AREA OF RMS ax[i].fill_between(auxwav, auxmedian - sigma, auxmedian + sigma, color="Green", alpha=0.3) # FILL AREA OF LY A FOREST #ax[i].axvspan(wave_grid.min(), 1215.67*(1+z), alpha=0.3, color="SkyBlue") xplotlim = (wave_grid.min(), wave_grid.max()) yplotlim = (min(ymins),max(ymaxs)) for i in xrange(npanels): ax[i].set_xlim(xplotlim[0],xplotlim[1]) ax[i].set_ylim(yplotlim[0],yplotlim[1]) ax[npanels-1].set_xlabel(r'Observed wavelength $[\AA]$') #0.08, 0.5, r'Flux $[10^{-17} \rm{erg/s/cm^2/\AA}]$', va='center', rotation='vertical') ax[0].text(0.96,0.5,'UNCORRECTED spectra', va='center', rotation='vertical') fig.text(6000,0.85*yplotlim[1],'CORRECTED spectra (this paper)') fig.text(6000,0.85*yplotlim[1],'CORRECTED spectra (Margala)') plt.savefig(outfile, format = 'pdf') print 'PLOT SAVED TO {0:s}'.format(outfile) plt.show()