def __init__(self, working_directory, output_directory, dry_run=False, debug=False): self.dry_run = dry_run logger.info("Input directory set to: %s" % working_directory) logger.info("Output directory set to: %s" % output_directory) working_context = context.get_context(working_directory) output_context = context.get_context(output_directory) if dry_run and working_context.is_remote(): sys.stdout.write("A dry run can only be done on local files.\n") sys.exit(0) if output_context.is_remote(): sys.stdout.write("The output directory must be local.\n") sys.exit(0) image_manager = self._create_image_manager() progress_manager = working_context.get_progress_manager() builder = self._create_workunit_builder(working_context, output_context, progress_manager) workunit_provider = WorkUnitProvider(self.input_suffix, working_context, progress_manager, builder, randomize=self.should_randomize_workunits) prefetching_workunit_provider = PreFetchingWorkUnitProvider(workunit_provider, config.read("PREFETCH.NUMBER"), image_manager) if working_context.is_remote(): synchronization_manager = SynchronizationManager(working_context) else: synchronization_manager = None model = TransAckValidationModel(prefetching_workunit_provider, image_manager, synchronization_manager) logger.debug("Created model.") view = self._create_view(model, debug=debug) logger.debug("Created view.") model.start_work() self.model = model self.view = view self.controller = view.controller self.controller.display_current_image() if not synchronization_manager: self.view.disable_sync_menu() self.view.show()
def build_source_reading(self, expnum, ccd, X, Y): """ Given the location of a source in the image, create a source reading. """ image_uri = storage.dbimages_uri(expnum=expnum, ccd=None, version='p', ext='.fits', subdir=None) logger.debug('Trying to access {}'.format(image_uri)) if not storage.exists(image_uri, force=False): logger.warning('Image not in dbimages? Trying subdir.') image_uri = storage.dbimages_uri(expnum=expnum, ccd=ccd, version='p') if not storage.exists(image_uri, force=False): logger.warning("Image doesn't exist in ccd subdir. %s" % image_uri) return None slice_rows=config.read("CUTOUTS.SINGLETS.SLICE_ROWS") slice_cols=config.read("CUTOUTS.SINGLETS.SLICE_COLS") if X == -9999 or Y == -9999 : logger.warning("Skipping {} as x/y not resolved.".format(image_uri)) return None if not (-slice_cols/2. < X < 2048+slice_cols/2. and -slice_rows/2. < Y < 4600+slice_rows/2.0): logger.warning("Central location ({},{}) off image cutout.".format(X,Y)) return None mopheader_uri = storage.dbimages_uri(expnum=expnum, ccd=ccd, version='p', ext='.mopheader') if not storage.exists(mopheader_uri, force=False): # ELEVATE! we need to know to go off and reprocess/include this image. logger.critical('Image exists but processing incomplete. Mopheader missing. {}'.format(image_uri)) return None mopheader = get_mopheader(expnum, ccd) # Build astrom.Observation observation = astrom.Observation(expnum=str(expnum), ftype='p', ccdnum=str(ccd), fk="") observation.rawname = os.path.splitext(os.path.basename(image_uri))[0]+str(ccd).zfill(2) observation.header = mopheader return observation
def __init__(self, view, controller): self.controller = controller self.view = view next_obs_kb_id = wx.NewId() prev_obs_kb_id = wx.NewId() accept_src_kb_id = wx.NewId() reject_src_kb_id = wx.NewId() reset_cmap_kb_id = wx.NewId() reset_src_kb_id = wx.NewId() autoplay_kb_id = wx.NewId() load_comparison_kb_id = wx.NewId() load_diff_comparison_kb_id = wx.NewId() toggle_reticule_kb_id = wx.NewId() def bind(handler, kb_id): view.Bind(wx.EVT_MENU, handler, id=kb_id) bind(self.on_load_comparison_keybind, load_comparison_kb_id) bind(self.on_load_diff_comparison_keybind, load_diff_comparison_kb_id) bind(self.on_next_obs_keybind, next_obs_kb_id) bind(self.on_prev_obs_keybind, prev_obs_kb_id) bind(self.on_accept_src_keybind, accept_src_kb_id) bind(self.on_reject_src_keybind, reject_src_kb_id) bind(self.on_reset_cmap_keybind, reset_cmap_kb_id) bind(self.on_reset_source_location_keybind, reset_src_kb_id) bind(self.on_toggle_autoplay, autoplay_kb_id) bind(self.on_toggle_reticule, toggle_reticule_kb_id) self.accept_key = config.read("KEYBINDS.ACCEPT_SRC") self.reject_key = config.read("KEYBINDS.REJECT_SRC") self.reset_cmap_key = config.read("KEYBINDS.RESET_CMAP") self.reset_source_key = config.read("KEYBINDS.RESET_SOURCE_LOCATION") self.autoplay_key = config.read("KEYBINDS.AUTOPLAY") self.toggle_reticule_key = config.read("KEYBINDS.TOGGLE_RETICULE") self.load_comparison_key = config.read("KEYBINDS.LOAD_COMPARISON") self.load_diff_comparison_key = config.read( "KEYBINDS.LOAD_DIFF_COMPARISON") logger.debug(str(self.load_diff_comparison_key)) accelerators = wx.AcceleratorTable([ (wx.ACCEL_NORMAL, wx.WXK_TAB, next_obs_kb_id), (wx.ACCEL_SHIFT, wx.WXK_TAB, prev_obs_kb_id), (wx.ACCEL_NORMAL, ord(self.accept_key), accept_src_kb_id), (wx.ACCEL_NORMAL, ord(self.reject_key), reject_src_kb_id), (wx.ACCEL_NORMAL, ord(self.reset_cmap_key), reset_cmap_kb_id), (wx.ACCEL_NORMAL, ord(self.reset_source_key), reset_src_kb_id), (wx.ACCEL_NORMAL, ord(self.load_comparison_key), load_comparison_kb_id), (wx.ACCEL_NORMAL, ord(self.load_diff_comparison_key), load_diff_comparison_kb_id), (wx.ACCEL_NORMAL, ord(self.autoplay_key), autoplay_kb_id), (wx.ACCEL_NORMAL, ord(self.toggle_reticule_key), toggle_reticule_kb_id), ]) view.SetAcceleratorTable(accelerators)
def __init__(self, view, controller): self.controller = controller self.view = view next_obs_kb_id = wx.NewId() prev_obs_kb_id = wx.NewId() accept_src_kb_id = wx.NewId() reject_src_kb_id = wx.NewId() reset_cmap_kb_id = wx.NewId() reset_src_kb_id = wx.NewId() autoplay_kb_id = wx.NewId() load_comparison_kb_id = wx.NewId() load_diff_comparison_kb_id = wx.NewId() toggle_reticule_kb_id = wx.NewId() def bind(handler, kb_id): view.Bind(wx.EVT_MENU, handler, id=kb_id) bind(self.on_load_comparison_keybind, load_comparison_kb_id) bind(self.on_load_diff_comparison_keybind, load_diff_comparison_kb_id) bind(self.on_next_obs_keybind, next_obs_kb_id) bind(self.on_prev_obs_keybind, prev_obs_kb_id) bind(self.on_accept_src_keybind, accept_src_kb_id) bind(self.on_reject_src_keybind, reject_src_kb_id) bind(self.on_reset_cmap_keybind, reset_cmap_kb_id) bind(self.on_reset_source_location_keybind, reset_src_kb_id) bind(self.on_toggle_autoplay, autoplay_kb_id) bind(self.on_toggle_reticule, toggle_reticule_kb_id) self.accept_key = config.read("KEYBINDS.ACCEPT_SRC") self.reject_key = config.read("KEYBINDS.REJECT_SRC") self.reset_cmap_key = config.read("KEYBINDS.RESET_CMAP") self.reset_source_key = config.read("KEYBINDS.RESET_SOURCE_LOCATION") self.autoplay_key = config.read("KEYBINDS.AUTOPLAY") self.toggle_reticule_key = config.read("KEYBINDS.TOGGLE_RETICULE") self.load_comparison_key = config.read("KEYBINDS.LOAD_COMPARISON") self.load_diff_comparison_key = config.read("KEYBINDS.LOAD_DIFF_COMPARISON") logger.debug(str(self.load_diff_comparison_key)) accelerators = wx.AcceleratorTable( [ (wx.ACCEL_NORMAL, wx.WXK_TAB, next_obs_kb_id), (wx.ACCEL_SHIFT, wx.WXK_TAB, prev_obs_kb_id), (wx.ACCEL_NORMAL, ord(self.accept_key), accept_src_kb_id), (wx.ACCEL_NORMAL, ord(self.reject_key), reject_src_kb_id), (wx.ACCEL_NORMAL, ord(self.reset_cmap_key), reset_cmap_kb_id), (wx.ACCEL_NORMAL, ord(self.reset_source_key), reset_src_kb_id), (wx.ACCEL_NORMAL, ord(self.load_comparison_key), load_comparison_kb_id), (wx.ACCEL_NORMAL, ord(self.load_diff_comparison_key), load_diff_comparison_kb_id), (wx.ACCEL_NORMAL, ord(self.autoplay_key), autoplay_kb_id), (wx.ACCEL_NORMAL, ord(self.toggle_reticule_key), toggle_reticule_kb_id), ] ) view.SetAcceleratorTable(accelerators)
def get_image_uri(self): # TODO: make more general - have logic for trying alternative locations uri = "%s/%s/" % (DATASET_ROOT, self.expnum) if self.is_fake(): uri += "ccd%s/%s.fits" % (self.ccdnum, self.rawname) else: uri += "%s%s.fits" % (self.expnum, self.ftype) logger.debug("sending back URI: {}".format(uri)) return uri
def __init__(self, x_offset, y_offset, invert=False): """ @type y_offset: float @type x_offset: float """ self._dx = x_offset self._dy = y_offset self._invert = invert and -1 or 1 logger.debug("Convert initialized as x_offset, y_offset {},{}".format(self.x_offset, self.y_offset))
def __init__(self, x_offset, y_offset, invert=False): """ @type y_offset: float @type x_offset: float """ self._dx = x_offset self._dy = y_offset self._invert = invert and -1 or 1 logger.debug("Convert initialized as x_offset, y_offset {},{}".format( self.x_offset, self.y_offset))
def download_triplets_for_workunit(self, workunit): if workunit in self._workunits_downloaded_for_triplets: return logger.debug("Starting to download triplets for workunit: %s" % workunit.get_filename()) self._workunits_downloaded_for_triplets.add(workunit) for source in workunit.get_unprocessed_sources(): self.download_triplets_for_source(source)
def _maximize_workers(self): self._prune_dead_workers() while len(self._workers) < MAX_THREADS: worker = DownloadThread(self._work_queue, self.downloader, self.error_handler) worker.daemon = True # Thread quits when application does self._workers.append(worker) worker.start() logger.debug("Created download worker thread (total=%d)" % len(self._workers))
def on_load_comparison(self, research=False): """ Display the comparison image """ logger.debug(str(research)) cutout = self.model.get_current_cutout() if research or cutout.comparison_image is None: cutout.retrieve_comparison_image(self.downloader) self.view.display(cutout.comparison_image) self.model.get_current_workunit().previous_obs() self.model.acknowledge_image_displayed()
def download_singlets_for_workunit(self, workunit): if workunit in self._workunits_downloaded_for_singlets: return logger.debug("Starting to download singlets for workunit: %s" % workunit.get_filename()) self._workunits_downloaded_for_singlets.add(workunit) needs_apcor = workunit.is_apcor_needed() for source in workunit.get_unprocessed_sources(): self.download_singlets_for_source(source, needs_apcor=needs_apcor)
def is_inverted(self): """ Returns: inverted: bool True if the stored image is inverted. """ astheader = storage.get_astheader(self.obs.expnum, self.obs.ccdnum, version=self.obs.ftype) pvwcs = wcs.WCS(astheader) (x,y) = pvwcs.sky2xy(self.ra, self.dec) logger.debug("is_inverted: X,Y {},{} -> wcs X,Y {},{}".format(self.x, self.y, x, y)) dr2 = ((x-self.x)**2 + (y-self.y)**2) logger.debug("inverted is {}".format(dr2>2)) return dr2 > 2
def on_load_comparison(self, research=False): """ Display the comparison image """ logger.debug(str(research)) cutout = self.model.get_current_cutout() if research or cutout.comparison_image is None: cutout.retrieve_comparison_image(self.downloader) if cutout.comparison_image is not None: # if a comparison image was found self.view.display(cutout.comparison_image) self.model.get_current_workunit().previous_obs() self.model.acknowledge_image_displayed()
def build_workunit(self, input_fullpath): try: parsed_data = self.parser.parse(input_fullpath) except AssertionError as e: logger.critical(str(e)) events.send(events.NO_AVAILABLE_WORK) logger.debug("Parsed %s (%d sources)" % (input_fullpath, parsed_data.get_source_count())) _, input_filename = os.path.split(input_fullpath) return self._do_build_workunit(input_filename, parsed_data, self.progress_manager, self.output_context, self.dry_run)
def download_raw(self, uri, **kwargs): """ Downloads raw data from VOSpace. Args: uri: The URI of the resource to download. kwargs: optional arguments to pass to the vos client. Returns: raw_string: str The data downloaded as a string. """ logger.debug("Starting download: %s" % uri) return self.vosclient.open(uri, **kwargs).read()
def from_source_reference(expnum, ccd, X, Y): """ Given the location of a source in the image, create a source reading. """ image_uri = storage.dbimages_uri(expnum=expnum, ccd=None, version='p', ext='.fits', subdir=None) logger.debug('Trying to access {}'.format(image_uri)) if not storage.exists(image_uri, force=False): logger.warning('Image not in dbimages? Trying subdir.') image_uri = storage.dbimages_uri(expnum=expnum, ccd=ccd, version='p') if not storage.exists(image_uri, force=False): logger.warning("Image doesn't exist in ccd subdir. %s" % image_uri) return None if X == -9999 or Y == -9999 : logger.warning("Skipping {} as x/y not resolved.".format(image_uri)) return None mopheader_uri = storage.dbimages_uri(expnum=expnum, ccd=ccd, version='p', ext='.mopheader') if not storage.exists(mopheader_uri, force=False): # ELEVATE! we need to know to go off and reprocess/include this image. logger.critical('Image exists but processing incomplete. Mopheader missing. {}'.format(image_uri)) return None mopheader = storage.get_mopheader(expnum, ccd) # Build astrom.Observation observation = Observation(expnum=str(expnum), ftype='p', ccdnum=str(ccd), fk="") observation.rawname = os.path.splitext(os.path.basename(image_uri))[0]+str(ccd).zfill(2) observation.header = mopheader return observation
def get_coord_offset(self, expnum, ccd, X, Y, ref_expnum, ref_ccd): # determine offsets to reference reference frame using wcs astheader = get_astheader(expnum, ccd) ref_astheader = get_astheader(ref_expnum, ref_ccd) ref_pvwcs = wcs.WCS(ref_astheader) pvwcs = wcs.WCS(astheader) (ra,dec) = pvwcs.xy2sky(X, Y) (x0, y0) = ref_pvwcs.sky2xy(ra,dec) logger.debug("{}p{} {},{} -> {}p{} {},{}".format(expnum,ccd, X,Y, ref_expnum, ref_ccd, x0,y0)) return (x0, y0)
def compute_inverted(self): """ Returns: inverted: bool True if the stored image is inverted. """ astheader = storage.get_astheader(self.obs.expnum, self.obs.ccdnum, version=self.obs.ftype) pvwcs = wcs.WCS(astheader) (x, y) = pvwcs.sky2xy(self.ra, self.dec) logger.debug("is_inverted: X,Y {},{} -> wcs X,Y {},{}".format( self.x, self.y, x, y)) dr2 = ((x - self.x)**2 + (y - self.y)**2) logger.debug("inverted is {}".format(dr2 > 2)) return dr2 > 2
def from_source_reference(expnum, ccd, x, y): """ Given the location of a source in the image, create a source reading. """ image_uri = storage.dbimages_uri(expnum=expnum, ccd=None, version='p', ext='.fits', subdir=None) logger.debug('Trying to access {}'.format(image_uri)) if not storage.exists(image_uri, force=False): logger.warning('Image not in dbimages? Trying subdir.') image_uri = storage.dbimages_uri(expnum=expnum, ccd=ccd, version='p') if not storage.exists(image_uri, force=False): logger.warning("Image doesn't exist in ccd subdir. %s" % image_uri) return None if x == -9999 or y == -9999: logger.warning( "Skipping {} as x/y not resolved.".format(image_uri)) return None mopheader_uri = storage.dbimages_uri(expnum=expnum, ccd=ccd, version='p', ext='.mopheader') if not storage.exists(mopheader_uri, force=False): # ELEVATE! we need to know to go off and reprocess/include this image. logger.critical( 'Image exists but processing incomplete. Mopheader missing. {}' .format(image_uri)) return None # Build astrom.Observation observation = Observation(expnum=str(expnum), ftype='p', ccdnum=str(ccd), fk="") observation.rawname = os.path.splitext( os.path.basename(image_uri))[0] + str(ccd).zfill(2) return observation
def build_workunit(self, input_fullpath): try: parsed_data = self.parser.parse(input_fullpath) except AssertionError as e: logger.critical(str(e)) events.send(events.NO_AVAILABLE_WORK) logger.debug("Parsed %s (%d sources)" % (input_fullpath, parsed_data.get_source_count())) _, input_filename = os.path.split(input_fullpath) return self._do_build_workunit( input_filename, parsed_data, self.progress_manager, self.output_context, self.dry_run)
def download_cutout(self, reading, focus=None, needs_apcor=False): """ Downloads a cutout of the FITS image for a given source reading. Args: source_reading: ossos.astrom.SourceReading The reading which will be the focus of the downloaded image. focus: tuple(int, int) The x, y coordinates that should be the focus of the downloaded image. These coordinates should be in terms of the source_reading parameter's coordinate system. Default value is None, in which case the source reading's x, y position is used as the focus. needs_apcor: bool If True, the apcor file with data needed for photometry calculations is downloaded in addition to the image. Defaults to False. Returns: cutout: ossos.downloads.data.SourceCutout """ if focus is None: focus = reading.source_point cutout_str, converter = self.cutout_calculator.build_cutout_str( reading.get_extension(), focus, reading.get_original_image_size(), inverted=reading.is_inverted()) image_uri = reading.get_image_uri() logger.debug("Calculated cutout: %s for %s" % (cutout_str, image_uri)) hdulist = self.download_hdulist(image_uri, view="cutout", cutout=cutout_str) apcor = None if needs_apcor: apcor = self.download_apcor(reading.get_apcor_uri()) return SourceCutout(reading, hdulist, converter, apcor)
def convert(self, point): """ Convert a point from one coordinate system to another. Args: point: tuple(int x, int y) The point in the original coordinate system. Returns: converted_point: tuple(int x, int y) The point in the new coordinate system. Example: convert coordinate from original image into a pixel location within a cutout image. """ x, y = point (x1, y1) = x - self.x_offset, y - self.y_offset logger.debug("converted {} {} to {} {}".format(x,y, x1, y1)) return x1, y1
def retrieve_comparison_image(self, downloader): """ Search the DB for a comparison image for this cutout. """ # selecting comparitor when on a comparitor should load a new one. ref_wcs = wcs.WCS(self.fits_header) ref_x = self.fits_header['NAXIS1']/2.0 ref_y = self.fits_header['NAXIS2']/2.0 (ref_ra, ref_dec) = ref_wcs.xy2sky(ref_x,ref_y) dra = self.fits_header['CD1_1']*self.fits_header['NAXIS1']/2.0 ddec= self.fits_header['CD2_2']*self.fits_header['NAXIS2']/2.0 radius=max(dra,ddec) logger.debug("BOX({} {} {} {})".format(ref_ra, ref_dec,dra, ddec)) query_result = storage.cone_search(ref_ra, ref_dec, dra, ddec) comparison = None for collectionID in query_result['collectionID']: if collectionID not in self._bad_comparison_images: comparison = collectionID self._bad_comparison_images.append(comparison) break if comparison is None: self._comparison_image = None return base_url = "https://www.cadc-ccda.hia-iha.nrc-cnrc.gc.ca/vospace/nodes/OSSOS/dbimages/{}/{}p.fits".format(comparison, comparison) cutout = 'CIRCLE ICRS {} {} {}'.format(ref_ra,ref_dec,radius) url = base_url+"?"+urllib.urlencode({'view': 'cutout', 'cutout': cutout}) hdu_list = downloader.download_hdulist(uri=None, URL=url) comp_wcs = wcs.WCS(hdu_list[-1].header) (x, y) = comp_wcs.sky2xy(ref_ra, ref_dec) obs = Observation(str(comparison),'p',ccdnum=str(hdu_list[-1].header.get('EXTVER',0))) reading = SourceReading(x,y,ref_x, ref_y, ref_ra, ref_dec,ref_x,ref_y, obs) self._comparison_image = SourceCutout(reading ,hdu_list, CoordinateConverter(0,0))
def download_hdulist(self, uri, **kwargs): """ Downloads a FITS image as a HDUList. Args: uri: The URI of the FITS image to download. kwargs: optional arguments to pass to the vos client. For example, passing view="cutout" and cutout=[1] will result in a cutout of extension 1 from the FITS image specified by the URI. Returns: hdulist: astropy.io.fits.hdu.hdulist.HDUList The requests FITS image as an Astropy HDUList object (http://docs.astropy.org/en/latest/io/fits/api/hdulists.html). """ logger.debug(str(kwargs)) hdulist = fits.open(cStringIO.StringIO(self.download_raw(uri, **kwargs))) logger.debug("Got fits hdulist of len {}".format(len(hdulist))) return hdulist
def get(self): """ :return: astropy.table.table :raise: AssertionError """ params = self.param_dict_biulder.params self.response = requests.get(SSOS_URL, params=params, headers=self.headers) logger.debug(self.response.url) assert isinstance(self.response, requests.Response) assert(self.response.status_code == requests.codes.ok ) lines = self.response.content if len(lines) < 1 or str(lines[1]).startswith(( "An error occurred getting the ephemeris") ): raise IOError(os.errno.EACCES, "call to SSOS failed on format error") return lines
def convert(self, point): """ Convert a point from one coordinate system to another. Args: point: tuple(int x, int y) The point in the original coordinate system. Returns: converted_point: tuple(int x, int y) The point in the new coordinate system. Example: convert coordinate from original image into a pixel location within a cutout image. @rtype: list(float,float) """ x, y = point (x1, y1) = x - self.x_offset, y - self.y_offset logger.debug("converted {} {} ==> {} {}".format(x, y, x1, y1)) return x1, y1
def download_hdulist(self, uri, **kwargs): """ Downloads a FITS image as a HDUList. Args: uri: The URI of the FITS image to download. kwargs: optional arguments to pass to the vos client. For example, passing view="cutout" and cutout=[1] will result in a cutout of extension 1 from the FITS image specified by the URI. Returns: hdulist: astropy.io.fits.hdu.hdulist.HDUList The requests FITS image as an Astropy HDUList object (http://docs.astropy.org/en/latest/io/fits/api/hdulists.html). """ logger.debug(str(kwargs)) hdulist = None try: vobj = storage.vofile(uri, **kwargs) try: fobj = io.StringIO(vobj.read()) fobj.seek(0) hdulist = fits.open(fobj) except Exception as e: sys.stderr.write("ERROR: {}\n".format(str(e))) sys.stderr.write("While loading {} {}\n".format(uri, kwargs)) pass finally: vobj.close() except Exception as e: sys.stderr.write(str(e) + "\n") sys.stderr.write("While opening connection to {}.\n".format(uri)) sys.stderr.write( "Sending back FLAT instead, too keep display happy.") hdulist = self.download_hdulist( 'vos:OSSOS/dbimages/calibrators/13AQ05_r_flat.fits', **kwargs) return hdulist
def download_hdulist(self, uri, **kwargs): """ Downloads a FITS image as a HDUList. Args: uri: The URI of the FITS image to download. kwargs: optional arguments to pass to the vos client. For example, passing view="cutout" and cutout=[1] will result in a cutout of extension 1 from the FITS image specified by the URI. Returns: hdulist: astropy.io.fits.hdu.hdulist.HDUList The requests FITS image as an Astropy HDUList object (http://docs.astropy.org/en/latest/io/fits/api/hdulists.html). """ logger.debug(str(kwargs)) hdulist = None try: vobj = storage.vofile(uri, **kwargs) try: fobj = cStringIO.StringIO(vobj.read()) fobj.seek(0) hdulist = fits.open(fobj) except Exception as e: sys.stderr.write("ERROR: {}\n".format(str(e))) sys.stderr.write("While loading {} {}\n".format(uri, kwargs)) pass finally: vobj.close() except Exception as e: sys.stderr.write(str(e)+"\n") sys.stderr.write("While opening connection to {}.\n".format(uri)) sys.stderr.write("Sending back FLAT instead, too keep display happy.") hdulist = self.download_hdulist('vos:OSSOS/dbimages/calibrators/13AQ05_r_flat.fits', **kwargs) return hdulist
def on_load_diff_comparison_keybind(self, event): logger.debug("BBB!") self.controller.on_load_comparison(research=True)
def start_work(self): logger.debug("Model starting work.") self.next_workunit()
def phot(fits_filename, x_in, y_in, aperture=15, sky=20, swidth=10, apcor=0.3, maxcount=30000.0, exptime=1.0, zmag=None): """ Compute the centroids and magnitudes of a bunch sources detected on CFHT-MEGAPRIME images. Args: fits_filename: str The name of the file containing the image to be processed. Returns a MOPfiles data structure. """ if not hasattr(x_in, '__iter__'): x_in = [ x_in, ] if not hasattr(y_in, '__iter__'): y_in = [ y_in, ] if (not os.path.exists(fits_filename) and not fits_filename.endswith(".fits")): # For convenience, see if we just forgot to provide the extension fits_filename += ".fits" try: input_hdulist = fits.open(fits_filename) except Exception as err: logger.debug(str(err)) raise TaskError("Failed to open input image: %s" % err.message) ## get the filter for this image filter = input_hdulist[0].header.get('FILTER', 'DEFAULT') ### Some nominal CFHT zeropoints that might be useful zeropoints = { "I": 25.77, "R": 26.07, "V": 26.07, "B": 25.92, "DEFAULT": 26.0, "g.MP9401": 26.4 } if zmag is None: zmag = input_hdulist[0].header.get('PHOTZP', zeropoints[filter]) ### check for magic 'zeropoint.used' files zpu_file = "zeropoint.used" if os.access(zpu_file, os.R_OK): with open(zpu_file) as zpu_fh: zmag = float(zpu_fh.read()) else: zpu_file = "%s.zeropoint.used" % (fits_filename[0:-5]) if os.access(zpu_file, os.R_OK): with open(zpu_file) as zpu_fh: zmag = float(zpu_fh.read()) photzp = input_hdulist[0].header.get( 'PHOTZP', zeropoints.get(filter, zeropoints["DEFAULT"])) if zmag != photzp: logger.warning( "ZEROPOINT {} sent to DAOPHOT doesn't match PHOTZP {} in header". format(zmag, photzp)) ### setup IRAF to do the magnitude/centroid measurements iraf.set(uparm="./") iraf.digiphot() iraf.apphot() iraf.daophot(_doprint=0) iraf.photpars.apertures = aperture iraf.photpars.zmag = zmag iraf.datapars.datamin = 0 iraf.datapars.datamax = maxcount iraf.datapars.exposur = "" iraf.datapars.itime = exptime iraf.fitskypars.annulus = sky iraf.fitskypars.dannulus = swidth iraf.fitskypars.salgorithm = "mode" iraf.fitskypars.sloclip = 5.0 iraf.fitskypars.shiclip = 5.0 iraf.centerpars.calgori = "centroid" iraf.centerpars.cbox = 5. iraf.centerpars.cthreshold = 0. iraf.centerpars.maxshift = 2. iraf.centerpars.clean = 'no' iraf.phot.update = 'no' iraf.phot.verbose = 'no' iraf.phot.verify = 'no' iraf.phot.interactive = 'no' # Used for passing the input coordinates coofile = tempfile.NamedTemporaryFile(suffix=".coo", delete=False) for i in range(len(x_in)): coofile.write("%f %f \n" % (x_in[i], y_in[i])) # Used for receiving the results of the task # mag_fd, mag_path = tempfile.mkstemp(suffix=".mag") magfile = tempfile.NamedTemporaryFile(suffix=".mag", delete=False) # Close the temp files before sending to IRAF due to docstring: # "Whether the name can be used to open the file a second time, while # the named temporary file is still open, varies across platforms" coofile.close() magfile.close() os.remove(magfile.name) iraf.phot(fits_filename, coofile.name, magfile.name) pdump_out = ascii.read(magfile.name, format='daophot') if not len(pdump_out) > 0: mag_content = open(magfile.name).read() raise TaskError("photometry failed. {}".format(mag_content)) # Clean up temporary files generated by IRAF os.remove(coofile.name) os.remove(magfile.name) return pdump_out
def download_cutout(self, reading, focus=None, needs_apcor=False): """ Downloads a cutout of the FITS image for a given source reading. Args: source_reading: ossos.astrom.SourceReading The reading which will be the focus of the downloaded image. focus: tuple(int, int) The x, y coordinates that should be the focus of the downloaded image. These coordinates should be in terms of the source_reading parameter's coordinate system. Default value is None, in which case the source reading's x, y position is used as the focus. needs_apcor: bool If True, the apcor file with data needed for photometry calculations is downloaded in addition to the image. Defaults to False. Returns: cutout: ossos.downloads.data.SourceCutout """ if focus is None: focus = reading.source_point cutout_str, converter = self.cutout_calculator.build_cutout_str( reading.get_extension(), focus, reading.get_original_image_size(), dx = reading.dx, dy = reading.dy, inverted=reading.is_inverted()) image_uri = reading.get_image_uri() cutout = re.findall(r'(\d+)', cutout_str) y2 = int(cutout[-1]) y1 = int(cutout[-2]) logger.info("Calculated cutout: %s for %s" % (cutout_str, image_uri)) hdulist = self.download_hdulist(image_uri, view="cutout", cutout=cutout_str) # modify the DATASEC to account for possible flip/flop and changes in dimensions of the image. (NAXIS1, NAXIS2) = reading.get_original_image_size() DATASEC = hdulist[0].header.get('DATASEC',None) if DATASEC is not None: datasec = re.findall(r'(\d+)', DATASEC) if y2 < y1: x2 = int(NAXIS1) - int(datasec[0]) + 1 x1 = int(NAXIS1) - int(datasec[1]) + 1 y2 = int(NAXIS2) - int(datasec[2]) + 1 y1 = int(NAXIS2) - int(datasec[3]) + 1 logger.info("Flip/Flopped DATASEC from {} to [{}:{}:{}:{}]".format(DATASEC, x1,x2,y1,y2)) datasec = (x1,x2,y1,y2) (x1,y1) = converter.convert((int(datasec[0]),int(datasec[2]))) x1 = max(1,x1) y1 = max(1,y1) (x2,y2) = converter.convert((int(datasec[1]),int(datasec[3]))) x2 = min(x2, int(hdulist[0].header['NAXIS1'])) y2 = min(y2, int(hdulist[0].header['NAXIS2'])) datasec = "[{}:{},{}:{}]".format(x1,x2,y1,y2) logger.info("Trimmed and offset DATASEC from {} to {}".format(DATASEC, datasec)) hdulist[0].header['DATASEC'] = datasec apcor = None if needs_apcor: try: apcor = self.download_apcor(reading.get_apcor_uri()) except: apcor = None zmag = None try: zmag = self.download_zmag(reading.get_zmag_uri()) except Exception as e: logger.debug(str(e)) pass return SourceCutout(reading, hdulist, converter, apcor, zmag=zmag)
def listdir(self): # Don't force because it causes a HUGE performance hit. logger.debug(f"Getting a listing of {self.directory}") dir_list = storage.listdir(self.directory, force=False) logger.debug(f"Got: {dir_list}") return dir_list
def __init__(self, view, controller): """ :param view: :param controller: the controller to bind this key to :type controller: AbstractController :return: """ logger.debug("Building KeybindManager.") self.controller = controller self.view = view next_obs_kb_id = wx.NewId() prev_obs_kb_id = wx.NewId() accept_src_kb_id = wx.NewId() auto_accept_src_kd_id = wx.NewId() reject_src_kb_id = wx.NewId() reset_cmap_kb_id = wx.NewId() reset_src_kb_id = wx.NewId() autoplay_kb_id = wx.NewId() load_comparison_kb_id = wx.NewId() load_diff_comparison_kb_id = wx.NewId() toggle_reticule_kb_id = wx.NewId() toggle_align_kb_id = wx.NewId() def bind(handler, kb_id): view.Bind(wx.EVT_MENU, handler, id=kb_id) bind(self.on_load_comparison_keybind, load_comparison_kb_id) bind(self.on_load_diff_comparison_keybind, load_diff_comparison_kb_id) bind(self.on_next_obs_keybind, next_obs_kb_id) bind(self.on_prev_obs_keybind, prev_obs_kb_id) bind(self.on_accept_src_keybind, accept_src_kb_id) bind(self.on_auto_accept_src_keybind, auto_accept_src_kd_id) bind(self.on_reject_src_keybind, reject_src_kb_id) bind(self.on_reset_cmap_keybind, reset_cmap_kb_id) bind(self.on_reset_source_location_keybind, reset_src_kb_id) bind(self.on_toggle_autoplay, autoplay_kb_id) bind(self.on_toggle_reticule, toggle_reticule_kb_id) bind(self.on_toggle_align, toggle_align_kb_id) self.toggle_align_key = config.read("KEYBINDS.TOGGLE_ALIGN") self.accept_key = config.read("KEYBINDS.ACCEPT_SRC") self.auto_accept_key = config.read("KEYBINDS.AUTO_ACCEPT_SRC") self.reject_key = config.read("KEYBINDS.REJECT_SRC") self.reset_cmap_key = config.read("KEYBINDS.RESET_CMAP") self.reset_source_key = config.read("KEYBINDS.RESET_SOURCE_LOCATION") self.autoplay_key = config.read("KEYBINDS.AUTOPLAY") self.toggle_reticule_key = config.read("KEYBINDS.TOGGLE_RETICULE") self.load_comparison_key = config.read("KEYBINDS.LOAD_COMPARISON") self.load_diff_comparison_key = config.read("KEYBINDS.LOAD_DIFF_COMPARISON") accelerators = [ (wx.ACCEL_NORMAL, wx.WXK_TAB, next_obs_kb_id), (wx.ACCEL_SHIFT, wx.WXK_TAB, prev_obs_kb_id), (wx.ACCEL_NORMAL, ord(self.accept_key), accept_src_kb_id), (wx.ACCEL_NORMAL, ord(self.auto_accept_key), auto_accept_src_kd_id), (wx.ACCEL_NORMAL, ord(self.reject_key), reject_src_kb_id), (wx.ACCEL_NORMAL, ord(self.reset_cmap_key), reset_cmap_kb_id), (wx.ACCEL_NORMAL, ord(self.reset_source_key), reset_src_kb_id), (wx.ACCEL_NORMAL, ord(self.load_comparison_key), load_comparison_kb_id), (wx.ACCEL_NORMAL, ord(self.load_diff_comparison_key), load_diff_comparison_kb_id), (wx.ACCEL_NORMAL, ord(self.autoplay_key), autoplay_kb_id), (wx.ACCEL_NORMAL, ord(self.toggle_reticule_key), toggle_reticule_kb_id), (wx.ACCEL_NORMAL, ord(self.toggle_align_key), toggle_align_kb_id), ] for line in config.read("MPC.NOTE1OPTIONS"): if not len(line) > 0: continue this_key = line.split()[0][0].lower() this_func = self._build_accept_func(this_key) this_key_id = wx.NewId() bind(this_func, this_key_id) accelerators.append((wx.ACCEL_CTRL, ord(this_key), this_key_id)) accelerators = wx.AcceleratorTable(accelerators) view.SetAcceleratorTable(accelerators)
def phot(fits_filename, x_in, y_in, aperture=15, sky=20, swidth=10, apcor=0.3, maxcount=30000.0, exptime=1.0, zmag=None): """ Compute the centroids and magnitudes of a bunch sources detected on CFHT-MEGAPRIME images. Args: fits_filename: str The name of the file containing the image to be processed. Returns a MOPfiles data structure. """ if (not os.path.exists(fits_filename) and not fits_filename.endswith(".fits")): # For convenience, see if we just forgot to provide the extension fits_filename += ".fits" try: input_hdulist = fits.open(fits_filename) except Exception as err: logger.debug(str(err)) raise TaskError("Failed to open input image: %s" % err.message) ## get the filter for this image filter = input_hdulist[0].header.get('FILTER', 'DEFAULT') ### Some nominal CFHT zeropoints that might be useful zeropoints = {"I": 25.77, "R": 26.07, "V": 26.07, "B": 25.92, "DEFAULT": 26.0, "g.MP9401": 26.4 } photzp = input_hdulist[0].header.get('PHOTZP', zeropoints.get(filter, zeropoints["DEFAULT"])) if zmag is None: zmag = input_hdulist[0].header.get('PHOTZP', zeropoints[filter]) ### check for magic 'zeropoint.used' files zpu_file = "zeropoint.used" if os.access(zpu_file, os.R_OK): with open(zpu_file) as zpu_fh: zmag = float(zpu_fh.read()) else: zpu_file = "%s.zeropoint.used" % ( fits_filename[0:-5]) if os.access(zpu_file, os.R_OK): with open(zpu_file) as zpu_fh: zmag = float(zpu_fh.read()) if zmag != photzp: logger.warning("ZEROPOINT {} used in DAOPHOT doesn't match PHOTZP {} in header".format(zmag, photzp)) ### setup IRAF to do the magnitude/centroid measurements iraf.set(uparm="./") iraf.digiphot() iraf.apphot() iraf.daophot(_doprint=0) iraf.photpars.apertures = aperture iraf.photpars.zmag = zmag iraf.datapars.datamin = 0 iraf.datapars.datamax = maxcount iraf.datapars.exposur = "" iraf.datapars.itime = exptime iraf.fitskypars.annulus = sky iraf.fitskypars.dannulus = swidth iraf.fitskypars.salgorithm = "mode" iraf.fitskypars.sloclip = 5.0 iraf.fitskypars.shiclip = 5.0 iraf.centerpars.calgori = "centroid" iraf.centerpars.cbox = 5. iraf.centerpars.cthreshold = 0. iraf.centerpars.maxshift = 2. iraf.centerpars.clean = 'no' iraf.phot.update = 'no' iraf.phot.verbose = 'no' iraf.phot.verify = 'no' iraf.phot.interactive = 'no' # Used for passing the input coordinates coofile = tempfile.NamedTemporaryFile(suffix=".coo", delete=False) coofile.write("%f %f \n" % (x_in, y_in)) # Used for receiving the results of the task # mag_fd, mag_path = tempfile.mkstemp(suffix=".mag") magfile = tempfile.NamedTemporaryFile(suffix=".mag", delete=False) # Close the temp files before sending to IRAF due to docstring: # "Whether the name can be used to open the file a second time, while # the named temporary file is still open, varies across platforms" coofile.close() magfile.close() os.remove(magfile.name) iraf.phot(fits_filename, coofile.name, magfile.name) # TODO: Move this filtering downstream to the user. phot_filter = "PIER==0 && CIER==0 && SIER==0" pdump_out = iraf.pdump(magfile.name, "XCENTER,YCENTER,MAG,MERR,ID,XSHIFT,YSHIFT,LID", phot_filter, header='no', parameters='yes', Stdout=1) if not len(pdump_out) > 0: mag_content = open(magfile.name).read() raise TaskError("photometry failed. {}".format(mag_content)) os.remove(coofile.name) os.remove(magfile.name) ### setup the mop output file structure hdu = {} hdu['header'] = {'image': input_hdulist, 'aper': aperture, 's_aper': sky, 'd_s_aper': swidth, 'aper_cor': apcor, 'zeropoint': zmag} hdu['order'] = ['X', 'Y', 'MAG', 'MERR', 'ID', 'XSHIFT', 'YSHIFT', 'LID'] hdu['format'] = {'X': '%10.2f', 'Y': '%10.2f', 'MAG': '%10.2f', 'MERR': '%10.2f', 'ID': '%8d', 'XSHIFT': '%10.2f', 'YSHIFT': '%10.2f', 'LID': '%8d'} hdu['data'] = {} for col in hdu['order']: hdu['data'][col] = [] for line in pdump_out: values = line.split() for col in hdu['order']: if re.match('\%.*f', hdu['format'][col]): if col == 'MAG': values[0] = float(values[0]) - float(apcor) hdu['data'][col].append(float(values.pop(0))) elif re.match('\%.*d', hdu['format'][col]): hdu['data'][col].append(int(values.pop(0))) else: hdu['data'][col].append(values.pop(0)) # Clean up temporary files generated by IRAF os.remove("datistabe.par") os.remove("datpdump.par") return hdu
def download_cutout(self, reading, focus=None, needs_apcor=False): """ Downloads a cutout of the FITS image for a given source reading. Args: source_reading: ossos.astrom.SourceReading The reading which will be the focus of the downloaded image. focus: tuple(int, int) The x, y coordinates that should be the focus of the downloaded image. These coordinates should be in terms of the source_reading parameter's coordinate system. Default value is None, in which case the source reading's x, y position is used as the focus. needs_apcor: bool If True, the apcor file with data needed for photometry calculations is downloaded in addition to the image. Defaults to False. Returns: cutout: ossos.downloads.data.SourceCutout """ if focus is None: focus = reading.source_point assert isinstance(reading, SourceReading) dx = dy = 2 * max(reading.dra, reading.ddec) dx = max(reading.dx, dx) dy = max(reading.dy, dy) (NAXIS1, NAXIS2) = reading.get_original_image_size() cutout_str, converter = self.cutout_calculator.build_cutout_str( reading.get_extension(), focus, (NAXIS1, NAXIS2), dx=dx, dy=dy, inverted=reading.is_inverted) image_uri = reading.get_image_uri() cutout = re.findall(r'(\d+)', cutout_str) y2 = int(cutout[-1]) y1 = int(cutout[-2]) logger.debug("Calculated cutout: %s for %s" % (cutout_str, image_uri)) hdulist = storage.get_image(expnum=reading.get_exposure_number(), ccd=reading.get_ccd_num(), cutout=cutout_str, version=reading.get_observation().ftype, prefix=reading.get_observation().fk, return_file=False) #hdulist = self.download_hdulist(image_uri, view="cutout", # cutout=cutout_str) # modify the DATASEC to account for possible flip/flop and changes in dimensions of the image. DATASEC = hdulist[0].header.get('DATASEC', None) if DATASEC is not None: datasec = re.findall(r'(\d+)', DATASEC) if y2 < y1: x2 = int(NAXIS1) - int(datasec[0]) + 1 x1 = int(NAXIS1) - int(datasec[1]) + 1 y2 = int(NAXIS2) - int(datasec[2]) + 1 y1 = int(NAXIS2) - int(datasec[3]) + 1 logger.debug( "Flip/Flopped DATASEC from {} to [{}:{}:{}:{}]".format( DATASEC, x1, x2, y1, y2)) datasec = (x1, x2, y1, y2) (x1, y1) = converter.convert((int(datasec[0]), int(datasec[2]))) x1 = max(1, x1) y1 = max(1, y1) (x2, y2) = converter.convert((int(datasec[1]), int(datasec[3]))) x2 = min(x2, int(hdulist[0].header['NAXIS1'])) y2 = min(y2, int(hdulist[0].header['NAXIS2'])) datasec = "[{}:{},{}:{}]".format(x1, x2, y1, y2) logger.debug("Trimmed and offset DATASEC from {} to {}".format( DATASEC, datasec)) hdulist[0].header['DATASEC'] = datasec apcor = None if needs_apcor: try: apcor = self.download_apcor(reading.get_apcor_uri()) except Exception as e: logger.error(str(e)) apcor = None zmag = None try: zmag = self.download_zmag(reading.get_zmag_uri()) except Exception as e: logger.error(str(e)) pass return SourceCutout(reading, hdulist, converter, apcor, zmag=zmag)
def on_accept(self): """ Initiates acceptance procedure, gathering required data. """ if self.model.is_current_source_named(): provisional_name = self.model.get_current_source_name() else: provisional_name = self._generate_provisional_name() band = self.model.get_current_band() default_comment = "" phot_failure = False source_cutout = self.model.get_current_cutout() display = ds9.ds9(target='validate') result = display.get('imexam key coordinate') values = result.split() logger.debug("IMEXAM returned {}".format(values)) cen_coords = (float(values[1]), float(values[2])) key = values[0] source_cutout.update_pixel_location(cen_coords) #source_cutout.pixel_x = float(values[1]) #source_cutout.pixel_y = float(values[2]) logger.debug("X, Y => {} , {}".format(source_cutout.pixel_x, source_cutout.pixel_y)) pixel_x = source_cutout.pixel_x pixel_y = source_cutout.pixel_y self.view.mark_apertures(self.model.get_current_cutout()) try: cen_x, cen_y, obs_mag, obs_mag_err = self.model.get_current_source_observed_magnitude( ) except Exception as error: logger.critical(str(error)) phot_failure = True obs_mag = "" cen_x = pixel_x cen_y = pixel_y obs_mag_err = -1 band = "" default_comment = str(error) if math.sqrt((cen_x - pixel_x)**2 + (cen_y - pixel_y)**2) > 1.5: # check if the user wants to use the 'hand' coordinates or these new ones. self.view.draw_error_ellipse(cen_x, cen_y, 10, 10, 0, color='r') self.view.show_offset_source_dialog((pixel_x, pixel_y), (cen_x, cen_y)) else: source_cutout.update_pixel_location((cen_x, cen_y)) self.model.get_current_cutout()._adjusted = False if self.model.is_current_source_adjusted(): note1_default = config.read("MPC.NOTE1_HAND_ADJUSTED") elif key in mpc.MPCNOTES['Note1'].keys(): note1_default = key else: note1_default = "" self.view.show_accept_source_dialog( provisional_name, self.model.get_current_observation_date(), self.model.get_current_ra(), self.model.get_current_dec(), obs_mag, obs_mag_err, band, note1_choices=config.read("MPC.NOTE1OPTIONS"), note2_choices=config.read("MPC.NOTE2OPTIONS"), note1_default=note1_default, note2_default=config.read("MPC.NOTE2DEFAULT"), default_observatory_code=config.read( "MPC.DEFAULT_OBSERVATORY_CODE"), default_comment=default_comment, phot_failure=phot_failure, pixel_x=source_cutout.pixel_x, pixel_y=source_cutout.pixel_y)
def __init__(self, working_directory, output_directory, dry_run=False, debug=False, name_filter=None, user_id=None): self.dry_run = dry_run self.user_id = user_id logger.info("Input directory set to: %s" % working_directory) logger.info("Output directory set to: %s" % output_directory) working_context = context.get_context(working_directory, userid=self.user_id) output_context = context.get_context(output_directory, userid=self.user_id) if dry_run and working_context.is_remote(): sys.stdout.write("A dry run can only be done on local files.\n") sys.exit(0) if output_context.is_remote(): sys.stdout.write("The output directory must be local.\n") sys.exit(0) image_manager = self._create_image_manager() progress_manager = working_context.get_progress_manager() builder = self._create_workunit_builder(working_context, output_context, progress_manager) workunit_provider = WorkUnitProvider( self.input_suffix, working_context, progress_manager, builder, randomize=self.should_randomize_workunits, name_filter=name_filter) prefetching_workunit_provider = PreFetchingWorkUnitProvider( workunit_provider, config.read("PREFETCH.NUMBER"), image_manager) if working_context.is_remote(): synchronization_manager = SynchronizationManager(working_context, sync_enabled=True) else: synchronization_manager = None model = TransAckValidationModel(prefetching_workunit_provider, image_manager, synchronization_manager) logger.debug("Created model.") view = self._create_view(model, debug=debug) logger.debug("Created view.") model.start_work() self.model = model self.view = view self.controller = view.controller self.controller.display_current_image() if not synchronization_manager: self.view.disable_sync_menu() self.view.show()
def on_accept(self): """ Initiates acceptance procedure, gathering required data. """ if self.model.is_current_source_named(): provisional_name = self.model.get_current_source_name() else: provisional_name = self._generate_provisional_name() band = self.model.get_current_band() default_comment = "" phot_failure = False source_cutout = self.model.get_current_cutout() display = ds9.ds9(target='validate') result = display.get('imexam key coordinate') values = result.split() logger.debug("IMEXAM returned {}".format(values)) cen_coords = (float(values[1]),float(values[2])) key = values[0] source_cutout.update_pixel_location(cen_coords) #source_cutout.pixel_x = float(values[1]) #source_cutout.pixel_y = float(values[2]) logger.debug("X, Y => {} , {}".format(source_cutout.pixel_x, source_cutout.pixel_y)) pixel_x = source_cutout.pixel_x pixel_y = source_cutout.pixel_y try: cen_x, cen_y, obs_mag, obs_mag_err = self.model.get_current_source_observed_magnitude() except TaskError as error: phot_failure = True obs_mag = "" cen_x = pixel_x cen_y = pixel_y obs_mag_err = -1 band = "" default_comment = str(error) if math.sqrt( (cen_x - pixel_x)**2 + (cen_y - pixel_y)**2 ) > 1.5: # check if the user wants to use the 'hand' coordinates or these new ones. self.view.draw_error_ellipse(cen_x, cen_y, 10, 10, 0, color='r') self.view.show_offset_source_dialog((pixel_x, pixel_y), (cen_x, cen_y)) else: source_cutout.update_pixel_location((cen_x, cen_y)) self.model.get_current_cutout()._adjusted = False if self.model.is_current_source_adjusted(): note1_default = config.read("MPC.NOTE1_HAND_ADJUSTED") elif key in mpc.MPCNOTES['Note1'].keys(): note1_default = key else: note1_default = "" self.view.show_accept_source_dialog( provisional_name, self.model.get_current_observation_date(), self.model.get_current_ra(), self.model.get_current_dec(), obs_mag, obs_mag_err, band, note1_choices=config.read("MPC.NOTE1OPTIONS"), note2_choices=config.read("MPC.NOTE2OPTIONS"), note1_default=note1_default, note2_default=config.read("MPC.NOTE2DEFAULT"), default_observatory_code=config.read("MPC.DEFAULT_OBSERVATORY_CODE"), default_comment=default_comment, phot_failure=phot_failure, pixel_x=source_cutout.pixel_x, pixel_y=source_cutout.pixel_y )
def __init__(self, x_offset, y_offset): self.x_offset = x_offset self.y_offset = y_offset logger.debug("Convert initialized as dx,dy,inverted {},{}".format(x_offset, y_offset))
def __init__(self, view, controller): """ :param view: :param controller: the controller to bind this key to :type controller: AbstractController :return: """ logger.debug("Building KeybindManager.") self.controller = controller self.view = view next_obs_kb_id = wx.NewId() prev_obs_kb_id = wx.NewId() accept_src_kb_id = wx.NewId() auto_accept_src_kd_id = wx.NewId() reject_src_kb_id = wx.NewId() reset_cmap_kb_id = wx.NewId() reset_src_kb_id = wx.NewId() autoplay_kb_id = wx.NewId() load_comparison_kb_id = wx.NewId() load_diff_comparison_kb_id = wx.NewId() toggle_reticule_kb_id = wx.NewId() toggle_align_kb_id = wx.NewId() def bind(handler, kb_id): view.Bind(wx.EVT_MENU, handler, id=kb_id) bind(self.on_load_comparison_keybind, load_comparison_kb_id) bind(self.on_load_diff_comparison_keybind, load_diff_comparison_kb_id) bind(self.on_next_obs_keybind, next_obs_kb_id) bind(self.on_prev_obs_keybind, prev_obs_kb_id) bind(self.on_accept_src_keybind, accept_src_kb_id) bind(self.on_auto_accept_src_keybind, auto_accept_src_kd_id) bind(self.on_reject_src_keybind, reject_src_kb_id) bind(self.on_reset_cmap_keybind, reset_cmap_kb_id) bind(self.on_reset_source_location_keybind, reset_src_kb_id) bind(self.on_toggle_autoplay, autoplay_kb_id) bind(self.on_toggle_reticule, toggle_reticule_kb_id) bind(self.on_toggle_align, toggle_align_kb_id) self.toggle_align_key = config.read("KEYBINDS.TOGGLE_ALIGN") self.accept_key = config.read("KEYBINDS.ACCEPT_SRC") self.auto_accept_key = config.read("KEYBINDS.AUTO_ACCEPT_SRC") self.reject_key = config.read("KEYBINDS.REJECT_SRC") self.reset_cmap_key = config.read("KEYBINDS.RESET_CMAP") self.reset_source_key = config.read("KEYBINDS.RESET_SOURCE_LOCATION") self.autoplay_key = config.read("KEYBINDS.AUTOPLAY") self.toggle_reticule_key = config.read("KEYBINDS.TOGGLE_RETICULE") self.load_comparison_key = config.read("KEYBINDS.LOAD_COMPARISON") self.load_diff_comparison_key = config.read( "KEYBINDS.LOAD_DIFF_COMPARISON") accelerators = [ (wx.ACCEL_NORMAL, wx.WXK_TAB, next_obs_kb_id), (wx.ACCEL_SHIFT, wx.WXK_TAB, prev_obs_kb_id), (wx.ACCEL_NORMAL, ord(self.accept_key), accept_src_kb_id), (wx.ACCEL_NORMAL, ord(self.auto_accept_key), auto_accept_src_kd_id), (wx.ACCEL_NORMAL, ord(self.reject_key), reject_src_kb_id), (wx.ACCEL_NORMAL, ord(self.reset_cmap_key), reset_cmap_kb_id), (wx.ACCEL_NORMAL, ord(self.reset_source_key), reset_src_kb_id), (wx.ACCEL_NORMAL, ord(self.load_comparison_key), load_comparison_kb_id), (wx.ACCEL_NORMAL, ord(self.load_diff_comparison_key), load_diff_comparison_kb_id), (wx.ACCEL_NORMAL, ord(self.autoplay_key), autoplay_kb_id), (wx.ACCEL_NORMAL, ord(self.toggle_reticule_key), toggle_reticule_kb_id), (wx.ACCEL_NORMAL, ord(self.toggle_align_key), toggle_align_kb_id), ] for line in config.read("MPC.NOTE1OPTIONS"): if not len(line) > 0: continue this_key = line.split()[0][0].lower() this_func = self._build_accept_func(this_key) this_key_id = wx.NewId() bind(this_func, this_key_id) accelerators.append((wx.ACCEL_CTRL, ord(this_key), this_key_id)) accelerators = wx.AcceleratorTable(accelerators) view.SetAcceleratorTable(accelerators)