Source code for rubin_scheduler.scheduler.utils.comcam_tessellate

__all__ = ("comcam_tessellate",)

import numpy as np


[docs] def comcam_tessellate(side_length=0.7, overlap=0.11): """Tesselate the sphere with a square footprint XXX--TODO: This really sucks at the poles, should add some different pole cap behavior. Parameters ---------- side_length : float (0.7) The length of a side of the square (degrees) overlap : float (0.11) How much overlap to have in pointings Returns ------- fields : numpy array With 'RA' and 'dec' keys that have the field positions in radians """ # Convert to radians for all internal work side_length = np.radians(side_length) overlap = np.radians(overlap) rotation_step = side_length / 2.0 step_size = side_length - overlap n_dec_steps = np.ceil(np.pi / 2.0 / step_size).astype(int) dec_stripes = np.linspace(0, np.pi / 2.0, n_dec_steps) # Lists to hold the RA and dec coords ras = [] decs = [] running_step = 0.0 test_decs = np.array([-step_size, 0.0, step_size]) for dec in dec_stripes: # Find the largest circumfrance the squares will have to cover circum = np.max(2.0 * np.pi * np.cos(test_decs + dec)) n_ra_steps = np.ceil(circum / step_size).astype(int) new_ras = np.linspace(0, 2.0 * np.pi, n_ra_steps) running_step += rotation_step / np.cos(dec) new_ras = (new_ras + running_step) % (2.0 * np.pi) ras.extend(new_ras.tolist()) new_decs = np.empty(new_ras.size) new_decs.fill(dec) decs.extend(new_decs.tolist()) # That was the northern hemisphere, copy to do the south north = np.where(np.array(decs) > 0) decs.extend((-1.0 * np.array(decs))[north].tolist()) new_ras = -1.0 * np.array(ras)[north] new_ras = new_ras % (2.0 * np.pi) ras.extend(new_ras.tolist()) names = ["RA", "dec"] types = [float, float] fields = np.empty(len(ras), dtype=list(zip(names, types))) fields["RA"] = np.array(ras) fields["dec"] = np.array(decs) return fields