def galCount_all(apparent_mag, coaddm5):
     if CFHTLSCounts:
         # LSST power law: eq. 3.7 from LSST Science Book converted to per sq degree:
         # (46*3600)*10^(0.31(i-25))
         dn_gal = 46.*3600.*np.power(10., 0.31*(apparent_mag+bandCorrection-25.))
     else:
         # full z-range considered here: 0.<z<4.0
         # sum the galaxy counts from each individual z-bin
         dn_gal = 0.
         for key in list(powerLawConst_a.keys()):
             dn_gal += np.power(10., powerLawConst_a[key]*(apparent_mag+bandCorrection)+powerLawConst_b[key])
     completeness = 0.5*scipy.special.erfc(apparent_mag-coaddm5)
     return dn_gal*completeness
 def galCount_all(apparent_mag, coaddm5):
     if CFHTLSCounts:
         # LSST power law: eq. 3.7 from LSST Science Book converted to per sq degree:
         # (46*3600)*10^(0.31(i-25))
         dn_gal = 46. * 3600. * np.power(
             10., 0.31 * (apparent_mag + bandCorrection - 25.))
     else:
         # full z-range considered here: 0.<z<4.0
         # sum the galaxy counts from each individual z-bin
         dn_gal = 0.
         for key in list(powerLawConst_a.keys()):
             dn_gal += np.power(
                 10., powerLawConst_a[key] *
                 (apparent_mag + bandCorrection) + powerLawConst_b[key])
     completeness = 0.5 * scipy.special.erfc(apparent_mag - coaddm5)
     return dn_gal * completeness
