Пример #1
0
def inject_and_save(rfi, tfrecordwriter, sim_number, descriptor):
    """
    inject pulsars/frbs into rfi event then save with tfrecordwriter
    """
    rfi_type = rfi.rfi_type if descriptor is None else rfi.rfi_type + descriptor

    example = convert_to_example(rfi, sim_number)
    tfrecordwriter.write(example.SerializeToString())
    sim_number += 1
    global rfi_sims
    rfi_sims += 1

    try: # ensure DM and duration are compatabile
        psr = Pulsar(background=rfi.sample, rate=rfi.rate, rfi_type=rfi_type)
        if psr.snr > 0: # dont save sim with snr == 0
            example = convert_to_example(psr, sim_number)
            tfrecordwriter.write(example.SerializeToString())
            sim_number += 1
            global psr_sims
            psr_sims += 1
        else:
            print("Pulsar creation failed due to signal-to-noise ratio")
    except ValueError as E:
        print("Pulsar creation failed due to DM duration mismatch")

    frb = FRB(background=rfi.sample, rate=rfi.rate, rfi_type=rfi_type)
    if frb.snr > 0: # dont save sim with snr == 0
        example = convert_to_example(frb, sim_number)
        tfrecordwriter.write(example.SerializeToString())
        sim_number += 1
        global frb_sims
        frb_sims += 1
    else:
        print("Pulsar creation failed due to signal-to-noise-ratio")
    return sim_number
Пример #2
0
if __name__ == '__main__':

    # Importing files.

    datadir = '../ppta/fit1data'
    parfiles = sorted(glob.glob(datadir + '/*.par'))
    timfiles = sorted(glob.glob(datadir + '/*.tim'))
    parfiles.remove(datadir + '/J1125-6014.par')
    timfiles.remove(datadir + '/J1125-6014.tim')

    # I throw away this certain pulsar because it may return a unstable, sometimes
    # very large ln-likelihood value. I think there is a bug somewhere.

    psrs = []
    for p, t in zip(parfiles, timfiles):
        psr = Pulsar(p, t)
        psrs.append(psr)

    save1 = np.load('noisepars.npy')
    save2 = np.load('noisepardict.npy')
    save3 = np.load('dpdmpars-maxposprob.npy')
    save4 = np.load('dpdmpardict.npy')
    Dict = {save2[i]: save1[i] for i in range(len(save2))}
    Dict.update({save4[i]: save3[i] for i in range(len(save4))})

    # The Big Model
    # dm noise
    log10_A_dm = parameter.Constant()
    gamma_dm = parameter.Constant()
    pl_dm = utils.powerlaw(log10_A=log10_A_dm, gamma=gamma_dm)
    dm_basis = utils.createfourierdesignmatrix_dm(nmodes=50, Tspan=None)
Пример #3
0
def generate(ngen,
             surveyList=None,
             pDistType='lnorm',
             radialDistType='lfl06',
             radialDistPars=7.5,
             electronModel='ne2001',
             pDistPars=[2.7, -0.34],
             siDistPars=[-1.6, 0.35],
             lumDistType='lnorm',
             lumDistPars=[-1.1, 0.9],
             zscaleType='exp',
             zscale=0.33,
             duty_percent=6.,
             scindex=-3.86,
             gpsArgs=[None, None],
             doubleSpec=[None, None],
             nostdout=False,
             pattern='gaussian',
             orbits=False):

    """
    Generate a population of pulsars.

    Keyword args:
    ngen -- the number of pulsars to generate (or detect)
    surveyList -- a list of surveys you want to use to try and detect
        the pulsars
    pDistType -- the pulsar period distribution model to use (def=lnorm)
    radialDistType -- radial distribution model
    electronModel -- mode to use for Galactic electron distribution
    pDistPars -- parameters to use for period distribution
    siDistPars -- parameters to use for spectral index distribution
    lumDistPars -- parameters to use for luminosity distribution
    radialDistPars -- parameters for radial distribution
    zscale -- if using exponential z height, set it here (in kpc)
    scindex -- spectral index of the scattering model
    gpsArgs -- add GPS-type spectrum sources
    doubleSpec -- add double-spectrum type sources
    nostdout -- (bool) switch off stdout
    """

    pop = Population()

    # check that the distribution types are supported....
    if lumDistType not in ['lnorm', 'pow']:
        print "Unsupported luminosity distribution: {0}".format(lumDistType)

    if pDistType not in ['lnorm', 'norm', 'cc97', 'lorimer12']:
        print "Unsupported period distribution: {0}".format(pDistType)

    if radialDistType not in ['lfl06', 'yk04', 'isotropic',
                              'slab', 'disk', 'gauss']:
        print "Unsupported radial distribution: {0}".format(radialDistType)

    if electronModel not in ['ne2001', 'lmt85']:
        print "Unsupported electron model: {0}".format(electronModel)

    if pattern not in ['gaussian', 'airy']:
        print "Unsupported gain pattern: {0}".format(pattern)

    if duty_percent < 0.:
        print "Unsupported value of duty cycle: {0}".format(duty_percent)

    # need to use properties in this class so they're get/set-type props
    pop.pDistType = pDistType
    pop.radialDistType = radialDistType
    pop.electronModel = electronModel
    pop.lumDistType = lumDistType

    pop.rsigma = radialDistPars
    pop.pmean, pop.psigma = pDistPars
    pop.simean, pop.sisigma = siDistPars

    pop.gpsFrac, pop.gpsA = gpsArgs
    pop.brokenFrac, pop.brokenSI = doubleSpec

    if pop.lumDistType == 'lnorm':
        pop.lummean, pop.lumsigma = \
                lumDistPars[0], lumDistPars[1]
    else:
        try:
            pop.lummin, pop.lummax, pop.lumpow = \
                lumDistPars[0], lumDistPars[1], lumDistPars[2]
        except ValueError:
            raise PopulateException('Not enough lum distn parameters')

    pop.zscaleType = zscaleType
    pop.zscale = zscale

    # store the dict of arguments inside the model. Could be useful.
    try:
        argspec = inspect.getargspec(generate)
        key_values = [(arg, locals()[arg]) for arg in argspec.args]
        pop.arguments = {key: value for (key, value) in key_values}
    except SyntaxError:
        pass

    if not nostdout:
        print "\tGenerating pulsars with parameters:"
        param_string_list = []
        for key, value in key_values:
            s = ": ".join([key, str(value)])
            param_string_list.append(s)

        # join this list of strings, and print it
        s = "\n\t\t".join(param_string_list)
        print "\t\t{0}".format(s)

        # set up progress bar for fun :)
        prog = ProgressBar(min_value=0,
                           max_value=ngen,
                           width=65,
                           mode='dynamic')

    # create survey objects here and put them in a list
    if surveyList is not None:
        surveys = [Survey(s, pattern) for s in surveyList]
        # initialise these counters to zero
        for surv in surveys:
            surv.ndet = 0  # number detected
            surv.nout = 0  # number outside survey region
            surv.nsmear = 0  # number smeared out
            surv.ntf = 0  # number too faint

            # surv.gainpat=pattern
    else:
        # make an empty list here - makes some code just a little
        # simpler - can still loop over an empty list (ie zero times)
        surveys = []

    while pop.ndet < ngen:
        # Declare new pulsar object
        p = Pulsar()

        # period, alpha, rho, width distribution calls
        # Start creating the pulsar!
        if pop.pDistType == 'lnorm':
            p.period = dists.drawlnorm(pop.pmean, pop.psigma)
        elif pop.pDistType == 'norm':
            p.period = random.gauss(pop.pmean, pop.psigma)
        elif pop.pDistType == 'cc97':
            p.period = _cc97()
        elif pop.pDistType == 'gamma':
            print "Gamma function not yet supported"
            sys.exit()
        elif pop.pDistType == 'lorimer12':
            p.period = _lorimer2012_msp_periods()

        if duty_percent > 0.:
            # use a simple duty cycle for each pulsar
            # with a log-normal scatter
            width = (float(duty_percent)/100.) * p.period**0.9
            width = math.log10(width)
            width = dists.drawlnorm(width, 0.3)

            p.width_degree = width*360./p.period
        else:
            # use the model to caculate if beaming
            p.alpha = _genAlpha()

            p.rho, p.width_degree = _genRhoWidth(p)

            if p.width_degree == 0.0 and p.rho == 0.0:
                continue
            # is pulsar beaming at us? If not, move on!
            p.beaming = _beaming(p)
            if not p.beaming:
                continue

        # Spectral index stuff here

        # suppose it might be nice to be able to have GPS sources
        # AND double spectra. But for now I assume only have one or
        # none of these types.
        if random.random() > pop.gpsFrac:
            # This will evaluate true when gpsArgs[0] is NoneType
            # might have to change in future
            p.gpsFlag = 0
        else:
            p.gpsFlag = 1
            p.gpsA = pop.gpsA

        if random.random() > pop.brokenFrac:
            p.brokenFlag = 0
        else:
            p.brokenFlag = 1
            p.brokenSI = pop.brokenSI

        p.spindex = random.gauss(pop.simean, pop.sisigma)

        # get galactic position
        # first, Galactic distribution models
        if pop.radialDistType == 'isotropic':
            # calculate gl and gb randomly
            p.gb = math.degrees(math.asin(random.random()))
            if random.random() < 0.5:
                p.gb = 0.0 - p.gb
            p.gl = random.random() * 360.0

            # use gl and gb to compute galactic coordinates
            # pretend the pulsar is at distance of 1kpc
            # not sure why, ask Dunc!
            p.galCoords = go.lb_to_xyz(p.gl, p.gb, 1.0)

        elif pop.radialDistType == 'slab':
            p.galCoords = go.slabDist()
            p.gl, p.gb = go.xyz_to_lb(p.galCoords)

        elif pop.radialDistType == 'disk':
            p.galCoords = go.diskDist()
            p.gl, p.gb = go.xyz_to_lb(p.galCoords)

        else:  # we want to use exponential z and a radial dist
            if pop.radialDistType == 'lfl06':
                p.r0 = go.lfl06()
            elif pop.radialDistType == 'yk04':
                p.r0 = go.ykr()
            elif pop.radialDistType == 'gauss':
                # guassian of mean 0
                # and stdDev given by parameter (kpc)
                p.r0 = random.gauss(0., pop.rsigma)

            # then calc xyz,distance, l and b
            if pop.zscaleType == 'exp':
                zheight = go._double_sided_exp(zscale)
            else:
                zheight = random.gauss(0., zscale)
            gx, gy = go.calcXY(p.r0)
            p.galCoords = gx, gy, zheight
            p.gl, p.gb = go.xyz_to_lb(p.galCoords)

        p.dtrue = go.calc_dtrue(p.galCoords)

        # then calc DM  using fortran libs
        if pop.electronModel == 'ne2001':
            p.dm = go.ne2001_dist_to_dm(p.dtrue, p.gl, p.gb)
        elif pop.electronModel == 'lmt85':
            p.dm = go.lmt85_dist_to_dm(p.dtrue, p.gl, p.gb)

        p.scindex = scindex
        # then calc scatter time
        p.t_scatter = go.scatter_bhat(p.dm, p.scindex)

        if pop.lumDistType == 'lnorm':
            p.lum_1400 = dists.drawlnorm(pop.lummean,
                                         pop.lumsigma)
        else:
            p.lum_1400 = dists.powerlaw(pop.lummin,
                                        pop.lummax,
                                        pop.lumpow)

        # add in orbital parameters
        if orbits:
            orbitalparams.test_1802_2124(p)
            print p.gb, p.gl

        # if no surveys, just generate ngen pulsars
        if surveyList is None:
            pop.population.append(p)
            pop.ndet += 1
            if not nostdout:
                prog.increment_amount()
                print prog, '\r',
                sys.stdout.flush()
        # if surveys are given, check if pulsar detected or not
        # in ANY of the surveys
        else:
            # just a flag to increment if pulsar is detected
            detect_int = 0
            for surv in surveys:
                # do SNR calculation
                SNR = surv.SNRcalc(p, pop)

                if SNR > surv.SNRlimit:
                    # SNR is over threshold

                    # increment the flag
                    # and survey ndetected
                    detect_int += 1
                    surv.ndet += 1
                    continue

                elif SNR == -1:
                    # pulse is smeared out
                    surv.nsmear += 1
                    continue

                elif SNR == -2:
                    # pulsar is outside survey region
                    surv.nout += 1
                    continue

                else:
                    # pulsar is just too faint
                    surv.ntf += 1
                    continue

            # add the pulsar to the population
            pop.population.append(p)

            # if detected, increment ndet (for whole population)
            # and redraw the progress bar
            if detect_int:
                pop.ndet += 1
                if not nostdout:
                    prog.increment_amount()
                    print prog, '\r',
                    sys.stdout.flush()

    # print info to stdout
    if not nostdout:
        print "\n"
        print "  Total pulsars = {0}".format(len(pop.population))
        print "  Total detected = {0}".format(pop.ndet)
        # print "  Number not beaming = {0}".format(surv.nnb)

        for surv in surveys:
            print "\n  Results for survey '{0}'".format(surv.surveyName)
            print "    Number detected = {0}".format(surv.ndet)
            print "    Number too faint = {0}".format(surv.ntf)
            print "    Number smeared = {0}".format(surv.nsmear)
            print "    Number outside survey area = {0}".format(surv.nout)

    return pop
