Beispiel #1
0
    def __init__(self, t, abcrun=None, prior_name=None):
        ''' A wrapper class for Inherit results with ABC best-fit parameters
        '''
        if abcrun is None:
            raise ValueError('specify abcrun')
        if prior_name is None:
            raise ValueError('specify prior_name')

        self.t = t
        self.abcrun = abcrun
        self.prior_name = prior_name

        # Read in the theta values of the ABC run with 'prior_name' priors
        # at time step t
        theta_file = ''.join([
            Util.code_dir(), 'dat/pmc_abc/', 'CenQue_theta_t',
            str(self.t), '_', self.abcrun, '.dat'
        ])
        w_file = ''.join([
            Util.code_dir(), 'dat/pmc_abc/', 'CenQue_w_t',
            str(t), '_', abcrun, '.dat'
        ])
        self.theta = np.loadtxt(theta_file)  # theta values
        self.w = np.loadtxt(w_file)  # w values

        self.med_theta = [
            np.median(self.theta[:, i]) for i in range(len(self.theta[0]))
        ]

        self.sim_kwargs = self._ABCrun_kwargs()
    def __init__(self, t, abcrun=None, prior_name=None): 
        ''' A wrapper class for Inherit results with ABC best-fit parameters
        '''
        if abcrun is None: 
            raise ValueError('specify abcrun') 
        if prior_name is None: 
            raise ValueError('specify prior_name') 

        self.t = t
        self.abcrun= abcrun
        self.prior_name = prior_name 
    
        # Read in the theta values of the ABC run with 'prior_name' priors 
        # at time step t
        theta_file = ''.join([Util.code_dir(), 
            'dat/pmc_abc/', 
            'CenQue_theta_t', str(self.t), '_', self.abcrun, '.dat']) 
        w_file = ''.join([Util.code_dir(), 
            'dat/pmc_abc/', 
            'CenQue_w_t', str(t), '_', abcrun, '.dat']) 
        self.theta = np.loadtxt(theta_file)      # theta values 
        self.w = np.loadtxt(w_file)              # w values 

        self.med_theta = [np.median(self.theta[:,i]) for i in range(len(self.theta[0]))]

        self.sim_kwargs = self._ABCrun_kwargs() 
    def PickleFile(self, snapshots): 
        ''' Name of the pickle file where the inherited snapshots are saved  
        '''
        if isinstance(snapshots, float): 
            snapshots = [snapshots] 
        elif isinstance(snapshots, list): 
            pass
        elif isinstance(snapshots, np.ndarray): 
            pass 
        elif isinstance(snapshots, str): 
            if snapshots == 'all': 
                snapshots = range(1, self.sim_kwargs['nsnap_ancestor']) 
            else: 
                raise ValueError
        else: 
            raise ValueError
        self.snapshots = snapshots

        if snapshots == range(1, self.sim_kwargs['nsnap_ancestor']): 
            snap_str = '_all' 
        else: 
            snap_str = '_'.join([str(snap) for snap in self.snapshots])
        
        abcinh_file = ''.join([Util.code_dir(), 'dat/pmc_abc/pickle/', 
            'Inherit', 
            '.t', str(self.t), 
            '.snapshots', snap_str, 
            '.ancestor', str(self.sim_kwargs['nsnap_ancestor']), 
            '.abcrun_', self.abcrun, '.p']) 
        return abcinh_file  
Beispiel #4
0
 def _ReadABCrun(self):
     ''' Read file that specifies all the choices of parameters and ABC settings.
     '''
     abcrun_file = ''.join([
         Util.code_dir(), 'dat/pmc_abc/run/', 'abcrun_', self.abcrun, '.p'
     ])
     return pickle.load(open(abcrun_file, 'rb'))
    def _ReadGroupCat_GalData(self): 
        '''
        '''
        h = 0.7
        
        galdata_file = ''.join([
            code_dir(), 'dat/observations/', 
            'clf_groups_M', str(self.Mrcut), '_', str(self.masscut), '_D360.', 
            'galdata_corr.fits']) 
        gal_data = mrdfits(galdata_file) 
        #print gal_data.__dict__.keys()
        for column in gal_data.__dict__.keys(): 
            column_data = getattr(gal_data, column)
            if column == 'stellmass': 
                # stellmass is in units of Msol/h^2
                column_data = column_data / h**2
                # convert to log Mass
                setattr(gal_data, 'mass', np.log10(column_data))
            elif column == 'ssfr': 
                column_data = column_data + np.log10(h**2)
                # convert to log Mass 
                setattr(gal_data, 'ssfr', column_data)    

            elif column == 'cz': 
                # convert to z else: 
                setattr(gal_data, 'z', column_data/299792.458)
            else: 
                pass

        setattr(gal_data, 'sfr', gal_data.mass + gal_data.ssfr)     # get sfr values
        
        return gal_data
Beispiel #6
0
    def PickleFile(self, snapshots):
        ''' Name of the pickle file where the inherited snapshots are saved  
        '''
        if isinstance(snapshots, float):
            snapshots = [snapshots]
        elif isinstance(snapshots, list):
            pass
        elif isinstance(snapshots, np.ndarray):
            pass
        elif isinstance(snapshots, str):
            if snapshots == 'all':
                snapshots = range(1, self.sim_kwargs['nsnap_ancestor'])
            else:
                raise ValueError
        else:
            raise ValueError
        self.snapshots = snapshots

        if snapshots == range(1, self.sim_kwargs['nsnap_ancestor']):
            snap_str = '_all'
        else:
            snap_str = '_'.join([str(snap) for snap in self.snapshots])

        abcinh_file = ''.join([
            Util.code_dir(), 'dat/pmc_abc/pickle/', 'Inherit', '.t',
            str(self.t), '.snapshots', snap_str, '.ancestor',
            str(self.sim_kwargs['nsnap_ancestor']), '.abcrun_', self.abcrun,
            '.p'
        ])
        return abcinh_file
    def _iSEDfitMatch(self): 
        ''' Match the GroupCat galaxies with iSEDfit galaxy properties from 
        John Moustakas's MFData objects. The matching is done using PyDL's 
        spherematch
        '''
        # import SDSS MFdata catalog
        mfdata = mrdfits(code_dir(), 'dat/observations/mfdata_all_supergrid01_sdss.fits.gz') 
        spherematch_time = time.time()
        match1, match2, d_match = spherematch(
                self.ra, self.dec, mfdata.ra, mfdata.dec, 0.001)
        print 'spherematch took ', time.time() - spherematch_time

        iSEDfit_mass = np.repeat(-999., len(self.ra))
        iSEDfit_SFR = np.repeat(-999., len(self.ra))
        iSEDfit_SSFR = np.repeat(-999., len(self.ra))
        
        if np.max(self.z[match1] - mfdata.z[match2]) > 0.1: 
            raise ValueError
        #wrong = np.argmax(self.z[match1] - mfdata.z[match2])
        #print self.ra[match1[wrong]], self.dec[match1[wrong]], self.z[match1[wrong]]
        #print mfdata.ra[match2[wrong]], mfdata.dec[match2[wrong]], mfdata.z[match2[wrong]]
        iSEDfit_mass[match1] = mfdata.mass[match2]
        iSEDfit_SFR[match1] = mfdata.sfr[match2]
        iSEDfit_SSFR[match1] = iSEDfit_SFR[match1]-iSEDfit_mass[match1]
        
        setattr(self, 'iSEDfit_mass', iSEDfit_mass) 
        setattr(self, 'iSEDfit_sfr', iSEDfit_SFR) 
        setattr(self, 'iSEDfit_ssfr', iSEDfit_SSFR) 
        return None
def PlotABC_InfallCondition(tf, cen_tf=7, cen_abcrun=None, cen_prior_name=None): 
    ''' 
    '''
    # Simulator 
    cen_assigned_sat_file = ''.join(['/data1/hahn/pmc_abc/pickle/', 
        'satellite', '.cenassign', 
        '.', cen_abcrun, '_ABC', 
        '.', cen_prior_name, '_prior', '.p'])
    if not os.path.isfile(cen_assigned_sat_file): 
        sat_cen = AssignCenSFR(cen_tf, abcrun=cen_abcrun, prior_name=cen_prior_name)
        pickle.dump(sat_cen, open(cen_assigned_sat_file, 'wb'))
    else: 
        sat_cen = pickle.load(open(cen_assigned_sat_file, 'rb'))

    abcrun_flag = cen_abcrun + '_central'
    theta_file = lambda pewl: ''.join([code_dir(), 
        'dat/pmc_abc/', 'Satellite.tQdelay.theta_t', str(pewl), '_', abcrun_flag, '.dat']) 
   
    theta = np.loadtxt(theta_file(tf)) 
    med_theta = [np.median(theta[:,i]) for i in range(len(theta[0]))]

    abc_tqdelay_dict = {'name': 'explin', 'm': med_theta[0], 'b': med_theta[1]}
    sg_obj = EvolveSatSFR(sat_cen, tqdelay_dict=abc_tqdelay_dict)

    #infall = np.where(
    #        (sg_obj.first_infall_mass > 0.) &
    #        (sg_obj.first_infall_sfr > -999.) & (sg_obj.first_infall_t >  5.7))
    infallmass0 = np.where(sg_obj.first_infall_mass == 0.) 
    infallmassG0 = np.where(sg_obj.first_infall_mass > 0.) 

    infall_nosfr = np.where(sg_obj.first_infall_sfr == -999.) 
    infall_longago = np.where(sg_obj.first_infall_t < 5.7) 

    print sg_obj.mass[infall_longago].min(), sg_obj.mass[infall_longago].max()
    print sg_obj.sfr[infall_longago].min(), sg_obj.sfr[infall_longago].max()
    print sg_obj.first_infall_sfr[infall_longago].min(), sg_obj.first_infall_sfr[infall_longago].max()

    
    m_arr = np.arange(9.5, 11.6, 0.1) 
    m_mid = 0.5 * (m_arr[:-1] + m_arr[1:])
    
    n_all, dum = np.histogram(sg_obj.mass, bins=m_arr)
    n_mass0, dum = np.histogram(sg_obj.mass[infallmass0], bins=m_arr)
    n_nosfr, dum = np.histogram(sg_obj.mass[infall_nosfr], bins=m_arr)
    n_longago, dum = np.histogram(sg_obj.mass[infall_longago], bins=m_arr)

    plt.plot(m_mid, n_mass0.astype('float')/n_all.astype('float')) 
    plt.plot(m_mid, n_nosfr.astype('float')/n_all.astype('float')) 
    plt.plot(m_mid, n_longago.astype('float')/n_all.astype('float')) 
    plt.show() 
    plt.close()

    ssfr_plot = PlotSSFR() 
    ssfr_plot.plot(mass=sg_obj.mass[infallmassG0], ssfr=sg_obj.ssfr[infallmassG0], line_color=5)
    ssfr_plot.plot(mass=sg_obj.mass, ssfr=sg_obj.ssfr, line_color='k', line_style='--')
    ssfr_plot.set_axes() 

    plt.show()
    return None 
    def _ReadGroupCat_Prob(self): 
        ''' wrapper for reading in probability galaxy data 
        '''
        file = ''.join([
            code_dir(), 'dat/observations/', 
            'clf_groups_M', str(self.Mrcut), '_', str(self.masscut), '_D360.', 
            'prob.fits']) 

        prob_data = mrdfits(file)            # import probability file 
        return prob_data
def ReadABCrun(abcrun, restart=False): 
    ''' Read text file that specifies all the choices of parameters and ABC settings.
    '''
    if abcrun is None: 
        abcrun = ''.join(['RENAME_ME_', str(datetime.today().date())])
    restart_str = ''
    if restart: 
        restart_str = '.restart'
    pickle_name = ''.join([code_dir(), 'dat/pmc_abc/run/', 'abcrun_', abcrun, restart_str, '.p']) 
    return pickle.load(open(pickle_name, 'rb')), abcrun
def ReadABCrun(abcrun, restart=False): 
    ''' Read text file that specifies all the choices of parameters and ABC settings.
    '''
    if abcrun is None: 
        abcrun = ''.join(['RENAME_ME_', str(datetime.today().date())])
    restart_str = ''
    if restart: 
        restart_str = '.restart'
    pickle_name = ''.join([code_dir(), 'dat/pmc_abc/run/', 'abcrun_', abcrun, restart_str, '.p']) 
    return pickle.load(open(pickle_name, 'rb')), abcrun
 def File(self, **spec_kwargs):
     ''' File name of output file given snapshot 
     '''
     # write to hdf5 file
     subsham_file = ''.join([
         code_dir(), 'dat/wetzel_tree/', 'subhalo_sham', '.satellite',
         '.snapshot',
         str(spec_kwargs['snapshot']),
         self._file_spec(**spec_kwargs), '.hdf5'
     ])
     return subsham_file
 def File(self): 
     ''' GroupCat File 
     '''
     output_file = ''.join([
         code_dir(), 'dat/observations/', 
         'GroupCat.', 
         'Mr', str(self.Mrcut), 
         '.Mass', str(self.masscut), 
         '.D360.', 
         self.position, 
         '.hdf5']) 
     return output_file 
