columns_ = [ephem[t].data for t in columns] for i in range(len(ephem)): out.write(fmt.format(*[c[i] for c in columns_])) epochs_1 = {'start': begins[0], 'stop': ends[0], 'step': step} epochs_2 = {'start': begins[1], 'stop': ends[1], 'step': step} kwargs_1 = {'location': location, 'epochs': epochs_1} kwargs_2 = {'location': location, 'epochs': epochs_2} with open(sys.argv[1]) as in_data: for line in in_data.readlines(): id_name = line.split()[0] id_name_orig = id_name try: horizons = Horizons(id=id_name, **kwargs_1) ephem = horizons.ephemerides() except Exception as exception_1: id_name = id_name.replace("_", " ") try: horizons = Horizons(id=id_name, **kwargs_1) ephem = horizons.ephemerides() except Exception as exception_2: print(id_name_orig, "FAILED") print(exception_1) print(exception_2) continue print_output(ephem, columns, directories[0], id_name_orig) horizons = Horizons(id=id_name, **kwargs_2) ephem = horizons.ephemerides() print_output(ephem, columns, directories[1], id_name_orig)
def get_horizons_coord(body, time='now', id_type='majorbody', *, include_velocity=False): """ Queries JPL HORIZONS and returns a `~astropy.coordinates.SkyCoord` for the location of a solar-system body at a specified time. This location is the instantaneous or "true" location, and is not corrected for light travel time or observer motion. .. note:: This function requires the Astroquery package to be installed and requires an Internet connection. Parameters ---------- body : `str` The solar-system body for which to calculate positions. One can also use the search form linked below to find valid names or ID numbers. id_type : `str` If 'majorbody', search by name for planets, satellites, or other major bodies. If 'smallbody', search by name for asteroids or comets. If 'id', search by ID number. time : {parse_time_types} Time to use in a parse_time-compatible format Keyword Arguments ----------------- include_velocity : `bool` If True, include the body's velocity in the output coordinate. Defaults to False. Returns ------- `~astropy.coordinates.SkyCoord` Location of the solar-system body Notes ----- Be aware that there can be discrepancies between the coordinates returned by JPL HORIZONS, the coordinates reported in mission data files, and the coordinates returned by `~sunpy.coordinates.get_body_heliographic_stonyhurst`. References ---------- * `JPL HORIZONS <https://ssd.jpl.nasa.gov/?horizons>`_ * `JPL HORIZONS form to search bodies <https://ssd.jpl.nasa.gov/horizons.cgi?s_target=1#top>`_ * `Astroquery <https://astroquery.readthedocs.io/en/latest/>`_ Examples -------- >>> from sunpy.coordinates.ephemeris import get_horizons_coord Query the location of Venus >>> get_horizons_coord('Venus barycenter', '2001-02-03 04:05:06') # doctest: +REMOTE_DATA INFO: Obtained JPL HORIZONS location for Venus Barycenter (2) [sunpy.coordinates.ephemeris] <SkyCoord (HeliographicStonyhurst: obstime=2001-02-03T04:05:06.000): (lon, lat, radius) in (deg, deg, AU) (-33.93155836, -1.64998443, 0.71915147)> Query the location of the SDO spacecraft >>> get_horizons_coord('SDO', '2011-11-11 11:11:11') # doctest: +REMOTE_DATA INFO: Obtained JPL HORIZONS location for Solar Dynamics Observatory (spac [sunpy.coordinates.ephemeris] <SkyCoord (HeliographicStonyhurst: obstime=2011-11-11T11:11:11.000): (lon, lat, radius) in (deg, deg, AU) (0.01019118, 3.29640728, 0.99011042)> Query the location of the SOHO spacecraft via its ID number (-21) >>> get_horizons_coord(-21, '2004-05-06 11:22:33', 'id') # doctest: +REMOTE_DATA INFO: Obtained JPL HORIZONS location for SOHO (spacecraft) (-21) [sunpy.coordinates.ephemeris] <SkyCoord (HeliographicStonyhurst: obstime=2004-05-06T11:22:33.000): (lon, lat, radius) in (deg, deg, AU) (0.25234902, -3.55863633, 0.99923086)> Query the location and velocity of the asteroid Juno >>> get_horizons_coord('Juno', '1995-07-18 07:17', 'smallbody', include_velocity=True) # doctest: +REMOTE_DATA INFO: Obtained JPL HORIZONS location for 3 Juno [sunpy.coordinates.ephemeris] <SkyCoord (HeliographicStonyhurst: obstime=1995-07-18T07:17:00.000): (lon, lat, radius) in (deg, deg, AU) (-25.16107572, 14.59098456, 3.17667662) (d_lon, d_lat, d_radius) in (arcsec / s, arcsec / s, km / s) (-0.00514936, -0.00205857, 8.89781348)> """ obstime = parse_time(time) array_time = np.reshape(obstime, (-1,)) # Convert to an array, even if scalar # Import here so that astroquery is not a module-level dependency from astroquery.jplhorizons import Horizons query = Horizons(id=body, id_type=id_type, location='500@10', # Heliocentric (mean ecliptic) epochs=array_time.tdb.jd.tolist()) # Time must be provided in JD TDB try: result = query.vectors() except Exception as e: # Catch and re-raise all exceptions, and also provide query URL if generated if query.uri is not None: log.error(f"See the raw output from the JPL HORIZONS query at {query.uri}") raise e finally: query._session.close() log.info(f"Obtained JPL HORIZONS location for {result[0]['targetname']}") log.debug(f"See the raw output from the JPL HORIZONS query at {query.uri}") # JPL HORIZONS results are sorted by observation time, so this sorting needs to be undone. # Calling argsort() on an array returns the sequence of indices of the unsorted list to put the # list in order. Calling argsort() again on the output of argsort() reverses the mapping: # the output is the sequence of indices of the sorted list to put that list back in the # original unsorted order. unsorted_indices = obstime.argsort().argsort() result = result[unsorted_indices] vector = CartesianRepresentation(result['x'], result['y'], result['z']) if include_velocity: velocity = CartesianDifferential(result['vx'], result['vy'], result['vz']) vector = vector.with_differentials(velocity) coord = SkyCoord(vector, frame=HeliocentricEclipticIAU76, obstime=obstime) return coord.transform_to(HeliographicStonyhurst).reshape(obstime.shape)
def from_horizons( cls, name, attractor, epoch=None, plane=Planes.EARTH_EQUATOR, id_type="smallbody", ): """Return osculating `Orbit` of a body using JPLHorizons module of Astroquery. Parameters ---------- name : string Name of the body to query for. epoch : ~astropy.time.Time, optional Epoch, default to None. plane : ~poliastro.frames.Planes Fundamental plane of the frame. id_type : string, optional Use "smallbody" for Asteroids and Comets, and "majorbody" for Planets and Satellites. """ if not epoch: epoch = time.Time.now() if plane == Planes.EARTH_EQUATOR: refplane = "earth" elif plane == Planes.EARTH_ECLIPTIC: refplane = "ecliptic" bodies_dict = { "sun": 10, "mercury": 199, "venus": 299, "earth": 399, "mars": 499, "jupiter": 599, "saturn": 699, "uranus": 799, "neptune": 899, } location = "500@{}".format(bodies_dict[attractor.name.lower()]) obj = Horizons(id=name, location=location, epochs=epoch.jd, id_type=id_type).elements(refplane=refplane) a = obj["a"][0] * u.au ecc = obj["e"][0] * u.one inc = obj["incl"][0] * u.deg raan = obj["Omega"][0] * u.deg argp = obj["w"][0] * u.deg nu = obj["nu"][0] * u.deg ss = cls.from_classical(attractor, a, ecc, inc, raan, argp, nu, epoch=epoch.tdb, plane=plane) return ss
m.cos(i_r) * m.sin(asc_node_r) * m.sin(a_of_p_r), -m.cos(asc_node_r) * m.sin(a_of_p_r) - m.cos(i_r) * m.cos(a_of_p_r) * m.sin(asc_node_r), m.sin(asc_node_r) * m.sin(i_r) ], [ m.cos(a_of_p_r) * m.sin(asc_node_r) + m.cos(asc_node_r) * m.cos(i_r) * m.sin(a_of_p_r), m.cos(asc_node_r) * m.cos(i_r) * m.cos(a_of_p_r) - m.sin(asc_node_r) * m.sin(a_of_p_r), -m.cos(asc_node_r) * m.sin(i_r) ], [m.sin(i_r) * m.sin(a_of_p_r), m.cos(a_of_p_r) * m.sin(i_r), m.cos(i_r)]]) conversion_3 = np.dot(perifocal_to_reference, r_perifocal_v) print("Conversion 3:", conversion_3) '''Benchmark: JPL Horizons nominal position and range at epoch''' apophis = Horizons(id='Apophis', location='@0', epochs={ 'start': '2006-09-01', 'stop': '2006-09-02', 'step': '1d' }) x = apophis.vectors()['x'][0] * au.value y = apophis.vectors()['y'][0] * au.value z = apophis.vectors()['z'][0] * au.value print("JPL Horizons calculated position: ", x, y, z)
'Date: ' + Time(self.time, format='jd', out_subfmt='date').iso) return plots + lines + [self.timestamp] plt.style.use('dark_background') fig = plt.figure(figsize=[6, 6]) ax = plt.axes([0., 0., 1., 1.], xlim=(-1.8, 1.8), ylim=(-1.8, 1.8)) ax.set_aspect('equal') ax.axis('off') ss = SolarSystem(Object("Sun", 28, 'red', [0, 0, 0], [0, 0, 0])) ss.time = Time(sim_start_date).jd colors = ['gray', 'orange', 'blue', 'yellow', 'chocolate'] sizes = [0.38, 0.95, 1., 0.27, 0.53] names = ['Mercury', 'Venus', 'Earth-Moon', 'Earth-Moon', 'Mars'] for i, nasaid in enumerate([1, 2, 399, 301, 4]): obj = Horizons(id=nasaid, location="@sun", epochs=ss.time, id_type='id').vectors() ss.add_planet( Object(nasaid, 20 * sizes[i], colors[i], [np.double(obj[xi]) for xi in ['x', 'y', 'z']], [np.double(obj[vxi]) for vxi in ['vx', 'vy', 'vz']])) ax.text(0, -([.47, .73, 1, 1.02, 1.5][i] + 0.1), names[2] if i in [2, 3] else names[i], color=colors[i], zorder=1000, ha='center', fontsize='large') def animate(i): return ss.evolve()
def locate(name): Davis = {'lon': -121.7405, 'lat': 38.5449, 'elevation': 0.0158} eph = Horizons(id=name, location=Davis).ephemerides() azi, elev = eph['AZ'][0], eph['EL'][0] return azi, elev
def from_horizons(cls, targetids, id_type='smallbody', epochs=None, center='500@10', **kwargs): """Load target orbital elements from `JPL Horizons <https://ssd.jpl.nasa.gov/horizons.cgi>`_ using `astroquery.jplhorizons.HorizonsClass.elements` Parameters ---------- targetids : str or iterable of str Target identifier, i.e., a number, name, designation, or JPL Horizons record number, for one or more targets. id_type : str, optional The nature of ``targetids`` provided; possible values are ``'smallbody'`` (asteroid or comet), ``'majorbody'`` (planet or satellite), ``'designation'`` (asteroid or comet designation), ``'name'`` (asteroid or comet name), ``'asteroid_name'``, ``'comet_name'``, ``'id'`` (Horizons id). Default: ``'smallbody'`` epochs : `~astropy.time.Time` object or iterable thereof, or dict, optional Epochs of elements to be queried; a list, tuple or `~numpy.ndarray` of `~astropy.time.Time` objects or Julian Dates as floats should be used for a number of discrete epochs; a dictionary including keywords ``start``, ``step``, and ``stop`` can be used to generate a range of epochs (see `~astroquery.jplhorizons.HorizonsClass.Horizons.elements` for details); if ``None`` is provided, current date and time are used. Default: ``None`` center : str, optional, default ``'500@10'`` (center of the Sun) Elements will be provided relative to this position. **kwargs : optional Arguments that will be provided to `astroquery.jplhorizons.HorizonsClass.elements`. Notes ----- * For detailed explanations of the queried fields, refer to `astroquery.jplhorizons.HorizonsClass.elements` and the `JPL Horizons documentation <https://ssd.jpl.nasa.gov/?horizons_doc>`_. * By default, elements are provided in the J2000.0 reference system and relative to the ecliptic and mean equinox of the reference epoch. Different settings can be chosen using additional keyword arguments as used by `astroquery.jplhorizons.HorizonsClass.elements`. Returns ------- `~Orbit` object Examples -------- >>> from sbpy.data import Orbit >>> from astropy.time import Time >>> epoch = Time('2018-05-14', scale='utc') >>> eph = Orbit.from_horizons('Ceres', epochs=epoch) ... # doctest: +REMOTE_DATA """ # modify epoch input to make it work with astroquery.jplhorizons # maybe this stuff should really go into that module.... if epochs is None: epochs = [Time.now().jd] elif isinstance(epochs, Time): epochs = [Time(epochs).jd] elif isinstance(epochs, dict): for key, val in epochs.items(): if isinstance(val, Time): val.format = 'iso' val.out_subfmt = 'date_hm' epochs[key] = "'" + val.value + "'" else: epochs[key] = "'" + epochs[key] + "'" elif isinstance(epochs, (list, tuple, ndarray)): new_epochs = [None] * len(epochs) for i in range(len(epochs)): if isinstance(epochs[i], Time): new_epochs[i] = epochs[i].jd else: new_epochs[i] = epochs[i] epochs = new_epochs # if targetids is a list, run separate Horizons queries and append if not isinstance(targetids, (list, ndarray, tuple)): targetids = [targetids] # append elements table for each targetid all_elem = None for targetid in targetids: # load elements using astroquery.jplhorizons obj = Horizons(id=targetid, id_type=id_type, location=center, epochs=epochs) elem = obj.elements(**kwargs) # workaround for current version of astroquery to make # column units compatible with astropy.table.QTable # should really change '---' units to None in # astroquery.jplhorizons.__init__.py for column_name in elem.columns: if elem[column_name].unit == '---': elem[column_name].unit = None if all_elem is None: all_elem = elem else: all_elem = vstack([all_elem, elem]) # identify time scales returned by Horizons query timescales = ['TDB'] * len(all_elem) all_elem['timescale'] = timescales if bib.status() is None or bib.status(): bib.register('sbpy.data.Orbit.from_horizons', {'data service': '1996DPS....28.2504G'}) return cls.from_table(all_elem)
def __init__( self, object_id: str, start_time: datetime, end_time: datetime, stepsize: Quantity, ): SALT_OBSERVATORY_ID = "B31" # enforce timezones if start_time.tzinfo is None or end_time.tzinfo is None: raise ValueError("The start and end time must be timezone-aware.") # avoid overly excessive queries self.stepsize = stepsize if self.stepsize < 5 * u.minute: raise ValueError( "The sampling interval must be at least 5 minutes.") # query Horizons self.object_id = object_id start = start_time.astimezone(tzutc()).strftime("%Y-%m-%d %H:%M:%S") # Make sure the whole time interval is covered by the queried ephemerides end_time_with_margin = end_time + timedelta( seconds=stepsize.to_value(u.second)) stop = end_time_with_margin.astimezone( tzutc()).strftime("%Y-%m-%d %H:%M:%S") # Horizons requires an int for the step size. As round() might call NumPy's # round method and thus produce a float, we have to round "manually" using # the int function. step = f"{int(0.5 + stepsize.to_value(u.minute))}m" obj = Horizons( id=self.object_id, location=SALT_OBSERVATORY_ID, epochs={ "start": start, "stop": stop, "step": step }, ) ephemerides = obj.ephemerides() # store the ephemerides in the format we need self._ephemerides = [] for row in range(len(ephemerides)): epoch = parse( ephemerides["datetime_str"][row]).replace(tzinfo=tzutc()) ra = float(ephemerides["RA"][row]) * u.deg dec = float(ephemerides["DEC"][row]) * u.deg ra_rate = float(ephemerides["RA_rate"][row]) * u.arcsec / u.hour dec_rate = ephemerides["DEC_rate"][row] * u.arcsec / u.hour magnitude = ephemerides["V"][row] if "V" in ephemerides.keys( ) else 0 magnitude_range = MagnitudeRange(min_magnitude=magnitude, max_magnitude=magnitude, bandpass="******") self._ephemerides.append( Ephemeris( ra=ra, dec=dec, ra_rate=ra_rate, dec_rate=dec_rate, magnitude_range=magnitude_range, epoch=epoch, ))
def get_horizons_ephemerides(name, pov, epoch_start, epoch_stop, step_size, type_elements): # step: step size, [10m, 1d, 1y] if pov.lower() == 'sun': loc = '500@10' # position relative to the sun elif pov.lower() == 'goldstone': loc = '257' # from goldstone elif pov.lower() == 'maunakea': loc = '568' # maunakea else: print('Not Valid Location Point Of View') # Process to get homogeneity from main script full name '2012QD8' to a valid name for Horizon call '2012 QD8' if len( re.findall('([0-9])', name) ) <= 4: # 4 is the min numbers in every name, the date year of discovery r = re.compile("([0-9]+)([a-zA-Z]+)").match(name) k1 = r.group(1) # the date of the name k2 = r.group(2) # the code of the date valid_name = k1 + " " + k2 else: r = re.compile("([0-9]+)([a-zA-Z]+)([0-9]+)").match(name) k1 = r.group(1) # the date of the name k2 = r.group(2) # the code of the date k3 = r.group(3) # id after the letters valid_name = k1 + " " + k2 + k3 obj = Horizons(id=valid_name, location=loc, epochs={ 'start': epoch_start, 'stop': epoch_stop, 'step': step_size }) if type_elements.lower() == 'vectors': data = obj.vectors() # vectorial elements len_rows = len(data) len_cols = 6 # 3 positions 'x','y','z', and 3 velocities 'vx', 'vy', 'vz' idx_x = 5 # 'x' is at position 5 in the table (starting from 0) adata = np.zeros([len_rows, len_cols]) for row in range(len_rows): for col in range(6): idx_col_in_table = idx_x + col # because the 'x' start at 6th col, going up till the 12th that is 'vz' adata[row, col] = data[row][idx_col_in_table] elif type_elements.lower() == 'elements': # refsystem = 'J2000', # Element reference system for geometric and astrometric quantities # refplane = 'ecliptic' #ecliptic and mean equinox of reference epoch data = obj.elements(refsystem='J2000', refplane='ecliptic') len_rows = len(data) len_cols = 6 # (a e i OM om theta) adata = np.zeros([len_rows, len_cols]) for row in range(len_rows): adata[row, 0] = data[row][14] # 15th column of data -> semimajor axis adata[row, 1] = data[row][5] # 6th column of data -> eccentricity adata[row, 2] = data[row][7] # 8th column of data -> inclination adata[row, 3] = data[row][8] # 9th column of data -> RAAN, (OMEGA) adata[row, 4] = data[row][ 9] # 10th column of data -> argument of perigee, (omega) adata[row, 5] = data[row][ 13] # 14th column of data -> True anomaly, (theta) return adata
import astropy.units as u from astroquery.jplhorizons import Horizons obj = Horizons(id='301', id_type='majorbody', location=None, epochs={ 'start': '2021-3-20 9:36', 'stop': '2021-3-20 9:38', 'step': '1m' }) data = obj.ephemerides(quantities='1,2,4,20,31') print(type(obj), type(data)) data2 = data['RA', 'DEC', 'RA_app', 'DEC_app', 'delta'] print(data2['RA'].quantity, data2['RA'].tolist(), data2['RA'].quantity.value)
ts = load.timescale() #load almanac e = load('de421.bsp') earth = e['earth'] sun = e['sun'] moon = e['moon'] #print(e) #setup ground station gs = sf.Topos(latitude_degrees=cfg['gs']['latitude'], longitude_degrees=cfg['gs']['longitude'], elevation_m=cfg['gs']['altitude']) print(cfg['gs']['name'], gs) #create query object obj = Horizons(id=cfg['body']['name'], location=cfg['body']['origin_center'], id_type=cfg['body']['id_type'], epochs=cfg['body']['epoch']) if cfg['body']['type'] == "vectors": vec = obj.vectors() #print(vec) print(vec.columns) keys = ['datetime_jd', 'x', 'y', 'z', 'vx', 'vy', 'vz'] pos_keys = ['x', 'y', 'z'] vel_keys = ['vx', 'vy', 'vz'] t_key = 'datetime_jd' #print(np.array(vec[pos_keys])[0]) #print(np.array(vec[t_key])[0]) t = ts.tdb(jd=np.array(vec[t_key])[0]) #print(vec['datetime_str'][0], t.tt, t.tdb) for i, t in enumerate(vec[t_key]):
JD_mean.append(epoch_jd) exp = header['EXPTIME'] try: header['GAIN'] except KeyError: print('There is no GAIN in header. Using gain 0.16 & RN = 4.3') gain = 0.16 RN = 4.3 else: gain = header['GAIN'] RN = header['RDNOISE'] # ************************************************************************************* # # * Bring the observer quantities from JPL Horizons * # # ************************************************************************************* # obj = Horizons(id=OBJECT, location=Observatory, epochs=epoch_jd) eph = obj.ephemerides() psANG = eph['sunTargetPA'][0] # [deg] pA = eph['alpha'][0] # [deg] PSANG.append(psANG) PA.append(pA) # ************************************************************************************* # # * BRING THE CENTER COORDINATE OF 2005 UD * # # ************************************************************************************* # # Here, we use Phot package in IRAF to find the center of the target # If you find the center of the target by other methods, please change this part. # Bring the center mag1 = ascii.read(image_i+'.mag.1') xo, yo = (mag1['XCENTER'][0]-1, mag1['YCENTER'][0]-1) # pixel coordinate (x,y) of target's center in ordinary component
def CheckObsType(filenames,telescope,obsparam,Method = 'Normal'): print(Method) # List of usual solar analog ID for astroquery List_ID_SA = ['HD 11532', 'HD 28099', 'HD 292561', 'BD+00 2717','BD-00 2719','HD 139287', 'BD+00 3383', 'TYC 447-508-1','BD-00 4074', 'BD-00 4251B','BD-00 4557'] # List of usual solar analog ID for astroquery with linked to usual used designation List_ID_SA_Comp = {'HD 11532': 'SA93-101', 'HD 28099': 'Hya-64', 'HD 292561': 'SA98-978', 'BD+00 2717': 'SA102-1081', 'BD-00 2719': 'SA105-56', 'HD 139287': 'SA107-684', 'BD+00 3383': 'SA107-998', 'TYC 447-508-1': 'SA110-361', 'BD-00 4074': 'SA112-1333','BD-00 4251B': 'SA113-276' , 'BD-00 4557': 'SA115-271'} # telescope, obsparam = CheckInstrument(filenames) CollFoc = []; # Loop over all files to prepare for idx, filename in enumerate(filenames): # If Gemini telescope use special function to open and stick together all the extentions try: if telescope == 'GMOSS' or telescope == 'GMOSN': hdulist = GMOS_open2([filename]) else: hdulist = fits.open(filename ,ignore_missing_end=True) except IOError: logging.error('cannot open file %s' % filename) print('ERROR: cannot open file %s' % filename) filenames.pop(idx) continue # Check if the focus header exist (collimator focus), if not put a fake value. # This is need to check for focus run expecialy for Deveny, The header was not present in early images. try: hdulist[0].header[obsparam['focus']] except KeyError: hdulist[0].header[obsparam['focus']] = (12, 'SP: dummy focus value') # put dummy value is 'focus' header not found # Update header print('Update header') hdulist[0].header['SP_PREPA'] = (str(True),'SP: Has this file been prepared?') hdulist[0].header['SP_PREPR'] = (str(False),'SP: Has this file been prepared?') hdulist[0].header['SP_COSMI'] = (str(False),'SP: Has this file been prepared?') hdulist[0].header['PROCTYPE'] = ('Prepared', 'SP: Type of processed file') # Still a special treatment for NOT, SHOULD BE FIXED if telescope == 'NOT': data = hdulist[1].data hdulist[0].data = data[800:-100,:].transpose() hdulist[1].data = [] else: data = hdulist[0].data # Check if the images need to be cropped and transposed data = hdulist[0].data if obsparam['crop']: if obsparam['Y_crop'] and obsparam['X_crop']: # images need to be cropped in both X and Y axes data = data[obsparam['Y_crop'][0]:obsparam['Y_crop'][1], obsparam['X_crop'][0]:obsparam['X_crop'][1]] # Update header hdulist[0].header['HISTORY'] = 'The image has been cropped in both X and Y coordinates from :' hdulist[0].header['HISTORY'] = 'X axis: ' + str(obsparam['X_crop'][0]) + ' to ' + str(obsparam['X_crop'][1]) hdulist[0].header['HISTORY'] = 'Y axis: ' + str(obsparam['Y_crop'][0]) + ' to ' + str(obsparam['Y_crop'][1]) if obsparam['Y_crop'] and not obsparam['X_crop']: # images need to be cropped in Y axes only data = data[obsparam['Y_crop'][0]:obsparam['Y_crop'][1], :] # Update header hdulist[0].header['HISTORY'] = 'The image has been cropped in coordinates from :' hdulist[0].header['HISTORY'] = 'Y axis: ' + str(obsparam['Y_crop'][0]) + ' to ' + str(obsparam['Y_crop'][1]) if obsparam['X_crop'] and not obsparam['Y_crop']: # images need to be cropped in X axes only data = data[:, obsparam['X_crop'][0]:obsparam['X_crop'][1]] if obsparam['transpose']: data = data.transpose() hdulist[0].header['HISTORY'] = 'Image has been rotated' hdulist[0].data = data # update the data in the fits file # Get statistic information about the data Med = np.nanmedian(data[10:-10,10:-10]) Max = np.nanmax(data[10:-10,10:-10]) std0 = np.nanstd(np.nanmedian(data[10:-10,10:-10],axis=0)) std1 = np.nanstd(np.nanmedian(data[10:-10,10:-10],axis=1)) std = np.nanstd(data[10:-10,10:-10]) Mean = np.nanmean(data[10:-10,10:-10]) Median = np.nanmedian(data[10:-10,10:-10]) # print(Mean) # print(std1) # Update the header with statistical information about the data hdulist[0].header['Mean'] = (Mean,'Mean of the images (SP)') hdulist[0].header['Median'] = (Median,'Median of the images (SP)') hdulist[0].header['Std'] = (std0,'Standard deviation of the image (SP)') hdulist[0].header['StdX'] = (std1,'Standard deviation of the image along the x axis (SP)') hdulist[0].header['StdY'] = (std,'Standard deviation of the image along the y axis (SP)') if telescope =='NOT': index = filename.split('.')[0] print(index) if 'Open' in hdulist[0].header[obsparam['grating']]: # Acquisition files TIME = hdulist[0].header[obsparam['date_keyword']].replace('-','').replace(':','').replace('.','') EXPTIME = str(hdulist[0].header[obsparam['exptime']]).replace('.','s') Name= telescope + '_' + index + '_' + TIME + '_ACQ_' + EXPTIME + '.fits' hdulist.writeto(Name) hdulist.close() # shutil.copy(filename,Name) _SP_conf.filenames.append(Name) logging.info('%s changed to %s' % (filename, Name)) print('%s changed to %s' % (filename, Name)) else: if std0 > 10000: hdulist[0].header[obsparam['obstype']] = 'FLAT' TIME = hdulist[0].header[obsparam['date_keyword']].replace('-','').replace(':','').replace('.','') EXPTIME = str(hdulist[0].header[obsparam['exptime']]).replace('.','s') Name= telescope + '_' + index + '_' + TIME + '_FLAT_' + EXPTIME + '.fits' hdulist.writeto(Name) hdulist.close() # shutil.copy(filename,Name) _SP_conf.filenames.append(Name) logging.info('%s changed to %s' % (filename, Name)) print('%s changed to %s' % (filename, Name)) else: # Biases if std0 + std1 < 20 and int(hdulist[0].header[obsparam['exptime']]) == 0: hdulist[0].header[obsparam['obstype']] = 'BIAS' TIME = hdulist[0].header[obsparam['date_keyword']].replace('-','').replace(':','').replace('.','') EXPTIME = str(hdulist[0].header[obsparam['exptime']]).replace('.','s') Name= telescope + '_' + filename.split('.')[1] + '_' + TIME + '_BIAS_' + EXPTIME + '.fits' hdulist.writeto(Name) hdulist.close() # shutil.copy(filename,Name) _SP_conf.filenames.append(Name) logging.info('%s changed to %s' % (filename, Name)) print('%s changed to %s' % (filename, Name)) else: hdulist[0].header[obsparam['obstype']] = 'OBJECT' TIME = hdulist[0].header[obsparam['date_keyword']].replace('-','').replace(':','').replace('.','') EXPTIME = str(hdulist[0].header[obsparam['exptime']]).replace('.','s') OBJECT = hdulist[0].header[obsparam['object']].replace(' ','').replace('/','') TYPE = 'Unknown' if OBJECT.replace(' ',''): try: Horizons(id=OBJECT).ephemerides() TYPE = 'Asteroid' except ValueError: try: #result_table = Simbad.query_object(OBJECT) result_table = Simbad.query_region(coord.SkyCoord(str(hdulist[0].header[obsparam['ra']]) + ' ' + str(hdulist[0].header[obsparam['dec']]) ,unit=(u.deg,u.deg), frame='icrs'), radius='0d1m00s') T = result_table['MAIN_ID'][0] print(T) if result_table['MAIN_ID'][0] in List_ID_SA: OBJECT = List_ID_SA_Comp[result_table['MAIN_ID'][0]] TYPE = 'SA' print(TYPE) except: pass if TYPE == 'Unknown': # except TypeError: if '(' in OBJECT and ')' in OBJECT: Number = OBJECT[OBJECT.find("(")+1:OBJECT.find(")")] if Number.isdigit(): try: Horizons(id=Number).ephemerides() TYPE = 'Asteroid' except ValueError: TYPE = 'Unknown' if OBJECT[0:3].isdigit(): if not ' ' in OBJECT: Name = OBJECT[0:4] + ' ' + OBJECT[4:] try: Horizons(id=Name).ephemerides() TYPE = 'Asteroid' except ValueError: TYPE = 'Unknown' Name= telescope + '_' + index + '_' + TIME + '_' + TYPE + '_' + OBJECT + '_' + EXPTIME + '.fits' hdulist.writeto(Name,overwrite=True) # shutil.copy(filename,Name) _SP_conf.filenames.append(Name) logging.info('%s changed to %s' % (filename, Name)) print('%s changed to %s' % (filename, Name)) hdulist.close() # print(hdulist[0].header[obsparam['grating']]) if telescope == 'SOAR': index = filename.split('_')[0] if hdulist[0].header[obsparam['grating']] == '<NO GRATING>': # Acquisition files # print('Acquisition files') TIME = hdulist[0].header[obsparam['date_keyword']].replace('-','').replace(':','').replace('.','') EXPTIME = str(hdulist[0].header[obsparam['exptime']]).replace('.','s') Name= telescope + '_' + index + '_' + TIME + '_ACQ_' + EXPTIME + '.fits' hdulist.close() # shutil.copy(filename,Name) _SP_conf.filenames.append(Name) logging.info('%s changed to %s' % (filename, Name)) print('%s changed to %s' % (filename, Name)) else: if Med > Max/6 and std0 > 1000: hdulist[0].header[obsparam['obstype']] = 'FLAT' TIME = hdulist[0].header[obsparam['date_keyword']].replace('-','').replace(':','').replace('.','') EXPTIME = str(hdulist[0].header[obsparam['exptime']]).replace('.','s') Name= telescope + '_' + index + '_' + TIME + '_FLAT_' + EXPTIME + '.fits' hdulist.close() # shutil.copy(filename,Name) _SP_conf.filenames.append(Name) logging.info('%s changed to %s' % (filename, Name)) print('%s changed to %s' % (filename, Name)) else: # Biases if std0 + std1 < 10 and int(hdulist[0].header[obsparam['exptime']]) == 0: hdulist[0].header[obsparam['obstype']] = 'BIAS' TIME = hdulist[0].header[obsparam['date_keyword']].replace('-','').replace(':','').replace('.','') EXPTIME = str(hdulist[0].header[obsparam['exptime']]).replace('.','s') Name= telescope + '_' + filename.split('.')[1] + '_' + TIME + '_BIAS_' + EXPTIME + '.fits' hdulist.close() # shutil.copy(filename,Name) _SP_conf.filenames.append(Name) logging.info('%s changed to %s' % (filename, Name)) print('%s changed to %s' % (filename, Name)) else: hdulist[0].header[obsparam['obstype']] = 'OBJECT' TIME = hdulist[0].header[obsparam['date_keyword']].replace('-','').replace(':','').replace('.','') EXPTIME = str(hdulist[0].header[obsparam['exptime']]).replace('.','s') OBJECT = hdulist[0].header[obsparam['object']].replace(' ','').replace('/','') TYPE = 'Unknown' if OBJECT.replace(' ',''): try: Horizons(id=OBJECT).ephemerides() TYPE = 'Asteroid' except ValueError: try: #result_table = Simbad.query_object(OBJECT) result_table = Simbad.query_region(coord.SkyCoord(hdulist[0].header[obsparam['ra']] + ' ' + hdulist[0].header[obsparam['dec']] ,unit=(u.hourangle,u.deg), frame='icrs'), radius='0d1m00s') T = result_table['MAIN_ID'][0] if result_table['MAIN_ID'][0] in List_ID_SA: OBJECT = List_ID_SA_Comp[result_table['MAIN_ID'][0]] TYPE = 'SA' except: pass if TYPE == 'Unknown': # except TypeError: if '(' in OBJECT and ')' in OBJECT: Number = OBJECT[OBJECT.find("(")+1:OBJECT.find(")")] if Number.isdigit(): try: Horizons(id=Number).ephemerides() TYPE = 'Asteroid' except ValueError: TYPE = 'Unknown' if OBJECT[0:3].isdigit(): if not ' ' in OBJECT: Name = OBJECT[0:4] + ' ' + OBJECT[4:] try: Horizons(id=Name).ephemerides() TYPE = 'Asteroid' except ValueError: TYPE = 'Unknown' if std0/std1 > 50: hdulist[0].header[obsparam['obstype']] = 'ARCS/FOCUS' TYPE = 'ARCS' OBJECT = filename.split('_')[1] Name= telescope + '_' + index + '_' + TIME + '_' + TYPE + '_' + OBJECT + '_' + EXPTIME + '.fits' # shutil.copy(filename,Name) hdulist[0].writeto(Name,overwrite=True) _SP_conf.filenames.append(Name) logging.info('%s changed to %s' % (filename, Name)) print('%s changed to %s' % (filename, Name)) hdulist.close() ###################################################################### # Prepare DEVENY DATA ###################################################################### if telescope == 'DEVENY': if Method == 'Gen': mean = np.nanmean(data) median = np.nanmedian(data) std0 = np.nanmean(np.std(data,axis=0)) std1 = np.nanmean(np.std(data,axis=1)) std = np.nanstd(data) clf = pickle.load( open( directory + "/Imag_Rec.p", "r" ) ) example_measures = np.array([mean, median, std, std0, std1]) example_measures = example_measures.reshape(1, -1) prediction = clf.predict(example_measures) print(prediction) if Method == 'Normal': if Med > Max/5 and std0 > 1000: prediction = 'Flat' else: if std0 + std1 < 10 and int(hdulist[0].header[obsparam['exptime']]) == 0: prediction = 'Bias' else: if std0/std1 > 100: prediction = 'Arcs' else: prediction = 'Spectrum' print(prediction) Arcs = False # Extract informations for header TIME = hdulist[0].header[obsparam['date_keyword']].replace('-','').replace(':','').replace('.','') EXPTIME = str(hdulist[0].header[obsparam['exptime']]).replace('.','s') # get the index of the file index = filename.split('.')[1] # Identify FLAT images if prediction == 'Flat': # Update header hdulist[0].header['HISTORY'] = 'SP: %s changed to FLAT' % (str(hdulist[0].header[obsparam['obstype']])) hdulist[0].header[obsparam['obstype']] = 'FLAT' Name= telescope + '_' + index + '_' + TIME + '_FLAT_' + EXPTIME + '.fits' hdulist[0].header['HISTORY'] = 'SP: %s changed to %s' % (filename, Name) if prediction == 'Bias': # Update header hdulist[0].header['HISTORY'] = 'SP: %s changed to BIAS' % (str(hdulist[0].header[obsparam['obstype']])) hdulist[0].header[obsparam['obstype']] = 'BIAS' Name= telescope + '_' + filename.split('.')[1] + '_' + TIME + '_BIAS_' + EXPTIME + '.fits' hdulist[0].header['HISTORY'] = 'SP: %s changed to %s' % (filename, Name) if prediction == 'Arcs': # Keep track of the focus value for arcs images CollFoc.append((int(filename.split('.')[1]),hdulist[0].header['COLLFOC'],idx)) # Update header hdulist[0].header['HISTORY'] = 'SP: %s changed to ARCS/FOCUS' % (str(hdulist[0].header[obsparam['obstype']])) hdulist[0].header[obsparam['obstype']] = 'ARCS/FOCUS' Arcs = True if prediction == 'Spectrum': # Update header hdulist[0].header['HISTORY'] = 'SP: %s changed to OBJECT' % (str(hdulist[0].header[obsparam['obstype']])) hdulist[0].header[obsparam['obstype']] = 'OBJECT' OBJECT = hdulist[0].header[obsparam['object']].replace(' ','').replace('/','') # Assume an unknown object as a first gest TYPE = 'Unknown' print(obsparam['object']) if OBJECT.replace(' ',''): print(OBJECT) try: # Try to retrieve the object using Horizons, if it find the object, assigned the object type to Asteroid Horizons(id=OBJECT).ephemerides() TYPE = 'Asteroid' except ValueError: #if object not find in Horizons, check simbad for standard stars try: result_table = Simbad.query_region(coord.SkyCoord(hdulist[0].header[obsparam['ra']] + ' ' + hdulist[0].header[obsparam['dec']] ,unit=(u.hourangle,u.deg), frame='icrs'), radius='0d1m00s') T = result_table['MAIN_ID'][0] if result_table['MAIN_ID'][0] in List_ID_SA: # Compares the ID found with simbad with our list of standard stars, if there is a match, Type = SA OBJECT = List_ID_SA_Comp[result_table['MAIN_ID'][0]] TYPE = 'SA' except: # If not found then object remains unknown pass if TYPE == 'Unknown': #if object still unknown try to clean the object name # except TypeError: if '(' in OBJECT and ')' in OBJECT: Number = OBJECT[OBJECT.find("(")+1:OBJECT.find(")")] if Number.isdigit(): try: Horizons(id=Number).ephemerides() TYPE = 'Asteroid' except ValueError: TYPE = 'Unknown' if OBJECT[0:3].isdigit(): if not ' ' in OBJECT: Name = OBJECT[0:4] + ' ' + OBJECT[4:] try: Horizons(id=Name).ephemerides() TYPE = 'Asteroid' except ValueError: TYPE = 'Unknown' Name= telescope + '_' + index + '_' + TIME + '_' + TYPE + '_' + OBJECT + '_' + EXPTIME + '.fits' hdulist[0].header['HISTORY'] = 'SP: %s changed to %s' % (filename, Name) if not Arcs: hdulist[0].writeto(Name,overwrite=True) _SP_conf.filenames.append(Name) print('%s changed to %s' % (filename, Name)) logging.info('%s changed to %s' % (filename, Name)) hdulist.close() if telescope == 'GMOSS': index = filename.split('S')[2].replace('.fits','') TIME = hdulist[0].header[obsparam['date_keyword']].replace('-','').replace(':','').replace('.','') EXPTIME = "{0:.1f}".format(round(hdulist[0].header['DARKTIME'],2)).replace('.','s') TYPE = hdulist[0].header[obsparam['obsclass']] CENTWAVE = str(int(hdulist[0].header['CENTWAVE'])) OBJECT = hdulist[0].header[obsparam['object']].replace(' ','').replace('/','') Name= telescope + '_' + index + '_' + TIME + '_' + TYPE + '_' + OBJECT + '_' + CENTWAVE +'_' + EXPTIME + '.fits' hdulist.writeto(Name) if telescope == 'GMOSN': index = filename.split('S')[1].replace('.fits','') TIME = hdulist[0].header[obsparam['date_keyword']].replace('-','').replace(':','').replace('.','') EXPTIME = "{0:.1f}".format(round(hdulist[0].header['DARKTIME'],2)).replace('.','s') TYPE = hdulist[0].header[obsparam['obsclass']] CENTWAVE = str(int(hdulist[0].header['CENTWAVE'])) OBJECT = hdulist[0].header[obsparam['object']].replace(' ','').replace('/','') Name= telescope + '_' + index + '_' + TIME + '_' + TYPE + '_' + OBJECT + '_' + CENTWAVE +'_' + EXPTIME + '.fits' hdulist.writeto(Name) if telescope == 'DEVENY': # Extract informations for header TIME = hdulist[0].header[obsparam['date_keyword']].replace('-','').replace(':','').replace('.','') EXPTIME = str(hdulist[0].header[obsparam['exptime']]).replace('.','s') # get the index of the file index = filename.split('.')[1] # Identify FLAT images if prediction == 'Flat': # Update header hdulist[0].header['HISTORY'] = 'SP: %s changed to FLAT' % (str(hdulist[0].header[obsparam['obstype']])) hdulist[0].header[obsparam['obstype']] = 'FLAT' Name= telescope + '_' + index + '_' + TIME + '_FLAT_' + EXPTIME + '.fits' hdulist[0].header['HISTORY'] = 'SP: %s changed to %s' % (filename, Name) if telescope == 'DEVENY': # In order to detect focus run and arcs run. During a focus run the focus # is changing while is stays the same during a calibration run Cons = Get_Consecutive(np.array(CollFoc)[:,0].astype(int)) Focus = [] Series = [] for idx, elem in enumerate(Cons): for idx2, elem2 in enumerate(elem): Focus.append(CollFoc[Cons[idx][idx2][0]][1]) if len(set(Focus)) == 1: Series.append('ARCS') else: Series.append('FOCUS') Focus = [] for idx, elem in enumerate(Cons): for idx2, elem2 in enumerate(elem): try: hdulist = fits.open(filenames[CollFoc[Cons[idx][idx2][0]][2]], mode='update' ,ignore_missing_end=True) except IOError: logging.error('cannot open file %s' % filename) print('ERROR: cannot open file %s' % filename) filenames.pop(idx) continue if Series[idx] == 'ARCS': hdulist[0].header[obsparam['obstype']] = 'ARCS' TIME = hdulist[0].header[obsparam['date_keyword']].replace('-','').replace(':','').replace('.','') EXPTIME = str(hdulist[0].header[obsparam['exptime']]).replace('.','s') Name= telescope + '_' + filenames[CollFoc[Cons[idx][idx2][0]][2]].split('.')[1] + '_' + TIME + '_ARCS_' + '_' + EXPTIME + '.fits' hdulist.close() shutil.copy(filenames[CollFoc[Cons[idx][idx2][0]][2]],Name) _SP_conf.filenames.append(Name) logging.info('%s changed to %s' % (filenames[CollFoc[Cons[idx][idx2][0]][2]], Name)) print('%s changed to %s' % (filenames[CollFoc[Cons[idx][idx2][0]][2]], Name)) else: hdulist[0].header[obsparam['obstype']] = 'FOCUS' TIME = hdulist[0].header[obsparam['date_keyword']].replace('-','').replace(':','').replace('.','') EXPTIME = str(hdulist[0].header[obsparam['exptime']]).replace('.','s') Name= telescope + '_' + filenames[CollFoc[Cons[idx][idx2][0]][2]].split('.')[1] + '_' + TIME + '_FOCUS_' + '_' + EXPTIME + '.fits' hdulist.close() shutil.copy(filenames[CollFoc[Cons[idx][idx2][0]][2]],Name) _SP_conf.filenames.append(Name) logging.info('%s changed to %s' % (filenames[CollFoc[Cons[idx][idx2][0]][2]], Name)) print('%s changed to %s' % (filenames[CollFoc[Cons[idx][idx2][0]][2]], Name)) # for elem in filenames: # os.remove(elem) return None
def curve_of_growth_analysis(filenames, parameters, display=False, diagnostics=False): output = {} obsparam = parameters['obsparam'] logging.info('starting photometry with parameters: %s' % (', '.join([('%s: %s' % (var, str(val))) for var, val in list(locals().items())]))) # re-extract sources for curve-of-growth analysis aprads = parameters['aprad'] if not isinstance(aprads, list) and not isinstance(aprads, numpy.ndarray): print('need a list of aprads...') os.abort() logging.info('run pp_extract using %d apertures' % len(aprads)) print('* extract sources from %d images using %d apertures' % (len(filenames), len(aprads))) extractparameters = {'sex_snr': parameters['sex_snr'], 'source_minarea': parameters['source_minarea'], 'paramfile': _pp_conf.rootpath + '/setup/twentyapertures.sexparam', 'aprad': aprads, 'telescope': parameters['telescope'], 'quiet': False} extraction = pp_extract.extract_multiframe(filenames, extractparameters) extraction = [e for e in extraction if len(e) > 0] # curve-of-growth analysis # arrays for accumulating source information as a function of aprad background_flux = [] # numpy.zeros(len(aprads)) target_flux = [] # numpy.zeros(len(aprads)) background_snr = [] # numpy.zeros(len(aprads)) target_snr = [] # numpy.zeros(len(aprads)) for filename in filenames: if display: print('processing curve-of-growth for frame %s' % filename) if not parameters['background_only']: hdu = fits.open(filename, ignore_missing_end=True) # pull target coordinates from Horizons targetname = hdu[0].header[obsparam['object']] if parameters['manobjectname'] is not None: targetname = parameters['manobjectname'].translate( _pp_conf.target2filename) image = hdu[0].data # derive MIDTIMJD, if not yet in the FITS header obsparam = parameters['obsparam'] if not 'MIDTIMJD' in hdu[0].header: exptime = float(hdu[0].header[obsparam['exptime']]) if obsparam['date_keyword'].find('|') == -1: date = hdu[0].header[obsparam['date_keyword']] date = dateobs_to_jd(date) + exptime/2./86400. else: date_key = obsparam['date_keyword'].split('|')[0] time_key = obsparam['date_keyword'].split('|')[1] date = hdu[0].header[date_key]+'T' +\ hdu[0].header[time_key] date = dateobs_to_jd(date) + exptime/2./86400. else: date = hdu[0].header['MIDTIMJD'] # call HORIZONS to get target coordinates obj = Horizons(targetname.replace('_', ' '), epochs=date, location=str(obsparam['observatory_code'])) try: eph = obj.ephemerides() n = len(eph) except ValueError: print('Target (%s) not a small body' % targetname) logging.warning('Target (%s) not a small body' % targetname) n = None if n is None or n == 0: logging.warning('WARNING: No position from Horizons!' + 'Name (%s) correct?' % targetname) logging.warning('HORIZONS call: %s' % obj.uri) logging.info('proceeding with background sources analysis') parameters['background_only'] = True else: logging.info('ephemerides for %s pulled from Horizons' % targetname) target_ra, target_dec = eph[0]['RA'], eph[0]['DEC'] # pull data from LDAC file ldac_filename = filename[:filename.find('.fit')]+'.ldac' data = catalog('Sextractor_LDAC') data.read_ldac(ldac_filename, maxflag=3) if data.shape[0] == 0: continue # identify target and extract its curve-of-growth n_target_identified = 0 if not parameters['background_only']: residuals = numpy.sqrt((data['ra_deg']-target_ra)**2 + (data['dec_deg']-target_dec)**2) target_idx = numpy.argmin(residuals) if residuals[target_idx] > _pp_conf.pos_epsilon/3600: logging.warning(('WARNING: frame %s, large residual to ' + 'HORIZONS position of %s: %f arcsec; ' + 'ignore this frame') % (filename, targetname, residuals[numpy.argmin(residuals)]*3600.)) else: target_flux.append(data[target_idx]['FLUX_'+_pp_conf.photmode] / max(data[target_idx][ 'FLUX_'+_pp_conf.photmode])) target_snr.append( data[target_idx]['FLUX_'+_pp_conf.photmode] / data[target_idx]['FLUXERR_'+_pp_conf.photmode] / max(data[target_idx]['FLUX_'+_pp_conf.photmode] / data[target_idx]['FLUXERR_'+_pp_conf.photmode])) n_target_identified += 1 # extract background source fluxes and snrs # assume n_background_sources >> 1, do not reject target if not parameters['target_only']: # n_src = data.shape[0] # use all sources n_src = 50 # use only 50 sources for idx, src in enumerate(data.data[:n_src]): if (numpy.any(numpy.isnan(src['FLUX_'+_pp_conf.photmode])) or numpy.any(numpy.isnan(src['FLUXERR_'+_pp_conf.photmode])) or src['FLAGS'] > 3): continue # create growth curve background_flux.append(src['FLUX_'+_pp_conf.photmode] / max(src['FLUX_'+_pp_conf.photmode])) background_snr.append(src['FLUX_'+_pp_conf.photmode] / src['FLUXERR_'+_pp_conf.photmode] / max(src['FLUX_'+_pp_conf.photmode] / src['FLUXERR_'+_pp_conf.photmode])) # investigate curve-of-growth logging.info('investigate curve-of-growth based on %d frames' % len(filenames)) # combine results n_target = len(target_flux) if n_target > 0: target_flux = (numpy.median(target_flux, axis=0), numpy.std(target_flux, axis=0)/numpy.sqrt(n_target)) target_snr = numpy.median(target_snr, axis=0) else: target_flux = (numpy.zeros(len(aprads)), numpy.zeros(len(aprads))) target_snr = numpy.zeros(len(aprads)) n_background = len(background_flux) if n_background > 0: background_flux = (numpy.median(background_flux, axis=0), numpy.std(background_flux, axis=0) / numpy.sqrt(n_background)) background_snr = numpy.median(background_snr, axis=0) else: background_flux = (numpy.zeros(len(aprads)), numpy.zeros(len(aprads))) background_snr = numpy.zeros(len(aprads)) if n_target == 0: logging.info('No target fluxes available, using background sources, ' + 'only') parameters['background_only'] = True if n_background == 0: logging.info('No background fluxes available, using target, only') parameters['target_only'] = True # find optimum aperture radius if parameters['target_only']: aprad_strategy = 'smallest target aprad that meets fluxlimit criterion' optimum_aprad_idx = numpy.argmin(numpy.fabs(target_flux[0] - _pp_conf.fluxlimit_aprad)) elif parameters['background_only']: aprad_strategy = 'smallest background aprad that meets fluxlimit ' + \ 'criterion' optimum_aprad_idx = numpy.argmin(numpy.fabs(background_flux[0] - _pp_conf.fluxlimit_aprad)) else: # flux_select: indices where target+background fluxes > fluxlimit flux_select = numpy.where((target_flux[0] > _pp_conf.fluxlimit_aprad) & (background_flux[0] > _pp_conf.fluxlimit_aprad))[0] flux_res = numpy.fabs(target_flux[0][flux_select] - background_flux[0][flux_select]) if numpy.min(flux_res) < _pp_conf.fluxmargin_aprad: aprad_strategy = 'target+background fluxes > fluxlimit, ' + \ 'flux difference < margin' optimum_aprad_idx = flux_select[numpy.where(flux_res < _pp_conf.fluxmargin_aprad)[0][0]] else: aprad_strategy = 'target+background fluxes > fluxlimit, ' + \ 'flux difference minimal' optimum_aprad_idx = flux_select[numpy.argmin(flux_res)] optimum_aprad = parameters['aprad'][optimum_aprad_idx] output['aprad_strategy'] = aprad_strategy output['optimum_aprad'] = optimum_aprad output['pos_epsilon'] = _pp_conf.pos_epsilon output['fluxlimit_aprad'] = _pp_conf.fluxlimit_aprad output['fluxmargin_aprad'] = _pp_conf.fluxmargin_aprad output['n_target'] = len(target_flux[0]) output['n_bkg'] = len(background_flux[0]) output['target_flux'] = target_flux output['target_snr'] = target_snr output['background_flux'] = background_flux output['background_snr'] = background_snr output['parameters'] = parameters # write results to file outf = open('aperturephotometry_curveofgrowth.dat', 'w') outf.writelines('# background target flux\n' + '# rad flux sigma snr flux sigma snr residual\n') for i in range(len(parameters['aprad'])): outf.writelines(('%5.2f %5.3f %5.3f %4.2f %6.3f %5.3f %4.2f ' + '%6.3f\n') % (parameters['aprad'][i], background_flux[0][i], background_flux[1][i], background_snr[i], target_flux[0][i], target_flux[1][i], target_snr[i], target_flux[0][i]-background_flux[0][i])) outf.close() # extraction content # # -> see pp_extract.py # ### # output content # # { 'aprad_strategy' : optimum aperture finding strategy, # 'optimum_aprad' : optimum aperature radius, # 'pos_epsilon' : required positional uncertainty ("), # 'fluxlimit_aprad' : min flux for both target and background, # 'fluxmargin_aprad': max flux difference between target and background, # 'n_target' : number of frames with target flux measurements, # 'n_bkg' : number of frames with background measurements, # 'target_flux' : target fluxes as a function of aprad, # 'target_snr' : target snrs as a function of aprad, # 'background_flux' : background fluxes as a function of aprad, # 'background_snr' : background snrs as a function of aprad, # 'parameters' : source extractor parameters # } ### # diagnostics if diagnostics: if display: print('creating diagnostic output') logging.info(' ~~~~~~~~~ creating diagnostic output') diag.add_photometry(output, extraction) # update image headers for filename in filenames: hdu = fits.open(filename, mode='update', ignore_missing_end=True) hdu[0].header['APRAD'] = (optimum_aprad, 'aperture phot radius (px)') hdu[0].header['APIDX'] = (optimum_aprad_idx, 'optimum aprad index') hdu.flush() hdu.close() # display results if display: print('\n#################################### PHOTOMETRY SUMMARY:\n###') print('### best-fit aperture radius %5.2f (px)' % (optimum_aprad)) print('###\n#####################################################\n') logging.info('==> best-fit aperture radius: %3.1f (px)' % (optimum_aprad)) return output
p.line.set_ydata(p.ys) plots.append(p.plot) lines.append(p.line) self.timestamp.set_text('Date: ' + self.time.iso) return plots + lines + [self.timestamp] plt.style.use('dark_background') fig = plt.figure(figsize=[10, 10]) ax = plt.axes([0., 0., 1., 1.], xlim=(-1.8, 1.8), ylim=(-1.8, 1.8)) ax.set_aspect('equal') ax.axis('off') ss = SolarSystem(Object("Sun", 28, 'red', [0, 0, 0], [0, 0, 0])) ss.time = Time(sim_start_date) ss.time.format='jd' colors = ['gray', 'orange', 'blue', 'chocolate', 'green'] sizes = [0.38, 0.95, 1., 0.53, 0.78] names = ['Mercury', 'Venus', 'Earth', 'Mars', 'Jupiter'] texty = [0.47, 0.82, 1., 1.5, 3.2] for i, nasaid in enumerate([1, 2, 3, 4, 5]): # The 1st, 2nd, 3rd, 4th, 5th planet in solar system obj = Horizons(id=nasaid, location="@sun", epochs=ss.time).vectors() ss.add_planet(Object(nasaid, 20 * sizes[i], colors[i], [np.double(obj[xi]) for xi in ['x', 'y', 'z']], [np.double(obj[vxi]) for vxi in ['vx', 'vy', 'vz']])) ax.text(0, - (texty[i] + 0.1), names[i], color=colors[i], zorder=1000, ha='center', fontsize='large') def animate(i): return ss.evolve() ani = animation.FuncAnimation(fig, animate, repeat=False, frames=sim_duration, blit=True, interval=20,) plt.show() ani.save('solar_system_6in_150dpi.mp4', fps=60, dpi=150)
def get_horizons_ephemerides_elements(name, pov, epoch_start): # step: step size, [10m, 1d, 1y] if pov.lower() == 'sun': loc = '500@10' # position relative to the sun elif pov.lower() == 'goldstone': loc = '257' # from goldstone elif pov.lower() == 'maunakea': loc = '568' # maunakea else: print('Not Valid Location Point Of View') # Process to get homogeneity from main script full name '2012QD8' to a valid name for Horizon call '2012 QD8' if len( re.findall('([0-9])', name) ) <= 4: # 4 is the min numbers in every name, the date year of discovery r = re.compile("([0-9]+)([a-zA-Z]+)").match(name) k1 = r.group(1) # the date of the name k2 = r.group(2) # the code of the date valid_name = k1 + " " + k2 else: r = re.compile("([0-9]+)([a-zA-Z]+)([0-9]+)").match(name) k1 = r.group(1) # the date of the name k2 = r.group(2) # the code of the date k3 = r.group(3) # id after the letters valid_name = k1 + " " + k2 + k3 # always a day after the input, anyway you consider the moment of input, the first of the data output extracted epoch_start chunks = epoch_start.split('-') chunks2 = int(chunks[2]) + 1 # add 1 day list_string = [chunks[0], chunks[1], str(chunks2)] epoch_stop = '-'.join(list_string) step_size = '1d' obj = Horizons(id=valid_name, location=loc, epochs={ 'start': epoch_start, 'stop': epoch_stop, 'step': step_size }) # refsystem = 'J2000', # Element reference system for geometric and astrometric quantities # refplane = 'ecliptic' #ecliptic and mean equinox of reference epoch data = obj.elements(refsystem='J2000', refplane='ecliptic') len_cols = 7 # jd,ec,qr,tp,incl,OM,om adata = np.zeros([1, len_cols]) # always assign the first row of output data -> the first date required! #for row in range(len_rows): adata[0, 0] = data[0][5] # 6th column of data -> e, eccentricity (-) adata[0, 1] = data[0][6] # 7th column of data -> qr, periapsis distance (AU) adata[0, 2] = data[0][10] # 11th column of data -> tp, time of periapsis (JD) adata[0, 3] = data[0][7] # 8th column of data -> incl, inclination (deg) adata[0, 4] = data[0][ 8] # 10th column of data -> OM, longitude of Asc. Node (deg) adata[0, 5] = data[0][ 9] # 11th column of data -> om, argument of periapsis (deg) adata[0, 6] = data[0][ 1] # 2nd column of the data extracted -> jd of evaluation return adata
def from_horizons( cls, name, epochs, *, attractor=None, plane=Planes.EARTH_EQUATOR, id_type=None, ): """Return `Ephem` for an object using JPLHorizons module of Astroquery. Parameters ---------- name : str Name of the body to query for. epochs : ~astropy.time.Time Epochs to sample the body positions. attractor : ~poliastro.bodies.SolarSystemPlanet, optional Body to use as central location, if not given the Solar System Barycenter will be used. plane : ~poliastro.frames.Planes, optional Fundamental plane of the frame, default to Earth Equator. id_type : NoneType or str, optional Use "smallbody" for Asteroids and Comets and None (default) to first search for Planets and Satellites. """ if epochs.isscalar: epochs = epochs.reshape(1) refplanes_dict = { Planes.EARTH_EQUATOR: "earth", Planes.EARTH_ECLIPTIC: "ecliptic", } refplane = refplanes_dict[plane] if attractor is not None: bodies_dict = { "sun": 10, "mercury": 199, "venus": 299, "earth": 399, "mars": 499, "jupiter": 599, "saturn": 699, "uranus": 799, "neptune": 899, } location = f"500@{bodies_dict[attractor.name.lower()]}" else: location = "@ssb" obj = Horizons( id=name, location=location, epochs=epochs.jd, id_type=id_type ).vectors(refplane=refplane) x = obj["x"] y = obj["y"] z = obj["z"] d_x = obj["vx"] d_y = obj["vy"] d_z = obj["vz"] coordinates = CartesianRepresentation( x, y, z, differentials=CartesianDifferential(d_x, d_y, d_z) ) return cls(coordinates, epochs, plane)
def from_horizons(cls, targetids, id_type='smallbody', epochs=None, center='500@10', **kwargs): """Load target orbital elements from `JPL Horizons <https://ssd.jpl.nasa.gov/horizons.cgi>`_ using `astroquery.jplhorizons.HorizonsClass.elements` Parameters ---------- targetids : str or iterable of str Target identifier, i.e., a number, name, designation, or JPL Horizons record number, for one or more targets. id_type : str, optional The nature of ``targetids`` provided; possible values are ``'smallbody'`` (asteroid or comet), ``'majorbody'`` (planet or satellite), ``'designation'`` (asteroid or comet designation), ``'name'`` (asteroid or comet name), ``'asteroid_name'``, ``'comet_name'``, ``'id'`` (Horizons id). Default: ``'smallbody'`` epochs : `~astropy.time.Time` or dict, optional Epochs of elements to be queried; requires a `~astropy.time.Time` object with a single or multiple epochs. A dictionary including keywords ``start`` and ``stop``, as well as either ``step`` or ``number``, can be used to generate a range of epochs. ``start`` and ``stop`` have to be `~astropy.time.Time` objects (see :ref:`epochs`). If ``step`` is provided, a range of epochs will be queries starting at ``start`` and ending at ``stop`` in steps of ``step``; ``step`` has to be provided as a `~astropy.units.Quantity` object with integer value and a unit of either minutes, hours, days, or years. If ``number`` is provided as an integer, the interval defined by ``start`` and ``stop`` is split into ``number`` equidistant intervals. If ``None`` is provided, current date and time are used. All epochs should be provided in TDB; if not, they will be converted to TDB and a `~sbpy.data.TimeScaleWarning` will be raised. Default: ``None`` center : str, optional, default ``'500@10'`` (center of the Sun) Elements will be provided relative to this position. **kwargs : optional Arguments that will be provided to `astroquery.jplhorizons.HorizonsClass.elements`. Notes ----- * For detailed explanations of the queried fields, refer to `astroquery.jplhorizons.HorizonsClass.elements` and the `JPL Horizons documentation <https://ssd.jpl.nasa.gov/?horizons_doc>`_. * By default, elements are provided in the J2000.0 reference system and relative to the ecliptic and mean equinox of the reference epoch. Different settings can be chosen using additional keyword arguments as used by `astroquery.jplhorizons.HorizonsClass.elements`. Returns ------- `~Orbit` object Examples -------- >>> from sbpy.data import Orbit >>> from astropy.time import Time >>> epoch = Time('2018-05-14', scale='tdb') >>> eph = Orbit.from_horizons('Ceres', epochs=epoch) # doctest: +REMOTE_DATA """ # modify epoch input to make it work with astroquery.jplhorizons # maybe this stuff should really go into that module.... if epochs is None: epochs = [Time.now().tdb.jd] elif isinstance(epochs, Time): if epochs.scale is not 'tdb': warn(('converting {} epochs to tdb for use in ' 'astroquery.jplhorizons').format(epochs.scale), TimeScaleWarning) epochs = epochs.tdb.jd elif isinstance(epochs, dict): if 'start' in epochs and 'stop' in epochs and 'number' in epochs: epochs['step'] = epochs['number']*u.dimensionless_unscaled # convert to tdb and iso for astroquery.jplhorizons epochs['start'] = epochs['start'].tdb.iso epochs['stop'] = epochs['stop'].tdb.iso if 'step' in epochs: if epochs['step'].unit is not u.dimensionless_unscaled: epochs['step'] = '{:d}{:s}'.format( int(epochs['step'].value), {u.minute: 'm', u.hour: 'h', u.d: 'd', u.year: 'y'}[epochs['step'].unit]) else: epochs['step'] = '{:d}'.format( int(epochs['step'].value-1)) # if targetids is a list, run separate Horizons queries and append if not isinstance(targetids, (list, ndarray, tuple)): targetids = [targetids] # append elements table for each targetid all_elem = None for targetid in targetids: # load elements using astroquery.jplhorizons obj = Horizons(id=targetid, id_type=id_type, location=center, epochs=epochs) try: elem = obj.elements(**kwargs) except ValueError as e: raise QueryError( ('Error raised by astroquery.jplhorizons: {:s}\n' 'The following query was attempted: {:s}').format( str(e), obj.uri)) # workaround for current version of astroquery to make # column units compatible with astropy.table.QTable # should really change '---' units to None in # astroquery.jplhorizons.__init__.py for column_name in elem.columns: if elem[column_name].unit == '---': elem[column_name].unit = None if all_elem is None: all_elem = elem else: all_elem = vstack([all_elem, elem]) # turn epochs into astropy.time.Time and apply timescale # https://ssd.jpl.nasa.gov/?horizons_doc all_elem['epoch'] = Time(all_elem['datetime_jd'], format='jd', scale='tdb') all_elem['Tp'] = Time(all_elem['Tp_jd'], format='jd', scale='tdb') all_elem.remove_column('datetime_jd') all_elem.remove_column('datetime_str') all_elem.remove_column('Tp_jd') return cls.from_table(all_elem)
def getHorizonsObserverState( observatory_codes, observation_times, origin="heliocenter", aberrations="geometric" ): """ Query JPL Horizons (through astroquery) for an object's elements at the given times. Parameters ---------- observatory_codes : list or `~numpy.ndarray` MPC observatory codes. observation_times : `~astropy.time.core.Time` Epochs for which to find the observatory locations. origin : {'barycenter', 'heliocenter'} Return observer state with heliocentric or barycentric origin. aberrations : {'geometric', 'astrometric', 'apparent'} Adjust state for one of three different aberrations. Returns ------- vectors : `~pandas.DataFrame` Dataframe containing the full cartesian state, r, r_rate, delta, delta_rate and light time of the object at each time. """ _checkTime(observation_times, "observation_times") if origin == "heliocenter": origin_horizons = "sun" elif origin == "barycenter": origin_horizons = "ssb" else: err = ( "origin should be one of {'heliocenter', 'barycenter'}" ) raise ValueError(err) dfs = [] for code in observatory_codes: obj = Horizons( id=origin_horizons, epochs=observation_times.tdb.mjd, location=code, id_type="majorbody", ) vectors = obj.vectors( refplane="ecliptic", aberrations=aberrations, cache=False, ).to_pandas() vectors = vectors.drop(columns="targetname") vectors.insert(0, "observatory_code", [code for i in range(len(vectors))]) vectors.loc[:, ["x", "y", "z", "vx", "vy", "vz"]] *= -1 dfs.append(vectors) vectors = pd.concat(dfs) vectors.reset_index( inplace=True, drop=True ) return vectors
from astroquery.jplhorizons import Horizons from numpy import pi dates = [] i = 0 date = 2450634.183786772 while i < 2: dates.append(date) date += 1 i += 1 location = {'lon': 149.066111, 'lat': -31.2768056, 'elevation': 1.1645} # obj = Horizons(id='2018 AJ12', location=location, epochs=dates, id_type='id') # obj = Horizons(id='Ceres', location=location, epochs=dates, id_type='id') obj = Horizons(id='2009 FD', location=location, epochs=dates, id_type='id') # eph = obj.ephemerides(quantities='1,9,36', get_raw_response=True, refsystem='B1950').split("\n") eph = obj.ephemerides(quantities='1,9,36', get_raw_response=True, refsystem='B1950') print(eph) with open("text.txt", "w") as test_file: for line in eph: test_file.write("\n{}".format(line)) for i in range(0, len(eph)): if "$$SOE" in eph[i]: lower_bound = i if "$$EOE" in eph[i]: upper_bound = i data_points = eph[lower_bound + 1:upper_bound]
def get_horizons_coord(body, time='now', id_type='majorbody', *, include_velocity=False): """ Queries JPL HORIZONS and returns a `~astropy.coordinates.SkyCoord` for the location of a solar-system body at a specified time. This location is the instantaneous or "true" location, and is not corrected for light travel time or observer motion. .. note:: This function requires the Astroquery package to be installed and requires an Internet connection. Parameters ---------- body : `str` The solar-system body for which to calculate positions. One can also use the search form linked below to find valid names or ID numbers. id_type : `str` If 'majorbody', search by name for planets, satellites, or other major bodies. If 'smallbody', search by name for asteroids or comets. If 'id', search by ID number. time : {parse_time_types}, `dict` Time to use in a parse_time-compatible format. Alternatively, this can be a dictionary defining a range of times and dates; the range dictionary has to be of the form {{'start': start_time, 'stop': stop_time, 'step':’n[y|d|m|s]’}}. ``start_time`` and ``stop_time`` must be in a parse_time-compatible format, and are interpreted as UTC time. ``step`` must be a string with either a number and interval length (e.g. for every 10 seconds, ``'10s'``), or a plain number for a number of evenly spaced intervals. For more information see the docstring of `astroquery.jplhorizons.HorizonsClass`. Keyword Arguments ----------------- include_velocity : `bool` If True, include the body's velocity in the output coordinate. Defaults to False. Returns ------- `~astropy.coordinates.SkyCoord` Location of the solar-system body Notes ----- Be aware that there can be discrepancies between the coordinates returned by JPL HORIZONS, the coordinates reported in mission data files, and the coordinates returned by `~sunpy.coordinates.get_body_heliographic_stonyhurst`. References ---------- * `JPL HORIZONS <https://ssd.jpl.nasa.gov/?horizons>`_ * `JPL HORIZONS form to search bodies <https://ssd.jpl.nasa.gov/horizons.cgi?s_target=1#top>`_ * `Astroquery <https://astroquery.readthedocs.io/en/latest/>`_ Examples -------- >>> from sunpy.coordinates.ephemeris import get_horizons_coord Query the location of Venus >>> get_horizons_coord('Venus barycenter', '2001-02-03 04:05:06') # doctest: +REMOTE_DATA INFO: Obtained JPL HORIZONS location for Venus Barycenter (2) [sunpy.coordinates.ephemeris] <SkyCoord (HeliographicStonyhurst: obstime=2001-02-03T04:05:06.000, rsun=695700.0 km): (lon, lat, radius) in (deg, deg, AU) (-33.93155836, -1.64998443, 0.71915147)> Query the location of the SDO spacecraft >>> get_horizons_coord('SDO', '2011-11-11 11:11:11') # doctest: +REMOTE_DATA INFO: Obtained JPL HORIZONS location for Solar Dynamics Observatory (spac [sunpy.coordinates.ephemeris] <SkyCoord (HeliographicStonyhurst: obstime=2011-11-11T11:11:11.000, rsun=695700.0 km): (lon, lat, radius) in (deg, deg, AU) (0.01019118, 3.29640728, 0.99011042)> Query the location of the SOHO spacecraft via its ID number (-21) >>> get_horizons_coord(-21, '2004-05-06 11:22:33', 'id') # doctest: +REMOTE_DATA INFO: Obtained JPL HORIZONS location for SOHO (spacecraft) (-21) [sunpy.coordinates.ephemeris] <SkyCoord (HeliographicStonyhurst: obstime=2004-05-06T11:22:33.000, rsun=695700.0 km): (lon, lat, radius) in (deg, deg, AU) (0.25234902, -3.55863633, 0.99923086)> Query the location and velocity of the asteroid Juno >>> get_horizons_coord('Juno', '1995-07-18 07:17', 'smallbody', include_velocity=True) # doctest: +REMOTE_DATA INFO: Obtained JPL HORIZONS location for 3 Juno (A804 RA) [sunpy.coordinates.ephemeris] <SkyCoord (HeliographicStonyhurst: obstime=1995-07-18T07:17:00.000, rsun=695700.0 km): (lon, lat, radius) in (deg, deg, AU) (-25.16107532, 14.59098438, 3.17667664) (d_lon, d_lat, d_radius) in (arcsec / s, arcsec / s, km / s) (-0.03306548, 0.00052415, -2.66709222)> Query the location of Solar Orbiter at a set of 12 regularly sampled times >>> get_horizons_coord('Solar Orbiter', ... time={{'start': '2020-12-01', ... 'stop': '2020-12-02', ... 'step': '12'}}) # doctest: +REMOTE_DATA INFO: Obtained JPL HORIZONS location for Solar Orbiter (spacecraft) (-144 [sunpy.coordinates.ephemeris] ... """ if isinstance(time, dict): if set(time.keys()) != set(['start', 'stop', 'step']): raise ValueError( 'time dictionary must have the keys ["start", "stop", "step"]') epochs = time jpl_fmt = '%Y-%m-%d %H:%M:%S' epochs['start'] = parse_time(epochs['start']).tdb.strftime(jpl_fmt) epochs['stop'] = parse_time(epochs['stop']).tdb.strftime(jpl_fmt) else: obstime = parse_time(time) array_time = np.reshape(obstime, (-1, )) # Convert to an array, even if scalar epochs = array_time.tdb.jd.tolist() # Time must be provided in JD TDB # Import here so that astroquery is not a module-level dependency from astroquery.jplhorizons import Horizons query = Horizons( id=body, id_type=id_type, location='500@10', # Heliocentric (mean ecliptic) epochs=epochs) try: result = query.vectors() except Exception as e: # Catch and re-raise all exceptions, and also provide query URL if generated if query.uri is not None: log.error( f"See the raw output from the JPL HORIZONS query at {query.uri}" ) raise e finally: query._session.close() log.info(f"Obtained JPL HORIZONS location for {result[0]['targetname']}") log.debug(f"See the raw output from the JPL HORIZONS query at {query.uri}") if isinstance(time, dict): obstime = parse_time(result['datetime_jd'], format='jd', scale='tdb') else: # JPL HORIZONS results are sorted by observation time, so this sorting needs to be undone. # Calling argsort() on an array returns the sequence of indices of the unsorted list to put the # list in order. Calling argsort() again on the output of argsort() reverses the mapping: # the output is the sequence of indices of the sorted list to put that list back in the # original unsorted order. unsorted_indices = obstime.argsort().argsort() result = result[unsorted_indices] vector = CartesianRepresentation(result['x'], result['y'], result['z']) if include_velocity: velocity = CartesianDifferential(result['vx'], result['vy'], result['vz']) vector = vector.with_differentials(velocity) coord = SkyCoord(vector, frame=HeliocentricEclipticIAU76, obstime=obstime) return coord.transform_to(HeliographicStonyhurst).reshape(obstime.shape)
def get_horizons_coord(body, time='now', id_type='majorbody'): """ Queries JPL HORIZONS and returns a `~astropy.coordinates.SkyCoord` for the location of a solar-system body at a specified time. This location is the instantaneous or "true" location, and is not corrected for light travel time or observer motion. This function requires the Astroquery package to be installed and requires an Internet connection. Parameters ---------- body : `str` The solar-system body for which to calculate positions id_type : `str` If 'majorbody', search by name for planets or satellites. If 'id', search by ID number. time : various Time to use as `~astropy.time.Time` or in a parse_time-compatible format Returns ------- `~astropy.coordinates.SkyCoord` Location of the solar-system body Notes ----- Be aware that there can be discrepancies between the coordinates returned by JPL HORIZONS, the coordinates reported in mission data files, and the coordinates returned by `~sunpy.coordinates.get_body_heliographic_stonyhurst`. References ---------- * `JPL HORIZONS <https://ssd.jpl.nasa.gov/?horizons>`_ * `Astroquery <https://astroquery.readthedocs.io/en/latest/>`_ Examples -------- .. Run these tests with a temp cache dir .. testsetup:: >>> from astropy.config.paths import set_temp_cache >>> import tempfile >>> c = set_temp_cache(tempfile.mkdtemp()) >>> _ = c.__enter__() >>> from sunpy.coordinates import get_horizons_coord Query the location of Venus >>> get_horizons_coord('Venus barycenter', '2001-02-03 04:05:06') # doctest: +REMOTE_DATA INFO: Obtained JPL HORIZONS location for Venus Barycenter (2) [sunpy.coordinates.ephemeris] <SkyCoord (HeliographicStonyhurst: obstime=2001-02-03T04:05:06.000): (lon, lat, radius) in (deg, deg, AU) (326.06844114, -1.64998481, 0.71915147)> Query the location of the SDO spacecraft >>> get_horizons_coord('SDO', '2011-11-11 11:11:11') # doctest: +REMOTE_DATA INFO: Obtained JPL HORIZONS location for Solar Dynamics Observatory (spac [sunpy.coordinates.ephemeris] <SkyCoord (HeliographicStonyhurst: obstime=2011-11-11T11:11:11.000): (lon, lat, radius) in (deg, deg, AU) (0.01018888, 3.29640407, 0.99011042)> Query the location of the SOHO spacecraft via its ID number (-21) >>> get_horizons_coord(-21, '2004-05-06 11:22:33', 'id') # doctest: +REMOTE_DATA INFO: Obtained JPL HORIZONS location for SOHO (spacecraft) (-21) [sunpy.coordinates.ephemeris] <SkyCoord (HeliographicStonyhurst: obstime=2004-05-06T11:22:33.000): (lon, lat, radius) in (deg, deg, AU) (0.2523461, -3.55863351, 0.99923086)> .. testcleanup:: >>> _ = c.__exit__() """ obstime = parse_time(time) # Import here so that astroquery is not a module-level dependency from astroquery.jplhorizons import Horizons query = Horizons(id=body, id_type=id_type, location='500@10', # Heliocentric (mean ecliptic) epochs=obstime.tdb.jd) # Time must be provided in JD TDB try: result = query.vectors() except Exception: # Catch and re-raise all exceptions, and also provide query URL if generated if query.uri is not None: log.error(f"See the raw output from the JPL HORIZONS query at {query.uri}") raise log.info(f"Obtained JPL HORIZONS location for {result[0]['targetname']}") vector = CartesianRepresentation(result[0]['x', 'y', 'z'])*u.AU coord = SkyCoord(vector, frame=HeliocentricMeanEcliptic, obstime=obstime) return coord.transform_to(HGS)
def moving_primary_target(catalogs, man_targetname, offset, is_asteroid=None, display=True): """ is_asteroid == True: this object is an asteroid is_asteroid == False: this object is a planet/moon/spacecraft is_asteroid == None: no information on target nature """ if display: print('# check JPL Horizons for primary target... ') sys.stdout.flush() logging.info('check JPL Horizons for primary target') obsparam = _pp_conf.telescope_parameters[ catalogs[0].origin.split(';')[0].strip()] objects = [] # check for target nature, if unknown if is_asteroid is None: cat = catalogs[0] targetname = cat.obj.replace('_', ' ') if man_targetname is not None: targetname = man_targetname.replace('_', ' ') for smallbody in [True, False]: obj = Horizons(targetname.replace('_', ' '), id_type={True: 'smallbody', False: 'majorbody'}[smallbody], epochs=cat.obstime[0], location=obsparam['observatory_code']) n = 0 try: eph = obj.ephemerides() n = len(eph) except ValueError: if display and smallbody is True: print("'%s' is not a small body" % targetname) logging.warning("'%s' is not a small body" % targetname) if display and smallbody is False: print("'%s' is not a Solar System object" % targetname) logging.warning("'%s' is not a Solar System object" % targetname) pass if n > 0: is_asteroid = smallbody break # if is_asteroid is still None, this object is not in the Horizons db if is_asteroid is None: return objects message_shown = False # query information for each image for cat_idx, cat in enumerate(catalogs): targetname = cat.obj.replace('_', ' ') if man_targetname is not None: targetname = man_targetname.replace('_', ' ') cat.obj = targetname obj = Horizons(targetname.replace('_', ' '), id_type={True: 'smallbody', False: 'majorbody'}[is_asteroid], epochs=cat.obstime[0], location=obsparam['observatory_code']) try: eph = obj.ephemerides() n = len(eph) except ValueError: # if is_asteroid: # if display and not message_shown: # print 'is \'%s\' an asteroid?' % targetname # logging.warning('Target (%s) is not an asteroid' % targetname) # else: # if display and not message_shown: # print ('is \'%s\' a different Solar System object?' % # )targetname # logging.warning('Target (%s) is not a Solar System object' % # targetname) # n = None pass if n is None or n == 0: logging.warning('WARNING: No position from Horizons! ' + 'Name (%s) correct?' % cat.obj.replace('_', ' ')) logging.warning('HORIZONS call: %s' % obj.uri) if display and not message_shown: print(' no Horizons data for %s ' % cat.obj.replace('_', ' ')) message_shown = True else: objects.append({'ident': eph[0]['targetname'].replace(" ", "_"), 'obsdate.jd': cat.obstime[0], 'cat_idx': cat_idx, 'ra_deg': eph[0]['RA']-offset[0]/3600, 'dec_deg': eph[0]['DEC']-offset[1]/3600}) logging.info('Successfully grabbed Horizons position for %s ' % cat.obj.replace('_', ' ')) logging.info('HORIZONS call: %s' % obj.uri) if display and not message_shown: print(cat.obj.replace('_', ' '), "identified") message_shown = True return objects
#!/usr/bin/env python # -*- coding: utf-8 -*- from astroquery.jplhorizons import Horizons from astroquery.jplhorizons import conf conf.horizons_server = 'https://ssd.jpl.nasa.gov/horizons_batch.cgi' ids = [str(i*100+99) for i in range(1,10)] ids.insert(0, '10') #ids.insert(len(ids), '1977 UB') objs = [Horizons(id=i, id_type= 'majorbody', epochs={'start':'2018-10-16', 'stop':'2018-11-15','step':'1d'}) for i in ids] vecs = [obj.vectors()[0] for obj in objs] planets = [[vec['targetname'], vec['x'], vec['y'], vec['z'], vec['vx'] * 365, vec['vy'] * 365, vec['vz'] * 365] for vec in vecs] masses = [2e30, 6e24, 1.9e25, 6.6e23, 4.9e24, 5.5e26, 3.3e23, 8.8e25, 1.03e26, 1.31e22] m_relative = [m/masses[0] for m in masses] i = -1 for p in planets : i += 1; print ('ss.addCelestialObj("', p[0], '", ', str(m_relative[i]), ', vec3(', str(p[1]), ', ', str(p[2]), ', ', str(p[3]), ')', ', vec3(', str(p[4]), ', ', str(p[5]), ', ', str(p[6]), '));') """with open('planets.txt', 'w') as file: for p in planets"""
# ["Titania", '703', 'majorbody', '500@10', 752218.6176], # ["Oberon", '704', 'majorbody', '500@10', 1163223.4176], # ['Neptune', '899', 'majorbody', '500@10', 58000.32, 2469806.5], # ['Triton', '801', 'majorbody', '500@10', 507772.8], # ['Pluto', '999', 'majorbody', '500@10', 551856.672, 2488068.5], # ['Charon', '901', 'majorbody', '500@10', 551856.70656, 2488068.5], ] for planet in planets: maxJD=float('inf') if len(planet) >= 6: maxJD=planet[5] obj = Horizons(id=planet[1], id_type=planet[2], location=planet[3], epochs={'start':'2000-01-01', 'stop':'2000-01-02', 'step':'1d'}) elem = obj.elements() print("-=-=-=-=-=-=-=-=-=- " + elem['targetname'][0] + " -=-=-=-=-=-=-=-=-=-") # Better hardcode for some bodies if planet[0] == "Jupiter" or planet[0] == "Io" or planet[0] == "Europa" or planet[0] == "Ganymede" or planet[0] == "Callisto": period=9502 elif planet[0] == "Saturn" or planet[0] == "Mimas" or planet[0] == "Enceladus" or planet[0] == "Tethys" or planet[0] == "Dione" or planet[0] == "Rhea" or planet[0] == "Titan" or planet[0] == "Hyperion" or planet[0] == "Iapetus": period=18000 elif planet[0] == "Uranus" or planet[0] == "Miranda" or planet[0] == "Ariel" or planet[0] == "Umbriel" or planet[0] == "Titania" or planet[0] == "Oberon": period = 50000 elif planet[0] == "Neptune" or planet[0] == "Triton": period=100000 else: period=math.ceil(elem['P'][0]) print("P: " + str(period) + " days")
def from_horizons(cls, targetids, id_type='smallbody', epochs=None, location='500', **kwargs): """Load target ephemerides from `JPL Horizons <https://ssd.jpl.nasa.gov/horizons.cgi>`_ using `astroquery.jplhorizons.HorizonsClass.ephemerides` Parameters ---------- targetids : str or iterable of str Target identifier, i.e., a number, name, designation, or JPL Horizons record number, for one or more targets. id_type : str, optional The nature of ``targetids`` provided; possible values are ``'smallbody'`` (asteroid or comet), ``'majorbody'`` (planet or satellite), ``'designation'`` (asteroid or comet designation), ``'name'`` (asteroid or comet name), ``'asteroid_name'``, ``'comet_name'``, ``'id'`` (Horizons id). Default: ``'smallbody'`` epochs : `~astropy.time.Time` object, or dictionary, optional Epochs of elements to be queried; `~astropy.time.Time` objects support single and multiple epochs; a dictionary including keywords ``start`` and ``stop``, as well as either ``step`` or ``number``, can be used to generate a range of epochs. ``start`` and ``stop`` have to be `~astropy.time.Time` objects (see :ref:`epochs`). If ``step`` is provided, a range of epochs will be queries starting at ``start`` and ending at ``stop`` in steps of ``step``; ``step`` has to be provided as a `~astropy.units.Quantity` object with integer value and a unit of either minutes, hours, days, or years. If ``number`` is provided as an integer, the interval defined by ``start`` and ``stop`` is split into ``number`` equidistant intervals. If ``None`` is provided, current date and time are used. All epochs should be provided in UTC; if not, they will be converted to UTC and a `~sbpy.data.TimeScaleWarning` will be raised. Default: ``None`` location : str or `~astropy.coordinates.EarthLocation`, optional Location of the observer using IAU observatory codes (see `IAU observatory codes <https://www.minorplanetcenter.net/iau/lists/ObsCodesF.html>`__) or as `~astropy.coordinates.EarthLocation`. Default: ``'500'`` (geocentric) **kwargs : optional Arguments that will be provided to `astroquery.jplhorizons.HorizonsClass.ephemerides`. Notes ----- * For detailed explanations of the queried fields, refer to `astroquery.jplhorizons.HorizonsClass.ephemerides` and the `JPL Horizons documentation <https://ssd.jpl.nasa.gov/?horizons_doc>`_. * By default, all properties are provided in the J2000.0 reference system. Different settings can be chosen using additional keyword arguments as used by `astroquery.jplhorizons.HorizonsClass.ephemerides`. Returns ------- `~Ephem` object The resulting object will be populated with columns as defined in `~astroquery.jplhorizons.HorizonsClass.ephemerides`; refer to that document on information on how to modify the list of queried parameters. Examples -------- >>> from sbpy.data import Ephem >>> from astropy.time import Time >>> epoch = Time('2018-05-14', scale='utc') >>> eph = Ephem.from_horizons('ceres', epochs=epoch) # doctest: +SKIP """ # modify epoch input to make it work with astroquery.jplhorizons # maybe this stuff should really go into that module.... _epochs = None # avoid modifying epochs in-place if epochs is None: _epochs = [Time.now().utc.jd] elif isinstance(epochs, Time): if epochs.scale != 'utc': warn(('converting {} epochs to utc for use in ' 'astroquery.jplhorizons').format(epochs.scale), TimeScaleWarning) _epochs = epochs.utc.jd elif isinstance(epochs, dict): _epochs = epochs.copy() if 'start' in _epochs and 'stop' in _epochs and 'number' in epochs: _epochs['step'] = _epochs['number'] * u.dimensionless_unscaled # convert to utc and iso for astroquery.jplhorizons _epochs['start'] = _epochs['start'].utc.iso _epochs['stop'] = _epochs['stop'].utc.iso if 'step' in _epochs: if _epochs['step'].unit is not u.dimensionless_unscaled: _epochs['step'] = '{:d}{:s}'.format( int(_epochs['step'].value), { u.minute: 'm', u.hour: 'h', u.d: 'd', u.year: 'y' }[_epochs['step'].unit]) else: _epochs['step'] = '{:d}'.format( int(_epochs['step'].value - 1)) else: raise ValueError('Invalid `epochs` parameter') # if targetids is a list, run separate Horizons queries and append if not isinstance(targetids, (list, ndarray, tuple)): targetids = [targetids] # turn EarthLocation into dictionary of strings as used by # astroquery.jplhorizons if isinstance(location, EarthLocation): location = { 'lon': location.lon.deg, 'lat': location.lat.deg, 'elevation': location.height.to('km') } # append ephemerides table for each targetid all_eph = None for targetid in targetids: # load ephemerides using astroquery.jplhorizons obj = Horizons(id=targetid, id_type=id_type, location=location, epochs=_epochs) try: eph = obj.ephemerides(**kwargs) except ValueError as e: raise QueryError( ('Error raised by astroquery.jplhorizons: {:s}\n' 'The following query was attempted: {:s}').format( str(e), obj.uri)) # workaround for current version of astroquery to make # column units compatible with astropy.table.QTable # should really change '---' units to None in # astroquery.jplhorizons.__init__.py for column_name in eph.columns: if eph[column_name].unit == '---': eph[column_name].unit = None # workaround for astroquery 0.3.9.dev5056 and earlier, # Horizons column named RA_rate always includes the # cos(Dec) term: if 'RA_rate' in eph.colnames: eph['RA_rate'].name = 'RA*cos(Dec)_rate' if all_eph is None: all_eph = eph else: all_eph = vstack([all_eph, eph]) # turn epochs into astropy.time.Time and apply timescale # convert ut1 epochs to utc # https://ssd.jpl.nasa.gov/?horizons_doc if any(all_eph['datetime_jd'] < 2437665.5): all_eph['datetime_jd'][all_eph['datetime_jd'] < 2437665.5] = Time( all_eph['datetime_jd'][all_eph['datetime_jd'] < 2437665.5], scale='ut1', format='jd').utc.jd all_eph['epoch'] = Time(all_eph['datetime_jd'], format='jd', scale='utc') if 'siderealtime' in all_eph.colnames: all_eph['siderealtime'].unit = u.Unit('hour') all_eph.remove_column('datetime_jd') all_eph.remove_column('datetime_str') return cls.from_table(all_eph)
def creator_gaia(table): """Creador de la tabla a partir de Gaia""" df = pd.read_csv('prueba2.csv') #Limpieza del archivo de gaia #Borrar las filas vacías df = df.dropna(how='any') #Borrar las magnitudes repetidas df = df.drop_duplicates(subset='g_mag', keep='first', inplace=False) #Ordenar por número mpc. Para cada nro mpc está ordenado por fecha dff = df.sort_values(by=['number_mp', 'epoch_utc']) #Agrego la columna de epoca utc pasada a JD jd = dff['epoch_utc'] + 2455197.5 dff.insert(2, 'jd', jd) #Borro valores repetidos para tener una lista de nro_mpc noob = df.drop_duplicates(subset="number_mp", keep="first", inplace=False) appended_data = [] #Arranca el loop que me dará para cada asteroide un archivo con: (nro-epoch_utc-JD-g_inst-r-delta-alfa) for nro in noob.number_mp: #Filtrar un solo asteroide data = dff[dff["number_mp"] == nro] #EFEMERIDES----------------------------------------------------------------------- #Descarga de las efemérides obj = Horizons(id=nro, location='@Gaia', epochs={ 'start': '2014-07-10', 'stop': '2016-06-20', 'step': '1d' }) eph = obj.ephemerides() #Los datos que necesito de las efemérides jdd = eph.columns['datetime_jd'] r = eph.columns['r'] delta = eph.columns['delta'] alpha = eph.columns['alpha'] efem = pd.DataFrame({ 'jd': jdd, 'r': r, 'delta': delta, 'alpha': alpha }) #Buscar las filas coincidentes entre archivos segun JD jd_list = data["jd"].tolist() bb = np.array([]) for i in range(len(jd_list)): b = int(jd_list[i]) + .5 bb = np.append(bb, b) r1 = np.array([]) delta1 = np.array([]) alfa1 = np.array([]) for i in range(len(bb)): lista = efem[efem.jd == bb[i]] rr = lista['r'].tolist() r1 = np.append(r1, rr) dd = lista['delta'].tolist() delta1 = np.append(delta1, dd) aa = lista['alpha'].tolist() alfa1 = np.append(alfa1, aa) #Agrego los datos a la tabla data.insert(4, 'r', r1) data.insert(5, 'delta', delta1) data.insert(6, 'alfa', alfa1) #Necesito quedarme con la magnitud mas chica de cada dia data = data.sort_values(by=['epoch_utc', 'g_mag'], ascending=True) data = data.drop_duplicates(subset='r', keep='first', inplace=False) data['g_red'] = data['g_mag'] - 5 * np.log10(data['r'] * data['delta']) styp = obj.ephemerides(get_raw_response=True) with open('ef.txt', 'w') as f: f.write(styp) with open('ef.txt') as file: file = file.read() x = file.find('STYP') tax = file[x + 6] if tax == 'n': tax = 'No' #Asigna un V-R promedio spec = pd.DataFrame({ 'Spectral Type': [ 'No', 'A', 'B', 'C', 'M', 'D', 'F', 'G', 'Q', 'R', 'S', 'L', 'K', 'P', 'T', 'V', 'X', 'E', 'O' ], 'V-R': [ 0.42875, 0.560, 0.361, 0.376, 0.376, 0.464, 0.366, 0.370, 0.424, 0.479, 0.475, 0.475, 0.475, 0.475, 0.447, 0.413, 0.410, 0.410, 0.410 ] }) VR = spec[spec['Spectral Type'] == tax] VR = VR.iat[0, 1] #Cálculo de V data['V'] = data['g_red'] + 0.008 + 0.190 * (VR) + 0.575 * (VR)**2 dat = data[['number_mp', 'alfa', 'V']] dat = dat.sort_values(by=['alfa']) dat = dat.rename(columns={'number_mp': 'nro', 'V': 'v'}) appended_data.append(dat) appended_data = pd.concat(appended_data) appended_data.to_csv('prueba3.csv', index=False)
# This file is to test if matplotlib is fast enough for me to use it in testing of the nonlinear optimization of spacecraft launch parameters C++ program import numpy as np import matplotlib.pyplot as plt import pylab as py from matplotlib import animation import astropy as aspy from astroquery.jplhorizons import Horizons # For some the location defaults to Earth @ my input. Not sure if I can get around this or not. Leaving it blank will use the sun as the center which is probably fine obj = Horizons(id='499',location='500@0',epochs={'start':'2020-01-01', 'stop':'2020-01-05','step':'1d'},id_type='majorbody') #eph = obj.ephemerides() vec = obj.vectors() print(obj) print(vec['targetname','datetime_str','x','y']) print(obj.uri) #TableColumns names=('x','y','z','vx','vy','vz') # First I'll need to load that data in from the Output.txt file RawData = np.loadtxt(fname = "/Users/4lius/Documents/C++/NonlinLaunchFinder/Output.txt") dims = np.shape(RawData) print(dims) py.figure(1) plt.plot(RawData[:,0],RawData[:,1]) # Mercury plt.plot(RawData[:,2],RawData[:,3]) # Venus plt.plot(RawData[:,4],RawData[:,5]) # Earth plt.plot(RawData[:,6],RawData[:,7]) # Mars #plt.plot(RawData[:,8],RawData[:,9]) # Jupiter #plt.plot(RawData[:,10],RawData[:,11]) # Saturn
def combine(filenames, obsparam, comoving, targetname, manual_rates, combine_method, keep_files, backsub=False, display=True, diagnostics=True): """ image combination wrapper output: diagnostic properties """ # start logging logging.info('starting image combination with parameters: %s' % (', '.join([('%s: %s' % (var, str(val))) for var, val in list(locals().items())]))) # check if images have been run through pp_prepare try: midtime_jd = fits.open(filenames[0], verify='silentfix', ignore_missing_end=True)[0].header['MIDTIMJD'] except KeyError: raise KeyError(('%s image header incomplete, have the data run ' + 'through pp_prepare?') % filenames[0]) return None # adopt first frame as reference frame hdulist = fits.open(filenames[0]) header = hdulist[0].header refdate = float(header['MIDTIMJD']) # read out ra and dec from header if obsparam['radec_separator'] == 'XXX': ref_ra_deg = float(header[obsparam['ra']]) ref_dec_deg = float(header[obsparam['dec']]) if obsparam['telescope_keyword'] == 'UKIRTWFCAM': ref_ra_deg = ref_ra_deg/24.*360. - 795/3600. ref_dec_deg -= 795/3600. else: ra_string = header[obsparam['ra']].split( obsparam['radec_separator']) dec_string = header[obsparam['dec']].split( obsparam['radec_separator']) ref_ra_deg = 15.*(float(ra_string[0]) + old_div(float(ra_string[1]), 60.) + old_div(float(ra_string[2]), 3600.)) ref_dec_deg = (abs(float(dec_string[0])) + old_div(float(dec_string[1]), 60.) + old_div(float(dec_string[2]), 3600.)) if dec_string[0].find('-') > -1: ref_dec_deg = -1 * ref_dec_deg if obsparam['telescope_keyword'] == 'UKIRTWFCAM': ref_ra_deg = ref_ra_deg/24.*360. if obsparam['telescope_keyword'] == "UKIRTWFCAM": ref_ra_deg -= float(header['TRAOFF'])/3600 ref_dec_deg -= float(header['TDECOFF'])/3600 hdulist.close() # modify individual frames if comoving == True if comoving: movingfilenames = [] # sort filenames by MIDTIMJD mjds = [] for filename in filenames: hdulist = fits.open(filename) mjds.append(float(hdulist[0].header['MIDTIMJD'])) filenames = [filenames[i] for i in numpy.argsort(mjds)] for filename in filenames: movingfilename = filename[:filename.find('.fits')]+'_moving.fits' print('shifting %s -> %s' % (filename, movingfilename)) logging.info('shifting %s -> %s' % (filename, movingfilename)) # read out date and pointing information hdulist = fits.open(filename) header = hdulist[0].header date = hdulist[0].header['MIDTIMJD'] data = hdulist[0].data hdulist.close() # use ephemerides from Horizons if no manual rates are provided if manual_rates is None: # call HORIZONS to get target coordinates obj = Horizons(targetname.replace('_', ' '), epochs=date, location=str(obsparam['observatory_code'])) try: eph = obj.ephemerides() n = len(eph) except ValueError: print('Target (%s) not an asteroid' % targetname) logging.warning('Target (%s) not an asteroid' % targetname) n = None if n is None or n == 0: logging.warning('WARNING: No position from Horizons!' + 'Name (%s) correct?' % targetname) logging.warning('HORIZONS call: %s' % eph.url) raise(ValueError, 'no Horizons ephemerides available') else: logging.info('ephemerides for %s pulled from Horizons' % targetname) logging.info('Horizons call: %s' % obj.uri) target_ra, target_dec = eph[0]['RA'], eph[0]['DEC'] # get image pointing from header if obsparam['radec_separator'] == 'XXX': ra_deg = float(header[obsparam['ra']]) dec_deg = float(header[obsparam['dec']]) if obsparam['telescope_keyword'] == 'UKIRTWFCAM': ra_deg = ra_deg/24.*360. - 795/3600. dec_deg -= 795/3600. else: ra_string = header[obsparam['ra']].split( obsparam['radec_separator']) dec_string = header[obsparam['dec']].split( obsparam['radec_separator']) ra_deg = 15.*(float(ra_string[0]) + old_div(float(ra_string[1]), 60.) + old_div(float(ra_string[2]), 3600.)) dec_deg = (abs(float(dec_string[0])) + old_div(float(dec_string[1]), 60.) + old_div(float(dec_string[2]), 3600.)) if dec_string[0].find('-') > -1: dec_deg = -1 * dec_deg if filename == filenames[0]: ref_offset_ra = target_ra - ref_ra_deg ref_offset_dec = target_dec - ref_dec_deg offset_ra = target_ra - ref_ra_deg - ref_offset_ra offset_dec = target_dec - ref_dec_deg - ref_offset_dec else: # use manual rates (since they are provided) offset_ra = ((float(header['MIDTIMJD'])-refdate)*86400 * float(manual_rates[0]))/3600 offset_dec = ((float(header['MIDTIMJD'])-refdate)*86400 * float(manual_rates[1]))/3600 logging.info('offsets in RA and Dec: %f, %f arcsec' % (offset_ra*3600, offset_dec*3600)) crval1 = float(header['CRVAL1']) crval2 = float(header['CRVAL2']) # write new CRVALi keywords in different file new_hdu = fits.PrimaryHDU(data) new_hdu.header = header new_hdu.header['CRVAL1'] = (crval1-offset_ra, 'updated in the moving frame of the object') new_hdu.header['CRVAL2'] = (crval2-offset_dec, 'updated in the moving frame of the object') movingfilenames.append(movingfilename) new_hdu.writeto(movingfilename, overwrite=True, output_verify='silentfix') if comoving: outfile_name = 'comove.fits' fileline = " ".join(movingfilenames) n_frames = len(movingfilenames) else: outfile_name = 'skycoadd.fits' fileline = " ".join(filenames) n_frames = len(filenames) # run swarp on all image catalogs using different catalogs commandline = (('swarp -combine Y -combine_type %s -delete_tmpfiles ' + 'Y -imageout_name %s -interpolate Y -subtract_back %s ' + '-weight_type NONE -copy_keywords %s -write_xml N ' + '-CENTER_TYPE MOST %s') % ({'median': 'MEDIAN', 'average': 'AVERAGE', 'clipped': 'CLIPPED -CLIP_AMPFRAC 0.2 -CLIP_SIGMA 0.1 '} [combine_method], outfile_name, {True: 'Y', False: 'N'}[backsub], obsparam['copy_keywords'], fileline)) logging.info('call SWARP as: %s' % commandline) print('running SWARP to combine {:d} frames...'.format(n_frames)) try: swarp = subprocess.Popen(shlex.split(commandline), stdout=DEVNULL, stderr=DEVNULL, close_fds=True) # do not direct stdout to subprocess.PIPE: # for large FITS files, PIPE will clog, stalling # subprocess.Popen except Exception as e: print('SWARP call:', (e)) logging.error('SWARP call:', (e)) return None swarp.wait() print('done!') # remove files that are not needed anymore if not keep_files: if comoving: for filename in movingfilenames: os.remove(filename) # update combined image header total_exptime = 0 for filename in filenames: hdulist = fits.open(filename) total_exptime += float(hdulist[0].header[obsparam['exptime']]) hdulist = fits.open(outfile_name, mode='update') hdulist[0].header[obsparam['exptime']] = (total_exptime, 'PP: cumulative') hdulist[0].header['COMBO_N'] = (len(filenames), 'PP: N files combo') hdulist[0].header['COMBO_M'] = (combine_method, 'PP: combo method') hdulist[0].header['COMOVE'] = (str(comoving), 'PP: comoving?') hdulist.flush() return n_frames
] locationConstant = 1.5e11 velocityConstant = 1731460 if __name__ == "__main__": sim_start_date = "2021-01-01" time = Time(sim_start_date).jd bodies = [] for bodySpec in bodiesSpec: obj = Horizons(id=bodySpec["id"], location="@sun", epochs=time, id_type='id').vectors() bodies.append( body(location=point(np.double(obj['x'] * locationConstant), np.double(obj['y'] * locationConstant), np.double(obj['z'] * locationConstant)), mass=bodySpec["mass"], velocity=point(np.double(obj['vx'] * velocityConstant), np.double(obj['vy'] * velocityConstant), np.double(obj['vz'] * velocityConstant)), name=bodySpec["name"], color=(random.random(), random.random(), random.random()))) print(prettyDistance(bodies)) matrice = matriceDistance(bodies)