Пример #4
0
def generate(ngen,
             surveyList=None,
             pDistType='lnorm',
             radialDistType='lfl06',
             radialDistPars=7.5,
             electronModel='ne2001',
             pDistPars=[2.7, -0.34],
             siDistPars=[-1.6, 0.35],
             lumDistType='lnorm',
             lumDistPars=[-1.1, 0.9],
             zscaleType='exp',
             zscale=0.33,
             duty_percent=6.,
             scindex=-3.86,
             gpsArgs=[-1, -1],
             doubleSpec=[-1, -1],
             nostdout=False,
             pattern='gaussian',
             orbits=False,
             dgf=None,
             singlepulse=False,
             giantpulse=False,
             dither=False,
             accelsearch=False,
             jerksearch=False,
             sig_factor=10.0,
             bns = False,
             orbparams = {'m': [1, 5], 'm1': [1.0, 2.4], 'm2': [0.2, 1e9], 'om': [0, 360.], 'inc': [0, 90], 'ec': [0., 1.], 'pod': [1e-3, 1e3]},
             brDistType='log_unif'):

    """
    Generate a population of pulsars.

    Keyword args:
    ngen -- the number of pulsars to generate (or detect)
    surveyList -- a list of surveys you want to use to try and detect
        the pulsars
    pDistType -- the pulsar period distribution model to use (def=lnorm)
    radialDistType -- radial distribution model
    electronModel -- mode to use for Galactic electron distribution
    pDistPars -- parameters to use for period distribution
    siDistPars -- parameters to use for spectral index distribution
    lumDistPars -- parameters to use for luminosity distribution
    radialDistPars -- parameters for radial distribution
    zscale -- if using exponential z height, set it here (in kpc)
    scindex -- spectral index of the scattering model
    gpsArgs -- add GPS-type spectrum sources
    doubleSpec -- add double-spectrum type sources
    nostdout -- (bool) switch off stdout
    """
    pop = Population()
    
    # check that the distribution types are supported....
    if 'd_g' in (pDistType,lumDistType,zscaleType,radialDistType,brDistType) and dgf is None:
        print("Provide the distribution generation file")
        sys.exit()
    elif dgf != None:
        try:
            f = open(dgf, 'rb')
        except IOError:
            print("Could not open file {0}.".format(dgf))
            sys.exit()
        dgf_pop_load = cPickle.load(f)
        f.close()
    
    if lumDistType not in ['lnorm', 'pow', 'log_unif', 'd_g', 'log_st']:
        print("Unsupported luminosity distribution: {0}".format(lumDistType))

    if brDistType not in ['log_unif', 'd_g']:
        print("Unsupported burst rate distribution: {0}".format(brDistType))

    if pDistType not in ['lnorm', 'norm', 'cc97', 'lorimer12','unif', 'd_g']:
        print("Unsupported period distribution: {0}".format(pDistType))
    
    if radialDistType not in ['lfl06', 'yk04', 'isotropic',
                              'slab', 'disk','unif' ,'gauss','d_g', 'gamma']:
        print("Unsupported radial distribution: {0}".format(radialDistType))

    if electronModel not in ['ne2001', 'lmt85','ymw16']:
        print("Unsupported electron model: {0}".format(electronModel))

    if pattern not in ['gaussian', 'airy']:
        print("Unsupported gain pattern: {0}".format(pattern))

    if duty_percent < 0.:
        print("Unsupported value of duty cycle: {0}".format(duty_percent))

    # need to use properties in this class so they're get/set-type props
    pop.pDistType = pDistType
    pop.radialDistType = radialDistType
    pop.electronModel = electronModel
    pop.lumDistType = lumDistType

    pop.rsigma = radialDistPars
    pop.pmean, pop.psigma = pDistPars
    pop.simean, pop.sisigma = siDistPars

    pop.gpsFrac, pop.gpsA = gpsArgs
    pop.brokenFrac, pop.brokenSI = doubleSpec
    
    #Set whether system is BNS:
    pop.bns = bns
    pop.orbparams = orbparams

    if pop.lumDistType == 'lnorm':
        pop.lummean, pop.lumsigma = \
                lumDistPars[0], lumDistPars[1]
    elif pop.lumDistType == 'log_unif':
        pop.lumlow, pop.lumhigh = \
                lumDistPars[0], lumDistPars[1]
    elif pop.lumDistType == 'log_st':
        try:
            pop.lumlow, pop.lumhigh, pop.lumslope = \
                    lumDistPars[0], lumDistPars[1], lumDistPars[2]
        except ValueError:
            raise PopulateException('Not enough lum distn parameters')
    elif pop.lumDistType == 'd_g':
        pass
    else:
        try:
            pop.lummin, pop.lummax, pop.lumpow = \
            	lumDistPars[0], lumDistPars[1], lumDistPars[2]
        except ValueError:
            raise PopulateException('Not enough lum distn parameters')

    pop.zscaleType = zscaleType
    pop.zscale = zscale

    # store the dict of arguments inside the model. Could be useful.
    try:
        if sys.version_info[0] > 3:
            argspec = inspect.getfullargspec(generate)
        else:
            argspec = inspect.getargspec(generate)
        lcl = locals()
        key_values = [(arg, lcl[arg]) for arg in argspec.args]
        #key_values = [(arg, locals()['argspec'][arg]) for arg in argspec.args]
        #pop.arguments = {key: value for (key, value) in key_values}
    except SyntaxError:
        pass

    if not nostdout:
        print("\tGenerating pulsars with parameters:")
        param_string_list = []
        for key, value in key_values:
            s = ": ".join([key, str(value)])
            param_string_list.append(s)

        # join this list of strings, and print it
        s = "\n\t\t".join(param_string_list)
        print("\t\t{0}".format(s))

        # set up progress bar for fun :)
        prog = ProgressBar(min_value=0,
                           max_value=ngen,
                           width=65,
                           mode='dynamic')

    # create survey objects here and put them in a list
    if surveyList is not None:
        surveys = [Survey(s, pattern) for s in surveyList]
        # initialise these counters to zero
        for surv in surveys:
            surv.ndet = 0  # number detected
            surv.nout = 0  # number outside survey region
            surv.nsmear = 0  # number smeared out
            surv.ntf = 0  # number too faint
            surv.nbr = 0 #number didn't burst

            # surv.gainpat=pattern
    else:
        # make an empty list here - makes some code just a little
        # simpler - can still loop over an empty list (ie zero times)
        surveys = []
    while pop.ndet < ngen:
        # Declare new pulsar object
        p = Pulsar()

        # period, alpha, rho, width distribution calls
        # Start creating the pulsar!
        if pop.pDistType == 'lnorm':
            p.period = dists.drawlnorm(pop.pmean, pop.psigma)
        elif pop.pDistType == 'unif':
	        p.period = dists.uniform(pop.pmean,pop.psigma)
        elif pop.pDistType == 'norm':
            p.period = random.gauss(pop.pmean, pop.psigma)
        elif pop.pDistType == 'cc97':
            p.period = _cc97()
        elif pop.pDistType == 'gamma':
            print("Gamma function not yet supported")
            sys.exit()
        elif pop.pDistType == 'd_g':
            Pbin_num=dists.draw1d(dgf_pop_load['pHist'])
            Pmin=dgf_pop_load['pBins'][0]
            Pmax=dgf_pop_load['pBins'][-1]
            p.period = Pmin + (Pmax-Pmin)*(Pbin_num+random.random())/len(dgf_pop_load['pHist'])

