def _update_rotSkyPos(self, observation): """If we have an undefined rotSkyPos, try to fill it out. """ alt, az = _approx_RaDec2AltAz(observation['RA'], observation['dec'], self.site.latitude_rad, self.site.longitude_rad, self.mjd) obs_pa = approx_altaz2pa(alt, az, self.site.latitude_rad) observation['rotSkyPos'] = (obs_pa + observation['rotTelPos']) % (2 * np.pi) observation['rotTelPos'] = 0. return observation
def __call__(self, observation_list, conditions): # XXX--should I convert the list into an array and get rid of this loop? for obs in observation_list: alt, az = _approx_RaDec2AltAz(obs['RA'], obs['dec'], conditions.site.latitude_rad, conditions.site.longitude_rad, conditions.mjd) obs_pa = approx_altaz2pa(alt, az, conditions.site.latitude_rad) obs['rotSkyPos'] = obs_pa return observation_list
def request_observation(self, mjd=None): """ Ask the scheduler what it wants to observe next Paramters --------- mjd : float (None) The Modified Julian Date. If None, it uses the MJD from the conditions from the last conditions update. Returns ------- observation object (ra,dec,filter,rotangle) Returns None if the queue fails to fill """ if mjd is None: mjd = self.conditions.mjd if len(self.queue) == 0: self._fill_queue() if len(self.queue) == 0: return None else: # If the queue has gone stale, flush and refill. Zero means no flush_by was set. if (int_rounded(mjd) > int_rounded(self.queue[0]['flush_by_mjd']) ) & (self.queue[0]['flush_by_mjd'] != 0): self.flushed += len(self.queue) self.flush_queue() self._fill_queue() if len(self.queue) == 0: return None observation = self.queue.pop(0) # If we are limiting the camera rotator if self.rotator_limits is not None: alt, az = _approx_RaDec2AltAz( observation['RA'], observation['dec'], self.conditions.site.latitude_rad, self.conditions.site.longitude_rad, mjd) obs_pa = approx_altaz2pa(alt, az, self.conditions.site.latitude_rad) rotTelPos_expected = (obs_pa - observation['rotSkyPos']) % (2. * np.pi) if (int_rounded(rotTelPos_expected) > int_rounded( self.rotator_limits[0])) & ( int_rounded(rotTelPos_expected) < int_rounded( self.rotator_limits[1])): diff = np.abs(self.rotator_limits - rotTelPos_expected) limit_indx = np.min(np.where(diff == np.min(diff))[0]) observation['rotSkyPos'] = ( obs_pa - self.rotator_limits[limit_indx]) % (2. * np.pi) return observation
def __call__(self, observation_list, conditions): # Generate offsets in RA and Dec offsets = self._generate_offsets(len(observation_list), conditions.night) for i, obs in enumerate(observation_list): alt, az = _approx_RaDec2AltAz(obs['RA'], obs['dec'], conditions.site.latitude_rad, conditions.site.longitude_rad, conditions.mjd) obs_pa = approx_altaz2pa(alt, az, conditions.site.latitude_rad) obs['rotSkyPos'] = (obs_pa + offsets[i]) % (2. * np.pi) return observation_list
def __call__(self, observation_list, conditions): favored_rotSkyPos = np.radians([0., 90., 180., 270., 360.]).reshape(5, 1) obs_array = np.concatenate(observation_list) alt, az = _approx_RaDec2AltAz(obs_array['RA'], obs_array['dec'], conditions.site.latitude_rad, conditions.site.longitude_rad, conditions.mjd) parallactic_angle = approx_altaz2pa(alt, az, conditions.site.latitude_rad) # If we set rotSkyPos to parallactic angle, rotTelPos will be zero. So, find the # favored rotSkyPos that is closest to PA to keep rotTelPos as close as possible to zero. ang_diff = np.abs(parallactic_angle - favored_rotSkyPos) min_indxs = np.argmin(ang_diff, axis=0) # can swap 360 and zero if needed? final_rotSkyPos = favored_rotSkyPos[min_indxs] # Set all the observations to the proper rotSkyPos for rsp, obs in zip(final_rotSkyPos, observation_list): obs['rotSkyPos'] = rsp return observation_list
def calc_pa(self): self._pa = approx_altaz2pa(self.alt, self.az, self.site.latitude_rad)