def os_bias_overplots_diff_dbs(out_dir, data_path, run_names, legend_labels, fsky_dict, fsky_best,
                               mock_data_path, theory_lim_mag, lim_mag_i,
                               ell_min=100, ell_max=300, lmax=500,
                               specified_dith_only=None,
                               filters=['u', 'g', 'r', 'i'],
                               nside=256, pixel_radius=14, yr_cutoff=None,
                               zbin='0.66<z<1.0', poisson_noise=False, zero_pt=True,
                               plot_interms=False, color_dict=None,
                               ylim_min=None, ylim_max=None, show_plot=False, suptitle=None, file_append=None):
    """

    Calculate/plot the OS bias uncertainty and the statistical floor for the specified redshift bin.

    Could vary the dither strategies, but the data should be for the same magnitude cut. The title of
    of each panel in final plot will be "<dither strategy>, and each panel can have
    OS bias uncertainity from many different cadences. Panel legends will specify the redshift bin
    and OpSim output tag.

    Required Parameters
    -------------------
      * out_dir: str: main directory where the output plots should be saved; a folder named
                      'os_bias_overplots' will be created in the directory, if its not there already.
      * data_path: str: path to the artificialStructure data.
      * run_names: list of str: list for run name tags to identify the output of specified OpSim outputs.
      * legend_labels: list of strings: list of the 'tags' for each case; will be used in the legends. e.g. if
                                          run_names=['enigma1189', 'minion1016'], legend_labels could be
                                          ['enigma_1189', 'minion_1016'].
      * fsky_dict: dict: dictionary of the dictionaries containing the fraction of sky covered for each of the
                         cadences. The keys should match the identifier; fsky_dict[indentifiers[:]] should have
                         the dither strategies as the keys.
      * fsky_best: float: best fsky for the survey to compare everything relative to.
      * mock_data_path: str: path to the mock data to consider
      * theory_lim_mag: float: magnitude cut as the identifer in the filename from Hu.
                               Allowed options: 24.0, 25.6, 27.5
      * lim_mag_i: float: i-band magnitude cut to get the data for.

    Optional Parameters
    -------------------
      * specified_dith_only: list of string: list of the names (strings) of the dither strategies to consider, e.g.
                                           if want to plot only NoDither, specified_dith_only=['NoDither']. If
                                           nothing is specified, all the dither strategies will be considered
                                           (based on the npy files available for the runs). Default: None
      * filters: list of strings: list containing the bands (in strings) to be used to calculate the OS bias
                                  and its error. should contain AT LEAST two bands.
                                  e.g. if filters=['g', 'r'], OS bias (at every ell) will be calculated as the
                                  mean across g and r c_ells, while the bias error (at every ell) will be calculated
                                  as the std. dev. across g and r c_ells.
                                  Default: ['u', 'g', 'r', 'i']
      * nside: int: HEALpix resolution parameter. Default: 256
      * pixel_radius: int: number of pixels to mask along the shallow border. Default: 14
      * yr_cutoff: int: year cut to restrict analysis to only a subset of the survey.
                         Must range from 1 to 9, or None for the full survey analysis (10 yrs).
                         Default: None
      * zbin: str: options include '0.15<z<0.37', '0.37<z<0.66, '0.66<z<1.0', '1.0<z<1.5', '1.5<z<2.0'
                           Default: '0.66<z<1.0'
      * poisson_noise: bool: set to True to consider the case where poisson noise is added to galaxy counts
                                   after border masking (and the incorporation of calibration errors).
                                   Default: False
      * zero_pt: bool: set to True to consider the case where 0pt calibration errors were incorporated.
                          Default: True
      * plot_interms: bool: set to True to plot intermediate plots, e.g. BAO data. Default: False
      * color_dict: dict: color dictionary; keys should be the indentifiers provided. Default: None
                    **** Please note that in-built colors are for only a few indentifiers:
                            minion1016, minion1020, kraken1043 ******
      * ylim_min: float: lower y-lim for the final plots. Defaut: None
      * ylim_max: float: upper y-lim for the final plots. Defaut: None
      * show_plot: bool: set to True if want to display the plot (aside from saving it). Default: False
      * suptitle: str: title to the plot. Default: None
      * file_append: str: optional string to append to the saved plot

    """
    # check to make sure redshift bin is ok.
    allowed_zbins = list(powerLawConst_a.keys()) + ['all']
    if zbin not in allowed_zbins:
        raise ValueError('Invalid redshift bin. Input bin can only be among %s\n'%(allowed_zbins))

    # check to make sure we have at least two bands to calculate the bias uncertainty.
    if len(filters)<2:
        raise ValueError('Need at least two filters to calculate bias uncertainty. Currently given only: %s\n'%filters)

    # all is ok. proceed.
    totCases = len(run_names)

    # get the outdir address for each 'case' and each band
    outdir_all = {}
    for i in range(totCases):
        outdir = {}
        for band in filters:
            out, yr_tag, zbin_tag, poisson_tag, zero_pt_tag = get_outdir_name(band, nside,
                                                                              pixel_radius, yr_cutoff,
                                                                              zbin, lim_mag_i,
                                                                              run_names[i], poisson_noise, zero_pt)
            outdir[band] = '%s/cls_DeltaByN/'%out
        outdir_all[run_names[i]] = outdir

    # get the cls and calculate the OS bias and error.
    osbias_all, osbias_err_all = {}, {}
    for i in range(totCases):
        outdir = outdir_all[run_names[i]]
        c_ells = {}
        for band in filters:
            c_ells[band] = return_cls(data_path, outdir[band], band, specified_dith=specified_dith_only)  # get the c_ells
        osbias, osbias_err = calc_os_bias_err(c_ells)
        osbias_all[run_names[i]] = osbias
        osbias_err_all[run_names[i]] = osbias_err

    # print stuff
    print('MagCuts: i<%s\nRedshift bin: %s, %s, %s, %s'%(lim_mag_i, zbin_tag, yr_tag, poisson_tag, zero_pt_tag))

    # get the data to calculate the statistical floor.
    ell, wBAO_cls, surf_num_density = get_theory_spectra(mock_data_path=mock_data_path,
                                                         mag_cut=theory_lim_mag, plot_spectra=plot_interms,
                                                         nside=nside)

    ########################################################################################################
    # set the directory
    outdir = 'os_bias_overplots'
    if not os.path.exists('%s/%s'%(out_dir, outdir)):
        os.makedirs('%s/%s'%(out_dir, outdir))

    inBuiltColors = {}
    inBuiltColors['minion1016'] = 'r'
    inBuiltColors['minion1020'] = 'b'
    inBuiltColors['kraken1043'] = 'g'

    if color_dict is None: colors = inBuiltColors
    else: colors = color_dict

    # figure out how many panels we need
    max_entries = 0
    if specified_dith_only is not None:
        max_entries = len(specified_dith_only)
    else:
        for identifier in run_names:
            max_entries = max(max_entries, len(list(osbias_err_all[identifier].keys())))

    ncols = 2
    if (max_entries==1): ncols = 1
    nrows = int(np.ceil(max_entries/ncols))

    # set up the figure
    plt.clf()
    fig, ax = plt.subplots(nrows, ncols)
    fig.subplots_adjust(hspace=0.4)

    diths_to_consider = []
    if specified_dith_only is not None:
        diths_to_consider = specified_dith_only
    else:
        diths_to_consider = colors.keys()

    for i in range(totCases):
        # ----------------------------------------------------------------------------------------
        fsky = fsky_dict[run_names[i]]
        osbias_err = osbias_err_all[run_names[i]]
        row, col = 0, 0
        for dith in diths_to_consider:
            # ----------------------------------------------------------------------------------------
            if (dith in osbias_err.keys()):
                # ----------------------------------------------------------------------------------------
                # look at the appropriate axis.
                if (nrows == 1):
                    if (ncols == 1): axis = ax
                    else: axis = ax[col]
                else: axis = ax[row, col]
                # ----------------------------------------------------------------------------------------
                # calcuate the floors with and without shot noise
                if zbin not in wBAO_cls:
                    raise ValueError('Invalid redshift bin: %s'%zbin)
                else:
                    # get the floor with shot noise
                    floor_with_eta = get_stat_floor(ell_arr=ell, zbin=zbin, wBAO_cls_zbin=wBAO_cls[zbin],
                                                    surf_num_density_zbin=surf_num_density[zbin],
                                                    dither_strategy=dith, fsky=fsky[dith], with_shot_noise=True)
                    # get the "best" floor for the fom calculation
                    floor_no_eta = get_stat_floor(ell_arr=ell, zbin=zbin, wBAO_cls_zbin=wBAO_cls[zbin],
                                                  surf_num_density_zbin=surf_num_density[zbin],
                                                  dither_strategy=dith, fsky=fsky_best, with_shot_noise=False)
                # calculate the FoM
                l = np.arange(np.size(osbias_err[dith]))
                FoM = get_fom(ell_min, ell_max, l, osbias_err[dith], ell, floor_with_eta, floor_no_eta)
                # ----------------------------------------------------------------------------------------
                if i==0:
                    # plot the floor with shot noise
                    axis.plot(ell, floor_with_eta, color='k', lw=2.0, label='$\Delta$C$_\ell$: $%s$'%zbin)

                # set up the legend
                add_leg = ''
                if (i==0):  add_leg = "$\mathrm{\sigma_{C_{\ell,OS}}}$: "
                else: add_leg = "         "

                # plot the osbias error
                axis.plot(l, osbias_err[dith], color=colors[run_names[i]],
                          label=r'%s%s ; FoM: %.6f'%(add_leg, legend_labels[i], FoM))
                # ----------------------------------------------------------------------------------------

                # plot details
                if ((ylim_min is not None) & (ylim_max is not None)):
                    axis.set_ylim(ylim_min, ylim_max)
                else:
                    ax.set_ylim(0, 0.00001)
                axis.set_title('%s: $i<%s$'%(dith, lim_mag_i))
                axis.set_xlabel(r'$\ell$')
                axis.set_xlim(0, lmax)
                if (totCases>4):
                    leg = axis.legend(labelspacing=0.001,)
                else:
                    leg = axis.legend()
                axis.ticklabel_format(axis='y', style='sci', scilimits=(-2,2))
                for legobj in leg.legendHandles:
                    legobj.set_linewidth(2.0)
                col += 1
                if (col > ncols-1):
                    col = 0
                    row +=  1
    # title to the plot?
    if suptitle is not None:
        plt.suptitle(suptitle, y=1.05)
    # turn off axes on unused panels
    if (max_entries%2 != 0) and (max_entries>1): # i.e. have odd number of diths
        ax[nrows-1, ncols-1].axis('off')
    fig.set_size_inches(20, int(nrows*30/7.))

    # set up the filename
    dith_tag = ''
    if specified_dith_only is not None:
        dith_tag = '%sdith'%max_entries
    date_tag = datetime.date.isoformat(datetime.date.today())
    bias_type_tag = ''.join(str(x) for x in filters)
    ell_tag = '_%s<ell<%s'%(ell_min, ell_max)
    if file_append is None:
        file_append = ''

    filename = '%s_OSbiaserr_%s_%s_'%(date_tag, bias_type_tag, dith_tag)
    if (totCases == 1):
        filename += '%s_'%(run_names[0])
    else:
        filename += '%scadences_'%(totCases)
    filename += 'th-r<%s_%s_%s_%s_%s%s%s.png'%(theory_lim_mag, zbin_tag, yr_tag, poisson_tag,
                                               zero_pt_tag, ell_tag, file_append)
    # save the plot
    plt.savefig('%s/%s/%s'%(out_dir, outdir, filename), format='png', bbox_inches='tight')
    print('\nSaved %s'%filename)
    if show_plot:
        plt.show()
    else:
        plt.close('all')