#            p.period = dg.gen_nos(dgf_pop_load['pHist'],dgf_pop_load['pBins'])
        elif pop.pDistType == 'lorimer12':
            p.period = _lorimer2012_msp_periods()

        if duty_percent > 0.:
            # use a simple duty cycle for each pulsar
            # with a log-normal scatter
            width = (float(duty_percent)/100.) * p.period**0.9
            width = math.log10(width)
            width = dists.drawlnorm(width, 0.3)
            
            # following are the numbers for the RRATs
            # from the period pulse width relation
            if singlepulse:
                width = 1000
                while width > 100:
                    A1=random.gauss(0.49986684,0.13035004)
                    A2=random.gauss(-0.77626305,0.4222085)
                    width = 10**(A1*math.log10(p.period)+ A2)
            p.width_degree = width*360./p.period
        else:
            # use the model to caculate if beaming
            p.alpha = _genAlpha()

            p.rho, p.width_degree = _genRhoWidth(p)

            if p.width_degree == 0.0 and p.rho == 0.0:
                continue
            # is pulsar beaming at us? If not, move on!
            p.beaming = _beaming(p)
            if not p.beaming:
                continue

        # Spectral index stuff here

        # suppose it might be nice to be able to have GPS sources
        # AND double spectra. But for now I assume only have one or
        # none of these types.
        if random.random() > pop.gpsFrac:
            # This will evaluate true when gpsArgs[0] is -1
            # might have to change in future
            p.gpsFlag = 0
        else:
            p.gpsFlag = 1
            p.gpsA = pop.gpsA

        if random.random() > pop.brokenFrac:
            p.brokenFlag = 0
        else:
            p.brokenFlag = 1
            p.brokenSI = pop.brokenSI

        p.spindex = random.gauss(pop.simean, pop.sisigma)

        # get galactic position
        # first, Galactic distribution models
        if pop.radialDistType == 'isotropic':
            # calculate gl and gb randomly
            p.gb = math.degrees(math.asin(random.random()))
            if random.random() < 0.5:
                p.gb = 0.0 - p.gb
            p.gl = random.random() * 360.0

            # use gl and gb to compute galactic coordinates
            # pretend the pulsar is at distance of 1kpc
            # not sure why, ask Dunc!
            #Adam comment ,1 Kpc makes no sense here...
            p.galCoords = go.lb_to_xyz(p.gl, p.gb, 1.0)

        elif pop.radialDistType == 'slab':
            p.galCoords = go.slabdist()
            p.gl, p.gb = go.xyz_to_lb(p.galCoords)

        elif pop.radialDistType == 'disk':
            p.galCoords = go.diskdist()
            p.gl, p.gb = go.xyz_to_lb(p.galCoords)

        else:
            if pop.radialDistType == 'lfl06':
                p.r0 = go.lfl06()

            elif pop.radialDistType == 'gamma':
                fit_alpha, fit_loc, fit_beta=1050.312227, -8.12315263841, 0.00756010693478
                p.r0 = 8.5*stats.gamma.rvs(fit_alpha, loc=fit_loc, scale=fit_beta, size=1) + 8.5


            elif pop.radialDistType == 'd_g':
                Rbin_num=dists.draw1d(dgf_pop_load['RHist'])
                Rmin=dgf_pop_load['RBins'][0]
                Rmax=dgf_pop_load['RBins'][-1]
                #p.r0 = dists.yet_another_try(dgf_pop_load['RHist'], dgf_pop_load['RBins'])
                p.r0 = Rmin + (Rmax-Rmin)*(Rbin_num+random.random())/len(dgf_pop_load['RHist'])
            
            elif pop.radialDistType == 'yk04':
                p.r0 = go.ykr()

            elif pop.radialDistType == 'unif':
                p.r0 = random.uniform(0,12.3)

            elif pop.radialDistType == 'gauss':
                # guassian of mean 0
                # and stdDev given by parameter (kpc)
                p.r0 = random.gauss(0., pop.rsigma)
            # then calc xyz,distance, l and b
            
            if pop.zscaleType == 'exp':
                zheight = go._double_sided_exp(zscale)

            elif pop.zscaleType == 'unif':
                zheight = random.uniform(-1.06489765758, 1.91849552866)
            
            elif pop.zscaleType == 'd_g':
                zbin_num=dists.draw1d(dgf_pop_load['ZHist'])
                logzmin=dgf_pop_load['ZBins'][0]
                logzmax=dgf_pop_load['ZBins'][-1]
                logz = logzmin + (logzmax-logzmin)*(zbin_num+random.random())/len(dgf_pop_load['ZHist'])
                zheight = logz
                #zheight = dg.gen_nos(dgf_pop_load['ZHist'],dgf_pop_load['ZBins'])
            
            else:
                zheight = random.gauss(0., zscale)
            
            gx, gy = go.calcXY(p.r0)
            p.galCoords = gx, gy, zheight
            p.gl, p.gb = go.xyz_to_lb(p.galCoords)

        p.dtrue = go.calc_dtrue(p.galCoords)

        if pop.lumDistType == 'lnorm':
            p.lum_1400 = dists.drawlnorm(pop.lummean,
                                         pop.lumsigma)
        elif pop.lumDistType == 'pow':
            p.lum_1400 = dists.powerlaw(pop.lummin,
                                        pop.lummax,
                                        pop.lumpow)
        elif pop.lumDistType == 'log_st':
            low_lim=pop.lumlow
            upr_lim=pop.lumhigh
            slope = pop.lumslope #-0.10227965
            p.lum_1400= 10.0**(low_lim + dists.st_line(slope,(upr_lim-low_lim)))

        elif pop.lumDistType == 'log_unif':
            p.lum_1400 = 10.0**dists.uniform(pop.lumlow,pop.lumhigh)

        elif pop.lumDistType == 'd_g':
            lbin_num=dists.draw1d(dgf_pop_load['lHist'])
            lmin=dgf_pop_load['lBins'][0]
            lmax=dgf_pop_load['lBins'][-1]
            logl = lmin + (lmax-lmin)*(lbin_num+random.random())/len(dgf_pop_load['lHist'])
            p.lum_1400 = 10.0**logl
        p.lum_inj_mu=p.lum_1400
        
        # add in orbital parameters
        if pop.bns:
            
            assert isinstance(orbparams, dict), "Orbital parameter distribution limits should be a dictionary of form {'name of orb_param': [min, max]}"
            
            #These represents the range in which NN was trained. 
            #DO NOT GO OUTSIDE THESE BOUNDS!!
            default_orbparams = {'m': [1, 5], 'm1': [1.0, 2.4], 'm2': [0.2, 1e9], 'om': [0, 360.], 'inc': [0, 90], 'ec': [0., 1.], 'pod': [1e-3, 1e3]}
            
            if len(pop.orbparams) == 0: 
                print("Warning: Supplied orbparams dict is empty; Setting ranges to default")
                pop.orbparams = default_orbparams
            else:
                temp_opd = dict(default_orbparams)
                temp_opd.update(orbparams)
                pop.orbparams = temp_opd
            
            #Draw a value for each of the orbital parameters from a uniform distribution
            p.m = np.int(np.random.uniform(pop.orbparams['m'][0], pop.orbparams['m'][1], size = 1)) #Should typically fix this to one value!
            p.m1 = np.random.uniform(pop.orbparams['m1'][0], pop.orbparams['m1'][1], size = 1)
            p.m2 = np.random.uniform(pop.orbparams['m2'][0], pop.orbparams['m2'][1], size = 1)
            p.om = np.random.uniform(pop.orbparams['om'][0], pop.orbparams['om'][1], size = 1)
            p.inc = np.random.uniform(pop.orbparams['inc'][0], pop.orbparams['inc'][1], size = 1)
            p.ec = np.random.uniform(pop.orbparams['ec'][0], pop.orbparams['ec'][1], size = 1)
            p.pod = np.random.uniform(pop.orbparams['pod'][0], pop.orbparams['pod'][1], size = 1)
        
        #dither the distance
        if dither:
            # find flux
            flux = p.lum_inj_mu/(p.dtrue**2)
            # dithered distance
            p.dold = p.dtrue
            p.dtrue += random.gauss(0.0,0.2*p.dtrue)
            # new luminosity
            p.lum_1400 = flux*p.dtrue**2
            p.lum_inj_mu=p.lum_1400
            # new R and z
            p.galCoords = go.lb_to_xyz(p.gl, p.gb, p.dtrue)
            p.r0=np.sqrt(p.galCoords[0]**2 + p.galCoords[1]**2)

        #define a burst rate if single pulse option is on
        if singlepulse:
            if brDistType == 'd_g':
                brbin_num=dists.draw1d(dgf_pop_load['brHist'])
                brmin=dgf_pop_load['brBins'][0]
                brmax=dgf_pop_load['brBins'][-1]
                p.br = 10**(brmin + (brmax-brmin)*(brbin_num+random.random())/len(dgf_pop_load['brHist']))
            else:
                p.br=_burst()
            p.lum_sig=sig_factor
            p.det_nos=0
        else:
            p.br=None
            p.det_nos=None

        # then calc DM  using fortran libs
        if pop.electronModel == 'ne2001':
            p.dm = go.ne2001_dist_to_dm(p.dtrue, p.gl, p.gb)
        elif pop.electronModel == 'lmt85':
            p.dm = go.lmt85_dist_to_dm(p.dtrue, p.gl, p.gb)
        elif pop.electronModel == 'ymw16':
            p.dm = go.ymw16_dist_to_dm(p.dtrue, p.gl, p.gb)

        p.scindex = scindex
        # then calc scatter time
        p.t_scatter = go.scatter_bhat(p.dm, p.scindex)
        
        # if no surveys, just generate ngen pulsars
        if surveyList is None:
            pop.population.append(p)
            pop.ndet += 1
            if not nostdout:
                prog.increment_amount()
                print(prog, '\r',)
                sys.stdout.flush()
        # if surveys are given, check if pulsar detected or not
        # in ANY of the surveys
        else:
            # just a flag to increment if pulsar is detected
            detect_int = 0
            for surv in surveys:
                # do SNR calculation
                if singlepulse:
                    #pop_time = int(p.br*surv.tobs)
                    #if pop_time >= 1.0:
                    SNR = surv.SNRcalc(p, pop,rratssearch=True)
                    #else:
                    #    SNR = -3
                elif accelsearch:
                    SNR = surv.SNRcalc(p, pop, accelsearch=True)
                elif jerksearch:
                    SNR = surv.SNRcalc(p, pop, jerksearch=True)
                else:
                    SNR = surv.SNRcalc(p, pop, rratssearch=False)

                if SNR > surv.SNRlimit:
                    # SNR is over threshold

                    # increment the flag
                    # and survey ndetected
                    detect_int += 1
                    surv.ndet += 1
                    continue

                elif SNR == -1:
                    # pulse is smeared out
                    surv.nsmear += 1
                    continue

                elif SNR == -2:
                    # pulsar is outside survey region
                    surv.nout += 1
                    continue
                elif SNR == -3:
                    # rrat didn't burst
                    surv.nbr += 1
                    continue

                else:
                    # pulsar is just too faint
                    surv.ntf += 1
                    continue

            # add the pulsar to the population
            pop.population.append(p)

            # if detected, increment ndet (for whole population)
            # and redraw the progress bar
            if detect_int:
                pop.ndet += 1
                if not nostdout:
                    prog.increment_amount()
                    print(prog, '\r',)
                    sys.stdout.flush()

    # print info to stdout
    if not nostdout:
        print("\n")
        print("  Total pulsars = {0}".format(len(pop.population)))
        print("  Total detected = {0}".format(pop.ndet))
        # print "  Number not beaming = {0}".format(surv.nnb)

        for surv in surveys:
            print("\n  Results for survey '{0}'".format(surv.surveyName))
            print("    Number detected = {0}".format(surv.ndet))
            print("    Number too faint = {0}".format(surv.ntf))
            print("    Number smeared = {0}".format(surv.nsmear))
            print("    Number outside survey area = {0}".format(surv.nout))
            if singlepulse:
                print("    Number didn't burst =  {0}".format(surv.nbr))

    return pop
