Ejemplo n.º 1
0
    def _simulate_stream(self, age):
        sigv_age = (0.3 * 3.2) / age
        impacts = self._compute_impact_times(age)
        # Smooth stream.
        # stream_smooth_leading = gd1_util.setup_gd1model(age=age,
        #     isob=self.isob,
        #     leading=True,
        #     new_orb_lb=self.new_orb_lb,
        #     sigv=sigv_age)
        stream_smooth_trailing = gd1_util.setup_gd1model(age=age,
            isob=self.isob,
            leading=False,
            new_orb_lb=self.new_orb_lb,
            sigv=sigv_age)
        # Leading stream.
        # stream_leading = gd1_util.setup_gd1model(age=age,
        #     hernquist=self.hernquist_profile,
        #     isob=self.isob,
        #     leading=True,
        #     length_factor=self.length_factor,
        #     new_orb_lb=self.new_orb_lb,
        #     sigv=sigv_age,
        #     timpact=impacts)
        # Trailing stream.
        stream_trailing = gd1_util.setup_gd1model(age=age,
            hernquist=self.hernquist_profile,
            isob=self.isob,
            leading=False,
            length_factor=self.length_factor,
            new_orb_lb=self.new_orb_lb,
            sigv=sigv_age,
            timpact=impacts)

        # return stream_smooth_leading, stream_smooth_trailing, stream_leading, stream_trailing
        return None, stream_smooth_trailing, None, stream_trailing
Ejemplo n.º 2
0
def sample_streamdf_smooth(N,
                           nobarpot,
                           stream='Pal5',
                           fo='sample_trailing.dat',
                           write=False,
                           trailing=True):
    '''
        Sample N points for a given stream using the freq-angle framework
        i.e., sample in the nobarpot, then integrate them back to stripping time
        and then integrat them forward in barred potential. Effects of progenitor's motion
        is not considered
        '''

    if stream == 'Pal5':
        sdf_trailing = pal5_util.setup_pal5model(pot=nobarpot)
        sdf_leading = pal5_util.setup_pal5model(pot=nobarpot, leading=True)

    elif stream == 'GD1':
        sdf_trailing = gd1_util.setup_gd1model(pot=nobarpot, leading=False)
        sdf_leading = gd1_util.setup_gd1model(pot=nobarpot)

    fo = stream + fo
    if trailing:

        R, vR, vT, z, vz, phi, dt = sdf_trailing.sample(n=N, returndt=True)
        fo = open(fo, 'w')

    else:

        R, vR, vT, z, vz, phi, dt = sdf_leading.sample(n=N, returndt=True)
        fo_lead = fo.replace('trailing', 'leading')
        fo = open(fo_lead, 'w')

    if write:
        fo.write("#R   phi   z   vR    vT    vz    ts" + "\n")

        for jj in range(N):
            fo.write(
                str(R[jj]) + "   " + str(phi[jj]) + "   " + str(z[jj]) +
                "   " + str(vR[jj]) + "   " + str(vT[jj]) + "   " +
                str(vz[jj]) + "   " + str(dt[jj]) + "\n")

        fo.close()

    else:

        return (R, phi, z, vR, vT, vz, dt)
Ejemplo n.º 3
0
def aparxv_GD1_stream_from_multiple_pkl(pot=MWPotential2014,sampling=7400,npart=116,td=9.0):
    
    '''
    compute apar,x,v from one or multiple pickle files
    pkl_fname : without fragment index and extension
    '''
     
    sdf_smooth= gd1_util.setup_gd1model(pot=pot)
    pkl_file='pkl_files/gd1pepper_Plummer_td{}_{}sampling_MW2014'.format(td,sampling)
    pkl_file=pkl_file + '_{}.pkl'
        
    apar=[]
    x_stream=[]
    y_stream=[]
    z_stream=[]
    vx_stream=[]
    vy_stream=[]
    vz_stream=[]
    timpact=[]
    
    for ii in range(npart):
        pkl_fname=pkl_file.format(ii)
        with open(pkl_fname,'rb') as savefile:
                    
            print (pkl_fname)

            sdf_pepper= pickle.load(savefile,encoding='latin1')
            ap,x,y,z,vx,vy,vz= aparxv_stream(sdf_smooth,sdf_pepper)
            apar.extend(ap)
            x_stream.extend(x)
            y_stream.extend(y)
            z_stream.extend(z)
            vx_stream.extend(vx)
            vy_stream.extend(vy)
            vz_stream.extend(vz)
            timpact.extend(sdf_pepper._timpact)
           
    return (timpact,apar,x_stream,y_stream,z_stream,vx_stream,vy_stream,vz_stream)