def get_outdir_name(band, nside, pixel_radius, yr_cutoff, zbin, mag_cut_i, run_name, poisson_noise, zero_pt):
    """

    Return the output directory name where the cls for deltaN/N would be, given the input parameters.
    We assume that dust extinction is always added and counts are always normalized.

    Returns: [outdir, yr_tag, zbin_tag, poisson_tag, zero_pt_tag]

    Required Parameters
    -------------------
      * band: str: band to get the output directory name for.
                   Options: 'u', 'g', 'r', 'i'
      * nside: int: HEALpix resolution parameter.
      * pixel_radius: int: number of pixels to mask along the shallow border
      * yr_cutoff: int: year cut to restrict analysis to only a subset of the survey.
                         Must range from 1 to 9, or None for the full survey analysis (10 yrs).
      * zbin: str: options include '0.<z<0.15', '0.15<z<0.37', '0.37<z<0.66, '0.66<z<1.0',
                          '1.0<z<1.5', '1.5<z<2.0', '2.0<z<2.5', '2.5<z<3.0','3.0<z<3.5', '3.5<z<4.0',
                          'all' for no redshift restriction (i.e. 0.<z<4.0)
      * mag_cut_i: float: upper limit on i-band magnitude when calculating the galaxy counts. will deal
                         with color correction automatically (for u,g,r bands ..) depending on the band
      * run_name: str: run name tag to identify the output of specified OpSim output.
                      Since new OpSim outputs have different columns, the run_name for enigma_1189 **must**
                      be 'enigma1189'; can be anything for other outputs, e.g. 'minion1016'
      * poisson_noise: bool: set to True to consider the case where poisson noise is added to  galaxy
                                   counts after border masking (and the incorporation of calibration errors).
      * zero_pt: bool: set to True to consider the case where photometric calibration errors were incorporated.

    """
    # check to make sure redshift bin is ok.
    allowed_zbins = powerLawConst_a.keys()
    if zbin not in allowed_zbins:
        raise ValueError('ERROR: Invalid redshift bin. Input bin can only be among %s\n'%(allowed_zbins))

    # set up the tags.
    dust_tag = 'withDustExtinction'

    zero_pt_tag = ''
    if zero_pt: zero_pt_tag = 'with0ptErrors'
    else: zero_pt_tag = 'no0ptErrors'

    if yr_cutoff is not None: yr_tag = '%syearCut'%yr_cutoff
    else: yr_tag = 'fullSurveyPeriod'

    zbin_tag = zbin
    if (zbin=='all'): zbin_tag = 'allRedshiftData'

    if poisson_noise: poisson_tag = 'withPoissonNoise'
    else: poisson_tag = 'noPoissonNoise'

    norm_tag = 'normalizedGalaxyCounts'

    # account for color corrections.
    mag_cut = {}
    mag_cut['i'] = mag_cut_i
    mag_cut['r'] = float('%.1f'%(mag_cut['i'] + 0.4))
    mag_cut['g'] = float('%.1f'%(mag_cut['r'] + 0.4))
    mag_cut['u'] = float('%.1f'%(mag_cut['g'] + 0.4))

    outdir = 'artificialStructure_%s_nside%s_%spixelRadiusForMasking_%s_%s'%(poisson_tag, nside,
                                                                             pixel_radius, zero_pt_tag, dust_tag)
    outdir += '_%s<%s_%s_%s_%s_%s_directory/'%(band, mag_cut[band], run_name,
                                               yr_tag, zbin_tag, norm_tag)

    return [outdir, yr_tag, zbin_tag, poisson_tag, zero_pt_tag]