Пример #5
0
def generate(ngen,
             surveyList=None,
             age_max=1.0E9,
             pDistPars=[.3, .15],
             bFieldPars=[12.65, 0.55],
             birthVPars=[0.0, 180.],
             siDistPars=[-1.6, 0.35],
             alignModel='orthogonal',
             lumDistType='fk06',
             lumDistPars=[-1.5, 0.5],
             alignTime=None,
             spinModel='fk06',
             beamModel='tm98',
             birthVModel='gaussian',
             electronModel='ne2001',
             braking_index=0,
             zscale=0.05,
             duty=5.,
             nodeathline=False,
             efficiencycut=None,
             nostdout=False,
             nospiralarms=False,
             keepdead=False):

    pop = Population()

    # set the parameters in the population object
    pop.pmean, pop.psigma = pDistPars
    pop.bmean, pop.bsigma = bFieldPars

    if lumDistType == 'pow':
        try:
            pop.lummin, pop.lummax, pop.lumpow = \
                lumDistPars[0], lumDistPars[1], lumDistPars[2]
        except ValueError:
            raise EvolveException('Not enough lum distn parameters for "pow"')

    elif lumDistType == 'fk06':
        pop.lumPar1, pop.lumPar2 = lumDistPars[0], lumDistPars[1]
        if len(lumDistPars) == 3:
            pop.lumPar3 = lumDistPars[2]
        else:
            pop.lumPar3 = 0.18

    else:
        pop.lumPar1, pop.lumPar2 = lumDistPars

    pop.simean, pop.sisigma = siDistPars
    pop.birthvmean, pop.birthvsigma = birthVPars

    pop.alignModel = alignModel
    pop.alignTime = alignTime
    pop.spinModel = spinModel
    pop.beamModel = beamModel
    pop.birthVModel = birthVModel
    pop.electronModel = electronModel

    pop.braking_index = braking_index
    pop.deathline = not nodeathline
    pop.nospiralarms = nospiralarms

    pop.zscale = zscale

    if not nostdout:
        print "\tGenerating evolved pulsars with parameters:"
        print "\t\tngen = {0}".format(ngen)
        print "\t\tUsing electron distn model {0}".format(pop.electronModel)
        print "\n\t\tPeriod mean, sigma = {0}, {1}".format(
            pop.pmean, pop.psigma)
        print "\t\tLuminosity mean, sigma = {0}, {1}".format(
            pop.lummean, pop.lumsigma)
        print "\t\tSpectral index mean, sigma = {0}, {1}".format(
            pop.simean, pop.sisigma)
        print "\t\tGalactic z scale height = {0} kpc".format(pop.zscale)

        print "\t\tWidth {0}% ".format(duty)

        # set up progress bar for fun :)
        prog = ProgressBar(min_value=0,
                           max_value=ngen,
                           width=65,
                           mode='dynamic')

    # create survey objects here and put them in a list
    if surveyList is not None:
        surveys = [Survey(s) for s in surveyList]
    else:
        # make an empty list here - makes some code just a little
        # simpler - can still loop over an empty list (ie zero times)
        surveys = []

    # initialise these counters to zero
    for surv in surveys:
        surv.ndet = 0  # number detected
        surv.nout = 0  # number outside survey region
        surv.nsmear = 0  # number smeared out
        surv.ntf = 0  # number too faint

    # this is the nitty-gritty loop for generating the pulsars
    while pop.ndet < ngen:
        pulsar = Pulsar()

        # initial age for pulsar
        pulsar.age = random.random() * age_max

        # initial period
        pulsar.p0 = -1.
        while pulsar.p0 <= 0.:
            pulsar.p0 = random.gauss(pop.pmean, pop.psigma)

        # initial magnetic field (in Gauss)
        pulsar.bfield_init = 10**random.gauss(pop.bmean, pop.bsigma)

        # aligment angle
        alignpulsar(pulsar, pop)

        # braking index
        if pop.braking_index == 0:
            pulsar.braking_index = 2.5 + 0.5 * random.random()
        else:
            pulsar.braking_index = float(pop.braking_index)

        #apply relevant spin down model
        pulsar.dead = False  # pulsar should start alive!

        if pop.spinModel == 'fk06':
            spindown_fk06(pulsar)

            # apply deathline if relevant
            if pop.deathline:
                bhattacharya_deathperiod_92(pulsar)

        elif pop.spinModel == 'cs06':
            # contopoulos and spitkovsky
            spindown_cs06(pulsar, pop)

        # define pulse width (default = 6% = 18 degrees)
        width = (float(duty) / 100.) * pulsar.period**0.9
        width = math.log10(width)
        width = dists.drawlnorm(width, 0.3)
        pulsar.width_degree = 360. * width / pulsar.period

        # plough on - only if the pulsar isn't dead!
        if not pulsar.dead or keepdead:
            # is the pulsar beaming?
            pulsar_beaming(pulsar, pop.beamModel)
            # if not, then skip onto next pulsar
            if not pulsar.beaming:
                continue

            # position of the pulsar
            galacticDistribute(pulsar, pop)
            # birthvelocity
            birthVelocity(pulsar, pop)

            # model the xyz velocity
            go.vxyz(pulsar)

            # luminosity
            if lumDistType == 'fk06':
                luminosity_fk06(pulsar,
                                alpha=pop.lumPar1,
                                beta=pop.lumPar2,
                                gamma=pop.lumPar3)

            elif lumDistType == 'lnorm':
                pulsar.lum_1400 = dists.drawlnorm(pop.lumPar1, pop.lumPar2)

            elif lumDistType == 'pow':
                pulsar.lum_1400 = dists.powerlaw(pop.lummin, pop.lummax,
                                                 pop.lumpow)
            else:
                # something's wrong!
                raise EvolveException('Invalid luminosity distn selected')

            # apply efficiency cutoff
            if efficiencycut is not None:
                if pulsar.efficiency() > efficiencycut:
                    pulsar.dead = True
                    if not keepdead:
                        continue

            # spectral index
            pulsar.spindex = random.gauss(pop.simean, pop.sisigma)

            # calculate galactic coords and distance
            pulsar.gl, pulsar.gb = go.xyz_to_lb(pulsar.galCoords)
            pulsar.dtrue = go.calc_dtrue(pulsar.galCoords)

            # then calc DM  using fortran libs
            if pop.electronModel == 'ne2001':
                pulsar.dm = go.ne2001_dist_to_dm(pulsar.dtrue, pulsar.gl,
                                                 pulsar.gb)
            elif pop.electronModel == 'lmt85':
                pulsar.dm = go.lmt85_dist_to_dm(pulsar.dtrue, pulsar.gl,
                                                pulsar.gb)
            else:
                raise EvolveException('Invalid electron dist model selected')

            # if surveys are given, check if pulsar detected or not
            # in ANY of the surveys
            if surveyList is not None:
                detect_int = 0  # just a flag if pulsar is detected
                for surv in surveys:
                    SNR = surv.SNRcalc(pulsar, pop)

                    if SNR > surv.SNRlimit:
                        # SNR is over threshold
                        # increment the flag
                        # and survey ndetected
                        detect_int += 1
                        surv.ndet += 1
                        continue

                    elif SNR == -1:
                        # pulse is smeared out
                        surv.nsmear += 1
                        continue

                    elif SNR == -2:
                        # pulsar is outside survey region
                        surv.nout += 1
                        continue

                    else:
                        #pulsar is just too faint
                        surv.ntf += 1
                        continue

                # if detected, increment ndet (for whole population)
                # and redraw the progress bar
                if detect_int:
                    pop.ndet += 1
                    # update the counter
                    if not nostdout:
                        prog.increment_amount()
                        print prog, '\r',
                        sys.stdout.flush()

            else:
                # no survey list, just add the pulsar to population,
                # and increment number of pulsars
                pop.ndet += 1
                # update the counter
                if not nostdout:
                    prog.increment_amount()
                    print prog, '\r',
                    sys.stdout.flush()

            # pulsar isn't dead, add to population!
            pop.population.append(pulsar)

        else:
            # pulsar is dead. If no survey list,
            # just increment number of pulsars
            if surveyList is None:
                pop.ndet += 1
                # update the counter
                if not nostdout:
                    prog.increment_amount()
                    print prog, '\r',
                    sys.stdout.flush()

    if not nostdout:
        print "\n\n"
        print "  Total pulsars = {0}".format(len(pop.population))
        print "  Total detected = {0}".format(pop.ndet)

        for surv in surveys:
            print "\n  Results for survey '{0}'".format(surv.surveyName)
            print "    Number detected = {0}".format(surv.ndet)
            print "    Number too faint = {0}".format(surv.ntf)
            print "    Number smeared = {0}".format(surv.nsmear)
            print "    Number outside survey area = {0}".format(surv.nout)

    # save list of arguments into the pop
    argspec = inspect.getargspec(generate)
    key_values = [(arg, locals()[arg]) for arg in argspec.args]
    pop.arguments = {key: value for (key, value) in key_values}

    return pop
