MicroLIA_Sim.param_generation ============================= .. py:module:: MicroLIA_Sim.param_generation Attributes ---------- .. autoapisummary:: MicroLIA_Sim.param_generation.ModelType Classes ------- .. autoapisummary:: MicroLIA_Sim.param_generation.Prior MicroLIA_Sim.param_generation.Fixed MicroLIA_Sim.param_generation.Uniform MicroLIA_Sim.param_generation.LogUniform MicroLIA_Sim.param_generation.Choice MicroLIA_Sim.param_generation.PerBandUniform MicroLIA_Sim.param_generation.GenerationConfig Functions --------- .. autoapisummary:: MicroLIA_Sim.param_generation.login_datalab MicroLIA_Sim.param_generation.datalab_login MicroLIA_Sim.param_generation.query_trilegal_stars MicroLIA_Sim.param_generation.generate_physical_pairs MicroLIA_Sim.param_generation.calculate_trilegal_physics MicroLIA_Sim.param_generation.draw_blend_g MicroLIA_Sim.param_generation.required_prior_names MicroLIA_Sim.param_generation.default_priors MicroLIA_Sim.param_generation.validate_priors MicroLIA_Sim.param_generation.describe_requirements MicroLIA_Sim.param_generation.is_in_footprint MicroLIA_Sim.param_generation.generate_trilegal_event_table Module Contents --------------- .. py:function:: login_datalab() -> None Prompt for Astro Data Lab credentials and authenticate the current session. This function interactively requests a username and password to obtain an authentication token (Data Lab client). If the returned token is not valid, a `RuntimeError` is raised. Will soon replace this function .. py:function:: datalab_login() -> None Ensure an active Astro Data Lab authentication token exists. This function attempts to reuse an existing cached token via `ac.getToken()`. If no valid token is available (or token retrieval raises an exception), it falls back to an interactive login via `login_datalab()`. .. py:function:: query_trilegal_stars(ra: float, dec: float, *, radius_deg: float = 0.1, ds_max_pc: float = 10000.0, limit: int = 5000, timeout: int = 600, random_selection: bool = False) -> pandas.DataFrame Query a TRILEGAL star sample from Astro Data Lab (their `lsst_sim.simdr2` table) near an input sky position. The query uses `q3c_radial_query` to select sources within `radius_deg` of (`ra`, `dec`) and applies a distance cut using the distance modulus `mu0`. Two derived columns are appended, the `distance_pc` (distance inferred from `mu0`) and the `mu_total` (total proper motion magnitude from `pmracosd` and `pmdec`). :param ra: Right ascension of the query center (degrees). :type ra: float :param dec: Declination of the query center (degrees). :type dec: float :param radius_deg: Radial search radius (degrees). Default is 0.1 degrees. :type radius_deg: float, optional :param ds_max_pc: Maximum source distance (pc). Implemented via a distance modulus cut (`mu0 < 5*log10(ds_max_pc) - 5`). Default is 10000.0 parsecs. :type ds_max_pc: float, optional :param limit: Maximum number of rows to return. Default is 5000. :type limit: int, optional :param timeout: Query timeout in seconds. Default is 600. :type timeout: int, optional :param random_selection: If True, the database results will be shuffled before limiting them. This is helpful if querying the same part of the sky (e.g., Bulge) multiple times with a small limit. Note that if True, the database must find all stars withing ``radius_deg`` first, so best to use a small radius in this case. :type random_selection: bool, optional :returns: Table of TRILEGAL sources with lowercase column names, containing: - Raw queried columns: `ra, dec, mu0, pmracosd, pmdec, umag, gmag, rmag, imag, zmag, ymag, logl, logte, mass` - Added columns: `distance_pc, mu_total` :rtype: pandas.DataFrame .. py:function:: generate_physical_pairs(df: pandas.DataFrame, n_events: int, *, min_dist_pc: float = 10.0, offset_pc: float = 0.1, random_seed: int | None = None, physical_vectors: bool = False, max_tries: int = 500000, dark_matter_lens: bool = False) -> pandas.DataFrame Construct source–lens (foreground) pairs from a TRILEGAL catalog. This routine selects background sources and assigns each one a randomly chosen foreground lens drawn from the same TRILEGAL sample, subject to a geometric distance ordering, such that a row is chosen as a source at distance ``D_S`` and a lens is then drawn from objects with ``min_dist_pc < D_L < D_S - offset_pc`` The output is an event-pair table containing source/lens distances, per-band magnitudes for both objects, and an estimate of relative proper motion. :param df: Input TRILEGAL table. Must contain (at minimum) the columns: ``distance_pc``, ``ra``, ``dec``, ``logl``, ``logte``, ``mu_total``, ``mass``, and band magnitudes ``umag, gmag, rmag, imag, zmag, ymag``. If ``physical_vectors=True``, the catalog must also contain ``pmracosd`` and ``pmdec``. :type df: pandas.DataFrame :param n_events: Number of source–lens pairs to generate (best effort; may return fewer). :type n_events: int :param min_dist_pc: Minimum allowed lens distance (pc). Default is 10.0. :type min_dist_pc: float, optional :param offset_pc: Minimum separation in distance between source and lens (pc), enforced via ``D_L < D_S - offset_pc``. Default is 0.1. :type offset_pc: float, optional :param random_seed: Seed for the random number generator. Default is None. :type random_seed: int or None, optional :param physical_vectors: If True, compute the relative proper motion vector from the catalog components (``pmracosd``, ``pmdec``) and return a physically consistent trajectory angle. If False, only the magnitudes of the proper motions are used (``mu_total``) and a random relative angle is drawn; in this case ``traj_angle`` is set to NaN. Default is False. :type physical_vectors: bool, optional :param max_tries: Maximum number of attempted draws used to reach ``n_events``. Default is 500000. :type max_tries: int, optional :param dark_matter_lens: Whether the event is a extended dark object, in which case the lens distance and relative proper motion between the lens and the source must be input as priors. :type dark_matter_lens: bool, optional :returns: Table of generated pairs with one row per event. Columns include: - ``mu_rel`` : float Relative proper motion magnitude (mas/yr). - ``traj_angle`` : float Trajectory angle (radians) for the relative proper-motion vector, or NaN if ``physical_vectors=False``. - ``distance_source`` : float Source distance ``D_S`` (pc). - ``distance_blend`` : float Lens distance ``D_L`` (pc). (Named “blend” to match downstream usage.) - ``logl_source``, ``logte_source`` : float Source stellar parameters copied from TRILEGAL. - ``ra``, ``dec`` : float Sky position (degrees) copied from the selected source. - Per-band magnitudes: ``{u,g,r,i,z,y}_source`` and ``{u,g,r,i,z,y}_blend``. The returned DataFrame may contain fewer than ``n_events`` rows if the input catalog does not provide enough valid source–lens combinations. :rtype: pandas.DataFrame .. rubric:: Notes - If ``physical_vectors=False``, ``mu_rel`` is computed from the scalar proper motion magnitudes using a random relative angle. The direction is intentionally deferred to a later prior. - A single foreground lens is drawn *with replacement* for each source; the same lens may appear in multiple pairs. .. py:function:: calculate_trilegal_physics(row: dict | pandas.Series, *, lens_mass_solar: Optional[float] = None, tE_days: Optional[float] = None, angle_rad: Optional[float], semi_major_axis_au: Optional[float]) -> dict | None Compute microlensing geometry and derived parameters for a TRILEGAL source–lens pair. Given a pre-constructed source–lens pairing (from the generate_physical_pairs function), this function computes the Einstein angle, Einstein timescale (unless tE days is input as a prior), finite-source parameter, and the microlensing parallax components (optional). The trajectory angle used to decompose the parallax vector is taken from ``row["traj_angle"]`` when available (i.e., when using physical proper-motion vectors), otherwise it must be supplied via the ``angle_rad`` argument. The Einstein angle is computed as: ``theta_E = sqrt( (4GM/c^2) * (1/D_L - 1/D_S) )``. The relative parallax is calculated as: ``pi_rel = AU * (1/D_L - 1/D_S)``. The parallax magnitude is: ``pi_E = pi_rel / theta_E`` (dimensionless). The source angular radius is estimated from TRILEGAL luminosity and effective temperature via Stefan–Boltzmann to get ``R_*``, then ``theta_* = R_* / D_S``. The function will return None if the lens is not in front of the source (``(1/D_L - 1/D_S) <= 0``) or if the ``traj_angle`` is NaN/missing and ``angle_rad`` is None. :param row: A single pair record containing (at minimum) the keys/columns: ``distance_source``, ``distance_blend``, ``mu_rel``, ``logl_source``, ``logte_source``, and optionally ``traj_angle``. Distances are interpreted as pc and ``mu_rel`` as mas/yr. :type row: dict or pandas.Series :param lens_mass_solar: Lens mass in solar masses (only used if tE_days is None). :type lens_mass_solar: float or None :param tE_days: Event timescale, if input will use this prior instead of the actual lens mass for the calculations. :type tE_days: float or None :param angle_rad: Trajectory angle in radians used to decompose the parallax magnitude into (piEN, piEE). Required if ``row["traj_angle"]`` is missing or NaN; ignored otherwise. :type angle_rad: float or None :param semi_major_axis_au: Physical semi-major axis (AU) used to compute a physically-motivated binary separation ``s_physical = theta_a / theta_E`` (dimensionless). If None, ``s_physical`` is returned as None. :type semi_major_axis_au: float or None :returns: Dictionary of derived quantities, or None if the geometry is unphysical or required inputs are missing. Returned keys: - ``tE`` : float Einstein timescale (days), computed as ``tE = theta_E / mu_rel``. - ``rho`` : float Finite-source size parameter ``rho = theta_* / theta_E`` (dimensionless). - ``piEN`` : float North component of microlensing parallax (dimensionless). - ``piEE`` : float East component of microlensing parallax (dimensionless). - ``s_physical`` : float or None Dimensionless binary separation computed from ``semi_major_axis_au``, or None if not requested. - ``M_L`` : float Lens mass (Msun). - ``D_S`` : float Source distance (pc). - ``D_L`` : float Lens distance (pc). - ``mu_rel`` : float Relative proper motion (mas/yr). - ``theta_E_mas`` : float Einstein angle (mas). - ``pi_rel_mas`` : float Relative parallax (mas). :rtype: dict or None .. py:function:: draw_blend_g(rng: numpy.random.Generator, bands: str = 'ugrizy') -> Dict[str, float] Draw per-band blend fractions for a simulated event. This is a convenience helper for cases where a dedicated per-band prior object is not being used. :param rng: Random number generator used to draw the blend fractions. :type rng: numpy.random.Generator :param bands: Photometric bands to generate blend fractions for. Each character is treated as a band label (e.g., ``"ugrizy"``). Default is ``"ugrizy"``. :type bands: str, optional :returns: Dictionary mapping each band label to a blend fraction in [0, 1) (e.g., ``{"g": 0.12, "r": 0.63, ...}``). :rtype: dict .. py:data:: ModelType .. py:class:: Prior The base class for parameter priors, used to generate random draws from a prior distribution. .. method:: sample(rng, n=None) Draw one sample (if ``n is None``) or ``n`` samples (if ``n`` is an int). .. method:: describe() Return a short string description of the prior, used for logging/debugging. .. py:method:: sample(rng: numpy.random.Generator, n: Optional[int] = None) -> Any :abstractmethod: Draw sample(s) from the prior distribution. :param rng: Random number generator used to draw samples. :type rng: numpy.random.Generator :param n: If None, return a single draw. If an integer, return ``n`` draws. Default is None. :type n: int or None, optional :returns: A single draw or a collection of draws, depending on ``n``. :rtype: Any .. py:method:: describe() -> str Return a short description of the prior. :returns: A human-readable name/description of the prior. By default this is the class name, but subclasses may override for more detail. :rtype: str .. py:class:: Fixed Bases: :py:obj:`Prior` Deterministic prior that always returns a fixed value. :param value: The constant value returned by this prior. This can be a scalar (float/int), a string, or any object expected by downstream code. :type value: Any .. py:attribute:: value :type: Any .. py:method:: sample(rng: numpy.random.Generator, n: Optional[int] = None) -> Any Return the fixed value (optionally repeated ``n`` times). :param rng: Random number generator (unused for this prior; included for API compatibility). :type rng: numpy.random.Generator :param n: If None, return a single value. If an integer, return a list of length ``n`` containing repeated values. Default is None. :type n: int or None, optional :returns: ``value`` if ``n is None``; otherwise a list of repeated values. :rtype: Any .. py:method:: describe() -> str Return a human-readable description of the prior. :returns: Description in the form ``"Fixed()"``. :rtype: str .. py:class:: Uniform Bases: :py:obj:`Prior` Continuous uniform prior over an interval [low, high). :param low: Lower bound of the uniform distribution. :type low: float :param high: Upper bound of the uniform distribution. :type high: float .. py:attribute:: low :type: float .. py:attribute:: high :type: float .. py:method:: sample(rng: numpy.random.Generator, n: Optional[int] = None) -> Any Draw sample(s) from a uniform distribution on [low, high). :param rng: Random number generator used to draw samples. :type rng: numpy.random.Generator :param n: If None, return a single float. If an integer, return an array of ``n`` samples. Default is None. :type n: int or None, optional :returns: A single draw if ``n is None``; otherwise an array of length ``n``. :rtype: float or numpy.ndarray .. py:method:: describe() -> str Return a human-readable description of the prior. :returns: Description in the form ``"Uniform(low, high)"``. :rtype: str .. py:class:: LogUniform Bases: :py:obj:`Prior` Log-uniform prior over an interval [low, high). Samples are drawn uniformly in log10-space and then exponentiated (``x = 10**U(log10(low), log10(high))``). :param low: Lower bound of the distribution. Must be > 0. :type low: float :param high: Upper bound of the distribution. Must be > 0 and > low. :type high: float .. py:attribute:: low :type: float .. py:attribute:: high :type: float .. py:method:: sample(rng: numpy.random.Generator, n: Optional[int] = None) -> Any Draw sample(s) from a log-uniform distribution on [low, high). Will raise an error if ``low`` or ``high`` are not positive, or if ``high <= low``. :param rng: Random number generator used to draw samples. :type rng: numpy.random.Generator :param n: If None, return a single float. If an integer, return an array of ``n`` samples. Default is None. :type n: int or None, optional :returns: A single draw if ``n is None``; otherwise an array of length ``n``. :rtype: float or numpy.ndarray .. py:method:: describe() -> str Return a human-readable description of the prior. :returns: Description in the form ``"LogUniform(low, high)"``. :rtype: str .. py:class:: Choice Bases: :py:obj:`Prior` Discrete prior that samples from a finite set of options. If ``n`` is None, returns a single element from ``options``. If ``n`` is an integer, returns an array of ``n`` draws. :param options: The allowed values to sample from. :type options: tuple of Any .. py:attribute:: options :type: Tuple[Any, Ellipsis] .. py:method:: sample(rng: numpy.random.Generator, n: Optional[int] = None) -> Any Draw one or more samples from ``options``. :param rng: Random number generator used to draw samples. :type rng: numpy.random.Generator :param n: If None, return a single draw. If an integer, return an array of ``n`` draws. Default is None. :type n: int or None, optional :returns: A single option if ``n is None``; otherwise a NumPy array of length ``n`` containing sampled options. :rtype: Any .. py:method:: describe() -> str Return a human-readable description of the prior. :returns: Description in the form ``"Choice([opt1, opt2, ...])"``. :rtype: str .. py:class:: PerBandUniform Bases: :py:obj:`Prior` Per-band uniform prior that returns a dictionary of independent draws (sampling is per event only!). This is intended for parameters that must be specified separately for each photometric band (e.g., per-band blend fractions). :param low: Lower bound of the uniform distribution for each band. :type low: float :param high: Upper bound of the uniform distribution for each band. :type high: float :param bands: Photometric bands to sample. Each character is treated as a band label. Default is ``"ugrizy"``. :type bands: str, optional .. py:attribute:: low :type: float .. py:attribute:: high :type: float .. py:attribute:: bands :type: str :value: 'ugrizy' .. py:method:: sample(rng: numpy.random.Generator, n: Optional[int] = None) -> Any Draw a per-band dictionary of independent uniform samples. :param rng: Random number generator used to draw samples. :type rng: numpy.random.Generator :param n: Must be None. This prior is not vectorized because it returns a dictionary of per-band scalars. :type n: int or None, optional :returns: Mapping ``{band: value}`` where each ``value`` is drawn uniformly from [low, high). :rtype: dict .. py:method:: describe() -> str Return a human-readable description of the prior. :returns: Description in the form ``"PerBandUniform(low, high, bands='...')"``. :rtype: str .. py:class:: GenerationConfig Configuration flags controlling TRILEGAL-based event-table generation. This class determines which physical parameters must be provided via priors, how relative proper motion is handled, whether parallax terms are computed, and how blending and (for binaries) separations are treated. .. attribute:: model_type Microlensing model family to generate parameters for. Supported values are ``"PSPL"``, ``"FSPL"``, ``"USBL"``, ``"NFW"``, and ``"BS"``. Default is ``"PSPL"``. :type: ModelType, optional .. attribute:: enable_parallax If True, compute and store microlensing parallax components (piEN, piEE). If False, piEN and piEE are stored as NaN in the output table. Default is True. :type: bool, optional .. attribute:: physical_vectors If True, derive relative proper motion and trajectory angle from TRILEGAL proper-motion components (``pmracosd``, ``pmdec``). If False, compute only the magnitude of relative proper motion using ``mu_total`` and treat the trajectory angle as an external prior. Default is False. :type: bool, optional .. attribute:: custom_blending If True, blending is controlled by an external per-band blend fraction prior (e.g., ``blend_g``), and the stored ``source_mags`` represent baseline total magnitudes (source+blend). If False, store the TRILEGAL source-only and lens-only magnitudes directly. Default is True. :type: bool, optional .. attribute:: use_physical_s USBL-only option. If True and a semi-major axis prior is provided, compute a physically motivated separation ``s_physical`` and use it as ``s`` when available; otherwise fall back to sampling ``s`` from a prior. If False, always sample ``s`` from its prior. Default is True. :type: bool, optional .. attribute:: use_trilegal_mass Whether to use the actual lens mass from TRILEGAL. If False, user must provide it as a prior (unless ``sample_tE_directly``=True). :type: bool, optional .. attribute:: sample_tE_directly Whether the tE is input as a prior, if True the code will use this prior to compute the lens mass :type: bool, optional .. attribute:: dark_matter_lens Whether the event is a extended dark object, in which case the lens distance and relative proper motion between the lens and the source must be input as priors. :type: bool, optional .. py:attribute:: model_type :type: ModelType :value: 'PSPL' .. py:attribute:: enable_parallax :type: bool :value: True .. py:attribute:: physical_vectors :type: bool :value: False .. py:attribute:: custom_blending :type: bool :value: True .. py:attribute:: use_physical_s :type: bool :value: True .. py:attribute:: use_trilegal_mass :type: bool :value: False .. py:attribute:: sample_tE_directly :type: bool :value: False .. py:attribute:: dark_matter_lens :type: bool :value: False .. py:function:: required_prior_names(cfg: GenerationConfig) -> List[str] Return the list of prior names required for a given generation configuration. This helper inspects :the GenerationConfig class and determines which priors must be provided to generate a valid event-parameter table. If ``cfg.enable_parallax`` is set to True and ``cfg.physical_vectors`` is False, the ``"traj_angle_rad"`` is required to decompose the parallax magnitude into (piEN, piEE) when ``traj_angle`` is not available from TRILEGAL. If ``cfg.custom_blending`` is True, ``"blend_g"`` is required (per-band blend fraction prior). If ``cfg.model_type == "USBL"``, then ``"q"``, ``"alpha"``, and ``"origin"`` are required, plus either ``"semi_major_axis_au_or_s"`` when ``cfg.use_physical_s`` is True (meaning the user must provide either ``semi_major_axis_au`` to compute a physical separation or an explicit ``s`` prior fallback), or ``"s"`` when ``cfg.use_physical_s`` is False. If ``cfg.model_type`` is ``"NFW"`` or ``"BS"``, then ``"t_m"`` is required. If ``cfg.use_trilegal_mass`` is True, the lens mass will come from the TRILEGAL catalog. Set to False to use prior. If ``cfg.sample_tE_directly`` is False, the timescale will come from the lens mass, otherwise will use input tE prior. :param cfg: Configuration specifying model type and which physical effects are enabled (parallax, physical proper-motion vectors, blending, and USBL separation mode). :type cfg: GenerationConfig :returns: Names of required priors. The base set always includes t0, u0 and either the lens mass ("lens_mass_solar") or the timescale ("tE"), depending on whether tE is input as a prior. Additional requirements depend on ``cfg``. :rtype: list of str .. py:function:: default_priors(cfg: GenerationConfig) -> Dict[str, Prior] Construct a default set of priors consistent with the generation configuration. This function returns a dictionary mapping parameter names to the objects in the Prior class, and is intended to provide a starting point that users can override as needed. :param cfg: Configuration controlling which model type is used and whether additional priors are required (parallax angle, blending, USBL parameters, etc.). :type cfg: GenerationConfig :returns: Dictionary of prior objects keyed by parameter name. Base priors (always included) - ``t0`` : Uniform(60000.0, 63650.0) Event time of closest approach (MJD). - ``u0`` : Uniform(0.0, 0.3) Impact parameter in units of theta_E. Conditional priors - ``traj_angle_rad`` : Uniform(0.0, 2pi) Included only if ``cfg.enable_parallax`` is True and ``cfg.physical_vectors`` is False (i.e., when the trajectory angle is not available from TRILEGAL and must be provided as a prior). - ``blend_g`` : PerBandUniform(0.0, 1.0, bands="ugrizy") Included only if ``cfg.custom_blending`` is True. - ``lens_mass_solar`` : Uniform(0.1, 1.0) Lens mass in solar masses. - ``tE`` : LogUniform(5.0, 100.0) Even timescale, if input as prior the lens mass will not be used to compute the physical params. Note that since the TRILEGAL stars are selected at random, using extreme tE priors might occasionally yield derived masses that are unphysical (e.g., very long timescale with a very fast moving star). USBL priors (only if ``cfg.model_type == "USBL"``) - ``q`` : LogUniform(1e-4, 1.0) Binary mass ratio. - ``alpha`` : Uniform(0.0, 2pi) Binary-lens trajectory angle (model convention). - ``origin`` : Choice(("center_of_mass", "central_caustic", "second_caustic")) Reference point for the binary-lens parameterization. - ``semi_major_axis_au`` : Uniform(0.1, 28.0) Included if ``cfg.use_physical_s`` is True; used to compute a physical separation ``s_physical`` when possible. - ``s`` : LogUniform(0.4, 2.5) Always included for USBL as a fallback when physical separation is not available (e.g., if ``semi_major_axis_au`` is not provided or ``cfg.use_physical_s`` is False). NFW/BS priors (only if ``cfg.model_type`` in {"NFW", "BS"}) - ``t_m`` : Uniform(0.1, 5.0) Model-specific timescale parameter. :rtype: dict of str -> Prior .. py:function:: validate_priors(cfg: GenerationConfig, priors: Dict[str, Prior]) -> None Validate that a prior dictionary satisfies the requirements of a configuration. This function enforces that all priors required by the required_prior_names function are present in the provided ``priors`` mapping. A good sanity check -- it raises errors if priors are missing, but functions with extra priors (but does print a warning). :param cfg: Configuration specifying which priors are required (model type, parallax, blending mode, physical-vector handling, etc.). :type cfg: GenerationConfig :param priors: Dictionary mapping prior names to :class:`Prior` instances. :type priors: dict of str -> Prior .. py:function:: describe_requirements(cfg: GenerationConfig, priors: Optional[Dict[str, Prior]] = None) -> str Build a human-readable summary of required (and optionally provided) priors. :param cfg: Configuration specifying which priors are required. :type cfg: GenerationConfig :param priors: If provided, the set of priors that will be used. These are included in the returned summary under "Provided priors:". :type priors: dict of str -> Prior, optional :returns: Text summary. :rtype: str .. py:function:: is_in_footprint(ra: float, dec: float, timeout: int = 5) -> bool Quickly probe if a coordinate is within the LSST TRILEGAL footprint, using short timeout to avoid hanging on empty regions. .. py:function:: generate_trilegal_event_table(*, n_events: int, ra: float, dec: float, cfg: GenerationConfig, priors: Optional[Dict[str, Prior]] = None, random_seed: Optional[int] = None, radius_deg: float = 0.2, query_limit: int = 50000, ds_max_pc: float = 10000.0, timeout: int = 600, min_dist_pc: float = 10.0, offset_pc: float = 0.1, random_selection: bool = False) -> pandas.DataFrame Generate a microlensing event-parameter table using TRILEGAL stars + user priors. This is the main function for building the parameter DataFrame. This function first queries a TRILEGAL catalog from Astro Data Lab around (ra, dec), then constructs source–lens pairs consistent with foreground lensing geometry. It then samples user-specified priors (t0, u0, lens mass, etc.) and computes derived microlensing physics (tE, rho, theta_E, parallax terms). Model-specific parameters (e.g., USBL q/alpha/origin/s) are then added, and the per-band photometry is handled according to the blending mode. Note that our pair selection can result in the same lens being used across multiple events (sampling with replacement), depending on the density of valid foreground objects. :param n_events: Number of events to generate (note that it may return fewer if filtering removes too many pairs). :type n_events: int :param ra: Right ascension of the TRILEGAL query center (degrees). :type ra: float :param dec: Declination of the TRILEGAL query center (degrees). :type dec: float :param cfg: Generation configuration controlling parallax, physical-vector usage, blending behavior, and model type. :type cfg: GenerationConfig :param priors: Mapping from parameter name to the Prior class. If None, defaults are created via default_priors(cfg). The required keys depend on ``cfg`` and are validated by the validate_priors function. :type priors: dict of str -> Prior, optional :param random_seed: Seed for the RNG used in prior sampling and (when applicable) pair selection. Default is None. :type random_seed: int or None, optional :param radius_deg: TRILEGAL cone-search radius passed to the query_trilegal_stars function. Default is 0.2. :type radius_deg: float, optional :param query_limit: Maximum number of TRILEGAL rows retrieved from Data Lab. Default is 50000. :type query_limit: int, optional :param ds_max_pc: Maximum distance (pc) used to cut TRILEGAL sources via a distance-modulus filter in the query_trilegal_stars function. Default is 10000.0. :type ds_max_pc: float, optional :param timeout: Data Lab query timeout in seconds. Default is 600. :type timeout: int, optional :param min_dist_pc: Minimum lens distance (pc) used when pairing sources and lenses. Default is 10.0. :type min_dist_pc: float, optional :param offset_pc: Minimum source–lens distance separation (pc), enforced as ``D_L < D_S - offset_pc`` during pairing. Default is 0.1. :type offset_pc: float, optional :param random_selection: If True, the database results will be shuffled before limiting them. This is helpful if querying the same part of the sky (e.g., Bulge) multiple times with a small limit. Note that if True, the database must find all stars withing ``radius_deg`` first, so best to use a small radius in this case. :type random_selection: bool, optional :returns: Event table with one row per generated simulation. Currently the code includes: Common microlensing parameters - ``sim_id`` : int Row index (for reproducibility/debugging). - ``model_type`` : str Model identifier (from ``cfg.model_type``). - ``ra``, ``dec`` : float Sky position (degrees). - ``t0`` : float Time of closest approach (MJD; drawn from prior). - ``u0`` : float Impact parameter (theta_E units; drawn from prior). - ``tE`` : float Einstein timescale (days; derived). - ``rho`` : float Finite-source size parameter (derived). - ``piEN``, ``piEE`` : float Parallax components (derived) or NaN if ``cfg.enable_parallax=False``. - ``M_L`` : float Lens mass (in units of Msun). - ``D_S``, ``D_L`` : float Source and lens distances (pc; from TRILEGAL pairing). - ``mu_rel`` : float Relative proper motion (mas/yr). - ``theta_E_mas`` : float Einstein angle (mas). - ``pi_rel_mas`` : float Relative parallax (mas). - ``a_au`` : float or None Semi-major axis (AU; sampled only when requested/available). - ``s_physical`` : float or None Separation implied by ``a_au`` and lens distance, in theta_E units. Photometry, which depends on the cfg.custom_blending input: - If ``cfg.custom_blending=True``: * ``blend_g`` : dict Per-band blend fractions (prior-driven). * ``source_mags`` : dict Baseline total magnitudes (source+blend) in each band, intended for later splitting using ``blend_g``. * ``blend_mags`` : None - If ``cfg.custom_blending=False``: * ``blend_g`` : None * ``source_mags`` : dict TRILEGAL source-only magnitudes. * ``blend_mags`` : dict TRILEGAL lens-only magnitudes. Model-specific columns - For ``cfg.model_type == "USBL"``: ``q``, ``alpha``, ``origin``, ``s``. - For ``cfg.model_type`` in {``"NFW"``, ``"BS"``}: ``t_m`` :rtype: pandas.DataFrame