Esempio n. 5
0
def os_bias_overplots_diff_dbs(out_dir,
                               data_path,
                               run_names,
                               legend_labels,
                               fsky_dict,
                               fsky_best,
                               mock_data_path,
                               theory_lim_mag,
                               lim_mag_i,
                               ell_min=100,
                               ell_max=300,
                               lmax=500,
                               specified_dith_only=None,
                               filters=['u', 'g', 'r', 'i'],
                               nside=256,
                               pixel_radius=14,
                               yr_cutoff=None,
                               zbin='0.66<z<1.0',
                               poisson_noise=False,
                               zero_pt=True,
                               plot_interms=False,
                               color_dict=None,
                               ylim_min=None,
                               ylim_max=None,
                               show_plot=False,
                               suptitle=None,
                               file_append=None):
    """

    Calculate/plot the OS bias uncertainty and the statistical floor for the specified redshift bin.

    Could vary the dither strategies, but the data should be for the same magnitude cut. The title of
    of each panel in final plot will be "<dither strategy>, and each panel can have
    OS bias uncertainity from many different cadences. Panel legends will specify the redshift bin
    and OpSim output tag.

    Required Parameters
    -------------------
      * out_dir: str: main directory where the output plots should be saved; a folder named
                      'os_bias_overplots' will be created in the directory, if its not there already.
      * data_path: str: path to the artificialStructure data.
      * run_names: list of str: list for run name tags to identify the output of specified OpSim outputs.
      * legend_labels: list of strings: list of the 'tags' for each case; will be used in the legends. e.g. if
                                          run_names=['enigma1189', 'minion1016'], legend_labels could be
                                          ['enigma_1189', 'minion_1016'].
      * fsky_dict: dict: dictionary of the dictionaries containing the fraction of sky covered for each of the
                         cadences. The keys should match the identifier; fsky_dict[indentifiers[:]] should have
                         the dither strategies as the keys.
      * fsky_best: float: best fsky for the survey to compare everything relative to.
      * mock_data_path: str: path to the mock data to consider
      * theory_lim_mag: float: magnitude cut as the identifer in the filename from Hu.
                               Allowed options: 24.0, 25.6, 27.5
      * lim_mag_i: float: i-band magnitude cut to get the data for.

    Optional Parameters
    -------------------
      * specified_dith_only: list of string: list of the names (strings) of the dither strategies to consider, e.g.
                                           if want to plot only NoDither, specified_dith_only=['NoDither']. If
                                           nothing is specified, all the dither strategies will be considered
                                           (based on the npy files available for the runs). Default: None
      * filters: list of strings: list containing the bands (in strings) to be used to calculate the OS bias
                                  and its error. should contain AT LEAST two bands.
                                  e.g. if filters=['g', 'r'], OS bias (at every ell) will be calculated as the
                                  mean across g and r c_ells, while the bias error (at every ell) will be calculated
                                  as the std. dev. across g and r c_ells.
                                  Default: ['u', 'g', 'r', 'i']
      * nside: int: HEALpix resolution parameter. Default: 256
      * pixel_radius: int: number of pixels to mask along the shallow border. Default: 14
      * yr_cutoff: int: year cut to restrict analysis to only a subset of the survey.
                         Must range from 1 to 9, or None for the full survey analysis (10 yrs).
                         Default: None
      * zbin: str: options include '0.15<z<0.37', '0.37<z<0.66, '0.66<z<1.0', '1.0<z<1.5', '1.5<z<2.0'
                           Default: '0.66<z<1.0'
      * poisson_noise: bool: set to True to consider the case where poisson noise is added to galaxy counts
                                   after border masking (and the incorporation of calibration errors).
                                   Default: False
      * zero_pt: bool: set to True to consider the case where 0pt calibration errors were incorporated.
                          Default: True
      * plot_interms: bool: set to True to plot intermediate plots, e.g. BAO data. Default: False
      * color_dict: dict: color dictionary; keys should be the indentifiers provided. Default: None
                    **** Please note that in-built colors are for only a few indentifiers:
                            minion1016, minion1020, kraken1043 ******
      * ylim_min: float: lower y-lim for the final plots. Defaut: None
      * ylim_max: float: upper y-lim for the final plots. Defaut: None
      * show_plot: bool: set to True if want to display the plot (aside from saving it). Default: False
      * suptitle: str: title to the plot. Default: None
      * file_append: str: optional string to append to the saved plot

    """
    # check to make sure redshift bin is ok.
    allowed_zbins = list(powerLawConst_a.keys()) + ['all']
    if zbin not in allowed_zbins:
        raise ValueError(
            'Invalid redshift bin. Input bin can only be among %s\n' %
            (allowed_zbins))

    # check to make sure we have at least two bands to calculate the bias uncertainty.
    if len(filters) < 2:
        raise ValueError(
            'Need at least two filters to calculate bias uncertainty. Currently given only: %s\n'
            % filters)

    # all is ok. proceed.
    totCases = len(run_names)

    # get the outdir address for each 'case' and each band
    outdir_all = {}
    for i in range(totCases):
        outdir = {}
        for band in filters:
            out, yr_tag, zbin_tag, poisson_tag, zero_pt_tag = get_outdir_name(
                band, nside, pixel_radius, yr_cutoff, zbin, lim_mag_i,
                run_names[i], poisson_noise, zero_pt)
            outdir[band] = '%s/cls_DeltaByN/' % out
        outdir_all[run_names[i]] = outdir

    # get the cls and calculate the OS bias and error.
    osbias_all, osbias_err_all = {}, {}
    for i in range(totCases):
        outdir = outdir_all[run_names[i]]
        c_ells = {}
        for band in filters:
            c_ells[band] = return_cls(
                data_path,
                outdir[band],
                band,
                specified_dith=specified_dith_only)  # get the c_ells
        osbias, osbias_err = calc_os_bias_err(c_ells)
        osbias_all[run_names[i]] = osbias
        osbias_err_all[run_names[i]] = osbias_err

    # print stuff
    print('MagCuts: i<%s\nRedshift bin: %s, %s, %s, %s' %
          (lim_mag_i, zbin_tag, yr_tag, poisson_tag, zero_pt_tag))

    # get the data to calculate the statistical floor.
    ell, wBAO_cls, surf_num_density = get_theory_spectra(
        mock_data_path=mock_data_path,
        mag_cut=theory_lim_mag,
        plot_spectra=plot_interms,
        nside=nside)

    ########################################################################################################
    # set the directory
    outdir = 'os_bias_overplots'
    if not os.path.exists('%s/%s' % (out_dir, outdir)):
        os.makedirs('%s/%s' % (out_dir, outdir))

    inBuiltColors = {}
    inBuiltColors['minion1016'] = 'r'
    inBuiltColors['minion1020'] = 'b'
    inBuiltColors['kraken1043'] = 'g'

    if color_dict is None: colors = inBuiltColors
    else: colors = color_dict

    # figure out how many panels we need
    max_entries = 0
    if specified_dith_only is not None:
        max_entries = len(specified_dith_only)
    else:
        for identifier in run_names:
            max_entries = max(max_entries,
                              len(list(osbias_err_all[identifier].keys())))

    ncols = 2
    if (max_entries == 1): ncols = 1
    nrows = int(np.ceil(max_entries / ncols))

    # set up the figure
    plt.clf()
    fig, ax = plt.subplots(nrows, ncols)
    fig.subplots_adjust(hspace=0.4)

    diths_to_consider = []
    if specified_dith_only is not None:
        diths_to_consider = specified_dith_only
    else:
        diths_to_consider = colors.keys()

    for i in range(totCases):
        # ----------------------------------------------------------------------------------------
        fsky = fsky_dict[run_names[i]]
        osbias_err = osbias_err_all[run_names[i]]
        row, col = 0, 0
        for dith in diths_to_consider:
            # ----------------------------------------------------------------------------------------
            if (dith in osbias_err.keys()):
                # ----------------------------------------------------------------------------------------
                # look at the appropriate axis.
                if (nrows == 1):
                    if (ncols == 1): axis = ax
                    else: axis = ax[col]
                else: axis = ax[row, col]
                # ----------------------------------------------------------------------------------------
                # calcuate the floors with and without shot noise
                if zbin not in wBAO_cls:
                    raise ValueError('Invalid redshift bin: %s' % zbin)
                else:
                    # get the floor with shot noise
                    floor_with_eta = get_stat_floor(
                        ell_arr=ell,
                        zbin=zbin,
                        wBAO_cls_zbin=wBAO_cls[zbin],
                        surf_num_density_zbin=surf_num_density[zbin],
                        dither_strategy=dith,
                        fsky=fsky[dith],
                        with_shot_noise=True)
                    # get the "best" floor for the fom calculation
                    floor_no_eta = get_stat_floor(
                        ell_arr=ell,
                        zbin=zbin,
                        wBAO_cls_zbin=wBAO_cls[zbin],
                        surf_num_density_zbin=surf_num_density[zbin],
                        dither_strategy=dith,
                        fsky=fsky_best,
                        with_shot_noise=False)
                # calculate the FoM
                l = np.arange(np.size(osbias_err[dith]))
                FoM = get_fom(ell_min, ell_max, l, osbias_err[dith], ell,
                              floor_with_eta, floor_no_eta)
                # ----------------------------------------------------------------------------------------
                if i == 0:
                    # plot the floor with shot noise
                    axis.plot(ell,
                              floor_with_eta,
                              color='k',
                              lw=2.0,
                              label='$\Delta$C$_\ell$: $%s$' % zbin)

                # set up the legend
                add_leg = ''
                if (i == 0): add_leg = "$\mathrm{\sigma_{C_{\ell,OS}}}$: "
                else: add_leg = "         "

                # plot the osbias error
                axis.plot(l,
                          osbias_err[dith],
                          color=colors[run_names[i]],
                          label=r'%s%s ; FoM: %.6f' %
                          (add_leg, legend_labels[i], FoM))
                # ----------------------------------------------------------------------------------------

                # plot details
                if ((ylim_min is not None) & (ylim_max is not None)):
                    axis.set_ylim(ylim_min, ylim_max)
                else:
                    ax.set_ylim(0, 0.00001)
                axis.set_title('%s: $i<%s$' % (dith, lim_mag_i))
                axis.set_xlabel(r'$\ell$')
                axis.set_xlim(0, lmax)
                if (totCases > 4):
                    leg = axis.legend(labelspacing=0.001, )
                else:
                    leg = axis.legend()
                axis.ticklabel_format(axis='y', style='sci', scilimits=(-2, 2))
                for legobj in leg.legendHandles:
                    legobj.set_linewidth(2.0)
                col += 1
                if (col > ncols - 1):
                    col = 0
                    row += 1
    # title to the plot?
    if suptitle is not None:
        plt.suptitle(suptitle, y=1.05)
    # turn off axes on unused panels
    if (max_entries % 2 != 0) and (max_entries >
                                   1):  # i.e. have odd number of diths
        ax[nrows - 1, ncols - 1].axis('off')
    fig.set_size_inches(20, int(nrows * 30 / 7.))

    # set up the filename
    dith_tag = ''
    if specified_dith_only is not None:
        dith_tag = '%sdith' % max_entries
    date_tag = datetime.date.isoformat(datetime.date.today())
    bias_type_tag = ''.join(str(x) for x in filters)
    ell_tag = '_%s<ell<%s' % (ell_min, ell_max)
    if file_append is None:
        file_append = ''

    filename = '%s_OSbiaserr_%s_%s_' % (date_tag, bias_type_tag, dith_tag)
    if (totCases == 1):
        filename += '%s_' % (run_names[0])
    else:
        filename += '%scadences_' % (totCases)
    filename += 'th-r<%s_%s_%s_%s_%s%s%s.png' % (
        theory_lim_mag, zbin_tag, yr_tag, poisson_tag, zero_pt_tag, ell_tag,
        file_append)
    # save the plot
    plt.savefig('%s/%s/%s' % (out_dir, outdir, filename),
                format='png',
                bbox_inches='tight')
    print('\nSaved %s' % filename)
    if show_plot:
        plt.show()
    else:
        plt.close('all')