Пример #6
0
def generate(ngen,
             surveyList=None,
             pDistType='lnorm',
             radialDistType='lfl06',
             radialDistPars=7.5,
             electronModel='ne2001',
             pDistPars=[2.7, -0.34],
             siDistPars=[-1.6, 0.35],
             lumDistType='lnorm',
             lumDistPars=[-1.1, 0.9],
             zscaleType='exp',
             zscale=0.33,
             duty_percent=6.,
             scindex=-3.86,
             gpsArgs=[None, None],
             doubleSpec=[None, None],
             nostdout=False,
             pattern='gaussian',
             orbits=False):
    """
    Generate a population of pulsars.

    Keyword args:
    ngen -- the number of pulsars to generate (or detect)
    surveyList -- a list of surveys you want to use to try and detect
        the pulsars
    pDistType -- the pulsar period distribution model to use (def=lnorm)
    radialDistType -- radial distribution model
    electronModel -- mode to use for Galactic electron distribution
    pDistPars -- parameters to use for period distribution
    siDistPars -- parameters to use for spectral index distribution
    lumDistPars -- parameters to use for luminosity distribution
    radialDistPars -- parameters for radial distribution
    zscale -- if using exponential z height, set it here (in kpc)
    scindex -- spectral index of the scattering model
    gpsArgs -- add GPS-type spectrum sources
    doubleSpec -- add double-spectrum type sources
    nostdout -- (bool) switch off stdout
    """

    pop = Population()

    # check that the distribution types are supported....
    if lumDistType not in ['lnorm', 'pow']:
        print "Unsupported luminosity distribution: {0}".format(lumDistType)

    #if pDistType not in ['lnorm', 'norm', 'cc97', 'lorimer12']:
    #    print "Unsupported period distribution: {0}".format(pDistType)
    if pDistType not in ['lnorm', 'norm', 'cc97', 'lorimer12', 'lorimer15']:
        print "Unsupported period distribution: {0}".format(pDistType)

    if radialDistType not in [
            'lfl06', 'yk04', 'isotropic', 'slab', 'disk', 'gauss'
    ]:
        print "Unsupported radial distribution: {0}".format(radialDistType)

    # Edited by Shi Dai, 2017/03/22
    if electronModel not in ['ne2001', 'lmt85', 'ymw16']:
        print "Unsupported electron model: {0}".format(electronModel)

    if pattern not in ['gaussian', 'airy']:
        print "Unsupported gain pattern: {0}".format(pattern)

    if duty_percent < 0.:
        print "Unsupported value of duty cycle: {0}".format(duty_percent)

    # need to use properties in this class so they're get/set-type props
    pop.pDistType = pDistType
    pop.radialDistType = radialDistType
    pop.electronModel = electronModel
    pop.lumDistType = lumDistType

    pop.rsigma = radialDistPars
    pop.pmean, pop.psigma = pDistPars
    pop.simean, pop.sisigma = siDistPars

    pop.gpsFrac, pop.gpsA = gpsArgs
    pop.brokenFrac, pop.brokenSI = doubleSpec

    if pop.lumDistType == 'lnorm':
        pop.lummean, pop.lumsigma = \
                lumDistPars[0], lumDistPars[1]
    else:
        try:
            pop.lummin, pop.lummax, pop.lumpow = \
                lumDistPars[0], lumDistPars[1], lumDistPars[2]
        except ValueError:
            raise PopulateException('Not enough lum distn parameters')

    pop.zscaleType = zscaleType
    pop.zscale = zscale

    # store the dict of arguments inside the model. Could be useful.
    try:
        argspec = inspect.getargspec(generate)
        key_values = [(arg, locals()[arg]) for arg in argspec.args]
        pop.arguments = {key: value for (key, value) in key_values}
    except SyntaxError:
        pass

    if not nostdout:
        print "\tGenerating pulsars with parameters:"
        param_string_list = []
        for key, value in key_values:
            s = ": ".join([key, str(value)])
            param_string_list.append(s)

        # join this list of strings, and print it
        s = "\n\t\t".join(param_string_list)
        print "\t\t{0}".format(s)

        # set up progress bar for fun :)
        prog = ProgressBar(min_value=0,
                           max_value=ngen,
                           width=65,
                           mode='dynamic')

    # create survey objects here and put them in a list
    if surveyList is not None:
        surveys = [Survey(s, absolute_importpattern) for s in surveyList]
        # initialise these counters to zero
        for surv in surveys:
            surv.ndet = 0  # number detected
            surv.nout = 0  # number outside survey region
            surv.nsmear = 0  # number smeared out
            surv.ntf = 0  # number too faint

            # surv.gainpat=pattern
    else:
        # make an empty list here - makes some code just a little
        # simpler - can still loop over an empty list (ie zero times)
        surveys = []

    Lorimer15 = np.loadtxt(
        '/Users/dai02a/Soft/psrpop/PsrPopPy/lib/python/lorimer15')
    while pop.ndet < ngen:
        # Declare new pulsar object
        p = Pulsar()

        # period, alpha, rho, width distribution calls
        # Start creating the pulsar!
        if pop.pDistType == 'lnorm':
            p.period = dists.drawlnorm(pop.pmean, pop.psigma)
        elif pop.pDistType == 'norm':
            p.period = random.gauss(pop.pmean, pop.psigma)
        elif pop.pDistType == 'cc97':
            p.period = _cc97()
        elif pop.pDistType == 'gamma':
            print "Gamma function not yet supported"
            sys.exit()
        elif pop.pDistType == 'lorimer12':
            p.period = _lorimer2012_msp_periods()
        elif pop.pDistType == 'lorimer15':
            #p.period = _lorimer2015_msp_periods()
            p.period = Lorimer15[pop.ndet]

        if duty_percent > 0.:
            # use a simple duty cycle for each pulsar
            # with a log-normal scatter
            width = (float(duty_percent) / 100.) * p.period**0.9
            width = math.log10(width)
            width = dists.drawlnorm(width, 0.3)

            p.width_degree = width * 360. / p.period
        else:
            # use the model to caculate if beaming
            p.alpha = _genAlpha()

            p.rho, p.width_degree = _genRhoWidth(p)

            if p.width_degree == 0.0 and p.rho == 0.0:
                continue
            # is pulsar beaming at us? If not, move on!
            p.beaming = _beaming(p)
            if not p.beaming:
                continue

        # Spectral index stuff here

        # suppose it might be nice to be able to have GPS sources
        # AND double spectra. But for now I assume only have one or
        # none of these types.
        if random.random() > pop.gpsFrac:
            # This will evaluate true when gpsArgs[0] is NoneType
            # might have to change in future
            p.gpsFlag = 0
        else:
            p.gpsFlag = 1
            p.gpsA = pop.gpsA

        if random.random() > pop.brokenFrac:
            p.brokenFlag = 0
        else:
            p.brokenFlag = 1
            p.brokenSI = pop.brokenSI

        p.spindex = random.gauss(pop.simean, pop.sisigma)

        # get galactic position
        # first, Galactic distribution models
        if pop.radialDistType == 'isotropic':
            # calculate gl and gb randomly
            p.gb = math.degrees(math.asin(random.random()))
            if random.random() < 0.5:
                p.gb = 0.0 - p.gb
            p.gl = random.random() * 360.0

            # use gl and gb to compute galactic coordinates
            # pretend the pulsar is at distance of 1kpc
            # not sure why, ask Dunc!
            p.galCoords = go.lb_to_xyz(p.gl, p.gb, 1.0)

        elif pop.radialDistType == 'slab':
            p.galCoords = go.slabDist()
            p.gl, p.gb = go.xyz_to_lb(p.galCoords)

        elif pop.radialDistType == 'disk':
            p.galCoords = go.diskDist()
            p.gl, p.gb = go.xyz_to_lb(p.galCoords)

        else:  # we want to use exponential z and a radial dist
            if pop.radialDistType == 'lfl06':
                p.r0 = go.lfl06()
            elif pop.radialDistType == 'yk04':
                p.r0 = go.ykr()
            elif pop.radialDistType == 'gauss':
                # guassian of mean 0
                # and stdDev given by parameter (kpc)
                p.r0 = random.gauss(0., pop.rsigma)

            # then calc xyz,distance, l and b
            if pop.zscaleType == 'exp':
                zheight = go._double_sided_exp(zscale)
            else:
                zheight = random.gauss(0., zscale)
            gx, gy = go.calcXY(p.r0)
            p.galCoords = gx, gy, zheight
            p.gl, p.gb = go.xyz_to_lb(p.galCoords)

        p.dtrue = go.calc_dtrue(p.galCoords)

        # Edited by Shi Dai, 2017/03/22
        # then calc DM  using fortran libs
        #if pop.electronModel == 'ne2001':
        #    p.dm = go.ne2001_dist_to_dm(p.dtrue, p.gl, p.gb)
        #elif pop.electronModel == 'lmt85':
        #    p.dm = go.lmt85_dist_to_dm(p.dtrue, p.gl, p.gb)

        #p.scindex = scindex
        ## then calc scatter time
        #p.t_scatter = go.scatter_bhat(p.dm, p.scindex)

        if pop.electronModel == 'ne2001':
            p.dm = go.ne2001_dist_to_dm(p.dtrue, p.gl, p.gb)
            p.t_scatter = go.scatter_bhat(p.dm, p.scindex)
        elif pop.electronModel == 'lmt85':
            p.dm = go.lmt85_dist_to_dm(p.dtrue, p.gl, p.gb)
            p.t_scatter = go.scatter_bhat(p.dm, p.scindex)
        elif pop.electronModel == 'ymw16':
            p.dm, p.t_scatter = go.ymw16_dist_to_dm(p.dtrue, p.gl, p.gb)

        p.scindex = scindex
        # then calc scatter time

        if pop.lumDistType == 'lnorm':
            p.lum_1400 = dists.drawlnorm(pop.lummean, pop.lumsigma)
        else:
            p.lum_1400 = dists.powerlaw(pop.lummin, pop.lummax, pop.lumpow)

        # add in orbital parameters
        if orbits:
            orbitalparams.test_1802_2124(p)
            print p.gb, p.gl

        # if no surveys, just generate ngen pulsars
        if surveyList is None:
            calc_delta(p)
            pop.population.append(p)
            pop.ndet += 1
            if not nostdout:
                prog.increment_amount()
                print prog, '\r',
                sys.stdout.flush()
        # if surveys are given, check if pulsar detected or not
        # in ANY of the surveys
        else:
            # just a flag to increment if pulsar is detected
            detect_int = 0
            for surv in surveys:
                # do SNR calculation
                SNR = surv.SNRcalc(p, pop)

                if SNR > surv.SNRlimit:
                    # SNR is over threshold

                    # increment the flag
                    # and survey ndetected
                    detect_int += 1
                    surv.ndet += 1
                    continue

                elif SNR == -1:
                    # pulse is smeared out
                    surv.nsmear += 1
                    continue

                elif SNR == -2:
                    # pulsar is outside survey region
                    surv.nout += 1
                    continue

                else:
                    # pulsar is just too faint
                    surv.ntf += 1
                    continue

            # added by Shi Dai, 2017/02/07
            #p.snr = SNR

            # add the pulsar to the population
            pop.population.append(p)

            # if detected, increment ndet (for whole population)
            # and redraw the progress bar
            if detect_int:
                pop.ndet += 1
                if not nostdout:
                    prog.increment_amount()
                    print prog, '\r',
                    sys.stdout.flush()

    # print info to stdout
    if not nostdout:
        print "\n"
        print "  Total pulsars = {0}".format(len(pop.population))
        print "  Total detected = {0}".format(pop.ndet)
        # print "  Number not beaming = {0}".format(surv.nnb)

        for surv in surveys:
            print "\n  Results for survey '{0}'".format(surv.surveyName)
            print "    Number detected = {0}".format(surv.ndet)
            print "    Number too faint = {0}".format(surv.ntf)
            print "    Number smeared = {0}".format(surv.nsmear)
            print "    Number outside survey area = {0}".format(surv.nout)

    return pop