Ejemplo n.º 4
0
def sample_streamdf_noprog(N,
                           barpot,
                           nobarpot,
                           stream='Pal5',
                           fo='sample_trailing.dat',
                           write=False,
                           trailing=True):
    '''
        Sample N points for a given stream using the freq-angle framework
        i.e., sample in the nobarpot, then integrate them back to stripping time
        and then integrat them forward in barred potential. Effects of progenitor's motion
        is not considered
        '''
    print("WARNING: Effects of progenitor's motion neglected")

    if stream == 'Pal5':
        sdf_trailing = pal5_util.setup_pal5model(pot=nobarpot)
        sdf_leading = pal5_util.setup_pal5model(pot=nobarpot, leading=True)

    elif stream == 'GD1':
        sdf_trailing = gd1_util.setup_gd1model(pot=nobarpot, leading=False)
        sdf_leading = gd1_util.setup_gd1model(pot=nobarpot)

    fo = stream + fo
    if trailing:

        R, vR, vT, z, vz, phi, dt = sdf_trailing.sample(n=N, returndt=True)
        fo = open(fo, 'w')

    else:

        R, vR, vT, z, vz, phi, dt = sdf_leading.sample(n=N, returndt=True)
        fo_lead = fo.replace('trailing', 'leading')
        fo = open(fo_lead, 'w')

    finalR = numpy.empty(N)
    finalvR = numpy.empty(N)
    finalvT = numpy.empty(N)
    finalvz = numpy.empty(N)
    finalphi = numpy.empty(N)
    finalz = numpy.empty(N)
    tt = numpy.empty(N)

    for ii in range(N):

        o = Orbit([R[ii], vR[ii], vT[ii], z[ii], vz[ii], phi[ii]])
        o.turn_physical_off()
        ts = numpy.linspace(0., -dt[ii], 1001)

        o.integrate(ts, nobarpot)
        orb = Orbit([
            o.R(ts[-1]),
            o.vR(ts[-1]),
            o.vT(ts[-1]),
            o.z(ts[-1]),
            o.vz(ts[-1]),
            o.phi(ts[-1])
        ])

        ts_future = numpy.linspace(-dt[ii], 0., 1001)
        #forward integrate in barred potential
        orb.integrate(ts_future, barpot)
        finalR[ii] = orb.R(ts_future[-1])
        finalphi[ii] = orb.phi(ts_future[-1])
        finalz[ii] = orb.z(ts_future[-1])
        finalvR[ii] = orb.vR(ts_future[-1])
        finalvT[ii] = orb.vT(ts_future[-1])
        finalvz[ii] = orb.vz(ts_future[-1])
        tt[ii] = dt[ii]

    if write:
        fo.write("#R   phi   z   vR    vT    vz    ts" + "\n")

        for jj in range(N):
            fo.write(
                str(finalR[jj]) + "   " + str(finalphi[jj]) + "   " +
                str(finalz[jj]) + "   " + str(finalvR[jj]) + "   " +
                str(finalvT[jj]) + "   " + str(finalvz[jj]) + "   " +
                str(tt[jj]) + "\n")

        fo.close()

    else:

        return (finalR, finalphi, finalz, finalvR, finalvT, finalvz, tt)
