def command(self, cmd): """ Run gphoto2 command """ # Test to see if there is a running command already if self._proc and self._proc.poll(): raise error.InvalidCommand("Command already running") else: # Build the command. run_cmd = [self._gphoto2, '--port', self.port] run_cmd.extend(listify(cmd)) self.logger.debug("gphoto2 command: {}".format(run_cmd)) try: self._proc = subprocess.Popen(run_cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True, shell=False) except OSError as e: raise error.InvalidCommand( "Can't send command to gphoto2. {} \t {}".format( e, run_cmd)) except ValueError as e: raise error.InvalidCommand( "Bad parameters to gphoto2. {} \t {}".format(e, run_cmd)) except Exception as e: raise error.PanError(e)
def _make_pretty_from_cr2(fname, timeout=15, **kwargs): verbose = kwargs.get('verbose', False) title = '{} {}'.format(kwargs.get('title', ''), current_time().isot) solve_field = "{}/scripts/cr2_to_jpg.sh".format(os.getenv('POCS')) cmd = [solve_field, fname, title] if kwargs.get('primary', False): cmd.append('link') if verbose: print(cmd) try: proc = subprocess.Popen(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) if verbose: print(proc) except OSError as e: raise error.InvalidCommand("Can't send command to gphoto2." " {} \t {}".format(e, cmd)) except ValueError as e: raise error.InvalidCommand("Bad parameters to gphoto2." " {} \t {}".format(e, cmd)) except Exception as e: raise error.PanError("Timeout on plate solving: {}".format(e)) return fname.replace('cr2', 'jpg')
def make_pretty_image(fname, timeout=15, **kwargs): # pragma: no cover """ Make a pretty image This calls out to an external script which will try to extract the JPG directly from the CR2 file, otherwise will do an actual conversion Notes: See `$POCS/scripts/cr2_to_jpg.sh` Arguments: fname {str} -- Name of CR2 file **kwargs {dict} -- Additional arguments to be passed to external script Keyword Arguments: timeout {number} -- Process timeout (default: {15}) Returns: str -- Filename of image that was created """ assert os.path.exists(fname),\ warn("File doesn't exist, can't make pretty: {}".format(fname)) verbose = kwargs.get('verbose', False) title = '{} {}'.format(kwargs.get('title', ''), current_time().isot) solve_field = "{}/scripts/cr2_to_jpg.sh".format(os.getenv('POCS')) cmd = [solve_field, fname, title] if kwargs.get('primary', False): cmd.append('link') if verbose: print(cmd) try: proc = subprocess.Popen(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) if verbose: print(proc) except OSError as e: raise error.InvalidCommand("Can't send command to gphoto2." " {} \t {}".format(e, cmd)) except ValueError as e: raise error.InvalidCommand("Bad parameters to gphoto2." " {} \t {}".format(e, cmd)) except Exception as e: raise error.PanError("Timeout on plate solving: {}".format(e)) return fname.replace('cr2', 'jpg')
def solve_field(fname, timeout=15, solve_opts=[], **kwargs): """ Plate solves an image. Args: fname(str, required): Filename to solve in either .cr2 or .fits extension. timeout(int, optional): Timeout for the solve-field command, defaults to 60 seconds. solve_opts(list, optional): List of options for solve-field. verbose(bool, optional): Show output, defaults to False. """ verbose = kwargs.get('verbose', False) if verbose: print("Entering solve_field") if fname.endswith('cr2'): if verbose: print("Converting cr2 to FITS") fname = cr2_to_fits(fname, **kwargs) if verbose: print("Solved filename: ", fname) solve_field_script = "{}/scripts/solve_field.sh".format(os.getenv('POCS'), '/var/panoptes/POCS') if not os.path.exists(solve_field_script): raise error.InvalidSystemCommand("Can't find solve-field: {}".format(solve_field_script)) # Add the options for solving the field if solve_opts: options = solve_opts else: options = [ '--guess-scale', '--cpulimit', str(timeout), '--no-verify', '--no-plots', '--crpix-center', '--downsample', '4', ] if kwargs.get('clobber', True): options.append('--overwrite') if kwargs.get('skip_solved', True): options.append('--skip-solved') if 'ra' in kwargs: options.append('--ra') options.append(str(kwargs.get('ra'))) if 'dec' in kwargs: options.append('--dec') options.append(str(kwargs.get('dec'))) if 'radius' in kwargs: options.append('--radius') options.append(str(kwargs.get('radius'))) if os.getenv('PANTEMP'): options.append('--temp-dir') options.append(os.getenv('PANTEMP')) cmd = [solve_field_script, ' '.join(options), fname] if verbose: print("Cmd: ", cmd) try: proc = subprocess.Popen(cmd, universal_newlines=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) except OSError as e: raise error.InvalidCommand("Can't send command to solve_field.sh. {} \t {}".format(e, cmd)) except ValueError as e: raise error.InvalidCommand("Bad parameters to solve_field.sh. {} \t {}".format(e, cmd)) except Exception as e: raise error.PanError("Timeout on plate solving: {}".format(e)) return proc
def get_wcsinfo(fits_fname, verbose=False): """Returns the WCS information for a FITS file. Uses the `wcsinfo` astrometry.net utility script to get the WCS information from a plate-solved file Parameters ---------- fits_fname : {str} Name of a FITS file that contains a WCS. verbose : {bool}, optional Verbose (the default is False) Returns ------- dict Output as returned from `wcsinfo` """ assert os.path.exists(fits_fname), warn( "No file exists at: {}".format(fits_fname)) wcsinfo = shutil.which('wcsinfo') if wcsinfo is None: raise error.InvalidCommand('wcsinfo not found') run_cmd = [wcsinfo, fits_fname] if verbose: print("wcsinfo command: {}".format(run_cmd)) proc = subprocess.Popen(run_cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True) try: output, errs = proc.communicate(timeout=5) except subprocess.TimeoutExpired: # pragma : no cover proc.kill() output, errs = proc.communicate() unit_lookup = { 'crpix0': u.pixel, 'crpix1': u.pixel, 'crval0': u.degree, 'crval1': u.degree, 'cd11': (u.deg / u.pixel), 'cd12': (u.deg / u.pixel), 'cd21': (u.deg / u.pixel), 'cd22': (u.deg / u.pixel), 'imagew': u.pixel, 'imageh': u.pixel, 'pixscale': (u.arcsec / u.pixel), 'orientation': u.degree, 'ra_center': u.degree, 'dec_center': u.degree, 'orientation_center': u.degree, 'ra_center_h': u.hourangle, 'ra_center_m': u.minute, 'ra_center_s': u.second, 'dec_center_d': u.degree, 'dec_center_m': u.minute, 'dec_center_s': u.second, 'fieldarea': (u.degree * u.degree), 'fieldw': u.degree, 'fieldh': u.degree, 'decmin': u.degree, 'decmax': u.degree, 'ramin': u.degree, 'ramax': u.degree, 'ra_min_merc': u.degree, 'ra_max_merc': u.degree, 'dec_min_merc': u.degree, 'dec_max_merc': u.degree, 'merc_diff': u.degree, } wcs_info = {} for line in output.split('\n'): try: k, v = line.split(' ') try: v = float(v) except Exception: pass wcs_info[k] = float(v) * unit_lookup.get(k, 1) except ValueError: pass # print("Error on line: {}".format(line)) wcs_info['wcs_file'] = fits_fname return wcs_info