Skip to content

Commit

Permalink
actually finished this tutorial
Browse files Browse the repository at this point in the history
  • Loading branch information
ismael-mendoza committed Apr 30, 2024
1 parent 8ebdd9a commit 9b805d6
Showing 1 changed file with 65 additions and 4 deletions.
69 changes: 65 additions & 4 deletions notebooks/01-advanced-generation.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
"%matplotlib inline\n",
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"from tqdm import tqdm\n",
"\n",
"import galsim"
]
Expand All @@ -52,8 +51,7 @@
"from btk.catalog import CatsimCatalog\n",
"from btk.survey import get_surveys\n",
"from btk.survey import Filter, Survey\n",
"from btk.draw_blends import CatsimGenerator\n",
"from btk.sampling_functions import DefaultSampling\n"
"from btk.draw_blends import CatsimGenerator"
]
},
{
Expand Down Expand Up @@ -198,7 +196,70 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"To write your own sampling function users should... (TBD)"
"To write your own sampling function, you should create a subclass of the `SamplingFunction` class available in the `btk.sampling_functions.py` module, or from one of the classes in that file. \n",
"\n",
"Below you can find the implementation of the `DefaultSamplingFunction` that is also available in this module (as an example): \n",
"\n",
"```python\n",
"class DefaultSampling(SamplingFunction):\n",
" \"\"\"Default sampling function used for producing blend catalogs.\"\"\"\n",
"\n",
" def __init__(\n",
" self,\n",
" max_number: int = 2,\n",
" min_number: int = 1,\n",
" stamp_size: float = 24.0,\n",
" max_shift: Optional[float] = None,\n",
" seed: int = DEFAULT_SEED,\n",
" max_mag: float = 25.3,\n",
" min_mag: float = -np.inf,\n",
" mag_name: str = \"i_ab\",\n",
" ):\n",
" super().__init__(max_number=max_number, min_number=min_number, seed=seed)\n",
" self.stamp_size = stamp_size\n",
" self.max_shift = max_shift if max_shift is not None else self.stamp_size / 10.0\n",
" self.min_mag, self.max_mag = min_mag, max_mag\n",
" self.mag_name = mag_name\n",
"\n",
" def __call__(self, table: Table) -> Table:\n",
" \"\"\"Take as input a large galaxy catalog, return a random sample of galaxies forming a blend.\"\"\"\n",
" if self.mag_name not in table.colnames:\n",
" raise ValueError(f\"Catalog must have '{self.mag_name}' column.\")\n",
"\n",
" # use `self.rng` for randomness purpose in the sampling function\n",
" # here it is used to determine the total number of objects forming the blend.\n",
" number_of_objects = self.rng.integers(self.min_number, self.max_number + 1)\n",
"\n",
" # you can enforce additional cuts on the galaxies that you want to be part of a blend too.\n",
" # in this example, we make a cut on the i-band magnitude\n",
" cond = (table[self.mag_name] <= self.max_mag) & (table[self.mag_name] > self.min_mag)\n",
" (q,) = np.where(cond)\n",
"\n",
" # here we use self.rng again to randomly choose the indices of galaxies that will form our\n",
" # blend. \n",
" blend_table = table[self.rng.choice(q, size=number_of_objects)]\n",
"\n",
"\n",
" # finally, the galaxies centroids are set to uniformly random shfits from the center of \n",
" # the stamp. In general, centroids should be adjust to be inside the stamp and w.r.t \n",
" # its center (0,0) in arsecs.\n",
" blend_table[\"ra\"] = 0.0\n",
" blend_table[\"dec\"] = 0.0\n",
" dx, dy = _get_random_center_shift(number_of_objects, self.max_shift, self.rng)\n",
" blend_table[\"ra\"] += dx\n",
" blend_table[\"dec\"] += dy\n",
" _raise_error_if_out_of_bounds(blend_table[\"ra\"], blend_table[\"dec\"], self.stamp_size)\n",
" return blend_table\n",
"```\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Your new sampling function should have the arguments in its initializer (`__init__`) that are at least the ones contained in the parent `SamplingFunction` class namely: `max_number`, `min_number`, and `seed`. \n",
"\n",
"It should also implement the `__call__` method, which should take as an argument an `astropy` table corresponding to the full galaxy catalog you are using to produce your simulations and return a smaller `astropy` table correspnoding to a subset of the entries which will be the galaxies forming a galaxy blend. Each time the `__call__` method is used, a new blend should be returned and the randomness needed for this should be derived from the random number generator `self.rng`, which ensures reproducibility in BTK. Finally, the positions of galaxies should be adjusted to be inside the postage stamp and w.r.t to its center (0,0). In the example above, we completely overwrite the galaxies centroids and set them to be random shifts from the center of the stamp up to some `self.max_shift`, but there are other ways of implementing this step to preserve some information on the relative positions of galaxies within the catalog. See, for example, `btk.sampling_functions.RandomSquareSampling` sampling function. For more details on implementing a `__call__` method for a sampling function, see the comments in the example above."
]
},
{
Expand Down

0 comments on commit 9b805d6

Please sign in to comment.