Ejemplo n.º 5
0
def run_simulations(sdf_pepper, sdf_smooth, options):
    # Setup apar grid
    apar = numpy.arange(options.amin, options.amax, options.dapar)
    # Check whether the output files already exist and if so, get the amin, amax, da from them
    if os.path.exists(options.outdens):
        # First read the file to check apar
        apar_file = numpy.genfromtxt(options.outdens,
                                     delimiter=',',
                                     max_rows=1)
        print(numpy.amax(numpy.fabs(apar_file - apar)))
        assert numpy.amax(
            numpy.fabs(apar_file - apar)
        ) < 10.**-5., 'apar according to options does not correspond to apar already in outdens'
        apar_file = numpy.genfromtxt(options.outomega,
                                     delimiter=',',
                                     max_rows=1)
        print(numpy.amax(numpy.fabs(apar_file - apar)))
        assert numpy.amax(
            numpy.fabs(apar_file - apar)
        ) < 10.**-5., 'apar according to options does not correspond to apar already in outomega'
        csvdens = open(options.outdens, 'a')
        csvomega = open(options.outomega, 'a')
        denswriter = csv.writer(csvdens, delimiter=',')
        omegawriter = csv.writer(csvomega, delimiter=',')
    else:
        csvdens = open(options.outdens, 'w')
        csvomega = open(options.outomega, 'w')
        denswriter = csv.writer(csvdens, delimiter=',')
        omegawriter = csv.writer(csvomega, delimiter=',')
        # First write apar and the smooth calculations
        denswriter.writerow([a for a in apar])
        omegawriter.writerow([a for a in apar])
        if sdf_smooth is None and options.stream.lower() == 'gd1like':
            sdf_smooth = gd1_util.setup_gd1model(age=options.age)
        elif sdf_smooth is None and options.stream.lower() == 'pal5like':
            sdf_smooth = pal5_util.setup_pal5model(age=options.age)
        dens_unp = [sdf_smooth._density_par(a) for a in apar]
        denswriter.writerow(dens_unp)
        omega_unp = [sdf_smooth.meanOmega(a, oned=True) for a in apar]
        omegawriter.writerow(omega_unp)
        csvdens.flush()
        csvomega.flush()
    # Parse mass
    massrange = parse_mass(options.mass)
    if len(massrange) == 1:
        sample_GM= lambda: 10.**(massrange[0]-10.)\
            /bovy_conversion.mass_in_1010msol(V0,R0)
        rate = options.timescdm * dNencdm(sdf_pepper,
                                          10.**massrange[0],
                                          Xrs=options.Xrs,
                                          plummer=options.plummer,
                                          rsfac=options.rsfac,
                                          sigma=options.sigma)
    elif len(massrange) == 2:
        # Sample from power-law
        if not options.cutoff is None:
            sample_GM = lambda: powerlaw_wcutoff(massrange, options.cutoff)
        elif numpy.fabs(options.massexp + 1.5) < 10.**-6.:
            sample_GM= lambda: 10.**(massrange[0]\
                                         +(massrange[1]-massrange[0])\
                                         *numpy.random.uniform())\
                                         /bovy_conversion.mass_in_msol(V0,R0)
        else:
            sample_GM= lambda: (10.**((options.massexp+1.5)*massrange[0])\
                                    +(10.**((options.massexp+1.5)*massrange[1])\
                                          -10.**((options.massexp+1.5)*massrange[0]))\
                                    *numpy.random.uniform())**(1./(options.massexp+1.5))\
                                    /bovy_conversion.mass_in_msol(V0,R0)
        rate_range = numpy.arange(massrange[0] + 0.5, massrange[1] + 0.5, 1)
        rate= options.timescdm\
            *numpy.sum([dNencdm(sdf_pepper,10.**r,Xrs=options.Xrs,
                                plummer=options.plummer,rsfac=options.rsfac,
                                sigma=options.sigma)
                        for r in rate_range])
        if not options.cutoff is None:
            rate*= integrate.quad(lambda x: x**-1.5\
                                      *numpy.exp(-10.**options.cutoff/x),
                                  10.**massrange[0],10.**massrange[1])[0]\
                                  /integrate.quad(lambda x: x**-1.5,
                                                  10.**massrange[0],
                                                  10.**massrange[1])[0]
    print("Using an overall rate of %f" % rate)
    sample_rs = lambda x: rs(x * bovy_conversion.mass_in_1010msol(V0, R0) * 10.
                             **10.,
                             plummer=options.plummer,
                             rsfac=options.rsfac)
    # Simulate
    start = time.time()
    ns = 0
    while True:
        if options.nsamples is None and time.time() >= (start +
                                                        options.dt * 60.):
            break
        elif not options.nsamples is None and ns > options.nsamples:
            break
        ns += 1
        sdf_pepper.simulate(rate=rate,
                            sample_GM=sample_GM,
                            sample_rs=sample_rs,
                            Xrs=options.Xrs,
                            sigma=options.sigma / V0)
        # Compute density and meanOmega and save
        try:
            densOmega = numpy.array(
                [sdf_pepper._densityAndOmega_par_approx(a) for a in apar]).T
        except IndexError:  # no hit
            dens_unp = [sdf_smooth._density_par(a) for a in apar]
            omega_unp = [sdf_smooth.meanOmega(a, oned=True) for a in apar]
            denswriter.writerow(dens_unp)
            omegawriter.writerow(omega_unp)
        else:
            denswriter.writerow(list(densOmega[0]))
            omegawriter.writerow(list(densOmega[1]))
        csvdens.flush()
        csvomega.flush()
    csvdens.close()
    csvomega.close()
    return None