Пример #7
0
def generate(ngen,
             surveyList=None,
             age_max=1.0E9,
             pDistPars=[0.3, 0.15],
             pDistType = 'norm' ,           # P distirbution for MSPs (Lorimer et al. 2015)
             bFieldPars=[12.65, 0.55],
             birthVPars=[0.0, 180.],
             siDistPars=[-1.6, 0.35],
             alignModel='orthogonal',
             lumDistType='fk06',
             lumDistPars=[-1.5, 0.5],
             alignTime=None,
             spinModel='fk06',
             beamModel='tm98',
             birthVModel='gaussian',
             electronModel='ne2001',
             braking_index=0,
             zscale=0.05,
             duty=5.,
             scindex=-3.86,
             widthModel=None,
             nodeathline=False,
             efficiencycut=None,
             nostdout=False,
             nospiralarms=False,
             keepdead=False,
             dosurveyList = None,
             makepop=False):

    pop = Population()

    # set the parameters in the population object

    pop.pmean, pop.psigma = pDistPars
    pop.bmean, pop.bsigma = bFieldPars

    if lumDistType == 'pow':
        try:
            pop.lummin, pop.lummax, pop.lumpow = \
                lumDistPars[0], lumDistPars[1], lumDistPars[2]
        except ValueError:
            raise EvolveException('Not enough lum distn parameters for "pow"')

    elif lumDistType == 'fk06':
        pop.lumPar1, pop.lumPar2 = lumDistPars[0], lumDistPars[1]
        if len(lumDistPars) == 3:
            pop.lumPar3 = lumDistPars[2]
        else:
            pop.lumPar3 = 0.18

    else:
        pop.lumPar1, pop.lumPar2 = lumDistPars

    pop.simean, pop.sisigma = siDistPars
    pop.birthvmean, pop.birthvsigma = birthVPars

    pop.alignModel = alignModel
    pop.alignTime = alignTime
    pop.spinModel = spinModel
    pop.beamModel = beamModel
    pop.birthVModel = birthVModel
    pop.electronModel = electronModel

    pop.braking_index = braking_index
    pop.deathline = not nodeathline
    pop.nospiralarms = nospiralarms

    pop.zscale = zscale

    if widthModel == 'kj07':
        print "\tLoading KJ07 models...."
        kj_p_vals, kj_pdot_vals, kj_dists = beammodels.load_kj2007_models()
        print "\tDone\n"

    if not nostdout:
        print "\tGenerating evolved pulsars with parameters:"
        print "\t\tngen = {0}".format(ngen)
        print "\t\tUsing electron distn model {0}".format(
                                        pop.electronModel)
        print "\n\t\tPeriod mean, sigma = {0}, {1}".format(
                                                    pop.pmean,
                                                    pop.psigma)
        print "\t\tLuminosity mean, sigma = {0}, {1}".format(
                                                    pop.lummean,
                                                    pop.lumsigma)
        print "\t\tSpectral index mean, sigma = {0}, {1}".format(
                                                    pop.simean,
                                                    pop.sisigma)
        print "\t\tGalactic z scale height = {0} kpc".format(
                                                    pop.zscale)
        if widthModel is None:
            print "\t\tWidth {0}% ".format(duty)
        else:
            print "\t\tUsing Karastergiou & Johnston beam width model"

        # set up progress bar for fun :)
        prog = ProgressBar(min_value=0,
                           max_value=ngen,
                           width=65,
                           mode='dynamic')

    # create survey objects here and put them in a list
    if surveyList is not None:
        surveys = [Survey(s) for s in surveyList]
    else:
        # make an empty list here - makes some code just a little
        # simpler - can still loop over an empty list (ie zero times)
        surveys = []

    # initialise these counters to zero
    for surv in surveys:
        surv.ndet = 0  # number detected
        surv.nout = 0  # number outside survey region
        surv.nsmear = 0  # number smeared out
        surv.ntf = 0  # number too faint

    # create dosurvey objects here and put them in a list
    if dosurveyList is not None:
        dosurveys = [Survey(s) for s in dosurveyList]
        # initialise these counters to zero
        for surv in dosurveys:
            surv.ndet = 0  # number detected
            surv.nout = 0  # number outside survey region
            surv.nsmear = 0  # number smeared out
            surv.ntf = 0  # number too faint

            # surv.gainpat=pattern
    else:
        # make an empty list here - makes some code just a little
        # simpler - can still loop over an empty list (ie zero times)
        dosurveys = []

    # this is the nitty-gritty loop for generating the pulsars
    ntot = 0   #total number of pulsars generated by the while loop (including dead, and the ones not beaming towards us)
    n_alive = 0  #total number of pulsars which are alive (beaming + not beaming towards Earth)
    n_alive_beam = 0 #total number of alive pulsars beaming towards Earth    
    while pop.ndet < ngen:
        pulsar = Pulsar()

        # initial age for pulsar
        pulsar.age = random.random() * age_max
        # initial period
        pulsar.p0 = -1.
        while (pulsar.p0 <= 0.):
          if(pDistType == 'norm'):
            pulsar.p0 = random.gauss(pop.pmean, pop.psigma)
          elif(pDistType == 'drl15'):
            L_p0 = np.random.lognormal(mean = pop.pmean, sigma = pop.psigma)  
            pulsar.p0 = np.exp(L_p0)/1000         # period in seconds
        # initial magnetic field (in Gauss)
        pulsar.bfield_init = 10**random.gauss(pop.bmean, pop.bsigma)

        # aligment angle
        alignpulsar(pulsar, pop)

        # braking index
        if pop.braking_index == 0:
            pulsar.braking_index = 2.5 + 0.5 * random.random()
        else:
            pulsar.braking_index = float(pop.braking_index)

        # apply relevant spin down model
        pulsar.dead = False  # pulsar should start alive!

        if pop.spinModel == 'fk06':
            spindown_fk06(pulsar)

            # apply deathline if relevant
            if pop.deathline:
                bhattacharya_deathperiod_92(pulsar)

        elif pop.spinModel == 'tk01':
            spindown_tk01(pulsar)

            # apply deathline if relevant
            if pop.deathline:
                bhattacharya_deathperiod_92(pulsar)
 
        elif pop.spinModel == 'cs06':
            # contopoulos and spitkovsky
            spindown_cs06(pulsar, pop)

        # if period > 10 seconds, just try a new one
        if pulsar.period > 10000.0 or pulsar.period < 1.5:
            continue
        # cut on pdot too - this doesn't help
        if pulsar.pdot > 1.e-11 or pulsar.pdot < 1.e-21:
            continue

        # define pulse width (default = 6% = 18 degrees)
        if widthModel is None:
            width = (float(duty)/100.) * pulsar.period**0.9
            width = math.log10(width)
            width = dists.drawlnorm(width, 0.3)
        elif widthModel == 'kj07':
            # Karastergiou & Johnston beam model

            # find closest p, pdot in the kj lists
            logp = math.log10(pulsar.period)
            logpdot = math.log10(pulsar.pdot)

            p_idx = (np.abs(kj_p_vals - logp)).argmin()
            pd_idx = (np.abs(kj_pdot_vals - logpdot)).argmin()

            # pick a width from relevant model
            dist = kj_dists[p_idx][pd_idx][2]
            width = np.random.choice(dist)

            """
            width = beammodels.kj2007_width(pulsar)
            no_width = 0
            while width  == 0.0:
                no_width+=1
                width = beammodels.kj2007_width(pulsar)

                # if we get to five, then try a new pulsar
                if no_width == 5:
                    no_width = 0
                    continue
            """

        else:
            print "Undefined width model!"
            sys.exit()
        # print width
        # print pulsar.period, width, pulsar.pdot
        if width == 0.0:
            # some kj2007 models make many zero-width sources. Skip!
            continue
        pulsar.width_degree = 360. * width / pulsar.period

        # incrementing the total number of physical pulsars generated by
        # the model after the unphysical ones are removed
        ntot += 1
        # plough on - only if the pulsar isn't dead!
        if not pulsar.dead or keepdead:
            n_alive+=1
            # is the pulsar beaming?
            pulsar_beaming(pulsar, pop.beamModel)
            # if not, then skip onto next pulsar
            if not pulsar.beaming:
                continue

            # position of the pulsar
            galacticDistribute(pulsar, pop)
            # birthvelocity
            birthVelocity(pulsar, pop)

            # model the xyz velocity
            go.vxyz(pulsar)

            # luminosity
            if lumDistType == 'fk06':
                luminosity_fk06(pulsar,
                                alpha=pop.lumPar1,
                                beta=pop.lumPar2,
                                gamma=pop.lumPar3)

            elif lumDistType == 'lnorm':
                pulsar.lum_1400 = dists.drawlnorm(pop.lumPar1, pop.lumPar2)

            elif lumDistType == 'pow':
                pulsar.lum_1400 = dists.powerlaw(pop.lummin,
                                                 pop.lummax,
                                                 pop.lumpow)
            else:
                # something's wrong!
                raise EvolveException('Invalid luminosity distn selected')

            # apply efficiency cutoff
            if efficiencycut is not None:
                if pulsar.efficiency() > efficiencycut:
                    pulsar.dead = True
                    if not keepdead:
                        continue

            # spectral index
            pulsar.spindex = random.gauss(pop.simean, pop.sisigma)

            # calculate galactic coords and distance
            pulsar.gl, pulsar.gb = go.xyz_to_lb(pulsar.galCoords)
            pulsar.dtrue = go.calc_dtrue(pulsar.galCoords)

            # then calc DM  using fortran libs
            if pop.electronModel == 'ne2001':
                pulsar.dm = go.ne2001_dist_to_dm(pulsar.dtrue,
                                                 pulsar.gl,
                                                 pulsar.gb)
            elif pop.electronModel == 'lmt85':
                pulsar.dm = go.lmt85_dist_to_dm(pulsar.dtrue,
                                                pulsar.gl,
                                                pulsar.gb)
            else:
                raise EvolveException('Invalid electron dist model selected')

            pulsar.scindex = scindex
            pulsar.t_scatter = go.scatter_bhat(pulsar.dm,
                                               pulsar.scindex)

            # if surveys are given, check if pulsar detected or not
            # in ANY of the surveys
            if surveyList is not None:
                detect_int = 0  # just a flag if pulsar is detected
                for surv in surveys:
                    SNR = surv.SNRcalc(pulsar, pop)

                    if SNR > surv.SNRlimit:
                        # SNR is over threshold
                        # increment the flag
                        # and survey ndetected
                        detect_int += 1
                        surv.ndet += 1
                        continue

                    elif SNR == -1:
                        # pulse is smeared out
                        surv.nsmear += 1
                        continue

                    elif SNR == -2:
                        # pulsar is outside survey region
                        surv.nout += 1
                        continue

                    else:
                        # pulsar is just too faint
                        surv.ntf += 1
                        continue

                # if detected, increment ndet (for whole population)
                # and redraw the progress bar
                if detect_int:
                    pop.ndet += 1
                    # update the counter
                    if not nostdout:
                        prog.increment_amount()
                        print prog, '\r',
                        sys.stdout.flush()

            else:
                # no survey list, just add the pulsar to population,
                # and increment number of pulsars
                pop.ndet += 1
                # update the counter
                if not nostdout:
                    prog.increment_amount()
                    print prog, '\r',
                    sys.stdout.flush()

            # increment the total number of alive pulsars beaming towards Earth
            # should be different from n_alive (as the loop was stopped if pulsar
            # was found to not beam towards Earth)
            # is incremented only when pulsar was beaming towards us
            n_alive_beam += 1            
            
            # pulsar isn't dead, and makepop True, add the pulsar to population!
            if makepop == True:
                pop.population.append(pulsar)

            # if dosurveys are given, check if pulsar detected or not
            # in each of the surveys or any of the survey
            # just a flag to increment if pulsar is detected
            if dosurveyList is not None:
                for surv in dosurveys:
                    SNR = surv.SNRcalc(pulsar, pop)

                    if SNR > surv.SNRlimit:
                        # SNR is over threshold
                        # increment survey ndetected
                        surv.ndet += 1
                        continue

                    elif SNR == -1:
                        # pulse is smeared out
                        surv.nsmear += 1
                        continue

                    elif SNR == -2:
                        # pulsar is outside survey region
                        surv.nout += 1
                        continue

                    else:
                        # pulsar is just too faint
                        surv.ntf += 1
                        continue

        else:
            # pulsar is dead. If no survey list,
            # just increment number of pulsars
            if surveyList is None:
                pop.ndet = ntot 
                # update the counter
                if not nostdout:
                    prog.increment_amount()
                    print prog, '\r',
                    sys.stdout.flush()

    if not nostdout:
        print "\n\n"