Esempio n. 6
0
def get_outdir_name(band, nside, pixel_radius, yr_cutoff, zbin, mag_cut_i,
                    run_name, poisson_noise, zero_pt):
    """

    Return the output directory name where the cls for deltaN/N would be, given the input parameters.
    We assume that dust extinction is always added and counts are always normalized.

    Returns: [outdir, yr_tag, zbin_tag, poisson_tag, zero_pt_tag]

    Required Parameters
    -------------------
      * band: str: band to get the output directory name for.
                   Options: 'u', 'g', 'r', 'i'
      * nside: int: HEALpix resolution parameter.
      * pixel_radius: int: number of pixels to mask along the shallow border
      * yr_cutoff: int: year cut to restrict analysis to only a subset of the survey.
                         Must range from 1 to 9, or None for the full survey analysis (10 yrs).
      * zbin: str: options include '0.<z<0.15', '0.15<z<0.37', '0.37<z<0.66, '0.66<z<1.0',
                          '1.0<z<1.5', '1.5<z<2.0', '2.0<z<2.5', '2.5<z<3.0','3.0<z<3.5', '3.5<z<4.0',
                          'all' for no redshift restriction (i.e. 0.<z<4.0)
      * mag_cut_i: float: upper limit on i-band magnitude when calculating the galaxy counts. will deal
                         with color correction automatically (for u,g,r bands ..) depending on the band
      * run_name: str: run name tag to identify the output of specified OpSim output.
                      Since new OpSim outputs have different columns, the run_name for enigma_1189 **must**
                      be 'enigma1189'; can be anything for other outputs, e.g. 'minion1016'
      * poisson_noise: bool: set to True to consider the case where poisson noise is added to  galaxy
                                   counts after border masking (and the incorporation of calibration errors).
      * zero_pt: bool: set to True to consider the case where photometric calibration errors were incorporated.

    """
    # check to make sure redshift bin is ok.
    allowed_zbins = powerLawConst_a.keys()
    if zbin not in allowed_zbins:
        raise ValueError(
            'ERROR: Invalid redshift bin. Input bin can only be among %s\n' %
            (allowed_zbins))

    # set up the tags.
    dust_tag = 'withDustExtinction'

    zero_pt_tag = ''
    if zero_pt: zero_pt_tag = 'with0ptErrors'
    else: zero_pt_tag = 'no0ptErrors'

    if yr_cutoff is not None: yr_tag = '%syearCut' % yr_cutoff
    else: yr_tag = 'fullSurveyPeriod'

    zbin_tag = zbin
    if (zbin == 'all'): zbin_tag = 'allRedshiftData'

    if poisson_noise: poisson_tag = 'withPoissonNoise'
    else: poisson_tag = 'noPoissonNoise'

    norm_tag = 'normalizedGalaxyCounts'

    # account for color corrections.
    mag_cut = {}
    mag_cut['i'] = mag_cut_i
    mag_cut['r'] = float('%.1f' % (mag_cut['i'] + 0.4))
    mag_cut['g'] = float('%.1f' % (mag_cut['r'] + 0.4))
    mag_cut['u'] = float('%.1f' % (mag_cut['g'] + 0.4))

    outdir = 'artificialStructure_%s_nside%s_%spixelRadiusForMasking_%s_%s' % (
        poisson_tag, nside, pixel_radius, zero_pt_tag, dust_tag)
    outdir += '_%s<%s_%s_%s_%s_%s_directory/' % (band, mag_cut[band], run_name,
                                                 yr_tag, zbin_tag, norm_tag)

    return [outdir, yr_tag, zbin_tag, poisson_tag, zero_pt_tag]
