def areaint(lats, lons): assert lats.size == lons.size, 'List of latitudes and longitudes are different sizes.' if isinstance(lats.iloc[0], u.Quantity): lat = np.array([lat.value for lat in lats] + [lats.iloc[0].value]) * u.deg lon = np.array([lon.value for lon in lons] + [lons.iloc[0].value]) * u.deg else: lat = np.append(lats, lats.iloc[0]) * u.deg lon = np.append(lons, lons.iloc[0]) * u.deg if lat.max() > 0: northern = True # Get colatitude (a measure of surface distance as an angle) and # azimuth of each point in segment from the center of mass. _, center_lat, center_lon = sph_center_of_mass(lat[:-1], lon[:-1]) if np.isnan(center_lat.value): center_lat = Latitude(0, unit=u.rad) if np.isnan(center_lon.value): center_lon = Longitude(0, unit=u.rad) # force centroid at the N or S pole # if northern: # center_lat = 90 * u.deg # else: # center_lat = -90 * u.deg # center_lon = 0 * u.deg colat = np.array([ distance(center_lon.to(u.deg), center_lat.to(u.deg), longi, latit).to( u.deg).value for latit, longi in zip(lat, lon) ]) * u.deg az = np.array([ azimuth(center_lon.to(u.deg), center_lat.to(u.deg), longi, latit).to( u.deg).value for latit, longi in zip(lat, lon) ]) * u.deg # Calculate step sizes, taking the complementary angle where needed daz = np.diff(az).to(u.rad) daz[np.where(daz > 180 * u.deg)] -= 360. * u.deg daz[np.where(daz < -180 * u.deg)] += 360. * u.deg # Determine average surface distance for each step deltas = np.diff(colat) / 2. colats = colat[0:-1] + deltas # Integral over azimuth is 1-cos(colatitudes) integrands = (1 - np.cos(colats)) * daz # Integrate and return the answer as a fraction of the unit sphere. # Note that the sum of the integrands will include a part of 4pi. return np.abs( np.nansum(integrands)) / (4 * np.pi * u.rad), center_lat, center_lon
def location(lat, lon, alt): # Reference location lon = Longitude(lon.strip(), u.degree, wrap_angle=180 * u.degree, copy=False) # noqa lat = Latitude(lat.strip(), u.degree, copy=False) height = u.Quantity(float(alt.strip()), u.m, copy=False) ref_location = EarthLocation(lat=lat.to(u.deg).value, lon=lon.to(u.deg).value, height=height.to(u.m).value) # noqa return ref_location
def pixel_to_data(self, x, y, origin=0): """ Convert a pixel coordinate to a data (world) coordinate by using `~astropy.wcs.WCS.wcs_pix2world`. Parameters ---------- x : float Pixel coordinate of the CTYPE1 axis. (Normally solar-x). y : float Pixel coordinate of the CTYPE2 axis. (Normally solar-y). origin : int Origin of the top-left corner. i.e. count from 0 or 1. Normally, origin should be 0 when passing numpy indices, or 1 if passing values from FITS header or map attributes. See `~astropy.wcs.WCS.wcs_pix2world` for more information. Returns ------- x : `~astropy.units.Quantity` Coordinate of the CTYPE1 axis. (Normally solar-x). y : `~astropy.units.Quantity` Coordinate of the CTYPE2 axis. (Normally solar-y). """ x, y = self.wcs.wcs_pix2world(x, y, origin) # If the wcs is celestial it is output in degress if self.wcs.is_celestial: x *= u.deg y *= u.deg else: x *= self.units.x y *= self.units.y x = Longitude(x, wrap_angle=180 * u.deg) y = Latitude(y) return x.to(self.units.x), y.to(self.units.y)