def create_pointing(self, event, label_text=None): """Plot the sky coverage of pointing at event.x,event.y on the canvas. """ (ra, dec) = self.c2p((self.canvasx(event.x), self.canvasy(event.y))) this_camera = Camera(camera=self.camera.get()) ccds = this_camera.getGeometry(ra, dec) items = [] for ccd in ccds: if len(ccd) == 4: (x1, y1) = self.p2c((ccd[0], ccd[1])) (x2, y2) = self.p2c((ccd[2], ccd[3])) item = self.create_rectangle(x1, y1, x2, y2, stipple='gray25', fill=None) else: (x1, y1) = self.p2c((ccd[0] - ccd[2], ccd[1] - ccd[2])) (x2, y2) = self.p2c((ccd[0] + ccd[2], ccd[1] + ccd[2])) item = self.create_oval(x1, y1, x2, y2) items.append(item) label = {} if label_text is None: label_text = self.plabel.get() label['text'] = label_text label['id'] = self.label(this_camera.ra, this_camera.dec, label['text']) self.pointings.append({ "label": label, "items": items, "camera": this_camera}) self.current = len(self.pointings) - 1 self.current_pointing(len(self.pointings) - 1)
def plot_points_list(self, points): for point in points: label = {} try: not_ephem = False date = Time(point[0], scale='utc') except: not_ephem = True if not_ephem: label['text'] = point[0] else: label['text'] = "EPHEM" try: (ra, dec) = (ephem.hours(point[1]), ephem.degrees(point[2])) except: logging.warn("Failed to convert {} {} to RA/DEC".format( point[1], point[2])) continue this_camera = Camera(camera=self.camera.get()) ccds = this_camera.getGeometry(float(ra), float(dec)) items = [] for ccd in ccds: if len(ccd) == 4: (x1, y1) = self.p2c((ccd[0], ccd[1])) (x2, y2) = self.p2c((ccd[2], ccd[3])) item = self.create_rectangle(x1, y1, x2, y2, stipple='gray25', fill=None) else: (x1, y1) = self.p2c( (ccd[0] - ccd[2] / math.cos(ccd[1]), ccd[1] - ccd[2])) (x2, y2) = self.p2c( (ccd[0] + ccd[2] / math.cos(ccd[1]), ccd[1] + ccd[2])) item = self.create_oval(x1, y1, x2, y2) items.append(item) self.pointings.append({ "label": label, "items": items, "camera": this_camera }) if not not_ephem: break self.plot_pointings() return
def plot_points_list(self, points): for point in points: label = {} try: not_ephem = False date = Time(point[0], scale='utc') except: not_ephem = True if not_ephem: label['text'] = point[0] else: label['text'] = "EPHEM" try: (ra, dec) = (ephem.hours(point[1]), ephem.degrees(point[2])) except: logging.warn("Failed to convert {} {} to RA/DEC".format(point[1], point[2])) continue this_camera = Camera(camera=self.camera.get()) ccds = this_camera.getGeometry(float(ra), float(dec)) items = [] for ccd in ccds: if len(ccd) == 4: (x1, y1) = self.p2c((ccd[0], ccd[1])) (x2, y2) = self.p2c((ccd[2], ccd[3])) item = self.create_rectangle(x1, y1, x2, y2, stipple='gray25', fill=None) else: (x1, y1) = self.p2c((ccd[0] - ccd[2] / math.cos(ccd[1]), ccd[1] - ccd[2])) (x2, y2) = self.p2c((ccd[0] + ccd[2] / math.cos(ccd[1]), ccd[1] + ccd[2])) item = self.create_oval(x1, y1, x2, y2) items.append(item) self.pointings.append({"label": label, "items": items, "camera": this_camera}) if not not_ephem: break self.plot_pointings() return
def create_pointing(self, event, label_text=None): """Plot the sky coverage of pointing at event.x,event.y on the canvas. """ (ra, dec) = self.c2p((self.canvasx(event.x), self.canvasy(event.y))) this_camera = Camera(camera=self.camera.get()) ccds = this_camera.getGeometry(ra, dec) items = [] for ccd in ccds: if len(ccd) == 4: (x1, y1) = self.p2c((ccd[0], ccd[1])) (x2, y2) = self.p2c((ccd[2], ccd[3])) item = self.create_rectangle(x1, y1, x2, y2, stipple='gray25', fill=None) else: (x1, y1) = self.p2c((ccd[0] - ccd[2], ccd[1] - ccd[2])) (x2, y2) = self.p2c((ccd[0] + ccd[2], ccd[1] + ccd[2])) item = self.create_oval(x1, y1, x2, y2) items.append(item) label = {} if label_text is None: label_text = self.plabel.get() label['text'] = label_text label['id'] = self.label(this_camera.ra, this_camera.dec, label['text']) self.pointings.append({ "label": label, "items": items, "camera": this_camera }) self.current = len(self.pointings) - 1 self.current_pointing(len(self.pointings) - 1)
def coverage(orbits, locations): """ @param orbits: a dictionary of orbits to optimize the point of. @param locations: list of CFHT pointings. @return: """ # For each required target find the pointing that will include the largest number of other required targets # and then tweak that specific pointing to include the maximum number of secondary targets. for location in locations: p = Camera( SkyCoord(location["RA__J2000.0_"], location["Dec.__J2000.0_"], unit=('degree', 'degree'))) for kbo_name in orbits: orbits[kbo_name].predict(Time(location["Start_Date"], format='mjd')) if p.polygon.isInside(orbits[kbo_name].coordinate.ra.degree, orbits[kbo_name].coordinate.dec.degree): print((location['Target_Name'], kbo_name))
def optimize(orbits, required, locations, tokens, camera_name="MEGACAM_40"): """ @param orbits: a dictionary of orbits to optimize the point of. @param required: list of objects that MUST be observed. @param locations: locations of the objects at the start of observing period. @param tokens: List of tokens (object names) that we will try and cover. @return: """ # Get the tokens that will be paged through in random order. token_order = np.random.permutation(required) optimal_pointings = {} covered = [ ] # the objects that have already been covered by a planned pointing. search_order = [ 0, ] # search_order = [22 + 4] # search_order.extend(range(len(Camera.names))) # For each required target find the pointing that will include the largest number of other required targets # and then tweak that specific pointing to include the maximum number of secondary targets. for token in token_order: if token in covered: continue logging.debug( "Optimizing pointing for required target: {}".format(token)) if token not in orbits: logging.error("No orbit available for: {}".format(token)) continue obj = orbits[token] separations = obj.coordinate.separation(locations) possible_tokens = tokens[separations < 1.3 * units.degree] this_required = [] for this_token in required: if this_token in possible_tokens: this_required.append(this_token) # This object is not inside the existing coverage. max_sources_in_pointing = 0 best_coverage = [] p = SkyCoord(obj.coordinate.ra, obj.coordinate.dec) pointing = Camera(p, camera=camera_name) if len(possible_tokens) == 1: optimal_pointings[token] = pointing, possible_tokens logging.info(" {} is all alone!".format(token)) continue logging.debug("examining possible optimizations") if len(this_required) == 1: best_coverage = [token] else: logging.debug("Maximizing inclusion of required targets") for idx in search_order: pointing.offset(index=idx) this_coverage = [] for this_token in this_required: if this_token in covered: continue this_obj = orbits[this_token] if pointing.polygon.isInside( this_obj.coordinate.ra.degree, this_obj.coordinate.dec.degree): this_coverage.append(this_token) if len(this_coverage) > max_sources_in_pointing: max_sources_in_pointing = len(this_coverage) best_coverage = this_coverage # best_pointing now contains the pointing that covers the largest number of required sources. # best_coverage is the list of sources (tokens) that this pointing covered. # now move around the best_pointing, keeping all the objects listed in best_coverage but maximizing the # number of other sources that get coverage (optimal_coverage) logging.info("{} pointing these {} required targets: {}".format( token, len(best_coverage), best_coverage)) max_sources_in_pointing = 0 optimal_coverage = [] optimal_pointing = None for idx in search_order: pointing.offset(index=idx) exclude = False # exclude this offset because it doesn't overlap one or more of the required sources. for this_token in best_coverage: this_obj = orbits[this_token] if not pointing.polygon.isInside( this_obj.coordinate.ra.degree, this_obj.coordinate.dec.degree): exclude = True break if exclude: continue # OK, this offset has all the required sources possible, how many extra sources do we get? this_coverage = [] for this_token in possible_tokens: if this_token in covered: continue this_obj = orbits[this_token] if pointing.polygon.isInside(this_obj.coordinate.ra.degree, this_obj.coordinate.dec.degree): this_coverage.append(this_token) if len(this_coverage) > max_sources_in_pointing: max_sources_in_pointing = len(this_coverage) optimal_coverage = this_coverage optimal_pointing = idx # remove all sources covered by optimal_pointing from further consideration. sys.stdout.write("{} pointing covers: ".format(token)) unique_coverage_list = [] for this_token in optimal_coverage: if this_token not in covered: unique_coverage_list.append(this_token) sys.stdout.write(" {} ".format(this_token)) covered.append(this_token) sys.stdout.write("\n") pointing.offset(index=optimal_pointing) optimal_pointings[token] = pointing, unique_coverage_list n = 0 new_required = [] for this_token in token_order: if this_token not in covered: new_required.append(this_token) n += 1 logging.info( "Remaining required targets: {}, targets covered: {}".format( n, len(covered))) required = new_required return optimal_pointings
def optimize(orbits, required, locations, tokens, camera_name="MEGACAM_40"): """ @param orbits: a dictionary of orbits to optimize the point of. @param required: list of objects that MUST be observed. @param locations: locations of the objects at the start of observing period. @param tokens: List of tokens (object names) that we will try and cover. @return: """ # Get the tokens that will be paged through in random order. token_order = np.random.permutation(required) optimal_pointings = {} covered = [] # the objects that have already been covered by a planned pointing. search_order = [0, ] # search_order = [22 + 4] # search_order.extend(range(len(Camera.names))) # For each required target find the pointing that will include the largest number of other required targets # and then tweak that specific pointing to include the maximum number of secondary targets. for token in token_order: if token in covered: continue logging.debug("Optimizing pointing for required target: {}".format(token)) if token not in orbits: logging.error("No orbit available for: {}".format(token)) continue obj = orbits[token] separations = obj.coordinate.separation(locations) possible_tokens = tokens[separations < 1.3 * units.degree] this_required = [] for this_token in required: if this_token in possible_tokens: this_required.append(this_token) # This object is not inside the existing coverage. max_sources_in_pointing = 0 best_coverage = [] p = SkyCoord(obj.coordinate.ra, obj.coordinate.dec) pointing = Camera(p, camera=camera_name) if len(possible_tokens) == 1: optimal_pointings[token] = pointing, possible_tokens logging.info(" {} is all alone!".format(token)) continue logging.debug("examining possible optimizations") if len(this_required) == 1: best_coverage = [token] else: logging.debug("Maximizing inclusion of required targets") for idx in search_order: pointing.offset(index=idx) this_coverage = [] for this_token in this_required: if this_token in covered: continue this_obj = orbits[this_token] if pointing.polygon.isInside(this_obj.coordinate.ra.degree, this_obj.coordinate.dec.degree): this_coverage.append(this_token) if len(this_coverage) > max_sources_in_pointing: max_sources_in_pointing = len(this_coverage) best_coverage = this_coverage # best_pointing now contains the pointing that covers the largest number of required sources. # best_coverage is the list of sources (tokens) that this pointing covered. # now move around the best_pointing, keeping all the objects listed in best_coverage but maximizing the # number of other sources that get coverage (optimal_coverage) logging.info("{} pointing these {} required targets: {}".format(token, len(best_coverage), best_coverage)) max_sources_in_pointing = 0 optimal_coverage = [] optimal_pointing = None for idx in search_order: pointing.offset(index=idx) exclude = False # exclude this offset because it doesn't overlap one or more of the required sources. for this_token in best_coverage: this_obj = orbits[this_token] if not pointing.polygon.isInside(this_obj.coordinate.ra.degree, this_obj.coordinate.dec.degree): exclude = True break if exclude: continue # OK, this offset has all the required sources possible, how many extra sources do we get? this_coverage = [] for this_token in possible_tokens: if this_token in covered: continue this_obj = orbits[this_token] if pointing.polygon.isInside(this_obj.coordinate.ra.degree, this_obj.coordinate.dec.degree): this_coverage.append(this_token) if len(this_coverage) > max_sources_in_pointing: max_sources_in_pointing = len(this_coverage) optimal_coverage = this_coverage optimal_pointing = idx # remove all sources covered by optimal_pointing from further consideration. sys.stdout.write("{} pointing covers: ".format(token)) unique_coverage_list = [] for this_token in optimal_coverage: if this_token not in covered: unique_coverage_list.append(this_token) sys.stdout.write(" {} ".format(this_token)) covered.append(this_token) sys.stdout.write("\n") pointing.offset(index=optimal_pointing) optimal_pointings[token] = pointing, unique_coverage_list n = 0 new_required = [] for this_token in token_order: if this_token not in covered: new_required.append(this_token) n += 1 logging.info("Remaining required targets: {}, targets covered: {}".format(n, len(covered))) required = new_required return optimal_pointings
def optimize(orbits, required, locations, tokens, camera_name="DEIMOS"): """ @param orbits: a dictionary of orbits to optimize the point of. @param required: list of objects that MUST be observed. @param locations: locations of the objects at the start of observing period. @param tokens: List of tokens (object names) that we will try and cover. @param camera_name: name of camera to look up in geometry file. @return: """ # Get the tokens that will be paged through in random order. token_order = np.random.permutation(required) optimal_pointings = {} covered = [] # the objects that have already been covered by a planned pointing. search_order = [0, ] # search_order = [22 + 4] # search_order.extend(range(len(Camera.names))) # For each required target find the pointing that will include the largest number of other required targets # and then tweak that specific pointing to include the maximum number of secondary targets. for token in token_order: if token in covered: continue logging.debug("Optimizing pointing for required target: {}".format(token)) if token not in orbits: logging.error("No orbit available for: {}".format(token)) continue obj = orbits[token] q = SkyCoord(obj.coordinate.ra, obj.coordinate.dec) pointing = Camera(q, camera=camera_name, name=token) bbox = pointing.polygon.boundingBox() radius = (max((bbox[1]-bbox[0])**2, (bbox[3]-bbox[2])**2)*2)**0.5 separations = obj.coordinate.separation(locations) logging.info(f"Seaching within {radius} degrees of {token}") possible_tokens = tokens[separations < radius * units.degree] best_coverage = [token] optimal_pointing = pointing if len(possible_tokens) == 1: continue for dx in np.arange((q.ra.degree-bbox[0]-1/60.0), (bbox[1] - q.ra.degree), 1/60.0): for dy in np.arange((q.dec.degree-bbox[2]-1/60.0), (bbox[3] - q.dec.degree), 1/60.0): p = SkyCoord(obj.coordinate.ra + dx*units.degree, obj.coordinate.dec + dy*units.degree) pointing = Camera(p, camera=camera_name, name=token) this_required = [] for this_token in required: if this_token in possible_tokens: this_required.append(this_token) logging.debug(f"Field {token} near required targets {this_required}") # This object is not inside the existing coverage. if len(this_required) == 1: continue else: logging.debug("Finding required targets within pointing") this_coverage = [] for this_token in this_required: if this_token in covered: continue if pointing.polygon.isInside(orbits[this_token].coordinate.ra.degree, orbits[this_token].coordinate.dec.degree): logging.debug(f"Adding {this_token} to pointing {token}") this_coverage.append(this_token) if len(this_coverage) > len(best_coverage): logging.info(f"Best {token} pointing is {pointing.coordinate} with {len(this_coverage)} targets.") best_coverage = this_coverage optimal_pointing = pointing optimal_coverage = [] for dx in np.arange((q.ra.degree - bbox[0] - 2 / 60.0), (bbox[1] - q.ra.degree - 1/60.0), 1 / 60.0): for dy in np.arange((q.dec.degree - bbox[2] - 2 / 60.0), (bbox[3] - q.dec.degree - 1/60.0), 1 / 60.0): p = SkyCoord(obj.coordinate.ra + dx * units.degree, obj.coordinate.dec + dy * units.degree) pointing = Camera(p, camera=camera_name, name=token) # Skip offset if we loose required object. exclude = False for this_token in best_coverage: if not pointing.polygon.isInside(orbits[this_token].coordinate.ra.degree, orbits[this_token].coordinate.dec.degree): exclude = True break if exclude: continue this_coverage = [] for this_token in possible_tokens: if this_token in covered: continue if pointing.polygon.isInside(orbits[this_token].coordinate.ra.degree, orbits[this_token].coordinate.dec.degree): this_coverage.append(this_token) if len(this_coverage) > len(optimal_coverage): print(pointing.polygon.isInside(orbits[token].coordinate.ra.degree, orbits[token].coordinate.dec.degree)) optimal_coverage = this_coverage optimal_pointing = pointing # remove all sources covered by optimal_pointing from further consideration. unique_coverage_list = [] for this_token in best_coverage: if this_token not in covered: unique_coverage_list.append(this_token) covered.append(this_token) optimal_pointings[token] = optimal_pointing, unique_coverage_list return optimal_pointings