Ejemplo n.º 6
0

if __name__ == '__main__':
    parser = get_options()
    options, args = parser.parse_args()
    # Setup
    if options.stream.lower() == 'gd1like':
        timpacts = parse_times(options.timpacts, options.age)
        if options.timpacts == '64sampling':
            # We've cached this one
            with open('gd1pepper_64.pkl', 'rb') as savefile:
                sdf_pepper = pickle.load(savefile)
        else:
            sdf_pepper = gd1_util.setup_gd1model(
                timpact=timpacts,
                hernquist=not options.plummer,
                age=options.age,
                length_factor=options.length_factor)

    elif options.stream.lower() == 'pal5like':
        timpacts = parse_times(options.timpacts, options.age)
        if options.timpacts == '64sampling':
            # We've cached this one
            with open('pal5_64sampling.pkl', 'rb') as savefile:
                sdf_smooth = pickle.load(savefile)
                sdf_pepper = pickle.load(savefile)
        else:
            sdf_pepper = pal5_util.setup_pal5model(
                timpact=timpacts,
                hernquist=not options.plummer,
                age=options.age,
Ejemplo n.º 7
0
def sample_streamdf_smooth(N,
                           nobarpot,
                           stream='Pal5',
                           prog=0.,
                           sigv=0.3,
                           trail_dir='',
                           fo='sample_trailing.dat',
                           write=False,
                           trailing=True):
    '''
        Sample N points for a given stream using the freq-angle framework
        i.e., sample in the nobarpot, then integrate them back to stripping time
        and then integrat them forward in barred potential. Effects of progenitor's motion
        is not considered
        '''

    if stream == 'Pal5':
        sdf_trailing = pal5_util.setup_pal5model(pot=nobarpot)
        sdf_leading = pal5_util.setup_pal5model(pot=nobarpot, leading=True)

    elif stream == 'GD1':
        if prog == 0:
            sdf_trailing = gd1_util.setup_gd1model(pot=nobarpot, leading=False)
            sdf_leading = gd1_util.setup_gd1model(pot=nobarpot)

        elif prog == -40.:
            new_orb_lb = [
                188.04928416766532, 51.848594007807456, 7.559027173643999,
                12.260258757214746, -5.140630283489461, 7.162732847549563
            ]
            isob = 0.45
            td = 3.2
            sdf_trailing = gd1_util.setup_gd1model(pot=nobarpot,
                                                   leading=False,
                                                   age=td,
                                                   new_orb_lb=new_orb_lb,
                                                   isob=isob,
                                                   sigv=sigv)
            sdf_leading = gd1_util.setup_gd1model(pot=nobarpot,
                                                  age=td,
                                                  new_orb_lb=new_orb_lb,
                                                  isob=isob,
                                                  sigv=sigv)

    fo = stream + fo
    if trailing:

        R, vR, vT, z, vz, phi, dt = sdf_trailing.sample(n=N, returndt=True)
        fo = open(trail_dir + fo, 'w')

    else:

        R, vR, vT, z, vz, phi, dt = sdf_leading.sample(n=N, returndt=True)
        lead_dir = trail_dir.replace('trailing', 'leading')
        fo_lead = fo.replace('trailing', 'leading')
        fo = open(lead_dir + fo_lead, 'w')

    if write:
        fo.write("#R   phi   z   vR    vT    vz    ts" + "\n")

        for jj in range(N):
            fo.write(
                str(R[jj]) + "   " + str(phi[jj]) + "   " + str(z[jj]) +
                "   " + str(vR[jj]) + "   " + str(vT[jj]) + "   " +
                str(vz[jj]) + "   " + str(dt[jj]) + "\n")

        fo.close()

    else:

        return (R, phi, z, vR, vT, vz, dt)
Ejemplo n.º 8
0
def sample_streamdf_noprog(nsamp,
                           barpot,
                           nobarpot,
                           stream='Pal5',
                           sigv=0.3,
                           prog=0.,
                           trail_dir='',
                           fo='sample_trailing.dat',
                           write=False,
                           trailing=True):
    '''
        Sample N points for a given stream using the freq-angle framework
        i.e., sample in the nobarpot, then integrate them back to stripping time
        and then integrat them forward in barred potential. Effects of progenitor's motion
        is not considered
        '''
    print("WARNING: Effects of progenitor's motion neglected")

    if stream == 'Pal5':
        sdf_trailing = pal5_util.setup_pal5model(pot=nobarpot)
        sdf_leading = pal5_util.setup_pal5model(pot=nobarpot, leading=True)

    elif stream == 'GD1':
        if prog == 0:
            sdf_trailing = gd1_util.setup_gd1model(pot=nobarpot, leading=False)
            sdf_leading = gd1_util.setup_gd1model(pot=nobarpot)

        elif prog == -40.:
            new_orb_lb = [
                188.04928416766532, 51.848594007807456, 7.559027173643999,
                12.260258757214746, -5.140630283489461, 7.162732847549563
            ]
            isob = 0.45
            td = 3.2
            sdf_trailing = gd1_util.setup_gd1model(pot=nobarpot,
                                                   leading=False,
                                                   age=td,
                                                   new_orb_lb=new_orb_lb,
                                                   isob=isob,
                                                   sigv=sigv)
            sdf_leading = gd1_util.setup_gd1model(pot=nobarpot,
                                                  age=td,
                                                  new_orb_lb=new_orb_lb,
                                                  isob=isob,
                                                  sigv=sigv)

    fo = stream + fo
    if trailing:

        R, vR, vT, z, vz, phi, dt = sdf_trailing.sample(n=nsamp, returndt=True)
        fo = open(trail_dir + fo, 'w')

    else:

        R, vR, vT, z, vz, phi, dt = sdf_leading.sample(n=nsamp, returndt=True)
        lead_dir = trail_dir.replace('trailing', 'leading')
        fo_lead = fo.replace('trailing', 'leading')
        fo = open(lead_dir + fo_lead, 'w')

    finalR = numpy.empty(nsamp)
    finalvR = numpy.empty(nsamp)
    finalvT = numpy.empty(nsamp)
    finalvz = numpy.empty(nsamp)
    finalphi = numpy.empty(nsamp)
    finalz = numpy.empty(nsamp)
    tt = numpy.empty(nsamp)

    for ii in range(nsamp):

        o = Orbit([R[ii], vR[ii], vT[ii], z[ii], vz[ii], phi[ii]])
        o.turn_physical_off()
        ts = numpy.linspace(0., -dt[ii], 1001)

        o.integrate(ts, nobarpot)
        orb = Orbit([
            o.R(ts[-1]),
            o.vR(ts[-1]),
            o.vT(ts[-1]),
            o.z(ts[-1]),
            o.vz(ts[-1]),
            o.phi(ts[-1])
        ])

        ts_future = numpy.linspace(-dt[ii], 0., 1001)
        #forward integrate in barred potential
        orb.integrate(ts_future, barpot)
        finalR[ii] = orb.R(ts_future[-1])
        finalphi[ii] = orb.phi(ts_future[-1])
        finalz[ii] = orb.z(ts_future[-1])
        finalvR[ii] = orb.vR(ts_future[-1])
        finalvT[ii] = orb.vT(ts_future[-1])
        finalvz[ii] = orb.vz(ts_future[-1])
        tt[ii] = dt[ii]

    if write:
        fo.write("#R   phi   z   vR    vT    vz    ts" + "\n")

        for jj in range(nsamp):
            fo.write(
                str(finalR[jj]) + "   " + str(finalphi[jj]) + "   " +
                str(finalz[jj]) + "   " + str(finalvR[jj]) + "   " +
                str(finalvT[jj]) + "   " + str(finalvz[jj]) + "   " +
                str(tt[jj]) + "\n")

        fo.close()

    else:

        return (finalR, finalphi, finalz, finalvR, finalvT, finalvz, tt)
    lead_name = 'trailing'
    lead = False

if options.plummer:
    hernquist = False
    sub_type = 'Plummer'
else:
    hernquist = True
    sub_type = 'Hernquist'

sigv_age = numpy.round((0.3 * 3.2) / options.td, 2)
print("velocity dispersion is set to %f" % sigv_age)

sdf_smooth = gd1_util.setup_gd1model(age=options.td,
                                     new_orb_lb=new_orb_lb,
                                     isob=isob,
                                     leading=lead,
                                     sigv=sigv_age)

pepperfilename = 'gd1_pepper_{}_{}_sigv{}_td{}_{}sampling_progphi1{}_MW2014_{}.pkl'.format(
    lead_name, sub_type, sigv_age, options.td, len(timpacts), prog,
    options.tind)

sdf_pepper = gd1_util.setup_gd1model(timpact=timpactn,
                                     age=options.td,
                                     hernquist=hernquist,
                                     new_orb_lb=new_orb_lb,
                                     isob=isob,
                                     leading=lead,
                                     length_factor=1.,
                                     sigv=sigv_age)
Ejemplo n.º 10
0
    return parser
    


            
apar=numpy.arange(0.03,1.15,0.01)

parser= get_options()
options,args= parser.parse_args()

ind=options.ind


index = [16,28,37,14,31,6,3,39,18,17,9,33,8,30,36,10,32,38,21,15,13,5,2,34,20]

sdf_smooth= gd1_util.setup_gd1model()
for jj in index :
    

        with open('impacted_pkl_files/GD1_7400_on_128impact_Plummer_td9.0_Mmin105_MW2014_{}.pkl'.format(jj),'rb') as savefile:
                #sdf_smooth=pickle.load(savefile,encoding='latin1')
                sdf_pepper= pickle.load(savefile,encoding='latin1')
        
        
        a=apar[options.ind]
        dens_unp= sdf_smooth._density_par(a)
        omega_unp=sdf_smooth.meanOmega(a,oned=True)
        
        densOmega= sdf_pepper._densityAndOmega_par_approx(a)
        
        
def run_simulations(sdf_pepper,sdf_smooth,options):
    # Setup apar grid
    apar= numpy.arange(options.amin,options.amax,options.dapar)
    # Check whether the output files already exist and if so, get the amin, amax, da from them
    if os.path.exists(options.outdens):
        # First read the file to check apar
        apar_file= numpy.genfromtxt(options.outdens,delimiter=',',max_rows=1)
        print numpy.amax(numpy.fabs(apar_file-apar))
        assert numpy.amax(numpy.fabs(apar_file-apar)) < 10.**-5., 'apar according to options does not correspond to apar already in outdens'
        apar_file= numpy.genfromtxt(options.outomega,delimiter=',',max_rows=1)
        print numpy.amax(numpy.fabs(apar_file-apar))
        assert numpy.amax(numpy.fabs(apar_file-apar)) < 10.**-5., 'apar according to options does not correspond to apar already in outomega'
        csvdens= open(options.outdens,'a')
        csvomega= open(options.outomega,'a')       
        denswriter= csv.writer(csvdens,delimiter=',')
        omegawriter= csv.writer(csvomega,delimiter=',')
    else:
        csvdens= open(options.outdens,'w')
        csvomega= open(options.outomega,'w')
        denswriter= csv.writer(csvdens,delimiter=',')
        omegawriter= csv.writer(csvomega,delimiter=',')
        # First write apar and the smooth calculations
        denswriter.writerow([a for a in apar])
        omegawriter.writerow([a for a in apar])
        if sdf_smooth is None and options.stream.lower() == 'gd1like':
            sdf_smooth= gd1_util.setup_gd1model(age=options.age)
        elif sdf_smooth is None and options.stream.lower() == 'pal5like':
            sdf_smooth= pal5_util.setup_pal5model(age=options.age)
        dens_unp= [sdf_smooth._density_par(a) for a in apar]
        denswriter.writerow(dens_unp)
        omega_unp= [sdf_smooth.meanOmega(a,oned=True) for a in apar]
        omegawriter.writerow(omega_unp)
        csvdens.flush()
        csvomega.flush()
    # Parse mass
    massrange= parse_mass(options.mass)
    if len(massrange) == 1:
        sample_GM= lambda: 10.**(massrange[0]-10.)\
            /bovy_conversion.mass_in_1010msol(V0,R0)
        rate= options.timescdm*dNencdm(sdf_pepper,
                                       10.**massrange[0],Xrs=options.Xrs,
                                       plummer=options.plummer,
                                       rsfac=options.rsfac,
                                       sigma=options.sigma)
    elif len(massrange) == 2:
        # Sample from power-law
        if not options.cutoff is None:
            sample_GM= lambda: powerlaw_wcutoff(massrange,options.cutoff)
        elif numpy.fabs(options.massexp+1.5) < 10.**-6.:
            sample_GM= lambda: 10.**(massrange[0]\
                                         +(massrange[1]-massrange[0])\
                                         *numpy.random.uniform())\
                                         /bovy_conversion.mass_in_msol(V0,R0)
        else:
            sample_GM= lambda: (10.**((options.massexp+1.5)*massrange[0])\
                                    +(10.**((options.massexp+1.5)*massrange[1])\
                                          -10.**((options.massexp+1.5)*massrange[0]))\
                                    *numpy.random.uniform())**(1./(options.massexp+1.5))\
                                    /bovy_conversion.mass_in_msol(V0,R0)
        rate_range= numpy.arange(massrange[0]+0.5,massrange[1]+0.5,1)
        rate= options.timescdm\
            *numpy.sum([dNencdm(sdf_pepper,10.**r,Xrs=options.Xrs,
                                plummer=options.plummer,rsfac=options.rsfac,
                                sigma=options.sigma)
                        for r in rate_range])
        if not options.cutoff is None:
            rate*= integrate.quad(lambda x: x**-1.5\
                                      *numpy.exp(-10.**options.cutoff/x),
                                  10.**massrange[0],10.**massrange[1])[0]\
                                  /integrate.quad(lambda x: x**-1.5,
                                                  10.**massrange[0],
                                                  10.**massrange[1])[0]
    print "Using an overall rate of %f" % rate
    sample_rs= lambda x: rs(x*bovy_conversion.mass_in_1010msol(V0,R0)*10.**10.,
                            plummer=options.plummer,rsfac=options.rsfac)
    # Simulate
    start= time.time()
    ns= 0
    while True:
        if options.nsamples is None and time.time() >= (start+options.dt*60.):
            break
        elif not options.nsamples is None and ns > options.nsamples:
            break
        ns+= 1
        sdf_pepper.simulate(rate=rate,sample_GM=sample_GM,sample_rs=sample_rs,
                            Xrs=options.Xrs,sigma=options.sigma/V0)
        # Compute density and meanOmega and save
        try:
            densOmega= numpy.array([sdf_pepper._densityAndOmega_par_approx(a)
                                    for a in apar]).T
        except IndexError: # no hit
            dens_unp= [sdf_smooth._density_par(a) for a in apar]
            omega_unp= [sdf_smooth.meanOmega(a,oned=True) for a in apar]
            denswriter.writerow(dens_unp)
            omegawriter.writerow(omega_unp)
        else:
            denswriter.writerow(list(densOmega[0]))
            omegawriter.writerow(list(densOmega[1]))
        csvdens.flush()
        csvomega.flush()
    csvdens.close()
    csvomega.close()
    return None
            denswriter.writerow(list(densOmega[0]))
            omegawriter.writerow(list(densOmega[1]))
        csvdens.flush()
        csvomega.flush()
    csvdens.close()
    csvomega.close()
    return None
        
if __name__ == '__main__':
    parser= get_options()
    options,args= parser.parse_args()
    # Setup 
    if options.stream.lower() == 'gd1like':
        timpacts= parse_times(options.timpacts,options.age)
        sdf_pepper= gd1_util.setup_gd1model(timpact=timpacts,
                                            hernquist=not options.plummer,
                                            age=options.age,
                                            length_factor=options.length_factor)
    elif options.stream.lower() == 'pal5like':
        timpacts= parse_times(options.timpacts,options.age)
        if options.timpacts == '64sampling':
            # We've cached this one
            with open('pal5_64sampling.pkl','rb') as savefile:
                sdf_smooth= pickle.load(savefile)
                sdf_pepper= pickle.load(savefile)
        else:
            sdf_pepper= pal5_util.setup_pal5model(timpact=timpacts,
                                                  hernquist=not options.plummer,
                                                  age=options.age,
                                                  length_factor=options.length_factor)
    # Need smooth?
    if options.amax is None or options.amin is None: