def _slice2obs(self, obs_row): """take a slice and return a full observation object """ observation = empty_observation() for key in ['RA', 'dec', 'filter', 'exptime', 'nexp', 'note', 'field_id']: observation[key] = obs_row[key] return observation
def testVisit_repeat_basis_function(self): bf = fs.Visit_repeat_basis_function() indx = np.array([1000]) # 30 minute step delta = 30. / 60. / 24. # Add 1st observation, should still be zero obs = fs.empty_observation() obs['filter'] = 'r' obs['mjd'] = 59000. conditions = {'mjd': obs['mjd']} bf.add_observation(obs, indx=indx) bf.update_conditions(conditions) self.assertEqual(np.max(bf()), 0.) # Advance time so now we want a pair conditions['mjd'] += delta bf.update_conditions(conditions) self.assertEqual(np.max(bf()), 1.) # Now complete the pair and it should go back to zero bf.add_observation(obs, indx=indx) conditions['mjd'] += delta bf.update_conditions(conditions) self.assertEqual(np.max(bf()), 0.)
def teststubb(self): so = speedo.Speed_observatory() # Check that we can get a status status = so.return_status() # Check that we can get an observation obs = empty_observation() obs['dec'] = np.radians(-30.) obs['filter'] = 'r' obs['exptime'] = 30. obs['nexp'] = 2. result = so.attempt_observe(obs) status2 = so.return_status() assert (status2['mjd'] > status['mjd']) obs['dec'] = np.radians(-35.) result = so.attempt_observe(obs) assert (result['airmass'] >= 1.)
def testPair_in_night(self): pin = fs.Pair_in_night(gap_min=25., gap_max=45.) self.assertEqual(np.max(pin.feature), 0.) indx = np.array([1000]) delta = 30. / 60. / 24. # Add 1st observation, feature should still be zero obs = fs.empty_observation() obs['filter'] = 'r' obs['mjd'] = 59000. pin.add_observation(obs, indx=indx) self.assertEqual(np.max(pin.feature), 0.) # Add 2nd observation obs['mjd'] += delta pin.add_observation(obs, indx=indx) self.assertEqual(np.max(pin.feature), 1.) obs['mjd'] += delta pin.add_observation(obs, indx=indx) self.assertEqual(np.max(pin.feature), 2.)
survey_length = 5.5 #365.25*10 # days nside = fs.set_default_nside(nside=32) # Define what we want the final visit ratio map to look like years = np.round(survey_length / 365.25) # get rid of silly northern strip. target_map = fs.standard_goals(nside=nside) norm_factor = fs.calc_norm_factor(target_map) # List to hold all the surveys (for easy plotting later) surveys = [] # Let's set up a scripted observation that will just interupt whenever mjd0 = 59583.060669 ssurvey = Scripted_survey(mjd0, 10.) for_type = fs.empty_observation() scripted_obs = np.zeros(20, dtype=for_type.dtype) scripted_obs['filter'] = 'r' # Take a strip of declination at constant RA. scripted_obs['RA'] = np.radians(53.) # radians scripted_obs['dec'] = np.radians(-np.arange(20) * 2. - 20.) # Assume about 37 seconds per visit scripted_obs['mjd'] = (np.arange(20) * 36.) / 3600. / 24. + mjd0 scripted_obs['exptime'] = 30. scripted_obs['nexp'] = 2 # Add a note so it's easy to see if they fire scripted_obs['note'] = 'scripted_tier1' ssurvey.set_script(scripted_obs) scripted_surveys = [ssurvey]
def __call__(self): """ Find a good block of observations. """ if not self.reward_checked: # This should set self.best_fields self.reward = self.calc_reward_function() # Let's find the alt, az coords of the points (right now, hopefully doesn't change much in time block) pointing_alt, pointing_az = stupidFast_RaDec2AltAz( self.fields['RA'][self.best_fields], self.fields['dec'][self.best_fields], self.lat, self.lon, self.extra_features['mjd'].feature, lmst=self.extra_features['lmst'].feature) # Let's find a good spot to project the points to a plane mid_alt = (np.max(pointing_alt) - np.min(pointing_alt)) / 2. # Code snippet from MAF for computing mean of angle accounting for wrap around # XXX-TODO: Maybe move this to sims_utils as a generally useful snippet. x = np.cos(pointing_az) y = np.sin(pointing_az) meanx = np.mean(x) meany = np.mean(y) angle = np.arctan2(meany, meanx) radius = np.sqrt(meanx**2 + meany**2) mid_az = angle % (2. * np.pi) if radius < 0.1: mid_az = np.pi # Project the alt,az coordinates to a plane. Could consider scaling things to represent # time between points rather than angular distance. pointing_x, pointing_y = gnomonic_project_toxy(pointing_az, pointing_alt, mid_az, mid_alt) # Now I have a bunch of x,y pointings. Drop into TSP solver to get an effiencent route towns = np.vstack((pointing_x, pointing_y)).T # Leaving optimize=False for speed. The optimization step doesn't usually improve much. better_order = tsp_convex(towns, optimize=False) # XXX-TODO: Could try to roll better_order to start at the nearest/fastest slew from current position. observations = [] counter2 = 0 for indx in better_order: field = self.best_fields[indx] if self.tag_fields: tag = np.unique( self.tag_map[np.where(self.hp2fields == field)])[0] else: tag = 1 if tag == 0: continue obs = empty_observation() obs['RA'] = self.fields['RA'][field] obs['dec'] = self.fields['dec'][field] obs['rotSkyPos'] = 0. obs['filter'] = self.filtername obs['nexp'] = self.nexp obs['exptime'] = self.exptimes_f1[indx] obs['field_id'] = -1 if self.tag_fields: obs['survey_id'] = np.unique( self.tag_map[np.where(self.hp2fields == field)])[0] else: obs['survey_id'] = 1 obs['note'] = '%s' % (self.survey_note) obs['block_id'] = self.counter obs['note'] = '%s, a' % (self.survey_note) observations.append(obs) counter2 += 1 # If we only want one filter block if self.filter2 is None: result = observations else: # Double the list to get a pair. observations_paired = [] for i, observation in enumerate(observations): obs = copy.copy(observation) obs['filter'] = self.filter2 obs['exptime'] = self.exptimes_f2[better_order[i]] obs['note'] = '%s, b' % (self.survey_note) observations_paired.append(obs) # Check loaded filter here to decide which goes first if self.extra_features['current_filter'].feature == self.filter2: result = observations_paired + observations else: result = observations + observations_paired # Keep track of which block we're on. Nice for debugging. self.counter += 1 return result