Exemple #1
0
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 =======================
    # from the input argument, fetch file names
    if args.spec_dir:
        uncorrected_files = glob(os.path.join(args.spec_dir,'uncorrected','*.fits'))
        corrected_files   = glob(os.path.join(args.spec_dir,'corrected','*.fits'))
        corrected_files_m = glob(os.path.join(args.spec_dir,'corrected','margala','*.fits'))
        # 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('/')[6]
        # 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 = []
    # ======================= READ DATA FROM FILES =======================
    # uncorrected spectra
    for file in uncorrected_files:
        spec = read_spec(file)
        wav_ucorr.append(spec.wav)
        flx_ucorr.append(spec.flx)
    wav_all.append(wav_ucorr)
    ra = spec.ra ; dec = spec.dec; z = spec.z
    flx_all.append(flx_ucorr)
    # corrected spectra
    for file in corrected_files:
        spec = read_spec(file)
        wav_corr.append(spec.wav)
        flx_corr.append(spec.flx_corr)
    wav_all.append(wav_corr)
    flx_all.append(flx_corr)
    # corrected margala spectra
    for file in corrected_files_m:
        spec = read_spec(file)
        wav_corr_m.append(spec.wav)
        flx_corr_m.append(spec.flx_corr)
    wav_all.append(wav_corr_m)
    flx_all.append(flx_corr_m)
    
    majorLocator   = MultipleLocator(500)
    majorFormatter = FormatStrFormatter('%d')
    minorLocator   = MultipleLocator(100)

    # ======================= PLOT =======================
    # PLOT NAME
    outfile = outfile = os.path.join(args.spec_dir,'%s_triple_panel_spectrum.pdf' %thingid)
    # PLOT PARAMETERS
    colors = ['Black','Crimson','Gold','Green','Navy','DarkMagenta','CornflowerBlue','MediumSpringGreen','Sienna','Green','Purple','Teal','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('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.09, 0.5, r'Flux $[10^{-17} \rm{erg/s/cm^2/\AA}]$', va='center', rotation='vertical')
    
    xmins = []
    xmaxs = []
    ymins = []
    ymaxs = []

    # PLOTTING DATA
    for i in xrange(np.size(numfiles)):
        k = 1
        for j in xrange(numfiles[i]):
            auxwav = np.array(wav_all[i][j])
            auxflx = np.array(flx_all[i][j])
            # ======================= 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 = 1.2*np.percentile(auxflx, 99);   ymaxs.append(ymax)

            if i == 0:
                ax1.plot(auxwav,auxflx,color=colors[k],label=labels[i][j])
            elif i == 1:
                ax2.plot(auxwav,auxflx,color=colors[k],label=labels[i][j])
            elif i == 2:
                ax3.plot(auxwav,auxflx,color=colors[k],label=labels[i][j])
            k = k+1
        
    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')
    ax2.text(6000,0.85*yplotlim[1],'Corrected spectra (this paper)')
    ax3.text(6000,0.85*yplotlim[1],'Corrected spectra (Margala)')
    
    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':10})

    plt.savefig(outfile, format = 'pdf')
    plt.show()