#        print "  Total pulsars = {0}".format(len(pop.population))
#        print "  Total detected = {0}".format(pop.ndet)
        print "  Total pulsars generated = {0}".format(ntot)
        print "  Total living pulsars = {0}".format(n_alive)
        print "  Total living pulsars beaming towards Earth = {0}".format(n_alive_beam)

        if surveyList is not None:
            print "  Total detected by all surveys = {0}".format(pop.ndet)


        for surv in surveys:
            print "\n  Results for survey '{0}'".format(surv.surveyName)
            print "    Number detected = {0}".format(surv.ndet)
            print "    Number too faint = {0}".format(surv.ntf)
            print "    Number smeared = {0}".format(surv.nsmear)
            print "    Number outside survey area = {0}".format(surv.nout)

        for surv in dosurveys:
            print "\n  Dosurvey Results for survey '{0}'".format(surv.surveyName)
            print "    Number detected = {0}".format(surv.ndet)
            print "    Number too faint = {0}".format(surv.ntf)
            print "    Number smeared = {0}".format(surv.nsmear)
            print "    Number outside survey area = {0}".format(surv.nout)

    dosurvey_result = []
    for surv in dosurveys:
        dosurvey_result.append([surv.surveyName, surv.ndet, surv.ntf, surv.nsmear, surv.nout])

    # save list of arguments into the pop
    #try:
    #    argspec = inspect.getargspec(generate)
    #    key_values = [(arg, locals()[arg]) for arg in argspec.args]
    #    pop.arguments = {key: value for (key, value) in key_values}
    #except SyntaxError:
     #   pass

    return pop, dosurvey_result
Пример #8
0
#!/usr/bin/python

import sys
import argparse
import math
import random

import cPickle

import matplotlib.pyplot as plt
from matplotlib.widgets import Button, RadioButtons, CheckButtons

import numpy as np

from population import Population
from pulsar import Pulsar

f = open(sys.argv[1], 'rb')
p = Pulsar()

p = cPickle.load(f)
f.close()

print p.size()
Пример #9
0
            web_interface_address = config_parser.get('web interface',
                                                      'address')
            web_interface_port = config_parser.get('web interface', 'port')
        except ConfigParser.NoOptionError as e:
            print 'Error: Config file error: {}'.format(e)
            sys.exit()
        except ConfigParser.NoSectionError as e:
            print 'Error: Config file error: {}. Is {} correct path?'.format(
                e, config_path)
            sys.exit()

        try:
            web_interface_port = int(web_interface_port)
        except ValueError as e:
            logger.error(
                'Incorrect web interface value in configuration file.')
            sys.exit()

    pulsar = Pulsar(refresh_time, url_list, web_interface_address,
                    web_interface_port)
    pulsar.start()

    if web_interface_enabled:
        pulsar.start_web_interface()

    try:
        while True:
            sleep(1)
    except (KeyboardInterrupt, SystemExit):
        pulsar.stop()
Пример #10
0
def generate(ngen,
             surveyList=None,
             age_max=1.0E9,
             pDistPars=[.3, .15],
             bFieldPars=[12.65, 0.55],
             birthVPars=[0.0, 180.],
             siDistPars=[-1.6, 0.35],
             alignModel='orthogonal',
             lumDistType='fk06',
             lumDistPars=[-1.5, 0.5],
             alignTime=None,
             spinModel='fk06',
             beamModel='tm98',
             birthVModel='gaussian',
             electronModel='ne2001',
             braking_index=0,
             zscale=0.05,
             duty=5.,
             scindex=-3.86,
             widthModel=None,
             nodeathline=False,
             efficiencycut=None,
             nostdout=False,
             nospiralarms=False,
             keepdead=False):

    pop = Population()

    # set the parameters in the population object
    pop.pmean, pop.psigma = pDistPars
    pop.bmean, pop.bsigma = bFieldPars

    if lumDistType == 'pow':
        try:
            pop.lummin, pop.lummax, pop.lumpow = \
                lumDistPars[0], lumDistPars[1], lumDistPars[2]
        except ValueError:
            raise EvolveException('Not enough lum distn parameters for "pow"')

    elif lumDistType == 'fk06':
        pop.lumPar1, pop.lumPar2 = lumDistPars[0], lumDistPars[1]
        if len(lumDistPars) == 3:
            pop.lumPar3 = lumDistPars[2]
        else:
            pop.lumPar3 = 0.18

    else:
        pop.lumPar1, pop.lumPar2 = lumDistPars

    pop.simean, pop.sisigma = siDistPars
    pop.birthvmean, pop.birthvsigma = birthVPars

    pop.alignModel = alignModel
    pop.alignTime = alignTime
    pop.spinModel = spinModel
    pop.beamModel = beamModel
    pop.birthVModel = birthVModel
    pop.electronModel = electronModel

    pop.braking_index = braking_index
    pop.deathline = not nodeathline
    pop.nospiralarms = nospiralarms

    pop.zscale = zscale

    if widthModel == 'kj07':
        print "\tLoading KJ07 models...."
        kj_p_vals, kj_pdot_vals, kj_dists = beammodels.load_kj2007_models()
        print "\tDone\n"

    if not nostdout:
        print "\tGenerating evolved pulsars with parameters:"
        print "\t\tngen = {0}".format(ngen)
        print "\t\tUsing electron distn model {0}".format(
                                        pop.electronModel)
        print "\n\t\tPeriod mean, sigma = {0}, {1}".format(
                                                    pop.pmean,
                                                    pop.psigma)
        print "\t\tLuminosity mean, sigma = {0}, {1}".format(
                                                    pop.lummean,
                                                    pop.lumsigma)
        print "\t\tSpectral index mean, sigma = {0}, {1}".format(
                                                    pop.simean,
                                                    pop.sisigma)
        print "\t\tGalactic z scale height = {0} kpc".format(
                                                    pop.zscale)
        if widthModel is None:
            print "\t\tWidth {0}% ".format(duty)
        else:
            print "\t\tUsing Karastergiou & Johnston beam width model"

        # set up progress bar for fun :)
        prog = ProgressBar(min_value=0,
                           max_value=ngen,
                           width=65,
                           mode='dynamic')

    # create survey objects here and put them in a list
    if surveyList is not None:
        surveys = [Survey(s) for s in surveyList]
    else:
        # make an empty list here - makes some code just a little
        # simpler - can still loop over an empty list (ie zero times)
        surveys = []

    # initialise these counters to zero
    for surv in surveys:
        surv.ndet = 0  # number detected
        surv.nout = 0  # number outside survey region
        surv.nsmear = 0  # number smeared out
        surv.ntf = 0  # number too faint

    # this is the nitty-gritty loop for generating the pulsars
    while pop.ndet < ngen:
        pulsar = Pulsar()

        # initial age for pulsar
        pulsar.age = random.random() * age_max

        # initial period
        pulsar.p0 = -1.
        while pulsar.p0 <= 0.:
            pulsar.p0 = random.gauss(pop.pmean, pop.psigma)

        # initial magnetic field (in Gauss)
        pulsar.bfield_init = 10**random.gauss(pop.bmean, pop.bsigma)

        # aligment angle
        alignpulsar(pulsar, pop)

        # braking index
        if pop.braking_index == 0:
            pulsar.braking_index = 2.5 + 0.5 * random.random()
        else:
            pulsar.braking_index = float(pop.braking_index)

        # apply relevant spin down model
        pulsar.dead = False  # pulsar should start alive!

        if pop.spinModel == 'fk06':
            spindown_fk06(pulsar)

            # apply deathline if relevant
            if pop.deathline:
                bhattacharya_deathperiod_92(pulsar)

        elif pop.spinModel == 'cs06':
            # contopoulos and spitkovsky
            spindown_cs06(pulsar, pop)

        # if period > 10 seconds, just try a new one
        if pulsar.period > 10000.0 or pulsar.period < 10.:
            continue
        # cut on pdot too - this doesn't help
        if pulsar.pdot > 1.e-11 or pulsar.pdot < 1.e-18:
            continue

        # define pulse width (default = 6% = 18 degrees)
        if widthModel is None:
            width = (float(duty)/100.) * pulsar.period**0.9
            width = math.log10(width)
            width = dists.drawlnorm(width, 0.3)
        elif widthModel == 'kj07':
            # Karastergiou & Johnston beam model

            # find closest p, pdot in the kj lists
            logp = math.log10(pulsar.period)
            logpdot = math.log10(pulsar.pdot)

            p_idx = (np.abs(kj_p_vals - logp)).argmin()
            pd_idx = (np.abs(kj_pdot_vals - logpdot)).argmin()

            # pick a width from relevant model
            dist = kj_dists[p_idx][pd_idx][2]
            width = np.random.choice(dist)

            """
            width = beammodels.kj2007_width(pulsar)
            no_width = 0
            while width  == 0.0:
                no_width+=1
                width = beammodels.kj2007_width(pulsar)

                # if we get to five, then try a new pulsar
                if no_width == 5:
                    no_width = 0
                    continue
            """

        else:
            print "Undefined width model!"
            sys.exit()
        # print width
        # print pulsar.period, width, pulsar.pdot
        if width == 0.0:
            # some kj2007 models make many zero-width sources. Skip!
            continue
        pulsar.width_degree = 360. * width / pulsar.period

        # plough on - only if the pulsar isn't dead!
        if not pulsar.dead or keepdead:
            # is the pulsar beaming?
            pulsar_beaming(pulsar, pop.beamModel)
            # if not, then skip onto next pulsar
            if not pulsar.beaming:
                continue

            # position of the pulsar
            galacticDistribute(pulsar, pop)
            # birthvelocity
            birthVelocity(pulsar, pop)

            # model the xyz velocity
            go.vxyz(pulsar)

            # luminosity
            if lumDistType == 'fk06':
                luminosity_fk06(pulsar,
                                alpha=pop.lumPar1,
                                beta=pop.lumPar2,
                                gamma=pop.lumPar3)

            elif lumDistType == 'lnorm':
                pulsar.lum_1400 = dists.drawlnorm(pop.lumPar1, pop.lumPar2)

            elif lumDistType == 'pow':
                pulsar.lum_1400 = dists.powerlaw(pop.lummin,
                                                 pop.lummax,
                                                 pop.lumpow)
            else:
                # something's wrong!
                raise EvolveException('Invalid luminosity distn selected')

            # apply efficiency cutoff
            if efficiencycut is not None:
                if pulsar.efficiency() > efficiencycut:
                    pulsar.dead = True
                    if not keepdead:
                        continue

            # spectral index
            pulsar.spindex = random.gauss(pop.simean, pop.sisigma)

            # calculate galactic coords and distance
            pulsar.gl, pulsar.gb = go.xyz_to_lb(pulsar.galCoords)
            pulsar.dtrue = go.calc_dtrue(pulsar.galCoords)

            # then calc DM  using fortran libs
            if pop.electronModel == 'ne2001':
                pulsar.dm = go.ne2001_dist_to_dm(pulsar.dtrue,
                                                 pulsar.gl,
                                                 pulsar.gb)
            elif pop.electronModel == 'lmt85':
                pulsar.dm = go.lmt85_dist_to_dm(pulsar.dtrue,
                                                pulsar.gl,
                                                pulsar.gb)
            else:
                raise EvolveException('Invalid electron dist model selected')

            pulsar.scindex = scindex
            pulsar.t_scatter = go.scatter_bhat(pulsar.dm,
                                               pulsar.scindex)

            # if surveys are given, check if pulsar detected or not
            # in ANY of the surveys
            if surveyList is not None:
                detect_int = 0  # just a flag if pulsar is detected
                for surv in surveys:
                    SNR = surv.SNRcalc(pulsar, pop)

                    if SNR > surv.SNRlimit:
                        # SNR is over threshold
                        # increment the flag
                        # and survey ndetected
                        detect_int += 1
                        surv.ndet += 1
                        continue

                    elif SNR == -1:
                        # pulse is smeared out
                        surv.nsmear += 1
                        continue

                    elif SNR == -2:
                        # pulsar is outside survey region
                        surv.nout += 1
                        continue

                    else:
                        # pulsar is just too faint
                        surv.ntf += 1
                        continue

                # if detected, increment ndet (for whole population)
                # and redraw the progress bar
                if detect_int:
                    pop.ndet += 1
                    # update the counter
                    if not nostdout:
                        prog.increment_amount()
                        print prog, '\r',
                        sys.stdout.flush()

            else:
                # no survey list, just add the pulsar to population,
                # and increment number of pulsars
                pop.ndet += 1
                # update the counter
                if not nostdout:
                    prog.increment_amount()
                    print prog, '\r',
                    sys.stdout.flush()

            # pulsar isn't dead, add to population!
            pop.population.append(pulsar)

        else:
            # pulsar is dead. If no survey list,
            # just increment number of pulsars
            if surveyList is None:
                pop.ndet += 1
                # update the counter
                if not nostdout:
                    prog.increment_amount()
                    print prog, '\r',
                    sys.stdout.flush()

    if not nostdout:
        print "\n\n"
        print "  Total pulsars = {0}".format(len(pop.population))
        print "  Total detected = {0}".format(pop.ndet)

        for surv in surveys:
            print "\n  Results for survey '{0}'".format(surv.surveyName)
            print "    Number detected = {0}".format(surv.ndet)
            print "    Number too faint = {0}".format(surv.ntf)
            print "    Number smeared = {0}".format(surv.nsmear)
            print "    Number outside survey area = {0}".format(surv.nout)

    # save list of arguments into the pop
    try:
        argspec = inspect.getargspec(generate)
        key_values = [(arg, locals()[arg]) for arg in argspec.args]
        pop.arguments = {key: value for (key, value) in key_values}
    except SyntaxError:
        pass

    return pop