def InheritSF_file(nsnap_descendant, nsnap_ancestor=20, tau='abc', abc_step=None, 
    subhalo_prop={'scatter': 0.2, 'source': 'li-march'}, 
    sfr_prop={'fq': {'name': 'wetzelsmooth'}, 'sfr': {'name': 'average'}},
    evol_prop={'sfr': {'dutycycle': {'name': 'notperiodic'}}, 'mass': {'name': 'sham'}}, 
    flag=None):
    '''
    '''
    if not isinstance(nsnap_descendant, list): 
        nsnap_descendant = [nsnap_descendant]
    tau_str = ''
    if abc_step is not None:
        tau_str = '.tau_ABC'+str(abc_step)
    else: 
        tau_str = evol_prop['tau']['name']

    # SFMS string
    sfms_str = '.SFMS'+sfr_prop['sfms']['name'].lower()
    if sfr_prop['sfms']['name'] == 'linear': 
        sfms_str += ''.join([
            '_z', str(round(sfr_prop['sfms']['zslope'],2))])
    elif sfr_prop['sfms']['name'] == 'kinked': 
        sfms_str += ''.join([
            '_Mlow', str(round(sfr_prop['sfms']['mslope_lowmass'],2)), 
            'z', str(round(sfr_prop['sfms']['zslope'],2))])
    # SFR assigned based on subhalo growth 
    if 'subhalogrowth' in sfr_prop.keys(): 
        sfms_str += '.halogrowth_SFRassign'
    # mass evolution string 
    if evol_prop['mass']['name'] == 'sham': 
        mass_str = '.Mevo_SHAM'
    elif evol_prop['mass']['name'] == 'integrated':
        if evol_prop['mass']['type'] == 'euler': 
            mass_str = '.Mevo_EulerInt'
        elif evol_prop['mass']['type'] == 'rk4': 
            mass_str = '.Mevo_RK4Int'
    flag_str = ''
    if flag is not None: 
        flag_str = '.'+flag

    hdf5_file = ''.join([
        code_dir(), 'dat/InheritSF/'
        'InheritSF', 
        '.Snap', ''.join([str(nsnap) for nsnap in nsnap_descendant]), '_', str(nsnap_ancestor), 
        '.subhalo_sig', str(round(subhalo_prop['scatter'], 2)), '_', subhalo_prop['source'], 
        '.fq_', sfr_prop['fq']['name'], 
        sfms_str, 
        '.', evol_prop['type'], '_evol',
        '.SF_Duty_', evol_prop['sfr']['dutycycle']['name'],  
        mass_str, 
        tau_str, 
        flag_str, '.hdf5'])
    return hdf5_file 
 def File(self, **spec_kwargs): 
     ''' File name of output file given snapshot 
     '''
     # write to hdf5 file 
     subsham_cen_file = ''.join([ 
         code_dir(), 'dat/wetzel_tree/', 
         'subhalo_sham', 
         '.central',
         '.snapshot', 
         str(spec_kwargs['snapshot']), 
         self._file_spec(**spec_kwargs), 
         '.hdf5']) 
     return subsham_cen_file 
    def Read(self): 
        '''
        '''
        sfr_class = [] 
        for sfq in ['star-forming', 'quiescent']:
            file_dir = code_dir()+'dat/observations/envcount/'
            if sfq == 'star-forming': 
                sfq_str = 'active'
            else: 
                sfq_str = sfq 

            sdss_file = ''.join([file_dir, 
                    'envcount_cylr2.5h35_thresh75_sdss_', sfq_str, '_z0.05_0.12_primuszerr.fits']) 
            primus_file = ''.join([file_dir, 
                    'envcount_cylr2.5h35_thresh75_', sfq_str, '_z0.2_1.0_lit.fits']) 
            # redshift determines SDSS or PRIMUS sample
            if self.redshift_bin < 0.2: 
                galdata = mrdfits(sdss_file) 
            else: 
                galdata = mrdfits(primus_file)
            # environment cuts 
            if self.environment == 'no': 
                envcuts = (galdata.envcount == 0.)
            else: 
                raise NotImplementedError
            # redshift cuts  
            zlow = [0., 0.2, 0.4, 0.6, 0.8]
            zhigh = [0.2, 0.4, 0.6, 0.8, 1.0]
            i_z = int(np.floor(self.redshift_bin/0.2))
            zcuts = (galdata.redshift >= zlow[i_z]) & (galdata.redshift < zhigh[i_z])

            all_cuts = np.where(
                    envcuts & zcuts & 
                    (galdata.mass > galdata.masslimit) & 
                    (galdata.edgecut == 1) 
                    ) 
            for key in galdata.__dict__.keys(): 
                try: 
                    setattr(self, key, 
                            np.concatenate([getattr(self,key), getattr(galdata, key)[all_cuts]]))
                except AttributeError: 
                    setattr(self, key, getattr(galdata, key)[all_cuts])
            
            sfr_class_tmp = np.chararray(len(all_cuts[0]), itemsize=16)
            sfr_class_tmp[:] = sfq

            sfr_class.append(sfr_class_tmp)

        setattr(self, 'sfr_class', np.concatenate(sfr_class))

        return None
Beispiel #17
0
    def __init__(self, t, abcrun=None, prior_name='try0'): 
        '''
        '''
        if abcrun is None: 
            raise ValueError('specify ABC run string') 

        self.t = t 
        self.abcrun = abcrun

        theta_file = ''.join([
            code_dir(), 'dat/pmc_abc/', 'CenQue_theta_t', str(t), '_', abcrun, '.dat']) 
        w_file = ''.join([
            code_dir(), 'dat/pmc_abc/', 'CenQue_w_t', str(t), '_', abcrun, '.dat']) 
        self.theta = np.loadtxt(theta_file)      # theta values 
        self.w = np.loadtxt(w_file)              # w values 
        
        self.med_theta = [np.median(self.theta[:,i]) for i in range(len(self.theta[0]))]
        
        # prior range 
        prior_min, prior_max = PriorRange(prior_name)
        self.prior_range = [(prior_min[i], prior_max[i]) for i in range(len(prior_min))]

        self.descendant = None
Beispiel #18
0
 def Corner(self): 
     ''' Wrapper to generate the corner plot of the ABC particle pool. The plot parameter 
     ranges are the prior ranges. The median of the parameters are marked in the plots.
     '''
     # list of parameters
     params = [
             'slope_gv', 
             'offset_gv', 
             'slope_fudge', 
             'offset_fudge', 
             'slope_tau', 
             'offset_tau'
             ]
     fig_name = ''.join([code_dir(), 
         'figure/', 'abc_step', str(self.t), '_', self.abcrun, '_weighted.png']) 
     self._thetas(self.theta, w=self.w, truths=self.med_theta, plot_range=self.prior_range, 
             parameters=params, 
             fig_name=fig_name)
     fig_name = ''.join([code_dir(), 
         'figure/', 'abc_step', str(self.t), '_', self.abcrun, '_unweighted.png']) 
     self._thetas(self.theta, truths=self.med_theta, plot_range=self.prior_range, 
             parameters=params, 
             fig_name=fig_name)
     return None
def abc_posterior_median(n_step):
    '''
    Median theat from ABC posterior 
    '''
    # read in ABC posterior file
    posterior_file = ''.join(
        [code_dir(), 'dat/pmc_abc/', 'theta_t',
         str(n_step), '.dat'])

    theta = np.loadtxt(posterior_file, unpack=True)

    med_theta = []
    for i_param in xrange(len(theta)):
        med_theta.append(np.median(theta[i_param]))

    return med_theta
Beispiel #20
0
    def File(self): 
        ''' File name of Lineage object. The name specifies the properties
        of the subhalo catalog. 
        ''' 
        # properties that are specified for SF assignment
        if 'subhalo_prop' not in self.__dict__.keys():
            raise ValueError

        file_spec_str = self._file_spec(subhalo_prop = self.subhalo_prop)
        
        lineage_filename = ''.join([
            Util.code_dir(), 'dat/lineage/', 
            'lineage', 
            '.ancestor', str(self.nsnap_ancestor), 
            file_spec_str, 
            '.hdf5']) 
        return lineage_filename
    def File(self):
        ''' File name of CGPop object. The file name acts as a tool to 
        label the properties of the object.  
        '''
        if self.nsnap is None:
            raise ValueError()
        if self.subhalo_prop is None:
            raise ValueError()

        # Cenque Object with assigned starformation properties
        file_spec_str = self._file_spec(subhalo_prop=self.subhalo_prop)
        cgpop_file = ''.join([
            Util.code_dir(), 'dat/galpop/', 'sgpop'
            '.snapshot',
            str(self.nsnap), file_spec_str, '.hdf5'
        ])

        return cgpop_file
Beispiel #22
0
    def QAplot(self, nsnap_descendant=1):
        ''' Quality assurance plots
        '''
        sfinherit_kwargs, abcrun_flag = ReadABCrun(self.abcrun)

        gv_slope = self.med_theta[0]
        gv_offset = self.med_theta[1]
        fudge_slope = self.med_theta[2]
        fudge_offset = self.med_theta[3]
        tau_slope = self.med_theta[4]
        tau_offset = self.med_theta[5]
        
        # tau slopes and offsets of random particles 
        tau_slopes = self.theta[:,4]
        tau_offsets = self.theta[:,5]

        sim_kwargs = sfinherit_kwargs.copy()
        sim_kwargs['sfr_prop']['gv'] = {
                'slope': gv_slope, 'fidmass': 10.5, 'offset': gv_offset}
        sim_kwargs['evol_prop']['fudge'] = {
                'slope': fudge_slope, 'fidmass': 10.5, 'offset': fudge_offset}
        sim_kwargs['evol_prop']['tau'] = {
                'name': 'line', 'slope': tau_slope, 'fid_mass': 11.1, 'yint': tau_offset}
        
        if self.descendant is not None and self.descendant.nsnap == nsnap_descendant: 
            descendant = self.descendant
        else: 
            bloodline = InheritSF(
                    nsnap_descendant,
                    nsnap_ancestor=sim_kwargs['nsnap_ancestor'],
                    subhalo_prop=sim_kwargs['subhalo_prop'], 
                    sfr_prop=sim_kwargs['sfr_prop'], 
                    evol_prop=sim_kwargs['evol_prop'])
            # descendant
            descendant = getattr(bloodline, 'descendant_snapshot'+str(nsnap_descendant)) 
            self.descendant = descendant
        
        fig_name = ''.join([code_dir(), 
            'figure/QAPlot',
            '.nsnap', str(nsnap_descendant), 
             '.abc_step', str(self.t), '_', self.abcrun, '.png']) 
        QAplot(descendant, sim_kwargs, fig_name=fig_name, taus=[tau_slopes, tau_offsets])

        return None 
def PlotABC_Corner(tf, cen_abcrun=None):
    '''
    '''
    abcrun_flag = cen_abcrun + '_central'
    theta_file = lambda pewl: ''.join([code_dir(), 
        'dat/pmc_abc/', 'Satellite.tQdelay.theta_t', str(pewl), '_', abcrun_flag, '.dat']) 
   
    theta = np.loadtxt(theta_file(tf)) 
    med_theta = [np.median(theta[:,i]) for i in range(len(theta[0]))]

    params = [ 'tqdelay_slope', 'tqdelay_offset']


    prior_min = [-11.75, 2.]
    prior_max = [-10.25, 4.]
    #prior_min = [-12.0, 3.]
    #prior_max = [-11.0, 5.]
    prior_range = [(prior_min[i], prior_max[i]) for i in range(len(prior_min))]

    fig = corner.corner(
            theta,
            truths=med_theta,
            truth_color='#ee6a50',
            labels=['$t_{Q,\;delay}$ Slope', '$t_{Q,\;delay}$ offset'],
            label_kwargs={'fontsize': 15},
            range=prior_range,
            quantiles=[0.16,0.5,0.84],
            show_titles=True,
            title_args={"fontsize": 12},
            plot_datapoints=True,
            fill_contours=True,
            levels=[0.68, 0.95],
            color='b',
            bins=20,
            smooth=1.0)
    
    fig_file = ''.join(['figure/',
        'Satellite',
        '.Corner',
        '.tQdelayABC',
        '.', cen_abcrun, '_central.png'])
    fig.savefig(fig_file, bbox_inches='tight') 
    plt.close()
    return None 
