def print_params(t='now'): """ Print out a summary of Solar ephemeris. """ # import here to avoid circular import from sunpy.coordinates.ephemeris import (get_sun_L0, get_sun_B0, get_sun_P, get_sunearth_distance) print('Solar Ephemeris for {}\n'.format(parse_time(t).ctime())) print('Distance = {}'.format(get_sunearth_distance(t))) print('Semidiameter = {}'.format(solar_semidiameter_angular_size(t))) print('True (long, lat) = ({}, {})'.format(true_longitude(t), true_latitude(t))) print('Apparent (long, lat) = ({}, {})'.format(apparent_longitude(t), apparent_latitude(t))) print('True (RA, Dec) = ({}, {})'.format(true_rightascension(t), true_declination(t))) print('Apparent (RA, Dec) = ({}, {})'.format(apparent_rightascension(t), apparent_declination(t))) print('Heliographic long. and lat of disk center = ({}, {})'.format( get_sun_L0(t), get_sun_B0(t))) print('Position angle of north pole in = {}'.format(get_sun_P(t))) print('Carrington Rotation Number = {}'.format( carrington_rotation_number(t)))
def print_params(t='now'): """ Print out a summary of solar ephemeris. 'True' values are true geometric values referred to the mean equinox of date, with no corrections for nutation or aberration. 'Apparent' values are referred to the true equinox of date, with corrections for nutation and aberration (for Earth motion). Parameters ---------- t : {parse_time_types} A time (usually the start time) specified as a parse_time-compatible time string, number, or a datetime object. """ # Import here to avoid circular import from sunpy.coordinates.ephemeris import (get_sun_L0, get_sun_B0, get_sun_P, get_sunearth_distance) print('Solar Ephemeris for {} UTC\n'.format(parse_time(t).utc)) print('Distance = {}'.format(get_sunearth_distance(t))) print('Semidiameter = {}'.format(solar_semidiameter_angular_size(t))) print('True (long, lat) = ({}, {})'.format(true_longitude(t).to_string(), true_latitude(t).to_string())) print('Apparent (long, lat) = ({}, {})'.format(apparent_longitude(t).to_string(), apparent_latitude(t).to_string())) print('True (RA, Dec) = ({}, {})'.format(true_rightascension(t).to_string(), true_declination(t).to_string())) print('Apparent (RA, Dec) = ({}, {})'.format(apparent_rightascension(t).to_string(), apparent_declination(t).to_string())) print('Heliographic long. and lat of disk center = ({}, {})'.format(get_sun_L0(t).to_string(), get_sun_B0(t).to_string())) print('Position angle of north pole = {}'.format(get_sun_P(t))) print('Carrington Rotation Number = {}'.format(carrington_rotation_number(t)))
def print_params(t='now'): """ Print out a summary of Solar ephemeris. Parameters ---------- t : {parse_time_types} A time (usually the start time) specified as a parse_time-compatible time string, number, or a datetime object. """ # import here to avoid circular import from sunpy.coordinates.ephemeris import (get_sun_L0, get_sun_B0, get_sun_P, get_sunearth_distance) print('Solar Ephemeris for {}\n'.format(parse_time(t).ctime())) print('Distance = {}'.format(get_sunearth_distance(t))) print('Semidiameter = {}'.format(solar_semidiameter_angular_size(t))) print('True (long, lat) = ({}, {})'.format(true_longitude(t), true_latitude(t))) print('Apparent (long, lat) = ({}, {})'.format(apparent_longitude(t), apparent_latitude(t))) print('True (RA, Dec) = ({}, {})'.format(true_rightascension(t), true_declination(t))) print('Apparent (RA, Dec) = ({}, {})'.format(apparent_rightascension(t), apparent_declination(t))) print('Heliographic long. and lat of disk center = ({}, {})'.format(get_sun_L0(t), get_sun_B0(t))) print('Position angle of north pole in = {}'.format(get_sun_P(t))) print('Carrington Rotation Number = {}'.format(carrington_rotation_number(t)))
def solar_semidiameter_angular_size(t='now'): """ Return the angular size of the semi-diameter of the Sun as viewed from Earth. Parameters ---------- t : {parse_time_types} A time (usually the start time) specified as a parse_time-compatible time string, number, or a datetime object. """ # Import here to avoid a circular import from sunpy.coordinates import get_sunearth_distance solar_semidiameter_rad = constants.radius / get_sunearth_distance(t) return Angle(solar_semidiameter_rad.to(u.arcsec, equivalencies=u.dimensionless_angles()))
def __init__(self, data, header, **kwargs): super().__init__(data, header, **kwargs) # Fill in some missing info self.meta['observatory'] = 'MLSO' self.meta['detector'] = 'KCor' self.meta['waveunit'] = 'nanometer' # Since KCor is on Earth, no need to raise the warning in mapbase self.meta['dsun_obs'] = (get_sunearth_distance(self.date)).to(u.m).value self.meta['hgln_obs'] = 0.0 self._nickname = self.detector self.plot_settings['cmap'] = plt.get_cmap(self._get_cmap_name()) self.plot_settings['norm'] = ImageNormalize(stretch=source_stretch(self.meta, PowerStretch(0.25))) # Negative value pixels can appear that lead to ugly looking images. # This can be fixed by setting the lower limit of the normalization. self.plot_settings['norm'].vmin = 0.0
def _dsunAtSoho(date, rad_d, rad_1au=None): """Determines the distance to the Sun from SOhO following d_{\sun,Object} = D_{\sun\earth} \frac{\tan(radius_{1au}[rad])}{\tan(radius_{d}[rad])} though tan x ~ x for x << 1 d_{\sun,Object} = D_{\sun\eart} \frac{radius_{1au}[rad]}{radius_{d}[rad]} since radius_{1au} and radius_{d} are dividing each other we can use [arcsec] instead. --- TODO: Does this apply just to observations on the same Earth-Sun line? If not it can be moved outside here. """ if not rad_1au: rad_1au = sun.solar_semidiameter_angular_size(date) dsun = get_sunearth_distance(date) * constants.au * (rad_1au / rad_d) # return scalar value not astropy.quantity return dsun.value
def solar_semidiameter_angular_size(t='now'): r""" Return the angular size of the semi-diameter of the Sun as a function of time as viewed from Earth (in arcsec) .. math:: Radius_{\odot}[rad]=\tan^{-1}\left(\frac{<Radius_{\odot}[m]>}{D_{\odot \oplus}(t)[m]}\right) since :math:`tan(x) \approx x` when :math:`x << 1` .. math:: Radius_{\odot}[rad]=\frac{<Radius_{\odot}[m]>}{D_{\odot \oplus}(t)[m]} """ # Import here to avoid a circular import from sunpy.coordinates import get_sunearth_distance solar_semidiameter_rad = (constants.radius.to(u.AU)) / get_sunearth_distance(t) return Angle(solar_semidiameter_rad.to(u.arcsec, equivalencies=u.dimensionless_angles()))
def __init__(self, data, header, **kwargs): super().__init__(data, header, **kwargs) # Fill in some missing info self.meta['observatory'] = 'MLSO' self.meta['detector'] = 'KCor' self.meta['waveunit'] = 'nanometer' # Since KCor is on Earth, no need to raise the warning in mapbase self.meta['dsun_obs'] = (get_sunearth_distance(self.date)).to( u.m).value self.meta['hgln_obs'] = 0.0 self._nickname = self.detector self.plot_settings['cmap'] = plt.get_cmap(self._get_cmap_name()) self.plot_settings['norm'] = ImageNormalize( stretch=source_stretch(self.meta, PowerStretch(0.25))) # Negative value pixels can appear that lead to ugly looking images. # This can be fixed by setting the lower limit of the normalization. self.plot_settings['norm'].vmin = 0.0
def backprojection(calibrated_event_list, pixel_size=(1., 1.) * u.arcsec, image_dim=(64, 64) * u.pix): """ Given a stacked calibrated event list fits file create a back projection image. .. warning:: The image is not in the right orientation! Parameters ---------- calibrated_event_list : string filename of a RHESSI calibrated event list pixel_size : `~astropy.units.Quantity` instance the size of the pixels in arcseconds. Default is (1,1). image_dim : `~astropy.units.Quantity` instance the size of the output image in number of pixels Returns ------- out : RHESSImap Return a backprojection map. Examples -------- This example is broken. >>> import sunpy.data >>> import sunpy.data.sample # doctest: +SKIP >>> import sunpy.instr.rhessi as rhessi >>> map = rhessi.backprojection(sunpy.data.sample.RHESSI_IMAGE) # doctest: +SKIP >>> map.peek() # doctest: +SKIP """ pixel_size = pixel_size.to(u.arcsec) image_dim = np.array(image_dim.to(u.pix).value, dtype=int) afits = sunpy.io.read_file(calibrated_event_list) info_parameters = afits[2] xyoffset = info_parameters.data.field('USED_XYOFFSET')[0] time_range = TimeRange(info_parameters.data.field('ABSOLUTE_TIME_RANGE')[0]) image = np.zeros(image_dim) # find out what detectors were used det_index_mask = afits[1].data.field('det_index_mask')[0] detector_list = (np.arange(9)+1) * np.array(det_index_mask) for detector in detector_list: if detector > 0: image = image + _backproject(calibrated_event_list, detector=detector, pixel_size=pixel_size.value, image_dim=image_dim) dict_header = { "DATE-OBS": time_range.center.strftime("%Y-%m-%d %H:%M:%S"), "CDELT1": pixel_size[0], "NAXIS1": image_dim[0], "CRVAL1": xyoffset[0], "CRPIX1": image_dim[0]/2 + 0.5, "CUNIT1": "arcsec", "CTYPE1": "HPLN-TAN", "CDELT2": pixel_size[1], "NAXIS2": image_dim[1], "CRVAL2": xyoffset[1], "CRPIX2": image_dim[0]/2 + 0.5, "CUNIT2": "arcsec", "CTYPE2": "HPLT-TAN", "HGLT_OBS": 0, "HGLN_OBS": 0, "RSUN_OBS": solar_semidiameter_angular_size(time_range.center).value, "RSUN_REF": sunpy.sun.constants.radius.value, "DSUN_OBS": get_sunearth_distance(time_range.center).value * sunpy.sun.constants.au.value } result_map = sunpy.map.Map(image, dict_header) return result_map
Adapted from https://github.com/sunpy/sunpy/blob/master/examples/units_and_coordinates/AltAz_Coordinate_transform.py """ from astropy.coordinates import EarthLocation, AltAz, SkyCoord from astropy.time import Time from sunpy.coordinates import frames, get_sunearth_distance import astropy.units as u obstime = "2013-09-21 16:00:00" c = SkyCoord(0 * u.arcsec, 0 * u.arcsec, obstime=obstime, frame=frames.Helioprojective) Fort_Sumner = EarthLocation(lat=34.4900 * u.deg, lon=-104.221800 * u.deg, height=40 * u.km) frame_altaz = AltAz(obstime=Time(obstime), location=Fort_Sumner) sun_altaz = c.transform_to(frame_altaz) print('Altitude is {0} and Azimuth is {1}'.format(sun_altaz.T.alt, sun_altaz.T.az)) distance = get_sunearth_distance(obstime) b = SkyCoord(az=sun_altaz.T.az, alt=sun_altaz.T.alt, distance=distance, frame=frame_altaz) sun_helio = b.transform_to(frames.Helioprojective) print('The helioprojective point is {0}, {1}'.format(sun_helio.T.Tx, sun_helio.T.Ty))
###################################################################################### # We use `~astropy.coordinates.SkyCoord` to define the center of the Sun obstime = "2013-09-21 16:00:00" c = SkyCoord(0 * u.arcsec, 0 * u.arcsec, obstime=obstime, frame=frames.Helioprojective) ###################################################################################### # Now we establish our location on the Earth, in this case Fort Sumner, NM. # We use the balloon's observational altitude as 'height'. Accuracy of 'height' is # far less of a concern than Lon/Lat accuracy. Fort_Sumner = EarthLocation(lat=34.4900*u.deg, lon=-104.221800*u.deg, height=40*u.km) ###################################################################################### # Now lets convert this to a local measurement of Altitude and Azimuth. frame_altaz = AltAz(obstime=Time(obstime), location=Fort_Sumner) sun_altaz = c.transform_to(frame_altaz) print('Altitude is {0} and Azimuth is {1}'.format(sun_altaz.T.alt, sun_altaz.T.az)) ###################################################################################### # Next let's check this calculation by converting it back to helioprojective. # We should get our original input which was the center of the Sun. # To go from Altitude/Azimuth to Helioprojective, you will need the distance to the Sun. # solar distance. Define distance with SunPy's almanac. distance = get_sunearth_distance(obstime) b = SkyCoord(az=sun_altaz.T.az, alt=sun_altaz.T.alt, distance=distance, frame=frame_altaz) sun_helio = b.transform_to(frames.Helioprojective) print('The helioprojective point is {0}, {1}'.format(sun_helio.T.Tx, sun_helio.T.Ty)) ###################################################################################### # The output is within a radius of 0.02 arcseccs.
def backprojection(calibrated_event_list, pixel_size: u.arcsec=(1., 1.) * u.arcsec, image_dim: u.pix=(64, 64) * u.pix): """ Given a stacked calibrated event list fits file create a back projection image. .. warning:: The image is not in the right orientation! Parameters ---------- calibrated_event_list : str filename of a RHESSI calibrated event list pixel_size : `~astropy.units.Quantity` instance the size of the pixels in arcseconds. Default is (1,1). image_dim : `~astropy.units.Quantity` instance the size of the output image in number of pixels Returns ------- out : RHESSImap Return a backprojection map. Examples -------- This example is broken. >>> import sunpy.data >>> import sunpy.data.sample # doctest: +REMOTE_DATA >>> import sunpy.instr.rhessi as rhessi >>> map = rhessi.backprojection(sunpy.data.sample.RHESSI_EVENT_LIST) # doctest: +SKIP >>> map.peek() # doctest: +SKIP """ # import sunpy.map in here so that net and timeseries don't end up importing map import sunpy.map pixel_size = pixel_size.to(u.arcsec) image_dim = np.array(image_dim.to(u.pix).value, dtype=int) afits = sunpy.io.read_file(calibrated_event_list) info_parameters = afits[2] xyoffset = info_parameters.data.field('USED_XYOFFSET')[0] time_range = TimeRange(info_parameters.data.field('ABSOLUTE_TIME_RANGE')[0], format='utime') image = np.zeros(image_dim) # find out what detectors were used det_index_mask = afits[1].data.field('det_index_mask')[0] detector_list = (np.arange(9)+1) * np.array(det_index_mask) for detector in detector_list: if detector > 0: image = image + _backproject(calibrated_event_list, detector=detector, pixel_size=pixel_size.value, image_dim=image_dim) dict_header = { "DATE-OBS": time_range.center.strftime("%Y-%m-%d %H:%M:%S"), "CDELT1": pixel_size[0], "NAXIS1": image_dim[0], "CRVAL1": xyoffset[0], "CRPIX1": image_dim[0]/2 + 0.5, "CUNIT1": "arcsec", "CTYPE1": "HPLN-TAN", "CDELT2": pixel_size[1], "NAXIS2": image_dim[1], "CRVAL2": xyoffset[1], "CRPIX2": image_dim[0]/2 + 0.5, "CUNIT2": "arcsec", "CTYPE2": "HPLT-TAN", "HGLT_OBS": 0, "HGLN_OBS": 0, "RSUN_OBS": solar_semidiameter_angular_size(time_range.center).value, "RSUN_REF": sunpy.sun.constants.radius.value, "DSUN_OBS": get_sunearth_distance(time_range.center).value * sunpy.sun.constants.au.value } result_map = sunpy.map.Map(image, dict_header) return result_map
print('Altitude is {0} and Azimuth is {1}'.format(sun_altaz.T.alt, sun_altaz.T.az)) ############################################################################## # As expected the Sun is below the horizon! Let's consider noon now. noon = Time('2018-11-14 12:00:00') - utcoffset sun_altaz = sun.transform_to(AltAz(obstime=noon, location=dkist)) print('Altitude is {0} and Azimuth is {1}'.format(sun_altaz.T.alt, sun_altaz.T.az)) ############################################################################## # Next let’s check this calculation by converting it back to helioprojective. # We should get our original input which was the center of the Sun. # To go from Altitude/Azimuth to Helioprojective, you will need the distance # to the Sun. solar distance. Define distance with SunPy’s almanac. distance = get_sunearth_distance(noon) b = SkyCoord(az=sun_altaz.T.az, alt=sun_altaz.T.alt, distance=distance, frame=AltAz(obstime=noon, location=dkist)) sun_helioproj = b.transform_to(frames.Helioprojective) print('The helioprojective point is {0}, {1}'.format(sun_helioproj.T.Tx, sun_helioproj.T.Ty)) ############################################################################## # Let's now show off how we can convert between Solar coordinates Coordinates. # Transform to HeliographicStonyhurst sun.transform_to(frames.HeliographicStonyhurst) ############################################################################## # Transform to Heliocentric
def make_sunpy(evtdata, hdr, norm_map=False): """ Make a sunpy map based on the NuSTAR data. Parameters ---------- evtdata: FITS data structure This should be an hdu.data structure from a NuSTAR FITS file. hdr: FITS header containing the astrometric information Optional keywords norm_map: Normalise the map data by the exposure (live) time, so units of DN/s. Defaults to "False" and DN Returns ------- nustar_map: A sunpy map objecct """ from sunpy.coordinates import get_sunearth_distance, get_sun_B0 # Parse Header keywords for field in hdr.keys(): if field.find('TYPE') != -1: if hdr[field] == 'X': print(hdr[field][5:8]) xval = field[5:8] if hdr[field] == 'Y': print(hdr[field][5:8]) yval = field[5:8] min_x= hdr['TLMIN'+xval] min_y= hdr['TLMIN'+yval] max_x= hdr['TLMAX'+xval] max_y= hdr['TLMAX'+yval] delx = abs(hdr['TCDLT'+xval]) dely = abs(hdr['TCDLT'+yval]) x = evtdata['X'][:] y = evtdata['Y'][:] met = evtdata['TIME'][:]*u.s mjdref=hdr['MJDREFI'] mid_obs_time = astropy.time.Time(mjdref*u.d+met.mean(), format = 'mjd') # Add in the exposure time (or livetime), just a number not units of seconds exp_time=hdr['EXPOSURE'] # Use the native binning for now # Assume X and Y are the same size resample = 1.0 scale = delx * resample bins = (max_x - min_x) / (resample) H, yedges, xedges = np.histogram2d(y, x, bins=bins, range = [[min_y,max_y], [min_x, max_x]]) #Normalise the data with the exposure (or live) time? if norm_map is True: H=H/exp_time pixluname='DN/s' else: pixluname='DN' dict_header = { "DATE-OBS": mid_obs_time.iso, "EXPTIME": exp_time, "CDELT1": scale, "NAXIS1": bins, "CRVAL1": 0., "CRPIX1": bins*0.5, "CUNIT1": "arcsec", "CTYPE1": "HPLN-TAN", "CDELT2": scale, "NAXIS2": bins, "CRVAL2": 0., "CRPIX2": bins*0.5 + 0.5, "CUNIT2": "arcsec", "CTYPE2": "HPLT-TAN", "PIXLUNIT": pixluname, "HGLT_OBS": get_sun_B0(mid_obs_time), "HGLN_OBS": 0, "RSUN_OBS": sun.solar_semidiameter_angular_size(mid_obs_time).value, "RSUN_REF": sun.constants.radius.value, # Assumes dsun_obs in m if don't specify the units, so give units "DSUN_OBS": get_sunearth_distance(mid_obs_time).value*u.astrophys.au } # For some reason the DSUN_OBS crashed the save... # header = sunpy.map.MapMeta(dict_header) header = sunpy.util.MetaDict(dict_header) nustar_map = sunpy.map.Map(H, header) return nustar_map