def GalaxyCounts_withPixelCalibration(coaddm5,
                                      upperMagLimit,
                                      nside=128,
                                      filterBand='i',
                                      redshiftBin='all',
                                      CFHTLSCounts=False,
                                      normalizedMockCatalogCounts=True):
    """

    Estimate galaxy counts for a given HEALpix pixel directly (without a slicer).

    Dependency (aside from MAF): constantsForPipeline.py
    ----------

    Required Parameters
    --------------------
      * coaddm5: float:coadded 5sigma limiting magnitude for the pixel.
      * upperMagLimit: float: upper limit on the magnitude, used to calculate numGal.
    
    Optional Parameters
    --------------------
      * nside: int: HEALpix resolution parameter. Default: 128
      * filterBand: str: any one of 'u', 'g', 'r', 'i', 'z', 'y'. Default: 'i'
      * redshiftBin: str: options include '0.<z<0.15', '0.15<z<0.37', '0.37<z<0.66, '0.66<z<1.0',
                          '1.0<z<1.5', '1.5<z<2.0', '2.0<z<2.5', '2.5<z<3.0','3.0<z<3.5', '3.5<z<4.0',
                          'all' for no redshift restriction (i.e. 0.<z<4.0)
                          Default: 'all'
      * CFHTLSCounts: boolean: set to True if want to calculate the total galaxy counts from CFHTLS
                               powerlaw from LSST Science Book. Must be run with redshiftBin= 'all'
                               Default: False
      * normalizedMockCatalogCounts: boolean: set to False if  want the raw/un-normalized galaxy
                                              counts from mock catalogs. Default: True

    """
    # Need to scale down to indivdual HEALpix pixels. Galaxy count from the Coadded depth is per 1 square degree.
    # Number of galaxies ~= 41253 sq. degrees in the full sky divided by number of HEALpix pixels.
    scale = 41253.0 / (int(12) * nside**2)
    # Reset units (otherwise uses magnitudes).
    units = 'Galaxy Counts'

    # ------------------------------------------------------------------------
    # calculate the change in the power law constant based on the band
    # colors assumed here: (u-g)=(g-r)=(r-i)=(i-z)= (z-y)=0.4
    bandCorrection = -100
    if (filterBand == 'u'
        ):  # dimmer than i: u-g= 0.4 => g= u-0.4 => i= u-0.4*3
        bandCorrection = -0.4 * 3.
    elif (filterBand == 'g'
          ):  # dimmer than i: g-r= 0.4 => r= g-0.4 => i= g-0.4*2
        bandCorrection = -0.4 * 2.
    elif (filterBand == 'r'):  # dimmer than i: i= r-0.4
        bandCorrection = -0.4
    elif (filterBand == 'i'):  # i
        bandCorrection = 0.
    elif (filterBand == 'z'):  # brighter than i: i-z= 0.4 => i= z+0.4
        bandCorrection = 0.4
    elif (filterBand == 'y'
          ):  # brighter than i: z-y= 0.4 => z= y+0.4 => i= y+0.4*2
        bandCorrection = 0.4 * 2.
    else:
        print(
            'ERROR: Invalid band in GalaxyCountsMetric_withPixelCalibErrors. Assuming i-band.'
        )
        bandCorrection = 0

    # ------------------------------------------------------------------------
    # check to make sure that the z-bin assigned is valid.
    if ((redshiftBin != 'all')
            and (redshiftBin not in list(powerLawConst_a.keys()))):
        print(
            'ERROR: Invalid redshift bin in GalaxyCountsMetric_withPixelCalibration. Defaulting to all redshifts.'
        )
        redshiftBin = 'all'

    # ------------------------------------------------------------------------
    # set up the functions for the integrand
    # when have a redshift slice
    def galCount_bin(apparent_mag, coaddm5):
        dn_gal = np.power(
            10., powerLawConst_a[redshiftBin] *
            (apparent_mag + bandCorrection) + powerLawConst_b[redshiftBin])
        completeness = 0.5 * scipy.special.erfc(apparent_mag - coaddm5)
        return dn_gal * completeness

    # when have to consider the entire z-range
    def galCount_all(apparent_mag, coaddm5):
        if CFHTLSCounts:
            # LSST power law: eq. 3.7 from LSST Science Book converted to per sq degree:
            # (46*3600)*10^(0.31(i-25))
            dn_gal = 46. * 3600. * np.power(
                10., 0.31 * (apparent_mag + bandCorrection - 25.))
        else:
            # full z-range considered here: 0.<z<4.0
            # sum the galaxy counts from each individual z-bin
            dn_gal = 0.
            for key in list(powerLawConst_a.keys()):
                dn_gal += np.power(
                    10., powerLawConst_a[key] *
                    (apparent_mag + bandCorrection) + powerLawConst_b[key])
        completeness = 0.5 * scipy.special.erfc(apparent_mag - coaddm5)
        return dn_gal * completeness

    # ------------------------------------------------------------------------
    # some coaddm5 values come out really small (i.e. min= 10**-314). Zero them out.
    if (coaddm5 < 1): coaddm5 = 0

    # Calculate the number of galaxies.
    with warnings.catch_warnings():
        warnings.simplefilter("ignore")
        # set up parameters to consider individual redshift range
        if (redshiftBin == 'all'):
            numGal, intErr = scipy.integrate.quad(galCount_all,
                                                  -np.inf,
                                                  upperMagLimit,
                                                  args=coaddm5)
        else:
            numGal, intErr = scipy.integrate.quad(galCount_bin,
                                                  -np.inf,
                                                  upperMagLimit,
                                                  args=coaddm5)

    if (normalizedMockCatalogCounts and not CFHTLSCounts):
        # Normalize the counts from mock catalogs to match up to CFHTLS counts fori<25.5 galaxy catalog
        # Found the scaling factor separately.
        numGal = normalizationConstant * numGal

    # coaddm5=0 implies no observation. Set no observation to zero to numGal.
    if (coaddm5 < 1.): numGal = 0.
    if (numGal < 1.): numGal = 0.

    # scale down to individual HEALpix pixel
    numGal *= scale
    return numGal
