Exemple #1
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