def PlotABC_Corner(tf, cen_abcrun=None):
    '''
    '''
    abcrun_flag = cen_abcrun + '_central'
    theta_file = lambda pewl: ''.join([
        code_dir(), 'dat/pmc_abc/', 'Satellite.tQdelay.theta_t',
        str(pewl), '_', abcrun_flag, '.dat'
    ])

    theta = np.loadtxt(theta_file(tf))
    med_theta = [np.median(theta[:, i]) for i in range(len(theta[0]))]

    params = ['tqdelay_slope', 'tqdelay_offset']

    prior_min = [-11.75, 2.]
    prior_max = [-10.25, 4.]
    #prior_min = [-12.0, 3.]
    #prior_max = [-11.0, 5.]
    prior_range = [(prior_min[i], prior_max[i]) for i in range(len(prior_min))]

    fig = corner.corner(
        theta,
        truths=med_theta,
        truth_color='#ee6a50',
        labels=['$t_{Q,\;delay}$ Slope', '$t_{Q,\;delay}$ offset'],
        label_kwargs={'fontsize': 15},
        range=prior_range,
        quantiles=[0.16, 0.5, 0.84],
        show_titles=True,
        title_args={"fontsize": 12},
        plot_datapoints=True,
        fill_contours=True,
        levels=[0.68, 0.95],
        color='b',
        bins=20,
        smooth=1.0)

    fig_file = ''.join([
        'figure/', 'Satellite', '.Corner', '.tQdelayABC', '.', cen_abcrun,
        '_central.png'
    ])
    fig.savefig(fig_file, bbox_inches='tight')
    plt.close()
    return None
def PlotABC_tQdelay(tf, cen_abcrun=None): 
    '''
    '''
    abcrun_flag = cen_abcrun + '_central'
    theta_file = lambda pewl: ''.join([code_dir(), 
        'dat/pmc_abc/', 'Satellite.tQdelay.theta_t', str(pewl), '_', abcrun_flag, '.dat']) 
   
    theta = np.loadtxt(theta_file(tf)) 

    m_arr = np.arange(7.5, 12.0, 0.1) 
    tdels = [] 
    for i in xrange(len(theta)): 
        i_tqdelay_dict = {'name': 'explin', 'm': theta[i][0], 'b': theta[i][1]}
        tdels.append(tDelay(m_arr, **i_tqdelay_dict))
    
    tdels = np.array(tdels)
    a, b, c, d, e = np.percentile(tdels, [2.5, 16, 50, 84, 97.5], axis=0)

    prettyplot()
    pretty_colors = prettycolors()
    fig = plt.figure(figsize=(7,7))
    sub = fig.add_subplot(111)

    mstar = np.array([1.56781e+11, 1.01089e+11, 6.27548e+10, 3.98107e+10, 2.49831e+10, 1.57633e+10, 9.89223e+9, 6.37831e+9])
    tqdel_high = np.array([1.36456e+0 , 2.53148e+0 , 3.06686e+0 , 3.52693e+0 , 3.62625e+0 , 3.99574e+0, 3.99915e+0 ,3.99915e+0])
    tqdel_low = np.array([8.15728e-1, 1.98257e+0, 2.29240e+0, 2.82772e+0, 2.99466e+0, 2.72548e+0, 2.99016e+0, 2.68333e+0])
    sub.fill_between(mstar, tqdel_low, tqdel_high, color=pretty_colors[0], edgecolor="none", label='Roughly Wetzel+(2013)')

    #sub.plot(10**m_arr, tDelay(m_arr, **abc_tqdelay_dict), c=pretty_colors[3], label='ABC Best-fit')
    
    sub.fill_between(10**m_arr, a, e, color=pretty_colors[3], alpha=0.5, edgecolor="none", 
            label='ABC Best-fit')
    sub.fill_between(10**m_arr, b, d, color=pretty_colors[3], alpha=1., edgecolor="none")
    sub.plot(10**m_arr, tDelay(m_arr, **{'name': 'hacked'}))

    sub.set_ylim([0.0, 4.0])
    sub.set_ylabel(r'$\mathtt{t_{Q, delay}}$', fontsize=25) 
    sub.set_xlim([5*10**9, 2*10**11.]) 
    sub.set_xscale("log") 
    sub.set_xlabel(r'$\mathtt{M}_*$', fontsize=25) 
    sub.legend(loc='lower left') 
    
    fig.savefig('figure/sallite_tqdelay_'+cen_abcrun+'.png', bbox_inches='tight') 
    return None
    def Corner(self, filename=None): 
        ''' Wrapper to generate the corner plot of the ABC particle pool. The plot parameter 
        ranges are the prior ranges. The median of the parameters are marked in the plots.
        '''
        # list of parameters
        if not self.satellite_run:
            params = [
                    'slope_gv', 
                    'offset_gv', 
                    'slope_fudge', 
                    'offset_fudge', 
                    'slope_tau', 
                    'offset_tau'
                    ]
        else: 
            params = [
                    'slope_gv', 
                    'offset_gv', 
                    'slope_fudge', 
                    'offset_fudge'
                    ]

        if filename is None: 
            fig_name = ''.join([code_dir(), 
                'figure/', 'abc_step', str(self.t), '_', self.abcrun, '_weighted.png']) 
        else: 
            fig_name = filename

        if 'weighted' not in fig_name:
            fig_name = '_weighted.pn'.join(fig_name.split('.pn'))

        self._thetas(self.theta, w=self.w, truths=self.med_theta, plot_range=self.prior_range, 
                parameters=params, 
                fig_name=fig_name)

        fig_name = 'unweighted'.join(fig_name.split('weighted'))
        # fig_name = ''.join([code_dir(), 
        #    'figure/', 'abc_step', str(self.t), '_', self.abcrun, '_unweighted.png']) 
        self._thetas(self.theta, truths=self.med_theta, plot_range=self.prior_range, 
                parameters=params, 
                fig_name=fig_name)
        return fig_name
    def QAplot(self, nsnap_descendant=1):
        ''' Quality assurance plots
        '''
        sfinherit_kwargs, abcrun_flag = ReadABCrun(self.abcrun)

        gv_slope = self.med_theta[0]
        gv_offset = self.med_theta[1]
        fudge_slope = self.med_theta[2]
        fudge_offset = self.med_theta[3]
        if not self.satellite_run: 
            tau_slope = self.med_theta[4]
            tau_offset = self.med_theta[5]
        
            # tau slopes and offsets of random particles 
            tau_slopes = self.theta[:,4]
            tau_offsets = self.theta[:,5]

        sim_kwargs = sfinherit_kwargs.copy()
        sim_kwargs['sfr_prop']['gv'] = {
                'slope': gv_slope, 'fidmass': 10.5, 'offset': gv_offset}
        sim_kwargs['evol_prop']['fudge'] = {
                'slope': fudge_slope, 'fidmass': 10.5, 'offset': fudge_offset}
        if not self.satellite_run: 
            sim_kwargs['evol_prop']['tau'] = {
                    'name': 'line', 'slope': tau_slope, 'fid_mass': 11.1, 'yint': tau_offset}
        else: 
            sim_kwargs['evol_prop']['tau'] = {'name': 'satellite'}
        
        inh = Inherit(nsnap_descendant, 
                nsnap_ancestor=sim_kwargs['nsnap_ancestor'],
                subhalo_prop=sim_kwargs['subhalo_prop'], 
                sfr_prop=sim_kwargs['sfr_prop'], 
                evol_prop=sim_kwargs['evol_prop'])
        des_dict = inh() 
        for nd in nsnap_descendant: 
            fig_name = ''.join([code_dir(), 
                'figure/QAPlot',
                '.nsnap', str(nd), 
                 '.abc_step', str(self.t), '_', self.abcrun, '.png']) 
            QAplot(des_dict[str(nd)], sim_kwargs, fig_name=fig_name)#, taus=[tau_slopes, tau_offsets])

        return None 
    def __init__(self, t, abcrun=None, prior_name='try0'): 
        '''
        '''
        if abcrun is None: 
            raise ValueError('specify ABC run string') 

        self.t = t 
        self.abcrun = abcrun
    
        if prior_name == 'satellite': 
            theta_file = ''.join([
                code_dir(), 'dat/pmc_abc/', 'CenQue_theta_t', str(t), '_', abcrun, '.satellite.dat']) 
            w_file = ''.join([
                code_dir(), 'dat/pmc_abc/', 'CenQue_w_t', str(t), '_', abcrun, '.satellite.dat']) 
            self.satellite_run = True 
        elif prior_name == 'longtau': 
            theta_file = ''.join([
                code_dir(), 'dat/pmc_abc/', 'CenQue_theta_t', str(t), '_', abcrun, 
                '.fixedtau.long.dat']) 
            w_file = ''.join([
                code_dir(), 'dat/pmc_abc/', 'CenQue_w_t', str(t), '_', abcrun, 
                '.fixedtau.long.dat']) 
            self.satellite_run = True 
        else: 
            theta_file = ''.join([
                code_dir(), 'dat/pmc_abc/', 'CenQue_theta_t', str(t), '_', abcrun, '.dat']) 
            w_file = ''.join([
                code_dir(), 'dat/pmc_abc/', 'CenQue_w_t', str(t), '_', abcrun, '.dat']) 
            dist_file = ''.join([
                code_dir(), 'dat/pmc_abc/', 'CenQue_dist_t', str(t), '_', abcrun, '.dat']) 
            self.satellite_run = False 
        self.theta = np.loadtxt(theta_file)      # theta values 
        self.w = np.loadtxt(w_file)              # w values 
        #self.dist = np.loadtxt(dist_file) 
        
        self.med_theta = [np.median(self.theta[:,i]) for i in range(len(self.theta[0]))]
        
        # prior range 
        prior_min, prior_max = PriorRange(prior_name)
        self.prior_range = [(prior_min[i], prior_max[i]) for i in range(len(prior_min))]

        self.descendant = None
    def File(self): 
        ''' File name of CGPop object. The file name acts as a tool to 
        label the properties of the object.  
        ''' 
        if self.nsnap is None: 
            raise ValueError()
        if self.subhalo_prop is None: 
            raise ValueError()
     
        # Cenque Object with assigned starformation properties
        file_spec_str = self._file_spec(
                subhalo_prop=self.subhalo_prop
                )
        cgpop_file = ''.join([Util.code_dir(), 
            'dat/galpop/', 
            'sgpop'
            '.snapshot', str(self.nsnap), 
            file_spec_str, 
            '.hdf5'
            ]) 

        return cgpop_file
def abc_posterior_median(n_step): 
    '''
    Median theat from ABC posterior 
    '''
    # read in ABC posterior file 
    posterior_file = ''.join([
        code_dir(), 'dat/pmc_abc/', 
        'theta_t', 
        str(n_step), 
        '.dat'])

    theta = np.loadtxt(
            posterior_file, 
            unpack = True
            ) 

    med_theta = [] 
    for i_param in xrange(len(theta)):
        med_theta.append( 
                np.median(theta[i_param])
                )

    return med_theta 
 def _ReadABCrun(self): 
     ''' Read file that specifies all the choices of parameters and ABC settings.
     '''
     abcrun_file = ''.join([Util.code_dir(), 
         'dat/pmc_abc/run/', 'abcrun_', self.abcrun, '.p']) 
     return pickle.load(open(abcrun_file, 'rb'))