def GalaxyCounts_withPixelCalibration(coaddm5, upperMagLimit, nside=128,
                                      filterBand='i', redshiftBin='all',
                                      CFHTLSCounts=False,
                                      normalizedMockCatalogCounts=True):
    """

    Estimate galaxy counts for a given HEALpix pixel directly (without a slicer).

    Dependency (aside from MAF): constantsForPipeline.py
    ----------

    Required Parameters
    --------------------
      * coaddm5: float:coadded 5sigma limiting magnitude for the pixel.
      * upperMagLimit: float: upper limit on the magnitude, used to calculate numGal.
    
    Optional Parameters
    --------------------
      * nside: int: HEALpix resolution parameter. Default: 128
      * filterBand: str: any one of 'u', 'g', 'r', 'i', 'z', 'y'. Default: 'i'
      * redshiftBin: str: options include '0.<z<0.15', '0.15<z<0.37', '0.37<z<0.66, '0.66<z<1.0',
                          '1.0<z<1.5', '1.5<z<2.0', '2.0<z<2.5', '2.5<z<3.0','3.0<z<3.5', '3.5<z<4.0',
                          'all' for no redshift restriction (i.e. 0.<z<4.0)
                          Default: 'all'
      * CFHTLSCounts: boolean: set to True if want to calculate the total galaxy counts from CFHTLS
                               powerlaw from LSST Science Book. Must be run with redshiftBin= 'all'
                               Default: False
      * normalizedMockCatalogCounts: boolean: set to False if  want the raw/un-normalized galaxy
                                              counts from mock catalogs. Default: True

    """
    # Need to scale down to indivdual HEALpix pixels. Galaxy count from the Coadded depth is per 1 square degree. 
    # Number of galaxies ~= 41253 sq. degrees in the full sky divided by number of HEALpix pixels.
    scale = 41253.0/(int(12)*nside**2)
    # Reset units (otherwise uses magnitudes).
    units = 'Galaxy Counts'

    # ------------------------------------------------------------------------
    # calculate the change in the power law constant based on the band
    # colors assumed here: (u-g)=(g-r)=(r-i)=(i-z)= (z-y)=0.4
    bandCorrection = -100
    if (filterBand=='u'):   # dimmer than i: u-g= 0.4 => g= u-0.4 => i= u-0.4*3
        bandCorrection = -0.4*3.
    elif (filterBand=='g'):   # dimmer than i: g-r= 0.4 => r= g-0.4 => i= g-0.4*2
        bandCorrection= -0.4*2.
    elif (filterBand=='r'):   # dimmer than i: i= r-0.4
        bandCorrection = -0.4
    elif (filterBand=='i'):   # i 
        bandCorrection = 0.
    elif (filterBand=='z'):   # brighter than i: i-z= 0.4 => i= z+0.4
        bandCorrection = 0.4
    elif (filterBand=='y'):   # brighter than i: z-y= 0.4 => z= y+0.4 => i= y+0.4*2
        bandCorrection = 0.4*2.
    else:
        print('ERROR: Invalid band in GalaxyCountsMetric_withPixelCalibErrors. Assuming i-band.')
        bandCorrection = 0

    # ------------------------------------------------------------------------
    # check to make sure that the z-bin assigned is valid.
    if ((redshiftBin != 'all') and (redshiftBin not in list(powerLawConst_a.keys()))):
        print('ERROR: Invalid redshift bin in GalaxyCountsMetric_withPixelCalibration. Defaulting to all redshifts.')
        redshiftBin = 'all'

    # ------------------------------------------------------------------------
    # set up the functions for the integrand
    # when have a redshift slice
    def galCount_bin(apparent_mag, coaddm5):
        dn_gal = np.power(10., powerLawConst_a[redshiftBin]*(apparent_mag+bandCorrection)+powerLawConst_b[redshiftBin])
        completeness = 0.5*scipy.special.erfc(apparent_mag-coaddm5)
        return dn_gal*completeness

    # when have to consider the entire z-range
    def galCount_all(apparent_mag, coaddm5):
        if CFHTLSCounts:
            # LSST power law: eq. 3.7 from LSST Science Book converted to per sq degree:
            # (46*3600)*10^(0.31(i-25))
            dn_gal = 46.*3600.*np.power(10., 0.31*(apparent_mag+bandCorrection-25.))
        else:
            # full z-range considered here: 0.<z<4.0
            # sum the galaxy counts from each individual z-bin
            dn_gal = 0.
            for key in list(powerLawConst_a.keys()):
                dn_gal += np.power(10., powerLawConst_a[key]*(apparent_mag+bandCorrection)+powerLawConst_b[key])
        completeness = 0.5*scipy.special.erfc(apparent_mag-coaddm5)
        return dn_gal*completeness

    # ------------------------------------------------------------------------
    # some coaddm5 values come out really small (i.e. min= 10**-314). Zero them out.
    if (coaddm5 <1): coaddm5 = 0
            
    # Calculate the number of galaxies.
    with warnings.catch_warnings():
        warnings.simplefilter("ignore")
        # set up parameters to consider individual redshift range
        if (redshiftBin == 'all'):
            numGal, intErr = scipy.integrate.quad(galCount_all, -np.inf,
                                                  upperMagLimit, args=coaddm5)
        else:
            numGal, intErr = scipy.integrate.quad(galCount_bin, -np.inf,
                                                  upperMagLimit, args=coaddm5)

    if (normalizedMockCatalogCounts and not CFHTLSCounts):
        # Normalize the counts from mock catalogs to match up to CFHTLS counts fori<25.5 galaxy catalog
        # Found the scaling factor separately.
        numGal = normalizationConstant*numGal

    # coaddm5=0 implies no observation. Set no observation to zero to numGal.
    if (coaddm5 < 1.): numGal = 0.
    if (numGal < 1.): numGal = 0.
        
    # scale down to individual HEALpix pixel
    numGal *= scale
    return numGal