def add_pulsar_parameters( table, B_mean=12.05, B_stdv=0.55, P_mean=0.3, P_stdv=0.15, random_state="random-seed", ): """Add pulsar parameters to the table. For the initial normal distribution of period and logB can exist the following Parameters: B_mean=12.05[log Gauss], B_stdv=0.55, P_mean=0.3[s], P_stdv=0.15 Parameters ---------- random_state : {int, 'random-seed', 'global-rng', `~numpy.random.RandomState`} Defines random number generator initialisation. Passed to `~gammapy.utils.random.get_random_state`. """ random_state = get_random_state(random_state) # Read relevant columns age = table["age"].quantity # Draw the initial values for the period and magnetic field def p_dist(x): return np.exp(-0.5 * ((x - P_mean) / P_stdv) ** 2) p0_birth = draw(0, 2, len(table), p_dist, random_state=random_state) p0_birth = Quantity(p0_birth, "s") log10_b_psr = random_state.normal(B_mean, B_stdv, len(table)) b_psr = Quantity(10 ** log10_b_psr, "G") # Compute pulsar parameters psr = Pulsar(p0_birth, b_psr) p0 = psr.period(age) p1 = psr.period_dot(age) p1_birth = psr.P_dot_0 tau = psr.tau(age) tau_0 = psr.tau_0 l_psr = psr.luminosity_spindown(age) l0_psr = psr.L_0 # Add columns to table table["P0"] = Column(p0, unit="s", description="Pulsar period") table["P1"] = Column(p1, unit="", description="Pulsar period derivative") table["P0_birth"] = Column(p0_birth, unit="s", description="Pulsar birth period") table["P1_birth"] = Column( p1_birth, unit="", description="Pulsar birth period derivative" ) table["CharAge"] = Column(tau, unit="yr", description="Pulsar characteristic age") table["Tau0"] = Column(tau_0, unit="yr") table["L_PSR"] = Column(l_psr, unit="erg s-1") table["L0_PSR"] = Column(l0_psr, unit="erg s-1") table["B_PSR"] = Column( b_psr, unit="Gauss", description="Pulsar magnetic field at the poles" ) return table
def make_base_catalog_galactic( n_sources, rad_dis="YK04", vel_dis="H05", max_age="1e6 yr", spiralarms=True, n_ISM="1 cm-3", random_state="random-seed", ): """Make a catalog of Galactic sources, with basic source parameters. Choose a radial distribution, a velocity distribution, the number of pulsars n_pulsars, the maximal age max_age[years] and the fraction of the individual morphtypes. There's an option spiralarms. If set on True a spiralarm modeling after Faucher&Kaspi is included. max_age and n_sources effectively correspond to s SN rate: SN_rate = n_sources / max_age Parameters ---------- n_sources : int Number of sources to simulate rad_dis : callable Radial surface density distribution of sources vel_dis : callable Proper motion velocity distribution of sources max_age : `~astropy.units.Quantity` Maximal age of the source spiralarms : bool Include a spiralarm model in the catalog? n_ISM : `~astropy.units.Quantity` Density of the interstellar medium random_state : {int, 'random-seed', 'global-rng', `~numpy.random.RandomState`} Defines random number generator initialisation. Passed to `~gammapy.utils.random.get_random_state`. Returns ------- table : `~astropy.table.Table` Catalog of simulated source positions and proper velocities """ max_age = Quantity(max_age).to_value("yr") n_ISM = Quantity(n_ISM).to("cm-3") random_state = get_random_state(random_state) if isinstance(rad_dis, str): rad_dis = radial_distributions[rad_dis] if isinstance(vel_dis, str): vel_dis = velocity_distributions[vel_dis] # Draw random values for the age age = random_state.uniform(0, max_age, n_sources) age = Quantity(age, "yr") # Draw spatial distribution r = draw( RMIN.to_value("kpc"), RMAX.to_value("kpc"), n_sources, pdf(rad_dis()), random_state=random_state, ) r = Quantity(r, "kpc") if spiralarms: r, theta, spiralarm = FaucherSpiral()(r, random_state=random_state) else: theta = Quantity(random_state.uniform(0, 2 * np.pi, n_sources), "rad") spiralarm = None x, y = astrometry.cartesian(r, theta) z = draw( ZMIN.to_value("kpc"), ZMAX.to_value("kpc"), n_sources, Exponential(), random_state=random_state, ) z = Quantity(z, "kpc") # Draw values from velocity distribution v = draw( VMIN.to_value("km/s"), VMAX.to_value("km/s"), n_sources, vel_dis(), random_state=random_state, ) v = Quantity(v, "km/s") # Draw random direction of initial velocity theta = Quantity(random_state.uniform(0, np.pi, x.size), "rad") phi = Quantity(random_state.uniform(0, 2 * np.pi, x.size), "rad") # Compute new position dx, dy, dz, vx, vy, vz = astrometry.motion_since_birth(v, age, theta, phi) # Add displacement to birth position x_moved = x + dx y_moved = y + dy z_moved = z + dz table = Table() table["age"] = Column(age, unit="yr", description="Age of the source") table["n_ISM"] = Column(n_ISM, description="Interstellar medium density") if spiralarms: table["spiralarm"] = Column(spiralarm, description="Which spiralarm?") table["x_birth"] = Column(x, description="Galactocentric x coordinate at birth") table["y_birth"] = Column(y, description="Galactocentric y coordinate at birth") table["z_birth"] = Column(z, description="Galactocentric z coordinate at birth") table["x"] = Column(x_moved.to("kpc"), description="Galactocentric x coordinate") table["y"] = Column(y_moved.to("kpc"), description="Galactocentric y coordinate") table["z"] = Column(z_moved.to("kpc"), description="Galactocentric z coordinate") table["vx"] = Column(vx, description="Galactocentric velocity in x direction") table["vy"] = Column(vy, description="Galactocentric velocity in y direction") table["vz"] = Column(vz, description="Galactocentric velocity in z direction") table["v_abs"] = Column(v, description="Galactocentric velocity (absolute)") return table