def ABC(T, eps_input, Npart=1000, prior_name='try0', observables=['ssfr'], abcrun=None, 
        restart=False, t_restart=None, eps_restart=None):
    ''' ABC-PMC implementation. 

    Parameters
    ----------
    T : (int) 
        Number of iterations

    eps_input : (float)
        Starting epsilon threshold value 

    N_part : (int)
        Number of particles

    prior_name : (string)
        String that specifies what prior to use.

    abcrun : (string)
        String that specifies abc run information 
    '''
    if isinstance(eps_input, list):
        if len(eps_input) != len(observables): 
            raise ValueError
    if len(observables) > 1 and isinstance(eps_input, float): 
        raise ValueError

    # output abc run details
    sfinherit_kwargs, abcrun_flag = MakeABCrun(
            abcrun=abcrun, Niter=T, Npart=Npart, prior_name=prior_name, 
            eps_val=eps_input, restart=restart) 

    # Data 
    data_sum = DataSummary(observables=observables)
    # Priors
    prior_min, prior_max = PriorRange(prior_name)
    prior = abcpmc.TophatPrior(prior_min, prior_max)    # ABCPMC prior object

    ## Read in ABC run file
    #sfinherit_kwargs, abcrun_flag = ReadABCrun(abcrun, restart=restart)

    def Simz(tt):       # Simulator (forward model) 
        gv_slope = tt[0]
        gv_offset = tt[1]
        fudge_slope = tt[2]
        fudge_offset = tt[3]
        tau_slope = tt[4]
        tau_offset = tt[5]

        sim_kwargs = sfinherit_kwargs.copy()
        sim_kwargs['sfr_prop']['gv'] = {'slope': gv_slope, 'fidmass': 10.5, 'offset': gv_offset}
        sim_kwargs['evol_prop']['fudge'] = {'slope': fudge_slope, 'fidmass': 10.5, 'offset': fudge_offset}
        sim_kwargs['evol_prop']['tau'] = {'name': 'line', 'slope': tau_slope, 'fid_mass': 11.1, 'yint': tau_offset}

        return SimSummary(observables=observables, **sim_kwargs)

    theta_file = lambda pewl: ''.join([code_dir(), 
        'dat/pmc_abc/', 'CenQue_theta_t', str(pewl), '_', abcrun_flag, '.dat']) 
    w_file = lambda pewl: ''.join([code_dir(), 
        'dat/pmc_abc/', 'CenQue_w_t', str(pewl), '_', abcrun_flag, '.dat']) 
    dist_file = lambda pewl: ''.join([code_dir(), 
        'dat/pmc_abc/', 'CenQue_dist_t', str(pewl), '_', abcrun_flag, '.dat']) 
    eps_file = ''.join([code_dir(), 
        'dat/pmc_abc/epsilon_', abcrun_flag, '.dat'])

    if observables == ['ssfr']:
        distfn = RhoSSFR
    elif observables == ['ssfr', 'fqz03']: 
        distfn = RhoSSFR_Fq
   
    if restart:
        if t_restart is None: 
            raise ValueError

        last_thetas = np.loadtxt(theta_file(t_restart))
        last_ws = np.loadtxt(w_file(t_restart))
        last_dist = np.loadtxt(dist_file(t_restart))

        init_pool = abcpmc.PoolSpec(t_restart, None, None, last_thetas, last_dist, last_ws)
    else: 
        init_pool = None 

    eps = abcpmc.ConstEps(T, eps_input)
    try:
        mpi_pool = mpi_util.MpiPool()
        abcpmc_sampler = abcpmc.Sampler(
                N=Npart,                # N_particles
                Y=data_sum,             # data
                postfn=Simz,            # simulator 
                dist=distfn,           # distance function  
                pool=mpi_pool)  
    except AttributeError: 
        abcpmc_sampler = abcpmc.Sampler(
                N=Npart,                # N_particles
                Y=data_sum,             # data
                postfn=Simz,            # simulator 
                dist=distfn)           # distance function  
    abcpmc_sampler.particle_proposal_cls = abcpmc.ParticleProposal

    pools = []
    if init_pool is None: 
        f = open(eps_file, "w")
        f.close()
    eps_str = ''
    for pool in abcpmc_sampler.sample(prior, eps, pool=init_pool):
        print '----------------------------------------'
        print 'eps ', pool.eps
        new_eps_str = '\t'+str(pool.eps)+'\n'
        if eps_str != new_eps_str:  # if eps is different, open fiel and append 
            f = open(eps_file, "a")
            eps_str = new_eps_str
            f.write(eps_str)
            f.close()

        print("T:{0},ratio: {1:>.4f}".format(pool.t, pool.ratio))
        print eps(pool.t)

        # write theta, weights, and distances to file 
        np.savetxt(theta_file(pool.t), pool.thetas, 
            header='gv_slope, gv_offset, fudge_slope, fudge_offset, tau_slope, tau_offset')
        np.savetxt(w_file(pool.t), pool.ws)
        np.savetxt(dist_file(pool.t), pool.dists)
    
        # update epsilon based on median thresholding 
        if len(observables) == 1: 
            eps.eps = np.median(pool.dists)
        else:
            #print pool.dists
            print np.median(np.atleast_2d(pool.dists), axis = 0)
            eps.eps = np.median(np.atleast_2d(pool.dists), axis = 0)
        print '----------------------------------------'
        pools.append(pool)

    return pools 
    def Ssfr(self, subsample_thetas=False): 
        ''' Plot the SSFR distribution of the median paramater values of the 
        ABC particle pool.
        '''
        sfinherit_kwargs, abcrun_flag = ReadABCrun(self.abcrun)
        
        ssfr_plot = None
        if subsample_thetas: 
            N_theta = len(self.theta)
            i_subs = np.random.choice(N_theta, size=20)

            for i_sub in i_subs: 
                gv_slope, gv_offset, fudge_slope, fudge_offset, tau_slope, tau_offset = self.theta[i_sub]

                sim_kwargs = sfinherit_kwargs.copy()
                sim_kwargs['sfr_prop']['gv'] = {'slope': gv_slope, 'fidmass': 10.5, 'offset': gv_offset}
                sim_kwargs['evol_prop']['fudge'] = {'slope': fudge_slope, 'fidmass': 10.5, 'offset': fudge_offset}
                sim_kwargs['evol_prop']['tau'] = {'name': 'line', 'slope': tau_slope, 'fid_mass': 11.1, 'yint': tau_offset}

                bloodline = InheritSF(
                        1,
                        nsnap_ancestor=sim_kwargs['nsnap_ancestor'],
                        subhalo_prop=sim_kwargs['subhalo_prop'], 
                        sfr_prop=sim_kwargs['sfr_prop'], 
                        evol_prop=sim_kwargs['evol_prop'])
                # descendant
                desc = getattr(bloodline, 'descendant_snapshot1') 

                ssfr_plot = desc.plotSsfr(line_color='red', lw=2, alpha=0.25, ssfr_plot=ssfr_plot)

        # plot the median 'best-fit' theta
        gv_slope = self.med_theta[0]
        gv_offset = self.med_theta[1]
        fudge_slope = self.med_theta[2]
        fudge_offset = self.med_theta[3]
        tau_slope = self.med_theta[4]
        tau_offset = self.med_theta[5]

        sim_kwargs = sfinherit_kwargs.copy()
        sim_kwargs['sfr_prop']['gv'] = {'slope': gv_slope, 'fidmass': 10.5, 'offset': gv_offset}
        sim_kwargs['evol_prop']['fudge'] = {'slope': fudge_slope, 'fidmass': 10.5, 'offset': fudge_offset}
        sim_kwargs['evol_prop']['tau'] = {'name': 'line', 'slope': tau_slope, 'fid_mass': 11.1, 'yint': tau_offset}

        if self.descendant is None: 
            bloodline = InheritSF(
                    1,
                    nsnap_ancestor=sim_kwargs['nsnap_ancestor'],
                    subhalo_prop=sim_kwargs['subhalo_prop'], 
                    sfr_prop=sim_kwargs['sfr_prop'], 
                    evol_prop=sim_kwargs['evol_prop'])
            # descendant
            descendant = getattr(bloodline, 'descendant_snapshot1') 
            self.descendant = descendant
        else: 
            descendant = self.descendant

        fig_name = ''.join([code_dir(), 
            'figure/SSFR.abc_step', str(self.t), '_', self.abcrun, '.png']) 
        descendant.plotSsfr(line_color='red', line_width=4, 
                sfms_prop=sim_kwargs['sfr_prop']['sfms'], z=descendant.zsnap, 
                groupcat=True, ssfr_plot=ssfr_plot, savefig=fig_name)
        plt.close()
        return None 
def ABC(T,
        eps_input,
        Npart=1000,
        cen_tf=None,
        cen_prior_name=None,
        cen_abcrun=None):
    ''' ABC-PMC implementation. 

    Parameters
    ----------
    T : (int) 
        Number of iterations

    eps_input : (float)
        Starting epsilon threshold value 

    N_part : (int)
        Number of particles

    prior_name : (string)
        String that specifies what prior to use.

    abcrun : (string)
        String that specifies abc run information 
    '''
    abcinh = ABCInherit(cen_tf, abcrun=cen_abcrun, prior_name=cen_prior_name)

    # Data (Group Catalog Satellite fQ)
    grpcat = GroupCat(Mrcut=18, position='satellite')
    grpcat.Read()
    qfrac = Fq()
    m_bin = np.array([9.7, 10.1, 10.5, 10.9, 11.3])
    M_mid = 0.5 * (m_bin[:-1] + m_bin[1:])

    sfq = qfrac.Classify(grpcat.mass,
                         grpcat.sfr,
                         np.median(grpcat.z),
                         sfms_prop=abcinh.sim_kwargs['sfr_prop']['sfms'])
    ngal, dum = np.histogram(grpcat.mass, bins=m_bin)
    ngal_q, dum = np.histogram(grpcat.mass[sfq == 'quiescent'], bins=m_bin)
    data_sum = [M_mid, ngal_q.astype('float') / ngal.astype('float')]

    # Simulator
    cen_assigned_sat_file = ''.join([
        '/data1/hahn/pmc_abc/pickle/', 'satellite', '.cenassign', '.',
        cen_abcrun, '_ABC', '.', cen_prior_name, '_prior', '.p'
    ])

    if not os.path.isfile(cen_assigned_sat_file):
        sat_cen = AssignCenSFR(cen_tf,
                               abcrun=cen_abcrun,
                               prior_name=cen_prior_name)
        pickle.dump(sat_cen, open(cen_assigned_sat_file, 'wb'))
    else:
        sat_cen = pickle.load(open(cen_assigned_sat_file, 'rb'))

    def Simz(tt):  # Simulator (forward model)
        tqdel_dict = {'name': 'explin', 'm': tt[0], 'b': tt[1]}

        sat_evol = EvolveSatSFR(sat_cen, tqdelay_dict=tqdel_dict)

        sfq_sim = qfrac.Classify(sat_evol.mass,
                                 sat_evol.sfr,
                                 sat_evol.zsnap,
                                 sfms_prop=sat_evol.sfms_prop)
        ngal_sim, dum = np.histogram(sat_evol.mass, bins=m_bin)
        ngal_q_sim, dum = np.histogram(sat_evol.mass[sfq_sim == 'quiescent'],
                                       bins=m_bin)
        sim_sum = [
            M_mid,
            ngal_q_sim.astype('float') / ngal_sim.astype('float')
        ]
        return sim_sum

    # Priors
    prior_min = [-11.75, 2.]
    prior_max = [-10.25, 4.]
    prior = abcpmc.TophatPrior(prior_min, prior_max)  # ABCPMC prior object

    def rho(simum, datum):
        datum_dist = datum[1]
        simum_dist = simum[1]
        drho = np.sum((datum_dist - simum_dist)**2)
        return drho

    abcrun_flag = cen_abcrun + '_central'

    theta_file = lambda pewl: ''.join([
        code_dir(), 'dat/pmc_abc/', 'Satellite.tQdelay.theta_t',
        str(pewl), '_', abcrun_flag, '.dat'
    ])
    w_file = lambda pewl: ''.join([
        code_dir(), 'dat/pmc_abc/', 'Satellite.tQdelay.w_t',
        str(pewl), '_', abcrun_flag, '.dat'
    ])
    dist_file = lambda pewl: ''.join([
        code_dir(), 'dat/pmc_abc/', 'Satellite.tQdelay.dist_t',
        str(pewl), '_', abcrun_flag, '.dat'
    ])
    eps_file = ''.join([
        code_dir(), 'dat/pmc_abc/Satellite.tQdelay.epsilon_', abcrun_flag,
        '.dat'
    ])

    eps = abcpmc.ConstEps(T, eps_input)
    try:
        mpi_pool = mpi_util.MpiPool()
        abcpmc_sampler = abcpmc.Sampler(
            N=Npart,  # N_particles
            Y=data_sum,  # data
            postfn=Simz,  # simulator 
            dist=rho,  # distance function  
            pool=mpi_pool)
    except AttributeError:
        abcpmc_sampler = abcpmc.Sampler(
            N=Npart,  # N_particles
            Y=data_sum,  # data
            postfn=Simz,  # simulator 
            dist=rho)  # distance function
    abcpmc_sampler.particle_proposal_cls = abcpmc.ParticleProposal

    pools = []
    f = open(eps_file, "w")
    f.close()
    eps_str = ''
    for pool in abcpmc_sampler.sample(prior, eps, pool=None):
        print '----------------------------------------'
        print 'eps ', pool.eps
        new_eps_str = '\t' + str(pool.eps) + '\n'
        if eps_str != new_eps_str:  # if eps is different, open fiel and append
            f = open(eps_file, "a")
            eps_str = new_eps_str
            f.write(eps_str)
            f.close()

        print("T:{0},ratio: {1:>.4f}".format(pool.t, pool.ratio))
        print eps(pool.t)

        # write theta, weights, and distances to file
        np.savetxt(theta_file(pool.t),
                   pool.thetas,
                   header='tQdelay_slope, tQdelay_offset')
        np.savetxt(w_file(pool.t), pool.ws)
        np.savetxt(dist_file(pool.t), pool.dists)

        # update epsilon based on median thresholding
        eps.eps = np.median(pool.dists)
        pools.append(pool)

    return pools
def MakeABCrun(abcrun=None, nsnap_start=15, subhalo=None, fq=None, sfms=None, dutycycle=None, mass_evol=None, 
        Niter=None, Npart=None, prior_name=None, eps_val=None, restart=False): 
    '''Pickle file that specifies all the choices of parameters and ABC settings 
    for record keeping purposes.
    '''
    if abcrun is None: 
        abcrun = ''.join(['RENAME_ME_', str(datetime.today().date())])
    restart_str = ''
    if restart: 
        restart_str = '.restart'
    file_name = ''.join([code_dir(), 'dat/pmc_abc/run/', 'abcrun_', abcrun, restart_str, '.txt']) 
    pickle_name = file_name.replace('.txt', '.p')

    f = open(file_name, 'w')

    # ABC properities
    f.write('# ABC Run Properties \n') 
    f.write('N_iter = '+str(Niter)+'\n')
    f.write('N_particles = '+str(Npart)+'\n')
    f.write('Prior Name = '+prior_name+'\n')
    f.write('Epsilon_0 = '+str(eps_val)+'\n')
    if restart: 
        f.write('Restarting')
    f.write('\n')

    # Subhalo properties
    f.write('# Subhalo Properties \n') 
    if subhalo is None:    
        subhalo_dict = {'scatter': 0.2, 'source': 'li-march'}
    elif isinstance(subhalo, str):  
        subhalo_dict = {'scatter': 0.2, 'source': subhalo}
    f.write(''.join(['scatter = ', str(subhalo_dict['scatter']), '\n']))
    f.write(''.join(['source = ', subhalo_dict['source'], '\n']))
    f.write('\n')
    
    # Quiescent fraction properties
    f.write('# Quiescent Fraction Properties \n') 
    if fq is None:          # quiescent fraction
        #fq = {'name': 'wetzel'}
        fq = {'name': 'cosmos_tinker'} 
    f.write(''.join(['name = ', fq['name'], '\n']))
    f.write('\n')

    # Starforming Main Sequence
    f.write('# Starforming Main Sequence Properties \n') 
    if sfms is None:   # SFMS  
        sfms = {'name': 'linear', 'zslope': 1.14}
    f.write(''.join(['name = ', sfms['name'], '\n']))
    f.write(''.join(['zslope = ', str(sfms['zslope']), '\n']))
    f.write('\n')
    
    # SF dutycycle properties
    f.write('# SF Dutycycle Properties \n') 
    if dutycycle is None:   
        dutycycle = {'name': 'notperiodic'}
        #dutycycle = {'name': 'newamp_squarewave', 'freq_range': [2.*np.pi, 20.*np.pi], 'sigma': 0.3}
    f.write(''.join(['name = ', dutycycle['name'], '\n']))
    if dutycycle['name'] == 'newamp_squarewave': 
        f.write(''.join(['frequency range = ', str(dutycycle['freq_range'][0]), ',', str(dutycycle['freq_range'][1]), '\n']))
        f.write(''.join(['sigma = ', str(dutycycle['sigma']), '\n']))
    f.write('\n')
    
    # Mass Evolution properties
    f.write('# Mass Evolution Properties \n') 
    if mass_evol is None:
        mass_evol = {'name': 'sham'} 
    if mass_evol['name'] == 'sham': 
        f.write(''.join(['name = ', mass_evol['name'], '\n']))
    f.close()

    evol_dict = { 
            'type': 'simult',
            'sfr': {'dutycycle': dutycycle},
            'mass': mass_evol
            }
    kwargs = {
            'nsnap_ancestor': nsnap_start, 
            'subhalo_prop': subhalo_dict, 
            'sfr_prop': {'fq': fq, 'sfms': sfms},
            'evol_prop': evol_dict
            }

    pickle.dump(kwargs, open(pickle_name, 'wb'))
    return kwargs, abcrun 
def FixedTauABC(T, eps_input, fixtau='satellite', Npart=1000, prior_name='try0', 
        observables=['fqz_multi'], abcrun=None, 
        restart=False, t_restart=None, eps_restart=None, **sim_kwargs):
    ''' Run ABC-PMC analysis for central galaxy SFH model with *FIXED* quenching 
    timescale

    Parameters
    ----------
    T : (int) 
        Number of iterations

    eps_input : (float)
        Starting epsilon threshold value 

    N_part : (int)
        Number of particles

    prior_name : (string)
        String that specifies what prior to use.

    abcrun : (string)
        String that specifies abc run information 
    '''
    if isinstance(eps_input, list):
        if len(eps_input) != len(observables): 
            raise ValueError
    if len(observables) > 1 and isinstance(eps_input, float): 
        raise ValueError

    # output abc run details
    sfinherit_kwargs, abcrun_flag = MakeABCrun(
            abcrun=abcrun, Niter=T, Npart=Npart, prior_name=prior_name, 
            eps_val=eps_input, restart=restart, **sim_kwargs) 

    # Data 
    data_sum = DataSummary(observables=observables)
    # Priors
    prior_min, prior_max = PriorRange(prior_name)
    prior = abcpmc.TophatPrior(prior_min, prior_max)    # ABCPMC prior object

    def Simz(tt):       # Simulator (forward model) 
        gv_slope = tt[0]
        gv_offset = tt[1]
        fudge_slope = tt[2]
        fudge_offset = tt[3]

        sim_kwargs = sfinherit_kwargs.copy()
        sim_kwargs['sfr_prop']['gv'] = {'slope': gv_slope, 'fidmass': 10.5, 'offset': gv_offset}
        sim_kwargs['evol_prop']['fudge'] = {'slope': fudge_slope, 'fidmass': 10.5, 'offset': fudge_offset}
        sim_kwargs['evol_prop']['tau'] = {'name': fixtau}
        
        sim_output = SimSummary(observables=observables, **sim_kwargs)
        return sim_output

    theta_file = lambda pewl: ''.join([code_dir(), 
        'dat/pmc_abc/', 'CenQue_theta_t', str(pewl), '_', abcrun_flag, 
        '.fixedtau.', fixtau, '.dat']) 
    w_file = lambda pewl: ''.join([code_dir(), 
        'dat/pmc_abc/', 'CenQue_w_t', str(pewl), '_', abcrun_flag, 
        '.fixedtau.', fixtau, '.dat']) 
    dist_file = lambda pewl: ''.join([code_dir(), 
        'dat/pmc_abc/', 'CenQue_dist_t', str(pewl), '_', abcrun_flag, 
        '.fixedtau.', fixtau, '.dat']) 
    eps_file = ''.join([code_dir(), 
        'dat/pmc_abc/epsilon_', abcrun_flag, 
        '.fixedtau.', fixtau, '.dat']) 

    distfn = RhoFq
   
    if restart:
        if t_restart is None: 
            raise ValueError

        last_thetas = np.loadtxt(theta_file(t_restart))
        last_ws = np.loadtxt(w_file(t_restart))
        last_dist = np.loadtxt(dist_file(t_restart))

        init_pool = abcpmc.PoolSpec(t_restart, None, None, last_thetas, last_dist, last_ws)
    else: 
        init_pool = None 

    eps = abcpmc.ConstEps(T, eps_input)
    try:
        mpi_pool = mpi_util.MpiPool()
        abcpmc_sampler = abcpmc.Sampler(
                N=Npart,                # N_particles
                Y=data_sum,             # data
                postfn=Simz,            # simulator 
                dist=distfn,           # distance function  
                pool=mpi_pool)  
    except AttributeError: 
        abcpmc_sampler = abcpmc.Sampler(
                N=Npart,                # N_particles
                Y=data_sum,             # data
                postfn=Simz,            # simulator 
                dist=distfn)           # distance function  
    abcpmc_sampler.particle_proposal_cls = abcpmc.ParticleProposal

    pools = []
    if init_pool is None: 
        f = open(eps_file, "w")
        f.close()
    eps_str = ''
    for pool in abcpmc_sampler.sample(prior, eps, pool=init_pool):
        print '----------------------------------------'
        print 'eps ', pool.eps
        new_eps_str = str(pool.eps)+'\t'+str(pool.ratio)+'\n'
        if eps_str != new_eps_str:  # if eps is different, open fiel and append 
            f = open(eps_file, "a")
            eps_str = new_eps_str
            f.write(eps_str)
            f.close()

        print("T:{0},ratio: {1:>.4f}".format(pool.t, pool.ratio))
        print eps(pool.t)

        # write theta, weights, and distances to file 
        np.savetxt(theta_file(pool.t), pool.thetas, 
            header='gv_slope, gv_offset, fudge_slope, fudge_offset')
        np.savetxt(w_file(pool.t), pool.ws)
        np.savetxt(dist_file(pool.t), pool.dists)
    
        # update epsilon based on median thresholding 
        if len(observables) == 1: 
            eps.eps = np.median(pool.dists)
        else:
            #print pool.dists
            print np.median(np.atleast_2d(pool.dists), axis = 0)
            eps.eps = np.median(np.atleast_2d(pool.dists), axis = 0)
        print '----------------------------------------'
        pools.append(pool)

    return pools 
def PlotABC_InfallCondition(tf,
                            cen_tf=7,
                            cen_abcrun=None,
                            cen_prior_name=None):
    ''' 
    '''
    # Simulator
    cen_assigned_sat_file = ''.join([
        '/data1/hahn/pmc_abc/pickle/', 'satellite', '.cenassign', '.',
        cen_abcrun, '_ABC', '.', cen_prior_name, '_prior', '.p'
    ])
    if not os.path.isfile(cen_assigned_sat_file):
        sat_cen = AssignCenSFR(cen_tf,
                               abcrun=cen_abcrun,
                               prior_name=cen_prior_name)
        pickle.dump(sat_cen, open(cen_assigned_sat_file, 'wb'))
    else:
        sat_cen = pickle.load(open(cen_assigned_sat_file, 'rb'))

    abcrun_flag = cen_abcrun + '_central'
    theta_file = lambda pewl: ''.join([
        code_dir(), 'dat/pmc_abc/', 'Satellite.tQdelay.theta_t',
        str(pewl), '_', abcrun_flag, '.dat'
    ])

    theta = np.loadtxt(theta_file(tf))
    med_theta = [np.median(theta[:, i]) for i in range(len(theta[0]))]

    abc_tqdelay_dict = {'name': 'explin', 'm': med_theta[0], 'b': med_theta[1]}
    sg_obj = EvolveSatSFR(sat_cen, tqdelay_dict=abc_tqdelay_dict)

    #infall = np.where(
    #        (sg_obj.first_infall_mass > 0.) &
    #        (sg_obj.first_infall_sfr > -999.) & (sg_obj.first_infall_t >  5.7))
    infallmass0 = np.where(sg_obj.first_infall_mass == 0.)
    infallmassG0 = np.where(sg_obj.first_infall_mass > 0.)

    infall_nosfr = np.where(sg_obj.first_infall_sfr == -999.)
    infall_longago = np.where(sg_obj.first_infall_t < 5.7)

    print sg_obj.mass[infall_longago].min(), sg_obj.mass[infall_longago].max()
    print sg_obj.sfr[infall_longago].min(), sg_obj.sfr[infall_longago].max()
    print sg_obj.first_infall_sfr[infall_longago].min(
    ), sg_obj.first_infall_sfr[infall_longago].max()

    m_arr = np.arange(9.5, 11.6, 0.1)
    m_mid = 0.5 * (m_arr[:-1] + m_arr[1:])

    n_all, dum = np.histogram(sg_obj.mass, bins=m_arr)
    n_mass0, dum = np.histogram(sg_obj.mass[infallmass0], bins=m_arr)
    n_nosfr, dum = np.histogram(sg_obj.mass[infall_nosfr], bins=m_arr)
    n_longago, dum = np.histogram(sg_obj.mass[infall_longago], bins=m_arr)

    plt.plot(m_mid, n_mass0.astype('float') / n_all.astype('float'))
    plt.plot(m_mid, n_nosfr.astype('float') / n_all.astype('float'))
    plt.plot(m_mid, n_longago.astype('float') / n_all.astype('float'))
    plt.show()
    plt.close()

    ssfr_plot = PlotSSFR()
    ssfr_plot.plot(mass=sg_obj.mass[infallmassG0],
                   ssfr=sg_obj.ssfr[infallmassG0],
                   line_color=5)
    ssfr_plot.plot(mass=sg_obj.mass,
                   ssfr=sg_obj.ssfr,
                   line_color='k',
                   line_style='--')
    ssfr_plot.set_axes()

    plt.show()
    return None
def PlotABC_EvolvedSat(tf, cen_tf=7, cen_abcrun=None, cen_prior_name=None):
    ''' Plot stuff for the evolved satellite population 
    '''
    # Simulator
    cen_assigned_sat_file = ''.join([
        '/data1/hahn/pmc_abc/pickle/', 'satellite', '.cenassign', '.',
        cen_abcrun, '_ABC', '.', cen_prior_name, '_prior', '.p'
    ])
    if not os.path.isfile(cen_assigned_sat_file):
        sat_cen = AssignCenSFR(cen_tf,
                               abcrun=cen_abcrun,
                               prior_name=cen_prior_name)
        pickle.dump(sat_cen, open(cen_assigned_sat_file, 'wb'))
    else:
        sat_cen = pickle.load(open(cen_assigned_sat_file, 'rb'))

    abcrun_flag = cen_abcrun + '_central'
    theta_file = lambda pewl: ''.join([
        code_dir(), 'dat/pmc_abc/', 'Satellite.tQdelay.theta_t',
        str(pewl), '_', abcrun_flag, '.dat'
    ])

    theta = np.loadtxt(theta_file(tf))
    med_theta = [np.median(theta[:, i]) for i in range(len(theta[0]))]

    abc_tqdelay_dict = {'name': 'explin', 'm': med_theta[0], 'b': med_theta[1]}
    sg_obj = EvolveSatSFR(sat_cen, tqdelay_dict=abc_tqdelay_dict)

    #infall = np.arange(len(sg_obj.first_infall_mass))

    infall = np.where(
        (sg_obj.first_infall_mass > 0.) &
        (sg_obj.first_infall_sfr > -999.))  # & (sg_obj.first_infall_t >  5.7))
    print len(sg_obj.first_infall_mass)
    print len(infall[0])

    # SSFR plot
    ssfr_plot = PlotSSFR()
    ssfr_plot.plot(mass=sg_obj.mass[infall],
                   ssfr=sg_obj.ssfr[infall],
                   line_color=3)

    ssfr_plot.GroupCat(position='satellite')
    ssfr_plot.set_axes()

    ssfr_fig_name = ''.join([
        'figure/', 'SSFR.Satellite', '.tQdelayABC', '.', sg_obj.abcrun, '.',
        sg_obj.prior_name, '_prior', '.png'
    ])
    ssfr_plot.save_fig(ssfr_fig_name)
    plt.close()

    # Quiescent fraction plot
    fq_plot = PlotFq()
    fq_plot.plot(mass=sg_obj.mass[infall],
                 sfr=sg_obj.sfr[infall],
                 z=sg_obj.zsnap,
                 line_color='r',
                 sfms_prop=sg_obj.sfms_prop,
                 label='SHAM Sat. Simulation')
    grpcat = GroupCat(Mrcut=18, position='satellite')
    grpcat.Read()
    fq_plot.plot(mass=grpcat.mass,
                 sfr=grpcat.sfr,
                 z=np.median(grpcat.z),
                 line_color='k',
                 line_style='--',
                 sfms_prop=sg_obj.sfms_prop,
                 label='Satellite Group Catalog')
    fq_plot.set_axes()
    fq_fig_name = ''.join([
        'figure/', 'Fq.Satellite', '.tQdelayABC', '.', sg_obj.abcrun, '.',
        sg_obj.prior_name, '_prior', '.png'
    ])
    fq_plot.save_fig(fq_fig_name)
    plt.close()

    return None
def PlotABC_tQdelay(tf, cen_abcrun=None):
    '''
    '''
    abcrun_flag = cen_abcrun + '_central'
    theta_file = lambda pewl: ''.join([
        code_dir(), 'dat/pmc_abc/', 'Satellite.tQdelay.theta_t',
        str(pewl), '_', abcrun_flag, '.dat'
    ])

    theta = np.loadtxt(theta_file(tf))

    m_arr = np.arange(7.5, 12.0, 0.1)
    tdels = []
    for i in xrange(len(theta)):
        i_tqdelay_dict = {'name': 'explin', 'm': theta[i][0], 'b': theta[i][1]}
        tdels.append(tDelay(m_arr, **i_tqdelay_dict))

    tdels = np.array(tdels)
    a, b, c, d, e = np.percentile(tdels, [2.5, 16, 50, 84, 97.5], axis=0)

    prettyplot()
    pretty_colors = prettycolors()
    fig = plt.figure(figsize=(7, 7))
    sub = fig.add_subplot(111)

    mstar = np.array([
        1.56781e+11, 1.01089e+11, 6.27548e+10, 3.98107e+10, 2.49831e+10,
        1.57633e+10, 9.89223e+9, 6.37831e+9
    ])
    tqdel_high = np.array([
        1.36456e+0, 2.53148e+0, 3.06686e+0, 3.52693e+0, 3.62625e+0, 3.99574e+0,
        3.99915e+0, 3.99915e+0
    ])
    tqdel_low = np.array([
        8.15728e-1, 1.98257e+0, 2.29240e+0, 2.82772e+0, 2.99466e+0, 2.72548e+0,
        2.99016e+0, 2.68333e+0
    ])
    sub.fill_between(mstar,
                     tqdel_low,
                     tqdel_high,
                     color=pretty_colors[0],
                     edgecolor="none",
                     label='Roughly Wetzel+(2013)')

    #sub.plot(10**m_arr, tDelay(m_arr, **abc_tqdelay_dict), c=pretty_colors[3], label='ABC Best-fit')

    sub.fill_between(10**m_arr,
                     a,
                     e,
                     color=pretty_colors[3],
                     alpha=0.5,
                     edgecolor="none",
                     label='ABC Best-fit')
    sub.fill_between(10**m_arr,
                     b,
                     d,
                     color=pretty_colors[3],
                     alpha=1.,
                     edgecolor="none")
    sub.plot(10**m_arr, tDelay(m_arr, **{'name': 'hacked'}))

    sub.set_ylim([0.0, 4.0])
    sub.set_ylabel(r'$\mathtt{t_{Q, delay}}$', fontsize=25)
    sub.set_xlim([5 * 10**9, 2 * 10**11.])
    sub.set_xscale("log")
    sub.set_xlabel(r'$\mathtt{M}_*$', fontsize=25)
    sub.legend(loc='lower left')

    fig.savefig('figure/sallite_tqdelay_' + cen_abcrun + '.png',
                bbox_inches='tight')
    return None
    def Ssfr(self, subsample_thetas=False, filename=None ): 
        ''' Plot the SSFR distribution of the median paramater values of the 
        ABC particle pool.
        '''
        sfinherit_kwargs, abcrun_flag = ReadABCrun(self.abcrun)
        
        ssfr_plot = None
        if subsample_thetas: 
            N_theta = len(self.theta)
            i_subs = np.random.choice(N_theta, size=20)

            for i_sub in i_subs: 
                if not self.satellite_run: 
                    gv_slope, gv_offset, fudge_slope, fudge_offset, tau_slope, tau_offset = self.theta[i_sub]
                else: 
                    gv_slope, gv_offset, fudge_slope, fudge_offset = self.theta[i_sub]

                sim_kwargs = sfinherit_kwargs.copy()
                sim_kwargs['sfr_prop']['gv'] = {'slope': gv_slope, 'fidmass': 10.5, 'offset': gv_offset}
                sim_kwargs['evol_prop']['fudge'] = {'slope': fudge_slope, 'fidmass': 10.5, 'offset': fudge_offset}
                if not self.satellite_run: 
                    sim_kwargs['evol_prop']['tau'] = {'name': 'line', 'slope': tau_slope, 'fid_mass': 11.1, 'yint': tau_offset}
                else: 
                    sim_kwargs['evol_prop']['tau'] = {'name': 'satellite'}

                inh = Inherit([1], 
                        nsnap_ancestor=sim_kwargs['nsnap_ancestor'],
                        subhalo_prop=sim_kwargs['subhalo_prop'], 
                        sfr_prop=sim_kwargs['sfr_prop'], 
                        evol_prop=sim_kwargs['evol_prop'])
                des_dict = inh() 
                # descendant
                desc = des_dict['1'] 

                ssfr_plot = desc.plotSsfr(line_color='red', lw=2, alpha=0.25, ssfr_plot=ssfr_plot)

        # plot the median 'best-fit' theta
        gv_slope = self.med_theta[0]
        gv_offset = self.med_theta[1]
        fudge_slope = self.med_theta[2]
        fudge_offset = self.med_theta[3]
        if not self.satellite_run: 
            tau_slope = self.med_theta[4]
            tau_offset = self.med_theta[5]

        sim_kwargs = sfinherit_kwargs.copy()
        sim_kwargs['sfr_prop']['gv'] = {'slope': gv_slope, 'fidmass': 10.5, 'offset': gv_offset}
        sim_kwargs['evol_prop']['fudge'] = {'slope': fudge_slope, 'fidmass': 10.5, 'offset': fudge_offset}
        if not self.satellite_run: 
            sim_kwargs['evol_prop']['tau'] = {'name': 'line', 'slope': tau_slope, 'fid_mass': 11.1, 'yint': tau_offset}
        else: 
            sim_kwargs['evol_prop']['tau'] = {'name': 'satellite'}

        inh = Inherit([1], 
                nsnap_ancestor=sim_kwargs['nsnap_ancestor'],
                subhalo_prop=sim_kwargs['subhalo_prop'], 
                sfr_prop=sim_kwargs['sfr_prop'], 
                evol_prop=sim_kwargs['evol_prop'])
        des_dict = inh() 
        descendant = des_dict['1'] 
        self.descendant = descendant
    
        if filename is None: 
            fig_name = ''.join([code_dir(), 
                'figure/SSFR.abc_step', str(self.t), '_', self.abcrun, '.png']) 
        else: 
            fig_name = filename 

        descendant.plotSsfr(line_color='red', line_width=4, 
                sfms_prop=sim_kwargs['sfr_prop']['sfms'], z=descendant.zsnap, 
                groupcat=True, ssfr_plot=ssfr_plot, savefig=fig_name)
        plt.close()
        return None 
def InheritSF_file(nsnap_descendant,
                   nsnap_ancestor=20,
                   tau='abc',
                   abc_step=None,
                   subhalo_prop={
                       'scatter': 0.2,
                       'source': 'li-march'
                   },
                   sfr_prop={
                       'fq': {
                           'name': 'wetzelsmooth'
                       },
                       'sfr': {
                           'name': 'average'
                       }
                   },
                   evol_prop={
                       'sfr': {
                           'dutycycle': {
                               'name': 'notperiodic'
                           }
                       },
                       'mass': {
                           'name': 'sham'
                       }
                   },
                   flag=None):
    '''
    '''
    if not isinstance(nsnap_descendant, list):
        nsnap_descendant = [nsnap_descendant]
    tau_str = ''
    if abc_step is not None:
        tau_str = '.tau_ABC' + str(abc_step)
    else:
        tau_str = evol_prop['tau']['name']

    # SFMS string
    sfms_str = '.SFMS' + sfr_prop['sfms']['name'].lower()
    if sfr_prop['sfms']['name'] == 'linear':
        sfms_str += ''.join(['_z', str(round(sfr_prop['sfms']['zslope'], 2))])
    elif sfr_prop['sfms']['name'] == 'kinked':
        sfms_str += ''.join([
            '_Mlow',
            str(round(sfr_prop['sfms']['mslope_lowmass'], 2)), 'z',
            str(round(sfr_prop['sfms']['zslope'], 2))
        ])
    # SFR assigned based on subhalo growth
    if 'subhalogrowth' in sfr_prop.keys():
        sfms_str += '.halogrowth_SFRassign'
    # mass evolution string
    if evol_prop['mass']['name'] == 'sham':
        mass_str = '.Mevo_SHAM'
    elif evol_prop['mass']['name'] == 'integrated':
        if evol_prop['mass']['type'] == 'euler':
            mass_str = '.Mevo_EulerInt'
        elif evol_prop['mass']['type'] == 'rk4':
            mass_str = '.Mevo_RK4Int'
    flag_str = ''
    if flag is not None:
        flag_str = '.' + flag

    hdf5_file = ''.join([
        code_dir(), 'dat/InheritSF/'
        'InheritSF', '.Snap',
        ''.join([str(nsnap) for nsnap in nsnap_descendant]), '_',
        str(nsnap_ancestor), '.subhalo_sig',
        str(round(subhalo_prop['scatter'], 2)), '_', subhalo_prop['source'],
        '.fq_', sfr_prop['fq']['name'], sfms_str, '.', evol_prop['type'],
        '_evol', '.SF_Duty_', evol_prop['sfr']['dutycycle']['name'], mass_str,
        tau_str, flag_str, '.hdf5'
    ])
    return hdf5_file
def PlotABC_EvolvedSat(tf, cen_tf=7, cen_abcrun=None, cen_prior_name=None): 
    ''' Plot stuff for the evolved satellite population 
    '''
    # Simulator 
    cen_assigned_sat_file = ''.join(['/data1/hahn/pmc_abc/pickle/', 
        'satellite', '.cenassign', 
        '.', cen_abcrun, '_ABC', 
        '.', cen_prior_name, '_prior', '.p'])
    if not os.path.isfile(cen_assigned_sat_file): 
        sat_cen = AssignCenSFR(cen_tf, abcrun=cen_abcrun, prior_name=cen_prior_name)
        pickle.dump(sat_cen, open(cen_assigned_sat_file, 'wb'))
    else: 
        sat_cen = pickle.load(open(cen_assigned_sat_file, 'rb'))

    abcrun_flag = cen_abcrun + '_central'
    theta_file = lambda pewl: ''.join([code_dir(), 
        'dat/pmc_abc/', 'Satellite.tQdelay.theta_t', str(pewl), '_', abcrun_flag, '.dat']) 
   
    theta = np.loadtxt(theta_file(tf)) 
    med_theta = [np.median(theta[:,i]) for i in range(len(theta[0]))]

    abc_tqdelay_dict = {'name': 'explin', 'm': med_theta[0], 'b': med_theta[1]}
    sg_obj = EvolveSatSFR(sat_cen, tqdelay_dict=abc_tqdelay_dict)

    #infall = np.arange(len(sg_obj.first_infall_mass)) 

    infall = np.where(
            (sg_obj.first_infall_mass > 0.) &
            (sg_obj.first_infall_sfr > -999.))# & (sg_obj.first_infall_t >  5.7))
    print len(sg_obj.first_infall_mass)
    print len(infall[0]) 
    
    # SSFR plot
    ssfr_plot = PlotSSFR() 
    ssfr_plot.plot(mass=sg_obj.mass[infall], ssfr=sg_obj.ssfr[infall], line_color=3)

    ssfr_plot.GroupCat(position='satellite') 
    ssfr_plot.set_axes() 

    ssfr_fig_name = ''.join(['figure/', 
        'SSFR.Satellite', 
        '.tQdelayABC',
        '.', sg_obj.abcrun, '.', sg_obj.prior_name, '_prior', 
        '.png'])
    ssfr_plot.save_fig(ssfr_fig_name)
    plt.close()

    # Quiescent fraction plot  
    fq_plot = PlotFq()
    fq_plot.plot(mass=sg_obj.mass[infall], sfr=sg_obj.sfr[infall], z=sg_obj.zsnap, line_color='r',
            sfms_prop=sg_obj.sfms_prop, label='SHAM Sat. Simulation')
    grpcat = GroupCat(Mrcut=18, position='satellite')
    grpcat.Read()
    fq_plot.plot(mass=grpcat.mass, sfr=grpcat.sfr, z=np.median(grpcat.z), line_color='k', line_style='--',
            sfms_prop=sg_obj.sfms_prop, label='Satellite Group Catalog')
    fq_plot.set_axes()
    fq_fig_name = ''.join(['figure/', 
        'Fq.Satellite',
        '.tQdelayABC',
        '.', sg_obj.abcrun, '.', sg_obj.prior_name, '_prior', 
        '.png'])
    fq_plot.save_fig(fq_fig_name)
    plt.close() 

    return None 
def fgas_comparison():
    '''
    Compare f_gas (gas fraction) from different literature 
    '''
    m_arr = np.arange(9.0, 12.1, 0.1)  # mass array

    prettyplot()
    pretty_colors = prettycolors()
    fig = plt.figure(figsize=(15, 7))
    fig1 = plt.figure(figsize=(15, 7))
    fig2 = plt.figure(figsize=(15, 7))
    for iz, z in enumerate([0.1, 0.4, 0.8]):
        sub = fig.add_subplot(1, 3, iz + 1)
        sub1 = fig1.add_subplot(1, 3, iz + 1)
        sub2 = fig2.add_subplot(1, 3, iz + 1)
        # Stewart+2009
        f_stargas = 0.04 * ((10.**m_arr) / (4.5 * 10.**11.))**(-0.59 *
                                                               (1. + z)**0.45)
        f_gas_Stewart = 1. - 1. / (1. + f_stargas)

        # Santini+2014
        if z < 0.2:
            dat_file = util.code_dir().split(
                'CenQue')[0] + 'dat/santini_fgas_z0.1.dat'
        elif (z >= 0.2) & (z < 0.6):
            dat_file = util.code_dir().split(
                'CenQue')[0] + 'dat/santini_fgas_z0.4.dat'
        elif (z >= 0.6) & (z < 1.):
            dat_file = util.code_dir().split(
                'CenQue')[0] + 'dat/santini_fgas_z0.8.dat'
        else:
            raise ValueError
        m_dat, fgas_dat = np.loadtxt(dat_file,
                                     delimiter=',',
                                     unpack=True,
                                     usecols=[0, 1])
        f_gas_Santini = fgas_dat

        # Boselli+2014
        f_gas_Boselli = 1. - 1. / (1. + 10**(-0.69 * m_arr + 6.63))

        M_gas_Stewart = np.log10(1. / (1. / f_gas_Stewart - 1.) * 10**m_arr)
        M_gas_Santini = np.log10(1. / (1. / f_gas_Santini - 1.) * 10**m_dat)
        M_gas_Boselli = np.log10(1. / (1. / f_gas_Boselli - 1.) * 10**m_arr)

        t_gas_stewart = 10**M_gas_Stewart / 10**AverageLogSFR_sfms(
            m_arr, z, sfms_prop={
                'name': 'linear',
                'zslope': 1.14
            }) / 10**9
        t_gas_santini = 10**M_gas_Santini / 10**AverageLogSFR_sfms(
            m_dat, z, sfms_prop={
                'name': 'linear',
                'zslope': 1.14
            }) / 10**9
        t_gas_boselli = 10**M_gas_Boselli / 10**AverageLogSFR_sfms(
            m_arr, z, sfms_prop={
                'name': 'linear',
                'zslope': 1.14
            }) / 10**9

        sub.plot(m_arr,
                 f_gas_Stewart,
                 lw=3,
                 c=pretty_colors[1],
                 label='Stewart+2009')
        sub.plot(m_dat,
                 f_gas_Santini,
                 lw=3,
                 c=pretty_colors[3],
                 label='Santini+2014')
        if z < 0.2:
            sub.plot(m_arr,
                     f_gas_Boselli,
                     lw=3,
                     c=pretty_colors[5],
                     label='Boselli+2014')
        sub.text(10.0, 0.05, r"$\mathtt{z = " + str(z) + "}$", fontsize=25)
        sub.set_xlim([9.7, 11.5])
        if iz == 1:
            sub.set_xlabel(r'Stellar Mass', fontsize=25)
        sub.set_ylim([0., 0.5])
        if iz == 0:
            sub.set_ylabel(
                r'$\mathtt{f_{gas}} = \mathtt{M_{gas}/(M_{gas} + M_{star})}$',
                fontsize=25)
            sub.legend(loc='upper right')
        else:
            sub.set_yticklabels([])

        sub1.plot(m_arr,
                  M_gas_Stewart,
                  lw=3,
                  c=pretty_colors[1],
                  label='Stewart+2009')
        sub1.plot(m_dat,
                  M_gas_Santini,
                  lw=3,
                  c=pretty_colors[3],
                  label='Santini+2014')
        if z < 0.2:
            sub1.plot(m_arr,
                      M_gas_Boselli,
                      lw=3,
                      c=pretty_colors[5],
                      label='Boselli+2014')

        sub1.text(10.0, 9.25, r"$\mathtt{z = " + str(z) + "}$", fontsize=25)
        sub1.set_xlim([9.7, 11.5])
        if iz == 1:
            sub1.set_xlabel(r'Stellar Mass', fontsize=25)
        sub1.set_ylim([9., 10.5])
        if iz == 0:
            sub1.set_ylabel(r'$\mathtt{M_{gas}}$', fontsize=25)
            sub1.legend(loc='upper right')
        else:
            sub1.set_yticklabels([])

        sub2.plot(m_arr,
                  t_gas_stewart,
                  lw=3,
                  c=pretty_colors[1],
                  label='Stewart+2009')
        sub2.plot(m_dat,
                  t_gas_santini,
                  lw=3,
                  c=pretty_colors[3],
                  label='Santini+2014')
        if z < 0.2:
            sub2.plot(m_arr,
                      t_gas_boselli,
                      lw=3,
                      c=pretty_colors[5],
                      label='Boselli+2014, z=0')

        sub2.text(10.0, 0.05, r"$\mathtt{z = " + str(z) + "}$", fontsize=25)
        sub2.set_xlim([9.7, 11.5])
        if iz == 1:
            sub2.set_xlabel(r'Stellar Mass', fontsize=25)
        sub2.set_ylim([0., 10.])
        if iz == 0:
            sub2.set_ylabel(r'$\mathtt{M_{gas}(z)/SFR^{SFMS}(z)}$ [Gyr]',
                            fontsize=25)
            sub2.legend(loc='upper right')
        else:
            sub2.set_yticklabels([])

    fig.subplots_adjust(wspace=0.0, hspace=0.0)
    fig_file = ''.join(['figure/', 'f_gas_comparison', '.png'])
    fig.savefig(fig_file, bbox_inches='tight', dpi=150)
    plt.close()

    fig1.subplots_adjust(wspace=0.0, hspace=0.0)
    fig_file = ''.join(['figure/', 'M_gas_comparison', '.png'])
    fig1.savefig(fig_file, bbox_inches='tight', dpi=150)
    plt.close()

    fig2.subplots_adjust(wspace=0.0, hspace=0.0)
    fig_file = ''.join(['figure/', 't_gas_comparison', '.png'])
    fig2.savefig(fig_file, bbox_inches='tight', dpi=150)
    plt.close()
    return None
def fgas_comparison(): 
    '''
    Compare f_gas (gas fraction) from different literature 
    '''
    m_arr = np.arange(9.0, 12.1, 0.1)   # mass array 

    prettyplot()
    pretty_colors = prettycolors() 
    fig = plt.figure(figsize=(15,7)) 
    fig1 = plt.figure(figsize=(15,7)) 
    fig2 = plt.figure(figsize=(15,7)) 
    for iz, z in enumerate([0.1, 0.4, 0.8]): 
        sub = fig.add_subplot(1, 3, iz+1)
        sub1 = fig1.add_subplot(1, 3, iz+1)
        sub2 = fig2.add_subplot(1, 3, iz+1)
        # Stewart+2009
        f_stargas = 0.04 * ((10.**m_arr)/(4.5*10.**11.))**(-0.59 * (1. + z)**0.45)
        f_gas_Stewart = 1. - 1./(1. + f_stargas)

        # Santini+2014
        if z < 0.2: 
            dat_file = util.code_dir().split('CenQue')[0]+'dat/santini_fgas_z0.1.dat'
        elif (z >= 0.2) & (z < 0.6): 
            dat_file = util.code_dir().split('CenQue')[0]+'dat/santini_fgas_z0.4.dat'
        elif (z >= 0.6) & (z < 1.): 
            dat_file = util.code_dir().split('CenQue')[0]+'dat/santini_fgas_z0.8.dat'
        else: 
            raise ValueError
        m_dat, fgas_dat = np.loadtxt(dat_file, delimiter=',', unpack=True, usecols=[0,1]) 
        f_gas_Santini = fgas_dat 
        
        # Boselli+2014
        f_gas_Boselli = 1. - 1./(1. + 10**(-0.69 * m_arr + 6.63))
        
        M_gas_Stewart = np.log10(1./(1./f_gas_Stewart-1.) * 10**m_arr)
        M_gas_Santini = np.log10(1./(1./f_gas_Santini-1.) * 10**m_dat)
        M_gas_Boselli = np.log10(1./(1./f_gas_Boselli-1.) * 10**m_arr)
    
        t_gas_stewart = 10**M_gas_Stewart / 10**AverageLogSFR_sfms(m_arr, z, sfms_prop={'name': 'linear', 'zslope':1.14})/10**9
        t_gas_santini = 10**M_gas_Santini / 10**AverageLogSFR_sfms(m_dat, z, sfms_prop={'name': 'linear', 'zslope':1.14})/10**9
        t_gas_boselli = 10**M_gas_Boselli / 10**AverageLogSFR_sfms(m_arr, z, sfms_prop={'name': 'linear', 'zslope':1.14})/10**9


        sub.plot(m_arr, f_gas_Stewart, lw=3, c=pretty_colors[1], label='Stewart+2009') 
        sub.plot(m_dat, f_gas_Santini, lw=3, c=pretty_colors[3], label='Santini+2014') 
        if z < 0.2: 
            sub.plot(m_arr, f_gas_Boselli, lw=3, c=pretty_colors[5], label='Boselli+2014') 
        sub.text(10.0, 0.05, r"$\mathtt{z = "+str(z)+"}$", fontsize=25) 
        sub.set_xlim([9.7, 11.5]) 
        if iz == 1: 
            sub.set_xlabel(r'Stellar Mass', fontsize=25) 
        sub.set_ylim([0., 0.5]) 
        if iz == 0: 
            sub.set_ylabel(r'$\mathtt{f_{gas}} = \mathtt{M_{gas}/(M_{gas} + M_{star})}$', fontsize=25) 
            sub.legend(loc='upper right') 
        else: 
            sub.set_yticklabels([]) 


        sub1.plot(m_arr, M_gas_Stewart, lw=3, c=pretty_colors[1], label='Stewart+2009') 
        sub1.plot(m_dat, M_gas_Santini, lw=3, c=pretty_colors[3], label='Santini+2014') 
        if z < 0.2: 
            sub1.plot(m_arr, M_gas_Boselli, lw=3, c=pretty_colors[5], label='Boselli+2014') 
    
        sub1.text(10.0, 9.25, r"$\mathtt{z = "+str(z)+"}$", fontsize=25) 
        sub1.set_xlim([9.7, 11.5]) 
        if iz == 1: 
            sub1.set_xlabel(r'Stellar Mass', fontsize=25) 
        sub1.set_ylim([9., 10.5]) 
        if iz == 0: 
            sub1.set_ylabel(r'$\mathtt{M_{gas}}$', fontsize=25) 
            sub1.legend(loc='upper right') 
        else: 
            sub1.set_yticklabels([]) 


        sub2.plot(m_arr, t_gas_stewart, lw=3, c=pretty_colors[1], label='Stewart+2009') 
        sub2.plot(m_dat, t_gas_santini, lw=3, c=pretty_colors[3], label='Santini+2014') 
        if z < 0.2: 
            sub2.plot(m_arr, t_gas_boselli, lw=3, c=pretty_colors[5], label='Boselli+2014, z=0') 
        
        sub2.text(10.0, 0.05, r"$\mathtt{z = "+str(z)+"}$", fontsize=25) 
        sub2.set_xlim([9.7, 11.5]) 
        if iz == 1: 
            sub2.set_xlabel(r'Stellar Mass', fontsize=25) 
        sub2.set_ylim([0., 10.]) 
        if iz == 0: 
            sub2.set_ylabel(r'$\mathtt{M_{gas}(z)/SFR^{SFMS}(z)}$ [Gyr]', fontsize=25) 
            sub2.legend(loc='upper right') 
        else: 
            sub2.set_yticklabels([]) 

    fig.subplots_adjust(wspace=0.0, hspace=0.0)
    fig_file = ''.join(['figure/',
        'f_gas_comparison',
        '.png'])
    fig.savefig(fig_file, bbox_inches='tight', dpi=150)
    plt.close()

    fig1.subplots_adjust(wspace=0.0, hspace=0.0)
    fig_file = ''.join(['figure/',
        'M_gas_comparison',
        '.png'])
    fig1.savefig(fig_file, bbox_inches='tight', dpi=150)
    plt.close()

    fig2.subplots_adjust(wspace=0.0, hspace=0.0)
    fig_file = ''.join(['figure/',
        't_gas_comparison',
        '.png'])
    fig2.savefig(fig_file, bbox_inches='tight', dpi=150)
    plt.close()
    return None
def ABC(T, eps_input, Npart=1000, cen_tf=None, cen_prior_name=None, cen_abcrun=None):
    ''' ABC-PMC implementation. 

    Parameters
    ----------
    T : (int) 
        Number of iterations

    eps_input : (float)
        Starting epsilon threshold value 

    N_part : (int)
        Number of particles

    prior_name : (string)
        String that specifies what prior to use.

    abcrun : (string)
        String that specifies abc run information 
    '''
    abcinh = ABCInherit(cen_tf, abcrun=cen_abcrun, prior_name=cen_prior_name) 

    # Data (Group Catalog Satellite fQ)
    grpcat = GroupCat(Mrcut=18, position='satellite')
    grpcat.Read()
    qfrac = Fq() 
    m_bin = np.array([9.7, 10.1, 10.5, 10.9, 11.3])
    M_mid = 0.5 * (m_bin[:-1] + m_bin[1:]) 

    sfq = qfrac.Classify(grpcat.mass, grpcat.sfr, np.median(grpcat.z), 
            sfms_prop=abcinh.sim_kwargs['sfr_prop']['sfms'])
    ngal, dum = np.histogram(grpcat.mass, bins=m_bin)
    ngal_q, dum = np.histogram(grpcat.mass[sfq == 'quiescent'], bins=m_bin)
    data_sum = [M_mid, ngal_q.astype('float')/ngal.astype('float')]
    
    # Simulator 
    cen_assigned_sat_file = ''.join(['/data1/hahn/pmc_abc/pickle/', 
        'satellite', '.cenassign', '.', cen_abcrun, '_ABC', '.', cen_prior_name, '_prior', '.p'])
    
    if not os.path.isfile(cen_assigned_sat_file): 
        sat_cen = AssignCenSFR(cen_tf, abcrun=cen_abcrun, prior_name=cen_prior_name)
        pickle.dump(sat_cen, open(cen_assigned_sat_file, 'wb'))
    else: 
        sat_cen = pickle.load(open(cen_assigned_sat_file, 'rb'))

    def Simz(tt):       # Simulator (forward model) 
        tqdel_dict = {'name': 'explin', 'm': tt[0] , 'b': tt[1]}

        sat_evol = EvolveSatSFR(sat_cen, tqdelay_dict=tqdel_dict)

        sfq_sim = qfrac.Classify(sat_evol.mass, sat_evol.sfr, sat_evol.zsnap, 
                sfms_prop=sat_evol.sfms_prop)
        ngal_sim, dum = np.histogram(sat_evol.mass, bins=m_bin)
        ngal_q_sim, dum = np.histogram(sat_evol.mass[sfq_sim == 'quiescent'], bins=m_bin)
        sim_sum = [M_mid, ngal_q_sim.astype('float')/ngal_sim.astype('float')]
        return sim_sum

    # Priors
    prior_min = [-11.75, 2.]
    prior_max = [-10.25, 4.]
    prior = abcpmc.TophatPrior(prior_min, prior_max)    # ABCPMC prior object

    def rho(simum, datum):  
        datum_dist = datum[1]
        simum_dist = simum[1]
        drho = np.sum((datum_dist - simum_dist)**2)
        return drho
    
    abcrun_flag = cen_abcrun + '_central'

    theta_file = lambda pewl: ''.join([code_dir(), 
        'dat/pmc_abc/', 'Satellite.tQdelay.theta_t', str(pewl), '_', abcrun_flag, '.dat']) 
    w_file = lambda pewl: ''.join([code_dir(), 
        'dat/pmc_abc/', 'Satellite.tQdelay.w_t', str(pewl), '_', abcrun_flag, '.dat']) 
    dist_file = lambda pewl: ''.join([code_dir(), 
        'dat/pmc_abc/', 'Satellite.tQdelay.dist_t', str(pewl), '_', abcrun_flag, '.dat']) 
    eps_file = ''.join([code_dir(), 
        'dat/pmc_abc/Satellite.tQdelay.epsilon_', abcrun_flag, '.dat'])
   
    eps = abcpmc.ConstEps(T, eps_input)
    try:
        mpi_pool = mpi_util.MpiPool()
        abcpmc_sampler = abcpmc.Sampler(
                N=Npart,                # N_particles
                Y=data_sum,             # data
                postfn=Simz,            # simulator 
                dist=rho,           # distance function  
                pool=mpi_pool)  
    except AttributeError: 
        abcpmc_sampler = abcpmc.Sampler(
                N=Npart,                # N_particles
                Y=data_sum,             # data
                postfn=Simz,            # simulator 
                dist=rho)           # distance function  
    abcpmc_sampler.particle_proposal_cls = abcpmc.ParticleProposal

    pools = []
    f = open(eps_file, "w")
    f.close()
    eps_str = ''
    for pool in abcpmc_sampler.sample(prior, eps, pool=None):
        print '----------------------------------------'
        print 'eps ', pool.eps
        new_eps_str = '\t'+str(pool.eps)+'\n'
        if eps_str != new_eps_str:  # if eps is different, open fiel and append 
            f = open(eps_file, "a")
            eps_str = new_eps_str
            f.write(eps_str)
            f.close()

        print("T:{0},ratio: {1:>.4f}".format(pool.t, pool.ratio))
        print eps(pool.t)

        # write theta, weights, and distances to file 
        np.savetxt(theta_file(pool.t), pool.thetas, 
            header='tQdelay_slope, tQdelay_offset')
        np.savetxt(w_file(pool.t), pool.ws)
        np.savetxt(dist_file(pool.t), pool.dists)
    
        # update epsilon based on median thresholding 
        eps.eps = np.median(pool.dists)
        pools.append(pool)

    return pools 
def MakeABCrun(abcrun=None, nsnap_start=15, subhalo=None, fq=None, sfms=None, dutycycle=None, mass_evol=None, 
        Niter=None, Npart=None, prior_name=None, eps_val=None, restart=False): 
    '''Pickle file that specifies all the choices of parameters and ABC settings 
    for record keeping purposes.
    '''
    if abcrun is None: 
        abcrun = ''.join(['RENAME_ME_', str(datetime.today().date())])
    restart_str = ''
    if restart: 
        restart_str = '.restart'
    file_name = ''.join([code_dir(), 'dat/pmc_abc/run/', 'abcrun_', abcrun, restart_str, '.txt']) 
    pickle_name = file_name.replace('.txt', '.p')

    f = open(file_name, 'w')

    # ABC properities
    f.write('# ABC Run Properties \n') 
    f.write('N_iter = '+str(Niter)+'\n')
    f.write('N_particles = '+str(Npart)+'\n')
    f.write('Prior Name = '+prior_name+'\n')
    f.write('Epsilon_0 = '+str(eps_val)+'\n')
    if restart: 
        f.write('Restarting')
    f.write('\n')

    # Subhalo properties
    f.write('# Subhalo Properties \n') 
    if subhalo is None:    
        subhalo = {'scatter': 0.2, 'source': 'li-march'}
    f.write(''.join(['scatter = ', str(subhalo['scatter']), '\n']))
    f.write(''.join(['source = ', subhalo['source'], '\n']))
    f.write('\n')
    
    # Quiescent fraction properties
    f.write('# Quiescent Fraction Properties \n') 
    if fq is None:          # quiescent fraction
        fq = {'name': 'wetzel'}
    f.write(''.join(['name = ', fq['name'], '\n']))
    f.write('\n')

    # Starforming Main Sequence
    f.write('# Starforming Main Sequence Properties \n') 
    if sfms is None:   # SFMS  
        sfms = {'name': 'linear', 'zslope': 1.14}
    f.write(''.join(['name = ', sfms['name'], '\n']))
    f.write(''.join(['zslope = ', str(sfms['zslope']), '\n']))
    f.write('\n')
    
    # SF dutycycle properties
    f.write('# SF Dutycycle Properties \n') 
    if dutycycle is None:   
        dutycycle = {'name': 'newamp_squarewave', 'freq_range': [2.*np.pi, 20.*np.pi], 'sigma': 0.3}
    f.write(''.join(['name = ', dutycycle['name'], '\n']))
    f.write(''.join(['frequency range = ', str(dutycycle['freq_range'][0]), ',', str(dutycycle['freq_range'][1]), '\n']))
    f.write(''.join(['sigma = ', str(dutycycle['sigma']), '\n']))
    f.write('\n')
    
    # Mass Evolution properties
    f.write('# Mass Evolution Properties \n') 
    if mass_evol is None:
        mass_evol = {'name': 'sham'} 
    if mass_evol['name'] == 'sham': 
        f.write(''.join(['name = ', mass_evol['name'], '\n']))
    f.close()

    evol_dict = { 
            'type': 'simult',
            'sfr': {'dutycycle': dutycycle},
            'mass': mass_evol
            }
    kwargs = {
            'nsnap_ancestor': nsnap_start, 
            'subhalo_prop': subhalo, 
            'sfr_prop': {'fq': fq, 'sfms': sfms},
            'evol_prop': evol_dict
            }

    pickle.dump(kwargs, open(pickle_name, 'wb'))
    return kwargs, abcrun