Пример #11
0
def generate(ngen,
             surveyList=None,
             age_max=1.0E9,
             pDistPars=[.3, .15],
             bFieldPars=[12.65, 0.55],
             birthVPars=[0.0, 180.],
             siDistPars= [-1.6,0.35],
             alignModel='orthogonal',
             lumDistType='fk06',
             lumDistPars=[-1.5, 0.5],
             alignTime=None,
             spinModel = 'fk06',
             beamModel = 'tm98',
             birthVModel = 'gaussian',
             electronModel='ne2001',
             braking_index=0,
             zscale=0.33,
             duty=5.,
             nodeathline=False,
             nostdout=False,
             nospiralarms=False):


    pop = Population()

    # set the parameters in the population object
    pop.pmean, pop.psigma = pDistPars
    pop.bmean, pop.bsigma = bFieldPars
    if lumDistType=='pow':
        try:
            pop.lummin, pop.lummax, pop.lumpow = \
                lumDistPars[0], lumDistPars[1], lumDistPars[2]
        except ValueError:
            raise EvolveException('Not enough lum distn parameters')
    else:
        pop.lumPar1, pop.lumPar2 = lumDistPars

    pop.simean, pop.sisigma = siDistPars
    pop.birthvmean, pop.birthvsigma = birthVPars
    
    pop.alignModel = alignModel
    pop.alignTime= alignTime
    pop.spinModel = spinModel
    pop.beamModel = beamModel
    pop.birthVModel = birthVModel
    pop.electronModel = electronModel

    pop.braking_index = braking_index
    pop.nodeathline = nodeathline
    pop.nospiralarms = nospiralarms

    pop.zscale = zscale

    if not nostdout:
        print "\tGenerating evolved pulsars with parameters:"
        print "\t\tngen = {0}".format(ngen)
        print "\t\tUsing electron distn model {0}".format(
                                        pop.electronModel)
        print "\n\t\tPeriod mean, sigma = {0}, {1}".format(
                                                    pop.pmean,
                                                    pop.psigma)
        print "\t\tLuminosity mean, sigma = {0}, {1}".format(
                                                    pop.lummean,
                                                    pop.lumsigma)
        print "\t\tSpectral index mean, sigma = {0}, {1}".format(
                                                    pop.simean,
                                                    pop.sisigma)
        print "\t\tGalactic z scale height = {0} kpc".format(
                                                    pop.zscale)

        print "\t\tWidth {0}% ".format(duty)

        # set up progress bar for fun :)
        prog = ProgressBar(min_value = 0,
                           max_value=ngen,
                           width=65,
                           mode='dynamic')

    # create survey objects here and put them in a list
    if surveyList is not None:
        surveys = [Survey(s) for s in surveyList]
    else:
        # make an empty list here - makes some code just a little
        # simpler - can still loop over an empty list (ie zero times)
        surveys=[]

    # initialise these counters to zero 
    for surv in surveys:
        surv.ndet =0 # number detected
        surv.nout=0 # number outside survey region
        surv.nsmear=0 # number smeared out
        surv.ntf=0 # number too faint

    # this is the nitty-gritty loop for generating the pulsars
    while pop.ndet < ngen:
        pulsar = Pulsar()

        # initial age for pulsar
        pulsar.age = random.random() * age_max

        # initial period
        pulsar.p0 = -1.
        while pulsar.p0 <= 0.:
            pulsar.p0 = random.gauss(pop.pmean, pop.psigma)

        # initial magnetic field (in Gauss)
        pulsar.bfield_init = 10**random.gauss(pop.bmean, pop.bsigma)

        # aligment angle
        alignpulsar(pulsar, pop)

        # braking index
        if pop.braking_index == 0:
            pulsar.braking_index = 2.5 + 0.5 * random.random()
        else:
            pulsar.braking_index = float(pop.braking_index)

        #apply relevant spin down model
        pulsar.dead = False # pulsar should start alive! 

        if pop.spinModel == 'fk06':
            spindown_fk06(pulsar)

            # apply deathline if relevant
            if not pop.nodeathline:
                bhattacharya_deathperiod_92(pulsar)

        elif pop.spinModel == 'cs06':
            # contopoulos and spitkovsky
            spindown_cs06(pulsar, pop)

        # define pulse width (default = 5% = 18 degrees)
        pulsar.width_degree = 360. * duty /100.

        # plough on - only if the pulsar isn't dead!
        if not pulsar.dead:
            # is the pulsar beaming? 
            pulsar_beaming(pulsar, pop.beamModel)
            # if not, then skip onto next pulsar
            if not pulsar.beaming:
                continue

            # position of the pulsar       
            galacticDistribute(pulsar, pop)
            # birthvelocity
            birthVelocity(pulsar, pop)

            # model the xyz velocity
            go.vxyz(pulsar)

            # luminosity
            if lumDistType == 'fk06':
                luminosity_fk06(pulsar, alpha=pop.lumPar1, beta=pop.lumPar2)

            elif lumDistType == 'lnorm':
                pulsar.lum_1400 = populate._drawlnorm(pop.lumPar1, pop.lumPar2)

            elif lumDistType == 'pow':
                pulsar.lum_1400 = populate._powerlaw(pop.lummin,
                                                     pop.lummax,
                                                     pop.lumpow)
            else:
                # something's wrong!
                raise EvolveException('Invalid luminosity distn selected')

            # spectral index
            pulsar.spindex = random.gauss(pop.simean, pop.sisigma)

            # calculate galactic coords and distance
            pulsar.gl, pulsar.gb = go.xyz_to_lb(pulsar.galCoords)
            pulsar.dtrue = go.calc_dtrue(pulsar.galCoords)

            # then calc DM  using fortran libs
            if pop.electronModel == 'ne2001':
                pulsar.dm = go.ne2001_dist_to_dm(pulsar.dtrue,
                                                   pulsar.gl, 
                                                   pulsar.gb)
            elif pop.electronModel == 'lmt85':
                pulsar.dm = go.lmt85_dist_to_dm(pulsar.dtrue,
                                                  pulsar.gl, 
                                                  pulsar.gb)

            # if surveys are given, check if pulsar detected or not
            # in ANY of the surveys
            if surveyList is not None:
                detect_int = 0 # just a flag if pulsar is detected
                for surv in surveys:
                    SNR = surv.SNRcalc(pulsar, pop)

                    if SNR > surv.SNRlimit:
                        # SNR is over threshold
                        # increment the flag 
                        # and survey ndetected
                        detect_int += 1
                        surv.ndet += 1
                        continue

                    elif SNR == -1:
                        # pulse is smeared out
                        surv.nsmear += 1
                        continue

                    elif SNR == -2:
                        # pulsar is outside survey region
                        surv.nout += 1
                        continue

                    else:
                        #pulsar is just too faint
                        surv.ntf += 1
                        continue 
            
                # if detected, increment ndet (for whole population)
                # and redraw the progress bar
                if detect_int:
                    pop.ndet += 1
                    # update the counter
                    if not nostdout:
                        prog.increment_amount()
                        print prog, '\r',
                        sys.stdout.flush()

            else:
                # no survey list, just add the pulsar to population,
                # and increment number of pulsars
                pop.ndet +=1
                # update the counter
                if not nostdout:
                    prog.increment_amount()
                    print prog, '\r',
                    sys.stdout.flush()

            # pulsar isn't dead, add to population!
            pop.population.append(pulsar)

        else:
            # pulsar is dead. If no survey list, 
            # just increment number of pulsars
            if surveyList is None:
                pop.ndet += 1
                # update the counter
                if not nostdout:
                    prog.increment_amount()
                    print prog, '\r',
                    sys.stdout.flush()


    if not nostdout:
        print "\n\n"
        print "  Total pulsars = {0}".format(len(pop.population))
        print "  Total detected = {0}".format(pop.ndet)

        for surv in surveys:
            print "\n  Results for survey '{0}'".format(surv.surveyName)
            print "    Number detected = {0}".format(surv.ndet)
            print "    Number too faint = {0}".format(surv.ntf)
            print "    Number smeared = {0}".format(surv.nsmear)
            print "    Number outside survey area = {0}".format(surv.nout)

    return pop
Пример #12
0
#!/usr/bin/python

import sys
import argparse
import math
import random

import cPickle

import matplotlib.pyplot as plt
from matplotlib.widgets import Button, RadioButtons, CheckButtons

import numpy as np

from population import Population 
from pulsar import Pulsar

f = open(sys.argv[1], 'rb')
p = Pulsar()

p = cPickle.load(f)
f.close()

#print p.size()
        
for psr in p.population:
#	print psr.period
	print psr.gl, psr.gb, psr.dm, psr.dtrue, psr.t_scatter, psr.lum_1400, psr.width_degree, psr.period, psr.spindex, psr.snr, psr.delta, psr.dead
#       if psr.dead:
#	    print psr.gl, psr.gb, psr.dm, psr.dtrue, psr.t_scatter, psr.lum_1400, psr.width_degree, psr.period, psr.spindex, psr.snr, psr.delta, psr.dead