Exemple #2
0
def main():
    # ======================= SETTINGS =======================
    settings = program_settings()
    settings.plot = True
    settings.smoothness = 5
    settings.resample = True
    keys = ['BOSS', 'CORR', 'MARG']
    # ======================= 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()

    data, medianSpec = read_spectra(args.spec_dir)

    # ======================= PRINT THE SPECTRAL INDEX =======================
    print '{0:>45s}'.format('SPECTRAL INDEX')
    print '{0:>33s} '.format('SI_medspec')

    print '{0:>20s} {1:15.12f} {2:15.12f}'.format(
        'UNCORRECTED:', np.nanmedian(medianSpec.alpha_BOSS),
        np.nanstd(medianSpec.alpha_BOSS))
    print '{0:>20s} {1:15.12f} {2:15.12f}'.format(
        'CORRECTED (Ours):', np.nanmedian(medianSpec.alpha_CORR),
        np.nanstd(medianSpec.alpha_CORR))
    print '{0:>20s} {1:15.12f} {2:15.12f}'.format(
        'CORRECTED (Margala):', np.nanmedian(medianSpec.alpha_MARG),
        np.nanstd(medianSpec.alpha_MARG))

    # ======================= CALCULATE THE VARIANCE =======================
    print 'Calculating the variance'
    # TRANSPOSE THE FLUXES TO CALCULATE RMS
    flux = np.transpose(data['FLUX'])

    row = data['FLUX'].dtype
    npix = data['WAVE'][0].size
    flux_rms = np.zeros(shape=(npix, ), dtype=row)
    flux_std = np.zeros(shape=(npix, ), dtype=row)
    for pix in xrange(npix):
        flux_rms['BOSS'][pix] = np.sqrt(np.mean(np.square(flux['BOSS'][pix])))
        flux_std['BOSS'][pix] = np.std(flux['BOSS'][pix])
        flux_rms['CORR'][pix] = np.sqrt(np.mean(np.square(flux['CORR'][pix])))
        flux_std['CORR'][pix] = np.std(flux['CORR'][pix])
        flux_rms['MARG'][pix] = np.sqrt(np.mean(np.square(flux['MARG'][pix])))
        flux_std['MARG'][pix] = 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_std['BOSS']),
        np.nanstd(flux_std['BOSS']))
    print '{0:>20s} {1:15.12f} {2:15.12f}'.format(
        'CORRECTED (Ours):', np.nanmedian(flux_std['CORR']),
        np.nanstd(flux_std['CORR']))
    print '{0:>20s} {1:15.12f} {2:15.12f}'.format(
        'CORRECTED (Margala):', np.nanmedian(flux_std['MARG']),
        np.nanstd(flux_std['MARG']))

    settings.plot = False
    if settings.plot == True:
        npanels = args.panels
        # ======================= PLOT =======================
        majorLocator = MultipleLocator(500)
        majorFormatter = FormatStrFormatter('%d')
        minorLocator = MultipleLocator(100)
        # PLOT NAME
        thingid = medianSpec.thingid
        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, medianSpec.nspectra))
        # ======================= 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 = data['WAVE'][0]
        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(medianSpec.nspectra):
                # j goes over the spectra
                auxflx = smooth_array(data['FLUX'][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],
                           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 = (auxwav.min(), auxwav.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()
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:
        spec_allfiles = glob(os.path.join(args.spec_dir, '*.fits'))
        numfiles = len(spec_allfiles)
        labels = []
        dir_basename = os.path.dirname(args.spec_dir)
        thingid = dir_basename.split('/')[6]
        for file in spec_allfiles:
            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)
    # ======================= =======================
    wav_all = []
    flx_all = []
    ivar_all = []
    dim_all = []
    # ======================= READ DATA FROM FILES =======================
    for i in xrange(numfiles):
        wav = []
        flx = []
        err = []
        spec_dirname = os.path.dirname(spec_allfiles[i])
        spec_basename = os.path.basename(spec_allfiles[i])
        print spec_basename
        print spec_dirname
        if 'corr' not in spec_basename:
            #print 'uncorrected'
            info, head = fitsio.read(spec_allfiles[i],
                                     ext=2,
                                     columns=['Z', 'RA', 'DEC'],
                                     header=True)
            data = fitsio.read(spec_allfiles[i],
                               ext=1,
                               columns=['FLUX', 'LOGLAM', 'IVAR'])
            outfile = '../paper/plots/' + thingid + '_spectrum.pdf'
        else:
            #print 'corrected'
            info, head = fitsio.read(spec_allfiles[i],
                                     ext=0,
                                     columns=['Z', 'RA', 'DEC'],
                                     header=True)
            data = fitsio.read(spec_allfiles[i],
                               ext=1,
                               columns=['WAV', 'FLUX_CORR', 'FLUX_ERR'])
            if 'margala' not in spec_dirname:
                outfile = '../paper/plots/' + thingid + '_corr_spectrum.pdf'
            else:
                outfile = '../paper/plots/' + thingid + '_corr_spectrum_margala.pdf'
        s = data.size
        dim_all.append(s)
        for j in xrange(s):
            if 'corr' not in spec_basename:
                z = info[0][0]
                ra = info[0][1]
                dec = info[0][2]
                flx.append(data[j][0])
                wav.append(10**data[j][1])
                err.append(data[j][2])
            else:
                z = head['Z']
                ra = head['RA']
                dec = head['DEC']
                flx.append(data[j][2])
                wav.append(data[j][0])
                err.append(data[j][1])
            # print wav[j], flx[j], err[j]
        flx_all.append(flx)
        wav_all.append(wav)
        err.append(err)
    #l = min(dim_all)

    majorLocator = MultipleLocator(500)
    majorFormatter = FormatStrFormatter('%d')
    minorLocator = MultipleLocator(100)

    # ======================= PLOT =======================

    # PLOT
    xmin = np.min(wav_all[0])
    xmax = np.max(wav_all[0])
    xplotlim = (xmin, xmax)
    colors = [
        'Black', 'Crimson', 'Blue', 'Green', 'Gold', 'Purple', 'Brown',
        'Sienna', 'DarkMagenta', 'Teal', 'Turquoise', 'FireBrick',
        'MediumSpringGreen', 'CornflowerBlue', 'Bisque', 'Yellow', 'Coral',
        'Linen'
    ]
    # ======================= 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(numfiles):
        auxwav = np.array(wav_all[i])
        auxflx = np.array(flx_all[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=colors[j], label=labels[i])
        ax2.plot(auxwav, auxflx, color=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()
Exemple #4
0
def main():
    # ======================= PARSER =======================
    parser = argparse.ArgumentParser(
        formatter_class=argparse.ArgumentDefaultsHelpFormatter)
    parser.add_argument('--dir', type=str, default=None, 
        help='full path to the directory containing the FITS files, required')
    args = parser.parse_args()

    # ======================= FILES =======================
    if args.dir:
        spec_allfiles = glob(os.path.join(args.dir,'*.fits'))
        numfiles = len(spec_allfiles)
        labels = []
        dir_basename = os.path.dirname(args.dir)
        thingid = dir_basename.split('/')[6]
        for file in spec_allfiles:
            spec_basename = os.path.basename(file).split('.fits')[0]
            plate, mjd, fiberid, zenith = [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('z = %2d' % zenith)
    #data, header = fitsio.read(file,ext=0,header=True)
    # ======================= =======================
    wav_all  = []
    flx_all  = []
    ivar_all = []
    dim_all  = []
    corr_all = []
    # ======================= READ DATA FROM FILES =======================
    for i in xrange(numfiles):
        wav  = []
        flx  = []
        err = []
        corr4000 = []
        corr5400 = []
        corr = []
        spec_dirname  = os.path.dirname(spec_allfiles[i])
        spec_basename = os.path.basename(spec_allfiles[i])
        #print spec_basename
        #print spec_dirname
        #print 'corrected'
        info, head = fitsio.read(spec_allfiles[i],ext=0,columns=['Z','RA','DEC'],header=True)
        data = fitsio.read(spec_allfiles[i],ext=1,columns=['WAV','FLUX_CORR','FLUX_ERR','CORR4000','CORR5400'])
        #if 'margala' not in spec_dirname:
        #    outfile = '../paper/plots/'+thingid+'_corr_spectrum.pdf'
        #else:
        outfile = '../paper/plots/'+thingid+'_corr_zenith.pdf'
        s = data.size
        dim_all.append(s)
        for j in xrange(s):
            z    = head['Z']
            ra   = head['RA']
            dec  = head['DEC']
            flx.append(data[j][2])
            wav.append(data[j][0])
            err.append(data[j][1])
            corr4000.append(data[j][3])
            corr5400.append(data[j][4])
            #print i, j, wav[j], corr4000[j], corr5400[j]
            if corr4000[j]!=0.0:
                corr.append(corr5400[j]/corr4000[j])
            else:
                corr.append(0.0)
        flx_all.append(flx)
        wav_all.append(wav)
        corr_all.append(corr)
        err.append(err)
    

    majorLocator   = MultipleLocator(1e-1)
    majorFormatter = FormatStrFormatter('%d')
    minorLocator   = MultipleLocator(1e-2)

    # ======================= PLOT =======================

    # PLOT
    xmin = np.min(wav_all[0]) ; xmax = np.max(wav_all[0])
    xplotlim = (xmin, xmax)
    colors = ['Blue','Crimson','Green','DarkOrange','Skyblue','DarkMagenta','Teal','Burlywood','MediumSpringGreen','CornflowerBlue','Bisque','Gold','Coral','Linen']
     # ======================= DEFINING THE CANVAS =======================
    fsize = (9,6)
    fig , ax1 = plt.subplots(1,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.03, 0.5, r'Correction function', va='center', rotation='vertical')
    
    xmins = []
    xmaxs = []
    ymins = []
    ymaxs = []
    for i in xrange(numfiles):
        auxwav = np.array(wav_all[i])
        auxflx = np.array(corr_all[i])
        #for i in xrange(np.size(auxflx)):
        #    print i, auxwav[i], auxflx[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 = min(0, np.percentile(auxflx,  1)); ymins.append(ymin)
        ymax = 1.1*np.percentile(auxflx, 99.9);   ymaxs.append(ymax)

        ax1.plot(auxwav,auxflx,color=colors[i],label=labels[i])
        #ax2.plot(auxwav,auxflx,color=colors[i],label=labels[i])

    
    xplotlim = (min(xmins),max(xmaxs))
    xplotlim = (min(xmins),5500)
    yplotlim = (3e-1,2e0)
    #print 'NEW GLOBAL MIN & MAX = ', yplotlim[0], yplotlim[1]
    #ax1.set_xscale('log')
    ax1.set_yscale('log')
    ax1.set_xlim(xplotlim[0],xplotlim[1])
    #ax2.set_xlim(xplotlim[2],xplotlim[1])

    ax1.set_ylim(yplotlim[0],yplotlim[1])
    #ax1.set_xlabel(r'Observed wavelength $[\AA]$')
    ax1.legend(loc='lower right',prop={'size':10})

    plt.savefig(outfile, format = 'pdf')
    plt.show()
Exemple #5
0
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():
    # ======================= SETTINGS =======================
    settings = corrutilis.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('--data',
                        choices=['BOSS', 'CORR', 'MARG'],
                        nargs='+',
                        type=str,
                        default=['BOSS', 'CORR'],
                        help='data to use')
    parser.add_argument('--noplot',
                        action='store_true',
                        help='number of panels')
    parser.add_argument('--rms', action='store_true', help='plot the RMS')
    parser.add_argument('--pl',
                        action='store_true',
                        help='plot the median power-law fit')
    parser.add_argument('--corr',
                        action='store_true',
                        help='plot the mean of the correction functions')
    parser.add_argument('--indpl',
                        action='store_true',
                        help='plot the median power-law fit')
    parser.add_argument('--show',
                        action='store_true',
                        help='show the figure instead of saving it')
    parser.add_argument('--step',
                        type=int,
                        default=1,
                        help='plots every x-th spectrum, where x = step')
    parser.add_argument(
        '--smooth',
        type=int,
        default=None,
        help='smooth the spectra with a boxcar b, where b = smooth')
    parser.add_argument('--xmax',
                        type=float,
                        default=None,
                        help='define the maximum of xrange')
    parser.add_argument('--xmin',
                        type=float,
                        default=None,
                        help='define the minimum of xrange')
    args = parser.parse_args()

    keys = args.data
    # READ DATA FROM INDIVIDUAL SPECTRA
    data, rmsSpec = corrutilis.read_spectra(args.spec_dir)

    # CREATE FILENAME & OUTFILE NAMES
    filename = '{}'.format(rmsSpec.thingid)
    if args.rms: filename = filename + '_RMS'
    if args.pl: filename = filename + '_PL'
    if args.corr: filename = filename + '_CORRECTION'
    for key in args.data:
        filename = filename + '_{}'.format(key)
    outfile = os.path.join(args.spec_dir, filename)
    # OPEN A FILE TO SAVE THE RESULTS
    outdb = outfile + '.hdf5'
    if os.path.isfile(outdb):
        os.remove(outdb)
    outhdf = pd.HDFStore(outdb, 'w')
    wave = pd.Series(data['WAVE'][0])
    outhdf.put('WAVE', wave)
    datakeys = [item[0] for item in data['FLUX'].__array_interface__['descr']]
    for key in datakeys:
        df = pd.DataFrame(data['FLUX'][key].T)
        outhdf.put(key, df)

    outhdf.close()

    corrutilis.print_info(rmsSpec)
    corrutilis.print_si_data(rmsSpec)
    corrutilis.print_rms_data(rmsSpec)
    corrutilis.print_pl_data(rmsSpec)

    if args.noplot == False:
        ndata = len(args.data)
        # number of panels corresponds to the number of data used
        if not args.corr:
            npanels = ndata
        if args.corr:
            npanels = 1
    # ======================= PLOT =======================
        xmajorLocator = MultipleLocator(1000)
        xmajorFormatter = FormatStrFormatter('%d')
        xminorLocator = MultipleLocator(250)
        # PLOT NAME
        outfig = outfile + '.pdf'
        if not args.corr:
            fsize = (12, 2 + 2 * ndata)
        if args.corr:
            fsize = (6, 4)
        # PLOT PARAMETERS
        cmap = plt.get_cmap('Paired')
        line_colors = cmap(np.linspace(1, 0, rmsSpec.nspectra))
        c = {'BOSS': 'b', 'CORR': 'g', 'MARG': 'purple'}
        lab = {
            'BOSS': 'BOSS',
            'CORR': 'Corrected BOSS',
            'MARG': 'Margala et al. 2015'
        }
        ls = {'BOSS': ':', 'CORR': '-', 'MARG': '--'}
        # ======================= DEFINING THE CANVAS =======================
        fig = plt.figure(figsize=fsize)
        delta = 0.01
        left = 0.1
        right = 0.9
        width = right - left
        bottom = 0.15
        top = 0.95
        # if plotting RMS, add aditional panel of height g, adjust other panels
        if args.rms:
            g = 0.15
            x = delta / g
        if args.rms and args.pl:
            g = 0.15
            x = delta / g
        if not args.rms:
            g = 0.0
            x = 0.0
        # height = total height for plotting data panles;        h = height of a panel (not including SNR)
        height = (top - bottom) - (npanels - 1) * delta - g * (1 + x)
        h = height / npanels
        # add axes for data panels
        for i in xrange(npanels):
            b = top - (i + 1) * h - i * delta
            fig.add_axes([left, b, width, h])
        # add panel for Q, if plotting RMS
        if args.rms:
            b = b - g - 2 * delta
            fig.add_axes([left, b, width, g])
        # attach axes to figure
        ax = fig.axes
        # SET TITLE
        #plt.suptitle('THING ID = %9s' %(rmsSpec.thingid))
        # ======================= AXES LABELS =======================
        if not args.corr:
            fig.text(0.06, (g + delta + bottom + top) / 2,
                     r'Flux $[10^{-17} \rm{erg/s/cm^2/\AA}]$',
                     va='center',
                     rotation='vertical')
        if args.corr:
            fig.text(0.0, (g + delta + bottom + top) / 2,
                     r'Correction',
                     va='center',
                     rotation='vertical')
        xmins = []
        ymins = []
        qmin = []
        xmaxs = []
        ymaxs = []
        qmax = []

        # PLOTTING DATA
        box = settings.smoothness
        auxwav = rmsSpec.wave
        print '{:-^80}'.format('PLOTTING')

        alpha_BOSS, alpha_error_BOSS, delta_BOSS = (np.mean(
            rmsSpec.alpha_BOSS.T[0]), np.std(
                rmsSpec.alpha_BOSS.T[0]), np.mean(rmsSpec.alpha_BOSS.T[2]))
        alpha_CORR, alpha_error_CORR, delta_CORR = (np.mean(
            rmsSpec.alpha_CORR.T[0]), np.std(
                rmsSpec.alpha_CORR.T[0]), np.mean(rmsSpec.alpha_CORR.T[2]))
        alpha_MARG, alpha_error_MARG, delta_MARG = (np.mean(
            rmsSpec.alpha_MARG.T[0]), np.std(
                rmsSpec.alpha_MARG.T[0]), np.mean(rmsSpec.alpha_MARG.T[2]))
        alpha = {'BOSS': alpha_BOSS, 'CORR': alpha_CORR, 'MARG': alpha_MARG}
        alpha_error = {
            'BOSS': alpha_error_BOSS,
            'CORR': alpha_error_CORR,
            'MARG': alpha_error_MARG
        }
        delta = {'BOSS': delta_BOSS, 'CORR': delta_CORR, 'MARG': delta_MARG}

        for i, key in zip(xrange(ndata), keys):
            print '{0:>20s}'.format(key),
            # i goes over the uncorrected, corrected, corrected_margala
            k = 0
            # ----------------------------------------------------------------------------------------------------------
            # PLOT FLUXES
            if not args.rms and not args.pl and not args.corr:
                for j in xrange(0, rmsSpec.nspectra, args.step):
                    # j goes over the spectra
                    if args.smooth:
                        auxflx = smooth_array(data[j]['FLUX'][key],
                                              args.smooth)
                    else:
                        auxflx = data[j]['FLUX'][key]
                        auxpl = data[j]['POWERLAW'][key]

                    if np.size(auxflx) != np.size(auxwav):
                        print np.shape(auxwav)
                        print np.shape(auxflx)
                        sys.exit(
                            'ERROR: Flux and wavelength grids not equal in size!'
                        )
                        #auxwav = auxwav[:np.size(auxflx)]

                    # get the limits in y-axis
                    ymin = np.nanpercentile(auxflx, 0.5)
                    ymins.append(ymin)
                    ymax = 1.2 * np.nanpercentile(auxflx, 99.5)
                    ymaxs.append(ymax)
                    if args.indpl:
                        alpha = 0.3
                    elif not args.indpl:
                        alpha = 1
                    ax[i].plot(auxwav,
                               auxflx,
                               color=line_colors[j],
                               label=rmsSpec.labels[j],
                               linestyle='-',
                               alpha=alpha)
                    if args.indpl:
                        ax[i].plot(auxwav,
                                   auxpl,
                                   color=line_colors[j],
                                   label=rmsSpec.labels[j],
                                   linestyle='--',
                                   linewidth=2,
                                   alpha=1)
                    k = k + 1
            # ----------------------------------------------------------------------------------------------------------
            # PLOT RMS and Q
            if args.rms and not args.pl:
                lw = 1.5
                if args.smooth:
                    auxrms = smooth_array(rmsSpec.flux[key], args.smooth)
                    auxdev = smooth_array(rmsSpec.flux_error[key], args.smooth)
                    bossdev = smooth_array(rmsSpec.flux_error['BOSS'],
                                           args.smooth)
                    auxcorr = smooth_array(rmsSpec.corr[key], args.smooth) - 1
                    R2 = smooth_array(rmsSpec.R2[key], args.smooth)
                else:
                    auxrms = rmsSpec.flux[key]
                    auxdev = rmsSpec.flux_error[key]
                    bossdev = rmsSpec.flux_error['BOSS']
                    auxcorr = rmsSpec.corr[key] - 1
                    R2 = rmsSpec.R2[key]
                qval = auxdev / bossdev - 1
                #absqval = np.absolute(qval[~np.isnan(qval)])
                #n = np.argmin(absqval)
                #print wave[n]

                ymin = np.nanpercentile(auxrms, 0.5)
                ymins.append(ymin)
                ymax = 1.2 * np.nanpercentile(auxrms, 99.5)
                ymaxs.append(ymax)
                # plot RMS and RMSD
                ax[i].plot(auxwav,
                           auxrms,
                           color='g',
                           linewidth=lw,
                           label='Mean flux')
                ax[i].fill_between(auxwav,
                                   auxrms - auxdev,
                                   auxrms + auxdev,
                                   color='g',
                                   alpha=0.3)
                ax[i].plot(auxwav,
                           R2,
                           color='r',
                           linewidth=lw,
                           label='Residuals')
                # plot the Q RMS value
                ax[-1].plot(auxwav,
                            qval,
                            color=c[key],
                            linewidth=lw,
                            label=lab[key],
                            linestyle='-')
                #ax[-1].plot(auxwav, auxcorr, color=c[key], linewidth=2, label = lab[key], linestyle = '--')
                qmin.append(0.5 * np.nanpercentile(qval, 1))
                qmax.append(1.5 * np.nanpercentile(qval, 99))
            # ----------------------------------------------------------------------------------------------------------
            # PLOT POWER-LAWS
            #alpha = {'BOSS':rmsSpec.alpha_BOSS,'CORR':rmsSpec.alpha_CORR,'MARG':rmsSpec.alpha_MARG}
            if args.pl and not args.rms:
                lw = 1.5
                auxpl = rmsSpec.powerlaw[key]
                auxple = rmsSpec.powerlaw_error[key]
                for j in xrange(0, rmsSpec.nspectra, args.step):
                    # j goes over the spectra
                    if args.smooth:
                        auxflx = smooth_array(data[j]['FLUX'][key],
                                              args.smooth)
                    else:
                        auxflx = data[j]['FLUX'][key]

                    if np.size(auxflx) != np.size(auxwav):
                        print np.shape(auxwav)
                        print np.shape(auxflx)
                        sys.exit(
                            'ERROR: Flux and wavelength grids not equal in size!'
                        )
                        #auxwav = auxwav[:np.size(auxflx)]

                    # get the limits in y-axis
                    ymin = np.nanpercentile(auxflx, 0.5)
                    ymins.append(ymin)
                    ymax = 1.2 * np.nanpercentile(auxflx, 99.5)
                    ymaxs.append(ymax)
                    ax[i].plot(auxwav,
                               auxflx,
                               color=line_colors[j],
                               label=rmsSpec.labels[j],
                               linestyle='-',
                               alpha=1)
                    k = k + 1
                #ax[i].plot(auxwav,auxpl, color = 'r', linewidth = lw, label = 'Powerlaw', linestyle = '--')
                ax[i].plot(auxwav,
                           auxpl,
                           color='b',
                           linewidth=lw,
                           label='Power-law',
                           linestyle='--')
                ax[i].fill_between(auxwav,
                                   auxpl - auxple,
                                   auxpl + auxple,
                                   color='b',
                                   alpha=0.6)
            # ----------------------------------------------------------------------------------------------------------
            # PLOT RMS AND POWER-LAW
            if args.pl and args.rms:
                rmsAlpha = {
                    'BOSS': rmsSpec.alpha[0],
                    'CORR': rmsSpec.alpha[1],
                    'MARG': rmsSpec.alpha[2]
                }
                rmsAlphaErr = {
                    'BOSS': rmsSpec.alpha_error[0],
                    'CORR': rmsSpec.alpha_error[1],
                    'MARG': rmsSpec.alpha_error[2]
                }
                rmsDelta = {
                    'BOSS': rmsSpec.delta[0],
                    'CORR': rmsSpec.delta[1],
                    'MARG': rmsSpec.delta[2]
                }
                # emission-free regions:
                emfree_regions = [[1280, 1292], [1312, 1328], [1345, 1365],
                                  [1440, 1475], [1685, 1715], [1730, 1742],
                                  [1805, 1837], [2020, 2055], [2190, 2210]]
                wave_regions = []
                for region in emfree_regions:
                    wave_regions.append([
                        region[0] * (1. + rmsSpec.z),
                        region[1] * (1. + rmsSpec.z)
                    ])
                # spectral indices
                lw = 1.5
                # spectral shapes
                auxpl = rmsSpec.powerlaw[key]
                auxple = rmsSpec.powerlaw_error[key]
                if args.smooth:
                    auxrms = smooth_array(rmsSpec.flux[key], args.smooth)
                    auxdev = smooth_array(rmsSpec.flux_error[key], args.smooth)
                    bossdev = smooth_array(rmsSpec.flux_error['BOSS'],
                                           args.smooth)
                    auxcorr = smooth_array(rmsSpec.corr[key], args.smooth) - 1
                else:
                    auxrms = rmsSpec.flux[key]
                    auxdev = rmsSpec.flux_error[key]
                    bossdev = rmsSpec.flux_error['BOSS']
                    auxcorr = rmsSpec.corr[key] - 1
                qval = rmsSpec.powerlaw_error[key] / rmsSpec.powerlaw_error[
                    'BOSS'] - 1
                ymin = np.nanpercentile(auxrms, 0.5)
                ymins.append(ymin)
                ymax = 1.2 * np.nanpercentile(auxrms, 99.5)
                ymaxs.append(ymax)
                qmax.append(1.2 * np.nanpercentile(auxrms, 90))
                # plot RMS and RMSD
                rmspl = 10**(rmsDelta[key] +
                             (-2 - rmsAlpha[key]) * np.log10(auxwav))
                print
                ax[i].plot(auxwav,
                           auxrms,
                           color='g',
                           linewidth=lw,
                           label='Mean flux')
                #ax[i].plot(auxwav, rmspl, color='r', linewidth=lw, label = 'RMS PL')
                ax[i].plot(auxwav,
                           auxpl,
                           color='orange',
                           linewidth=lw,
                           label='Power-law',
                           linestyle='--')
                ax[i].fill_between(auxwav,
                                   auxpl - auxple,
                                   auxpl + auxple,
                                   color='orange',
                                   alpha=0.6)
                print key, 'MEAN of individual:', alpha[key], alpha_error[
                    key], delta[key]
                print key, 'RMS', rmsAlpha[key], rmsAlphaErr[key], rmsDelta[
                    key]

                # plot the Q value
                if key != 'BOSS':
                    ax[-1].plot(auxwav,
                                qval,
                                color=c[key],
                                linewidth=lw,
                                label=lab[key],
                                linestyle='-')
                qmin.append(0.5 * np.nanpercentile(qval, 1))
                qmax.append(1.5 * np.nanpercentile(qval, 99))
                # plot vertical lines for regions
                for region in wave_regions:
                    ax[i].axvspan(region[0],
                                  region[1],
                                  alpha=0.2,
                                  color='grey')
            # ----------------------------------------------------------------------------------------------------------
            # PLOT CORRECTION FUNCTION
            if args.corr:
                lw = 1.5
                corr = rmsSpec.corr[key].T
                if args.smooth:
                    auxcorr = smooth_array(corr[0], args.smooth)
                    auxdevlow = smooth_array(corr[1], args.smooth)
                    auxdevhigh = smooth_array(corr[2], args.smooth)
                else:
                    auxcorr = corr[0]
                    auxdevlow = corr[1]
                    auxdevhigh = corr[2]
                ymin = np.nanpercentile(auxcorr, 0.5)
                ymins.append(ymin)
                ymax = 1.2 * np.nanpercentile(auxcorr, 99.5)
                ymaxs.append(ymax)
                # plot CORR and limits
                print auxwav.shape, auxcorr.shape
                ax[-1].plot(auxwav,
                            auxcorr,
                            color=c[key],
                            linewidth=lw,
                            linestyle=ls[key],
                            label=lab[key])
                ax[-1].fill_between(auxwav,
                                    auxdevlow,
                                    auxdevhigh,
                                    color=c[key],
                                    alpha=0.3)
                ax[-1].xaxis.set_major_locator(xmajorLocator)
                ax[-1].xaxis.set_minor_locator(xminorLocator)
            if not args.corr:
                ax[i].xaxis.set_major_locator(xmajorLocator)
                ax[i].xaxis.set_minor_locator(xminorLocator)
        # XRANGE
        if not args.xmin:
            xmin = rmsSpec.wave.min()
        if args.xmin:
            xmin = args.xmin
        if not args.xmax:
            xmax = rmsSpec.wave.max()
        if args.xmax:
            xmax = args.xmax
        xplotlim = (xmin, xmax)
        # YRANGE
        yplotlim = (min(ymins), max(ymaxs))
        for i in xrange(len(ax)):
            ax[i].set_xlim(xplotlim[0], xplotlim[1])
            ax[i].set_ylim(yplotlim[0], yplotlim[1])
        # X-AXIS LABELS
        for i in xrange(len(ax) - 1):
            ax[i].xaxis.set_ticklabels([])
        ax[-1].set_xlabel(r'Observed wavelength $[\AA]$')
        # LEGEND
        if args.corr and ndata > 1:
            ax[0].legend(loc='upper left', prop={'size': 9})
        if (rmsSpec.nspectra <= 10) and not args.rms and not args.corr:
            ncol = int(rmsSpec.nspectra // 2.)
            handles, labels = ax[0].get_legend_handles_labels()
            ax[0].legend(flip(handles, 2),
                         flip(labels, 2),
                         loc='upper right',
                         prop={'size': 9},
                         ncol=ncol)
        if args.rms and not args.pl and not args.corr:
            ymajorLocator = MultipleLocator(1)
            ymajorFormatter = FormatStrFormatter('%d')
            yminorLocator = MultipleLocator(.25)
            ax[0].legend(loc='upper right', prop={'size': 12})
            fig.text(0.06, (2 * bottom + g) / 2,
                     r'$Q_{Flux}$',
                     va='center',
                     rotation='vertical')
            handles, labels = ax[-1].get_legend_handles_labels()
            handles = handles[1::2]
            labels = labels[1::2]
            ax[-1].legend(handles,
                          labels,
                          loc='upper left',
                          prop={'size': 12},
                          ncol=len(args.data))
            ax[-1].set_ylim(-0.85, max(qmax))
            ax[-1].xaxis.set_major_locator(xmajorLocator)
            ax[-1].xaxis.set_minor_locator(xminorLocator)
            ax[-1].yaxis.set_major_locator(ymajorLocator)
            ax[-1].yaxis.set_minor_locator(yminorLocator)
            print
        if args.rms and args.pl and not args.corr:
            ymajorLocator = MultipleLocator(1)
            ymajorFormatter = FormatStrFormatter('%d')
            yminorLocator = MultipleLocator(.25)
            ax[-1].plot(auxwav,
                        np.zeros(shape=auxwav.shape),
                        color='k',
                        linewidth=lw,
                        label='',
                        linestyle='--')
            ax[0].legend(loc='upper right', prop={'size': 12})
            fig.text(0.06, (2 * bottom + g) / 2,
                     r'$Q_{PL}$',
                     va='center',
                     rotation='vertical')
            handles, labels = ax[-1].get_legend_handles_labels()
            #handles = handles[1::2] ; labels = labels[1::2]
            ax[-1].legend(handles,
                          labels,
                          loc='upper left',
                          prop={'size': 12},
                          ncol=len(args.data))
            ax[-1].set_ylim(-0.85, 1.75)
            ax[-1].xaxis.set_major_locator(xmajorLocator)
            ax[-1].xaxis.set_minor_locator(xminorLocator)
            ax[-1].yaxis.set_major_locator(ymajorLocator)
            ax[-1].yaxis.set_minor_locator(yminorLocator)
            print
        if args.show:
            plt.show()
        if not args.show:
            plt.savefig(outfig, format='pdf')
            print
            print 'PLOT SAVED TO {0:s}'.format(outfig)
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()