def running_difference(mc, offset=1, use_offset_for_meta='mean', image_normalize=True): """ Calculate the running difference of a mapcube. Parameters ---------- mc : sunpy.map.MapCube A sunpy mapcube object offset : [ int ] Calculate the running difference between map 'i + offset' and image 'i'. use_offset_for_meta : {'ahead', 'behind', 'mean'} Which meta header to use in layer 'i' in the returned mapcube, either from map 'i + offset' (when set to 'ahead') and image 'i' (when set to 'behind'). When set to 'mean', the ahead meta object is copied, with the observation date replaced with the mean of the ahead and behind observation dates. image_normalize : bool If true, return the mapcube with the same image normalization applied to all maps in the mapcube. Returns ------- sunpy.map.MapCube A mapcube containing the running difference of the input mapcube. The value normalization function used in plotting the data is changed, prettifying movies of resultant mapcube. """ # Create a list containing the data for the new map object new_mc = [] for i in range(0, len(mc.maps) - offset): new_data = mc[i + offset].data - mc[i].data if use_offset_for_meta == 'ahead': new_meta = mc[i + offset].meta plot_settings = mc[i + offset].plot_settings elif use_offset_for_meta == 'behind': new_meta = mc[i].meta plot_settings = mc[i].plot_settings elif use_offset_for_meta == 'mean': new_meta = deepcopy(mc[i + offset].meta) new_meta['date_obs'] = _mean_time([parse_time(mc[i + offset].date), parse_time(mc[i].date)]) plot_settings = mc[i + offset].plot_settings else: raise ValueError('The value of the keyword "use_offset_for_meta" has not been recognized.') # Update the plot scaling. The default here attempts to produce decent # looking images new_map = Map(new_data, new_meta) new_map.plot_settings = plot_settings new_mc.append(new_map) # Create the new mapcube and return if image_normalize: return movie_normalization(Map(new_mc, cube=True), stretch=LinearStretch()) else: return Map(new_mc, cube=True)
def test_split_series_using_lytaf(): '''test the downloading of the LYTAF file and subsequent queries''' tmp_dir = tempfile.mkdtemp() lyra.download_lytaf_database(lytaf_dir=tmp_dir) assert os.path.exists(os.path.join(tmp_dir, 'annotation_ppt.db')) # test split_series_using_lytaf # construct a dummy signal for testing purposes basetime = parse_time('2010-06-13 02:00') seconds = 3600 dummy_time = [basetime + TimeDelta(s*u.second) for s in range(seconds)] dummy_data = np.random.random(seconds) lytaf_tmp = lyra.get_lytaf_events('2010-06-13 02:00', '2010-06-13 06:00', lytaf_path=tmp_dir, combine_files=["ppt"]) split = lyra.split_series_using_lytaf(dummy_time, dummy_data, lytaf_tmp) assert type(split) == list assert len(split) == 4 assert is_time_equal(split[0]['subtimes'][0], parse_time((2010, 6, 13, 2, 0))) assert is_time_equal(split[0]['subtimes'][-1], parse_time((2010, 6, 13, 2, 7, 2))) assert is_time_equal(split[3]['subtimes'][0], parse_time((2010, 6, 13, 2, 59, 42))) assert is_time_equal(split[3]['subtimes'][-1], parse_time((2010, 6, 13, 2, 59, 58))) # Test case when no LYTAF events found in time series. split_no_lytaf = lyra.split_series_using_lytaf(dummy_time, dummy_data, LYTAF_TEST) assert type(split_no_lytaf) == list assert type(split_no_lytaf[0]) == dict assert not set(split_no_lytaf[0].keys()).symmetric_difference({'subtimes', 'subdata'}) assert split_no_lytaf[0]["subtimes"] == dummy_time assert split_no_lytaf[0]["subdata"].all() == dummy_data.all()
def test_detector_angles(): # set a test date date = parse_time('2012-02-15') file = fermi.download_weekly_pointing_file(date) det = fermi.get_detector_sun_angles_for_date(date, file) assert len(det) == 13 assert_almost_equal(det['n0'][0].value, 21.73944, decimal=1) assert_almost_equal(det['n1'][0].value, 30.62983, decimal=1) assert_almost_equal(det['n2'][0].value, 74.67486, decimal=1) assert_almost_equal(det['n3'][0].value, 30.46062, decimal=1) assert_almost_equal(det['n4'][0].value, 73.89734, decimal=1) assert_almost_equal(det['n5'][0].value, 58.99893, decimal=1) assert_almost_equal(det['n6'][0].value, 47.31091, decimal=1) assert_almost_equal(det['n7'][0].value, 70.63391, decimal=1) assert_almost_equal(det['n8'][0].value, 106.30992, decimal=1) assert_almost_equal(det['n9'][0].value, 70.07033, decimal=1) assert_almost_equal(det['n10'][0].value, 106.97884, decimal=1) assert_almost_equal(det['n11'][0].value, 121.09603, decimal=1) det2 = fermi.get_detector_sun_angles_for_time( parse_time('2012-02-15 02:00'), file) assert len(det2) == 13 assert type(det2) == dict assert_almost_equal(det2['n0'].value, 83.76092, decimal=1) assert_almost_equal(det2['n1'].value, 66.65847, decimal=1) assert_almost_equal(det2['n10'].value, 123.28952, decimal=1) assert_almost_equal(det2['n11'].value, 170.69869, decimal=1) assert_almost_equal(det2['n2'].value, 58.78532, decimal=1) assert_almost_equal(det2['n3'].value, 66.69068, decimal=1) assert_almost_equal(det2['n4'].value, 57.16402, decimal=1) assert_almost_equal(det2['n5'].value, 9.04924, decimal=1) assert_almost_equal(det2['n6'].value, 112.21230, decimal=1) assert_almost_equal(det2['n7'].value, 127.35783, decimal=1) assert_almost_equal(det2['n8'].value, 122.98894, decimal=1) assert_almost_equal(det2['n9'].value, 126.95987, decimal=1)
def __init__(self, start, end, near=None): self.start = parse_time(start) self.end = parse_time(end) self.near = None if near is None else parse_time(near) _Range.__init__(self, self.start, self.end, self.__class__) Attr.__init__(self)
def julian_day(t='now'): """Returns the (fractional) Julian day defined as the number of days between the queried day and the reference date of 12:00 (noon) Jan 1, 4713 BC.""" # Good online reference for fractional julian day # http://www.stevegs.com/jd_calc/jd_calc.htm JULIAN_REF_DAY = parse_time('1900/1/1 12:00:00') time = parse_time(t) tdiff = time - JULIAN_REF_DAY julian = tdiff.days + JULIAN_DAY_ON_NOON01JAN1900 result = julian + 1 / 24. * (time.hour + time.minute / 60.0 + time.second / (60. * 60.)) # This is because the days in datetime objects start at 00:00, # not 12:00 as for Julian days. if time.hour >= 12: result = result - 0.5 else: result = result + 0.5 return result
def from_range(cls, from_, to, **kwargs): url = cls._get_url_for_date_range(parse_time(from_), parse_time(to)) filepath = cls._download( url, kwargs, err = "Unable to download data for specified date range" ) return cls.from_file(filepath)
def test_lytaf_utils(): '''test the downloading of the LYTAF file and subsequent queries''' tmp_dir=tempfile.mkdtemp() lyra.download_lytaf_database(lytaf_dir=tmp_dir) assert os.path.exists(os.path.join(tmp_dir,'annotation_ppt.db')) #try doing a query on the temporary database lar=lyra.get_lytaf_events(TimeRange('2010-06-13 02:00','2010-06-13 06:00'),lytaf_dir=tmp_dir) assert type(lar) == list assert type(lar[0]) == dict assert type(lar[0]['start_time']) == datetime.datetime assert type(lar[0]['end_time']) == datetime.datetime assert type(lar[0]['roi_description']) == str assert type(lar[0]['event_type_description']) == str assert lar[0]['start_time'] == parse_time('2010-06-13 02:07:04') assert lar[0]['end_time'] == parse_time('2010-06-13 02:10:04') assert lar[0]['event_type_description'] == 'LAR' #test split_series_using_lytaf #construct a dummy signal for testing purposes basetime=parse_time('2010-06-13 02:00') seconds=3600 dummy_time = [basetime + datetime.timedelta(0, s) for s in range(seconds)] dummy_data=np.random.random(seconds) split=lyra.split_series_using_lytaf(dummy_time, dummy_data, lar) assert type(split) == list assert len(split) == 4 assert split[0]['subtimes'][0] == datetime.datetime(2010, 6, 13, 2, 0) assert split[0]['subtimes'][-1] == datetime.datetime(2010, 6, 13, 2, 7, 2) assert split[3]['subtimes'][0] == datetime.datetime(2010, 6, 13, 2, 59, 41) assert split[3]['subtimes'][-1] == datetime.datetime(2010, 6, 13, 2, 59, 58)
def _get_url_for_date_range(*args): """Returns a URL to the GOES data for the specified date. Parameters ---------- args : `~sunpy.time.TimeRange`, `datetime.datetime`, str Date range should be specified using a TimeRange, or start and end dates at datetime instances or date strings. satellite_number : int GOES satellite number (default = 15) data_type : str Data type to return for the particular GOES satellite. Supported types depend on the satellite number specified. (default = xrs_2s) """ # TimeRange if len(args) == 1 and isinstance(args[0], TimeRange): start = args[0].start end = args[0].end elif len(args) == 2: start = parse_time(args[0]) end = parse_time(args[1]) if end < start: raise ValueError('start time > end time') # find out which satellite and datatype to query from the query times sat_num = GOESLightCurve._get_goes_sat_num(start, end) base_url = 'http://umbra.nascom.nasa.gov/goes/fits/' if start < parse_time('1999/01/15'): url = base_url + "{date:%Y}/go{sat:02d}{date:%y%m%d}.fits".format( date=start, sat=sat_num[0]) else: url = base_url + "{date:%Y}/go{sat:02d}{date:%Y%m%d}.fits".format( date=start, sat=sat_num[0]) return url
def __init__(self, a, b=None, julian_date=False): """Creates a new TimeRange instance""" from sunpy.time import parse_time # if already a timeRange object just return it #if isinstance(a, TimeRange): # return a # Normalize different input types if b is None: x = a[0] y = a[1] else: x = a y = b # Start time self.t1 = parse_time(x) # End date if isinstance(y, str): self.t2 = parse_time(y) # Timedelta if isinstance(y, timedelta): self.t2 = self.t1 + y # Seconds offset if isinstance(y, (float, int)): if julian_date: self.t2 = parse_time(y) else: self.t2 = self.t1 + timedelta(0, y) self.dt = self.t2 - self.t1
def test_query(mock_search): qr1 = LCClient.search( Time('2012/8/9', '2012/8/10'), Instrument('noaa-indices')) assert isinstance(qr1, QueryResponse) assert len(qr1) == 1 assert qr1.time_range().start == parse_time('2012/08/09') assert qr1.time_range().end == parse_time('2012/08/10')
def from_range(cls, instrument, start, end, **kwargs): """ Automatically download data from instrument between start and end and join it together. Parameters ---------- instrument : str instrument to retrieve the data from start : parse_time compatible start of the measurement end : parse_time compatible end of the measurement """ kw = { 'maxgap': 1, 'fill': cls.JOIN_REPEAT, } kw.update(kwargs) start = parse_time(start) end = parse_time(end) urls = query(start, end, [instrument]) data = map(cls.from_url, urls) freq_buckets = defaultdict(list) for elem in data: freq_buckets[tuple(elem.freq_axis)].append(elem) try: return cls.combine_frequencies( [cls.join_many(elem, **kw) for elem in freq_buckets.itervalues()] ) except ValueError: raise ValueError("No data found.")
def test_parse_time_int_float(): # int and float values are not unique # The format has to be mentioned with pytest.raises(ValueError): parse_time(100) with pytest.raises(ValueError): parse_time(100.0)
def date(self): """Image observation time""" time = parse_time(self.meta.get('date-obs', 'now')) if time is None: warnings.warn_explicit("Missing metadata for observation time. Using current time.", Warning, __file__, inspect.currentframe().f_back.f_lineno) return parse_time(time)
def get_times_from_start(mc, start_date=None): # Get the times of the images if start_date is None: start_time = parse_time(mc[0].date) else: start_time = parse_time(start_date) return np.asarray([(parse_time(m.date) - start_time).seconds for m in mc]) * u.s
def __init__(self, a, b=None): """Creates a new TimeRange instance""" # If a is a TimeRange object, copy attributes to new instance. if isinstance(a, TimeRange): self.__dict__ = a.__dict__.copy() return # Normalize different input types if b is None: x = a[0] y = a[1] else: x = a y = b # Start time self.t1 = parse_time(x) # End date if isinstance(y, str): self.t2 = parse_time(y) # Datetime if isinstance(y, datetime): self.t2 = y # Timedelta if isinstance(y, timedelta): self.t2 = self.t1 + y # Seconds offset if isinstance(y, (float, int)): self.t2 = self.t1 + timedelta(0, y) self.dt = self.t2 - self.t1
def from_range(cls, start, end, **kwargs): """Called by Conditional Dispatch object when start and end time are passed as input to create method.""" url = cls._get_url_for_date_range(parse_time(start), parse_time(end), **kwargs) filepath = cls._download(url, kwargs, err="Unable to download data for specified date range") result = cls.from_file(filepath) result.data = result.data.truncate(start, end) return result
def test_parse_time_ISO(): assert parse_time('1966-02-03') == LANDING assert ( parse_time('1966-02-03T20:17:40') == datetime(1966, 2, 3, 20, 17, 40) ) assert ( parse_time('19660203T201740') == datetime(1966, 2, 3, 20, 17, 40) ) lst = [ ('2007-05-04T21:08:12.999999', datetime(2007, 5, 4, 21, 8, 12, 999999)), ('20070504T210812.999999', datetime(2007, 5, 4, 21, 8, 12, 999999)), ('2007/05/04 21:08:12.999999', datetime(2007, 5, 4, 21, 8, 12, 999999)), ('2007-05-04 21:08:12.999999', datetime(2007, 5, 4, 21, 8, 12, 999999)), ('2007/05/04 21:08:12', datetime(2007, 5, 4, 21, 8, 12)), ('2007-05-04 21:08:12', datetime(2007, 5, 4, 21, 8, 12)), ('2007-05-04 21:08', datetime(2007, 5, 4, 21, 8)), ('2007-05-04T21:08:12', datetime(2007, 5, 4, 21, 8, 12)), ('20070504T210812', datetime(2007, 5, 4, 21, 8, 12)), ('2007-May-04 21:08:12', datetime(2007, 5, 4, 21, 8, 12)), ('2007-May-04 21:08', datetime(2007, 5, 4, 21, 8)), ('2007-May-04', datetime(2007, 5, 4)), ('2007-05-04', datetime(2007, 5, 4)), ('2007/05/04', datetime(2007, 5, 4)), ('04-May-2007', datetime(2007, 5, 4)), ('20070504_210812', datetime(2007, 5, 4, 21, 8, 12)) ] for k, v in lst: assert parse_time(k) == v
def test_parse_observing_summary_dbase_file(): """ Test that we get the observing summary dbase file with the content we expect. """ obssum = rhessi.parse_observing_summary_dbase_file(get_test_filepath("hsi_obssumm_filedb_201104.txt")) assert obssum['filename'][0][0:20] == 'hsi_obssumm_20110401' assert obssum['filename'][1][0:20] == 'hsi_obssumm_20110402' assert obssum['orb_st'][0] == 0 assert obssum['orb_st'][-1] == 0 assert obssum['orb_end'][0] == 0 assert obssum['orb_end'][-1] == 0 assert obssum['start_time'][0] == parse_time((2011, 4, 1, 0, 0, 0)) assert obssum['start_time'][-1] == parse_time((2011, 4, 30, 0, 0, 0)) assert obssum['end_time'][0] == parse_time((2011, 4, 2, 0, 0, 0)) assert obssum['end_time'][-1] == parse_time((2011, 5, 1, 0, 0, 0)) assert obssum['status_flag'][0] == 0 assert obssum['status_flag'][-1] == 0 assert obssum['npackets'][0] == 0 assert obssum['npackets'][-1] == 0
def test_payload_protocol(): start = parse_time('2012/1/1T00:00:00') end = parse_time('2012/1/1T00:00:45') payload = client._make_query_payload( start, end, 'hmi.M_42s', protocol='as-is') payload_expected = { 'ds': '{0}[{1}-{2}]'.format('hmi.M_42s', start.strftime("%Y.%m.%d_%H:%M:%S_TAI"), end.strftime("%Y.%m.%d_%H:%M:%S_TAI")), 'format': 'json', 'method': 'url', 'notify': '', 'op': 'exp_request', 'process': 'n=0|no_op', 'protocol': 'as-is', 'requestor': 'none', 'filenamefmt': '{0}.{{T_REC:A}}.{{CAMERA}}.{{segment}}'.format('hmi.M_42s') } assert payload == payload_expected
def test_parse_observing_summary_dbase_file_mock(): """ Ensure that all required data are extracted from the RHESSI observing summary database file mocked in `hessi_data()` """ # We need to mock this test differently for <= 3.7.0 and below. if LooseVersion(platform.python_version()) <= LooseVersion("3.7.0"): mock_file = mock.mock_open() mock_file.return_value.__iter__.return_value = hessi_data().splitlines() else: mock_file = mock.mock_open(read_data=hessi_data()) dbase_data = {} with mock.patch('sunpy.instr.rhessi.open', mock_file, create=True): dbase_data = rhessi.parse_observing_summary_dbase_file(None) assert len(dbase_data.keys()) == 7 # verify each of the 7 fields assert dbase_data['filename'] == ['hsi_obssumm_19721101_139.fit', 'hsi_obssumm_19721102_144.fit'] assert dbase_data['orb_st'] == [7, 9] assert dbase_data['orb_end'] == [8, 10] assert dbase_data['start_time'] == [parse_time((1972, 11, 1, 0, 0)), parse_time((1972, 11, 2, 0, 0))] assert dbase_data['end_time'] == [parse_time((1972, 11, 2, 0, 0)), parse_time((1972, 11, 3, 0, 0))] assert dbase_data['status_flag'] == [3, 4] assert dbase_data['npackets'] == [2, 1]
def time_from_file_name(f, fits_level=1.0): if fits_level == 1.0: start = 14 year = f[start:start+4] month = f[start+5:start+7] day = f[start+8:start+10] hour = f[start+11:start+13] minute = f[start+14:start+16] second = f[start+17:start+19] time = '{:s}-{:s}-{:s} {:s}:{:s}:{:s}'.format(year, month, day, hour, minute, second) try: return parse_time(time) except ValueError: if fits_level == 1.0: start = 17 year = f[start:start+4] month = f[start+5:start+7] day = f[start+8:start+10] hour = f[start+11:start+13] minute = f[start+13:start+15] second = f[start+15:start+17] time = '{:s}-{:s}-{:s} {:s}:{:s}:{:s}'.format(year, month, day, hour, minute, second) return parse_time(time)
def test_detector_angles(): #set a test date date = parse_time('2012-02-15') file = fermi.download_weekly_pointing_file(date) det=fermi.get_detector_sun_angles_for_date(date,file) assert len(det) == 13 #assert type(det) == collections.OrderedDict assert_almost_equal(det['n0'][0].value, 20.30309,decimal=1) assert_almost_equal(det['n1'][0].value, 30.30430, decimal=1) assert_almost_equal(det['n2'][0].value, 74.86032, decimal=1) assert_almost_equal(det['n3'][0].value, 31.24400, decimal=1) assert_almost_equal(det['n4'][0].value, 75.10403, decimal=1) assert_almost_equal(det['n5'][0].value, 60.40967, decimal=1) assert_almost_equal(det['n6'][0].value, 46.14087, decimal=1) assert_almost_equal(det['n7'][0].value, 69.71780, decimal=1) assert_almost_equal(det['n8'][0].value, 106.08064, decimal=1) assert_almost_equal(det['n9'][0].value, 68.543067, decimal=1) assert_almost_equal(det['n10'][0].value, 105.76825, decimal=1) assert_almost_equal(det['n11'][0].value, 119.69057, decimal=1) det2=fermi.get_detector_sun_angles_for_time(parse_time('2012-02-15 02:00'),file) assert len(det2) == 13 assert type(det2) == dict assert_almost_equal(det2['n0'].value, 87.24744,decimal=1) assert_almost_equal(det2['n1'].value, 69.90883,decimal=1) assert_almost_equal(det2['n10'].value, 123.56429,decimal=1) assert_almost_equal(det2['n11'].value, 167.26615,decimal=1) assert_almost_equal(det2['n2'].value, 59.82642,decimal=1) assert_almost_equal(det2['n3'].value, 69.18959,decimal=1) assert_almost_equal(det2['n4'].value, 56.83158,decimal=1) assert_almost_equal(det2['n5'].value, 12.49959,decimal=1) assert_almost_equal(det2['n6'].value, 115.31259,decimal=1) assert_almost_equal(det2['n7'].value, 129.49283,decimal=1) assert_almost_equal(det2['n8'].value, 121.91083,decimal=1) assert_almost_equal(det2['n9'].value, 130.04144,decimal=1)
def test_unified_response(): start = parse_time("2012/1/1") end = parse_time("2012/1/2") qr = Fido.search(a.Instrument('EVE'), a.Level(0), a.Time(start, end)) assert qr.file_num == 2 strings = ['eve', 'SDO', start.strftime(TIMEFORMAT), end.strftime(TIMEFORMAT)] assert all(s in qr._repr_html_() for s in strings)
def testFilesRange_sameDirectory_months_remote(): pattern = ('http://www.srl.caltech.edu/{spacecraft}/DATA/{instrument}/' 'Ahead/1minute/AeH%y%b.1m') s = Scraper(pattern, spacecraft='STEREO', instrument='HET') startdate = parse_time((2007, 8, 1)) enddate = parse_time((2007, 9, 10)) timerange = TimeRange(startdate, enddate) assert len(s.filelist(timerange)) == 2
def test_query(mock_get_observing_summary_dbase_file, mock_parse_observing_summary_dbase_file, mock_get_base_url): qr1 = LCClient.search(a.Time('2003-11-01', '2003-11-03'), a.Instrument('rhessi')) assert isinstance(qr1, QueryResponse) assert len(qr1) == 3 assert qr1.time_range().start == parse_time('2003/11/01') assert qr1.time_range().end == parse_time('2003/11/03T23:59:59.999')
def test_HEE_creation(): # Smoke test to make sure HEE constructors work fine _ = HeliographicStonyhurst(lon=0*u.deg, lat=90*u.deg, obstime=parse_time('2018-12-21')) _ = HeliographicStonyhurst(lon=0*u.deg, lat=90*u.deg, radius=1*u.km, obstime=parse_time('2018-12-21')) _ = HeliographicStonyhurst(x=1*u.km, y=1*u.km, z=1*u.km, obstime=parse_time('2018-12-21'), representation_type='cartesian')
def test_parse_time_leap_second(): dt1 = parse_time('1995-12-31 23:59:60') dt2 = Time('1995-12-31T23:59:60') assert dt1.jd == dt2.jd dt3 = parse_time('1995-Dec-31 23:59:60') assert dt2.jd == dt3.jd
def from_range(cls, start, end, **kwargs): url = cls._get_url_for_date_range(parse_time(start), parse_time(end)) filepath = cls._download( url, kwargs, err = "Unable to download data for specified date range" ) result = cls.from_file(filepath) result.data = result.data.ix[result.data.index.indexer_between_time(start, end)] return result
def test_reprs(): map_ = {} map_['Time_start'] = parse_time("2012/1/1") map_['Time_end'] = parse_time("2012/1/2") resp = QueryResponse.create(map_, ['']) assert isinstance(resp, QueryResponse) strs = ["2012-01-01 00:00:00", "2012-01-02 00:00:00"] assert all(s in str(resp) for s in strs) assert all(s in repr(resp) for s in strs)
def download_weekly_pointing_file(date): """ Downloads the FERMI/LAT weekly pointing file corresponding to the specified date. This file contains 1 minute cadence data on the spacecraft pointing, useful for calculating detector angles. Parameters ---------- date : `datetime.datetime` A datetime object or other date format understood by the parse_time function. """ date = parse_time(date) # use a temp directory to hold the file tmp_dir = tempfile.mkdtemp() # use Fermi data server to access weekly LAT pointing file. base_url = 'ftp://legacy.gsfc.nasa.gov/FTP/glast/data/lat/weekly/spacecraft/' fbasename = 'lat_spacecraft_weekly_w' # find out which file to get based on date # earliest full file in the FERMI server is for mission week 10, # beginning 2008 August 7. weekly_file_start = parse_time('2008-08-07') base_week = 10 # find out which mission week corresponds to date time_diff = date - weekly_file_start weekdiff = time_diff.days // 7 week = weekdiff + base_week # weekstr = ('%03.0f' % week) weekstr = '{:03.0f}'.format(week) # construct the full url for the weekly pointing file full_fname = fbasename + weekstr + '_p202_v001.fits' pointing_file_url = base_url + full_fname # try to download the file from the FTP site try: resp = urllib.request.urlopen(pointing_file_url) exists = True except: urllib.error.HTTPError exists = False # if no matches at all were found, then the pointing file doesn't exist if not exists: raise ValueError('No Fermi pointing files found for given date!') # download the file destination = os.path.join(tmp_dir, full_fname) urllib.request.urlretrieve(pointing_file_url, destination) # return the location of the downloaded file return destination
def test_date_aia(aia171_test_map): assert aia171_test_map.date == parse_time('2011-02-15T00:00:00.34')
#t_end ='2018-Dec-06' #t_start ='2018-Dec-03' #t_end ='2018-Dec-06' #orbit all outputdirectory='results/plots_wind_psp_sta_april2020_1' animdirectory='results/movie_wind_psp_sta_april2020_1' t_start ='2018-Oct-01' t_end ='2019-Dec-28' #Time resolution res_in_days=1/24. #1hour =1/24 #make time range time_array = [ parse_time(t_start).datetime + timedelta(hours=1*n) \ for n in range(int ((parse_time(t_end).datetime - parse_time(t_start).datetime).days*24))] k_all=np.size(time_array) days_window=3 #size of in situ timerange if os.path.isdir(outputdirectory) == False: os.mkdir(outputdirectory) if os.path.isdir(animdirectory) == False: os.mkdir(animdirectory) positions_plot_directory='results/plots_positions/' if os.path.isdir(positions_plot_directory) == False: os.mkdir(positions_plot_directory)
def test_roi_times_str(): region = roi(times='2012-06-20 05:00') expected_time = parse_time((2012, 6, 20, 5, 0)) assert (region.start_time == expected_time) assert (region.end_time == expected_time)
def test_roi_times_list_two_elements(): region = roi(times=['2012-06-20 05:00', '2012-06-20 07:00']) expected_start_time = parse_time((2012, 6, 20, 5, 0)) expected_end_time = parse_time((2012, 6, 20, 7, 0)) assert (region.start_time == expected_start_time) assert (is_time_equal(region.end_time, expected_end_time)) # A float comparison error
def get_horizons_coord(body, time='now', id_type=None, *, 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 : `None`, `str` See the astroquery documentation for information on id_types: `astroquery.jplhorizons`. If the installed astroquery version is less than 0.4.4, defaults to ``'majorbody'``. 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`. include_velocity : `bool`, optional 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') # 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] ... """ # Import here so that astroquery is not a module-level dependency import astroquery from astroquery.jplhorizons import Horizons if id_type is None and version.parse( astroquery.__version__) < version.parse('0.4.4'): # For older versions of astroquery retain default behaviour of this function # if id_type isn't manually specified. id_type = 'majorbody' 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 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 diffrot_map(smap, time=None, dt=None, pad=False, **diffrot_kwargs): """ Function to apply solar differential rotation to a sunpy map. Parameters ---------- smap : `~sunpy.map` Original map that we want to transform. time : sunpy-compatible time date/time at which the input co-ordinate will be rotated to. dt : `~astropy.units.Quantity` or `datetime` Desired interval between the input map and returned map. pad : `bool` Whether to create a padded map for submaps to don't loose data Returns ------- diffrot_map : `~sunpy.map` A map with the result of applying solar differential rotation to the input map. """ if (time is not None) and (dt is not None): raise ValueError('Only a time or an interval is accepted') elif not (time or dt): raise ValueError( 'Either a time or an interval (`dt=`) needs to be provided') elif time: new_time = parse_time(time) dt = (new_time - smap.date).total_seconds() * u.s else: new_time = smap.date + datetime.timedelta(seconds=dt.to(u.s).value) # Check for masked maps if smap.mask is not None: smap_data = np.ma.array(smap.data, mask=smap.mask) else: smap_data = smap.data submap = False # Check whether the input is a submap if ((2 * smap.rsun_obs > smap.top_right_coord.Tx - smap.bottom_left_coord.Tx) or (2 * smap.rsun_obs > smap.top_right_coord.Ty - smap.bottom_left_coord.Ty)): submap = True if pad: # Calculating the largest distance between the corners and their rotation values deltax = deltay = 0 for corner in product(*product([0 * u.pix], smap.dimensions)): corner_world = smap.pixel_to_world(*corner) corner_world_rotated = solar_rotate_coordinate( corner_world, new_time, **diffrot_kwargs) corner_px_rotated = smap.world_to_pixel(corner_world_rotated) dx = np.abs(corner_px_rotated.x - corner[0]) dy = np.abs(corner_px_rotated.y - corner[1]) deltax = dx if dx > deltax else deltax deltay = dy if dy > deltay else deltay deltax = np.int(np.ceil(deltax.value)) deltay = np.int(np.ceil(deltay.value)) # Create a new `smap` with the padding around it smap_data = np.pad(smap.data, ((deltay, deltay), (deltax, deltax)), 'constant', constant_values=0) smap_meta = deepcopy(smap.meta) smap_meta['naxis2'], smap_meta['naxis1'] = smap_data.shape smap_meta['crpix1'] += deltax smap_meta['crpix2'] += deltay smap = sunpy.map.Map(smap_data, smap_meta) warp_args = {'smap': smap, 'dt': dt} warp_args.update(diffrot_kwargs) # Apply solar differential rotation as a scikit-image warp out = transform.warp(to_norm(smap_data), inverse_map=_warp_sun_coordinates, map_args=warp_args) # Recover the original intensity range. out = un_norm(out, smap.data) # Update the meta information with the new date and time, and reference pixel. out_meta = deepcopy(smap.meta) if out_meta.get('date_obs', False): del out_meta['date_obs'] out_meta['date-obs'] = "{:%Y-%m-%dT%H:%M:%S}".format(new_time) if submap: crval_rotated = solar_rotate_coordinate(smap.reference_coordinate, new_time, **diffrot_kwargs) out_meta['crval1'] = crval_rotated.Tx.value out_meta['crval2'] = crval_rotated.Ty.value return sunpy.map.Map((out, out_meta))
def testExtractDates_notSeparators(): s = Scraper('data/%Y/%m/swap%m%d_%H%M%S') testURL = 'data/2014/05/swap0514_200135' timeURL = parse_time((2014, 5, 14, 20, 1, 35)) assert s._extractDateURL(testURL) == timeURL
def test_download_weekly_pointing_file(): # set a test date date = parse_time('2011-10-01') afile = fermi.download_weekly_pointing_file(date) assert isinstance(afile, str) assert afile.endswith('.fits')
def test_met_to_utc(): time = fermi.met_to_utc(500000000) assert (time - parse_time('2016-11-05T00:53:16.000')) < 1e-7 * u.s
def get_detector_sun_angles_for_date(date, file): """ Get the GBM detector angles vs the Sun as a function of time for a given date. Parameters ---------- date : {parse_time_types} A date specified as a parse_time-compatible time string, number, or a datetime object. file : `str` A filepath to a Fermi/LAT weekly pointing file (e.g. as obtained by the download_weekly_pointing_file function). Returns ------- `tuple`: A tuple of all the detector angles. """ date = parse_time(date) tran = TimeRange(date, date + TimeDelta(1 * u.day)) scx, scz, times = get_scx_scz_in_timerange(tran, file) # retrieve the detector angle information in spacecraft coordinates detectors = nai_detector_angles() detector_to_sun_angles = [] # get the detector vs Sun angles for each t and store in a list of # dictionaries. for i in range(len(scx)): detector_radecs = nai_detector_radecs(detectors, scx[i], scz[i], times[i]) # this gets the sun position with RA in hours in decimal format # (e.g. 4.3). DEC is already in degrees sunpos_ra_not_in_deg = [ sun.apparent_rightascension(times[i]), sun.apparent_declination(times[i]) ] # now Sun position with RA in degrees sun_pos = [sunpos_ra_not_in_deg[0].to('deg'), sunpos_ra_not_in_deg[1]] # now get the angle between each detector and the Sun detector_to_sun_angles.append( get_detector_separation_angles(detector_radecs, sun_pos)) # slice the list of dictionaries to get the angles for each detector in a # list form angles = OrderedDict() key_list = [ 'n0', 'n1', 'n2', 'n3', 'n4', 'n5', 'n6', 'n7', 'n8', 'n9', 'n10', 'n11', 'time' ] for i in range(13): if not key_list[i] == 'time': angles[key_list[i]] = [ item[key_list[i]].value for item in detector_to_sun_angles ] * u.deg else: angles[key_list[i]] = [ item[key_list[i]] for item in detector_to_sun_angles ] return angles
def download_weekly_pointing_file(date): """ Downloads the FERMI/LAT weekly pointing file corresponding to the specified date. This file contains 1 minute cadence data on the spacecraft pointing, useful for calculating detector angles. Parameters ---------- date : {parse_time_types} A date specified as a parse_time-compatible time string, number, or a datetime object. Returns ------- `str`: The filepath to the downloaded file. """ date = parse_time(date) # use a temp directory to hold the file tmp_dir = tempfile.mkdtemp() # use Fermi data server to access weekly LAT pointing file. base_url = 'https://heasarc.gsfc.nasa.gov/FTP/fermi/data/lat/weekly/spacecraft/' fbasename = 'lat_spacecraft_weekly_w' # find out which file to get based on date # earliest full file in the FERMI server is for mission week 10, # beginning 2008 August 7. weekly_file_start = parse_time('2008-08-07') base_week = 10 # find out which mission week corresponds to date time_diff = date - weekly_file_start weekdiff = time_diff.to(u.day).value // 7 week = weekdiff + base_week # weekstr = ('%03.0f' % week) weekstr = f'{week:03.0f}' # construct the full url for the weekly pointing file full_fname = fbasename + weekstr + '_p202_v001.fits' pointing_file_url = base_url + full_fname # try to download the file try: urllib.request.urlopen(pointing_file_url) exists = True except urllib.error.HTTPError: exists = False # if no matches at all were found, then the pointing file doesn't exist if not exists: raise ValueError('No Fermi pointing files found for given date!') # download the file destination = os.path.join(tmp_dir, full_fname) urllib.request.urlretrieve(pointing_file_url, destination) # return the location of the downloaded file return destination
def __getitem__(self, idx): # sampling with probability from SIDC print("Sampling from SIDC...") row = self.sidc_csv.sample(weights=self.sidc_csv[4]) day = '/'.join(map(str, row.iloc[0][:-1])) date = datetime.strptime(day + ' 12:00:00', '%Y/%m/%d %H:%M:%S') # loading sunspot data from DPD print("Loading sunspot data...", date) dpd = self.fenyi_sunspot.query(("year == @date.year & " "month == @date.month & " "day == @date.day")) dpd = dpd[(dpd[['projected_umbra', 'projected_whole_spot']].T != 0).any()] time = datetime.strptime( '-'.join([str(i) for i in list(dpd.iloc[0])[1:7]]), '%Y-%m-%d-%H-%M-%S') start_time = (time - timedelta(minutes=30)).strftime('%Y-%m-%dT%H:%M:%S') end_time = (time + timedelta(minutes=30)).strftime('%Y-%m-%dT%H:%M:%S') try: print("Searching VSO...") continuum_file, magnetic_file = None, None continuum_file, magnetic_file = search_VSO(start_time, end_time) hmi_cont = Map(continuum_file) hmi_mag = Map(magnetic_file) except Exception as e: print(e) remove_if_exists(continuum_file) remove_if_exists(magnetic_file) return self.__getitem__(idx) # get the data from the maps img_cont = normalize_map(hmi_cont) img_mag = 2 * normalize_map(hmi_mag) - 1 inputs = np.array([img_cont, img_mag]) # get the coordinates and the date of the sunspots from DPD print("Creating mask...") ss_coord = dpd[['heliographic_latitude', 'heliographic_longitude']] ss_date = parse_time(time) sunspots = rotate_coord(hmi_cont, ss_coord, ss_date) # mask = (255 * img_cont).astype(np.uint8) mask = np.zeros(img_cont.shape, dtype=np.float32) ws = dpd[['projected_whole_spot', 'group_number', 'group_spot_number']] for index, row in ws.iterrows(): wsa = row['projected_whole_spot'] if wsa < 0: match = ws.query(("group_number == @row.group_number & " "group_spot_number == -@wsa")) area = match['projected_whole_spot'].iloc[0] ws.loc[row.name, 'projected_whole_spot'] = area groups = list(ws['group_number'].unique()) disk_mask = np.where(255 * img_cont > 10) disk_mask = {(c[0], c[1]) for c in np.column_stack(disk_mask)} disk_mask_num_px = len(disk_mask) whole_spot_mask = set() for i in range(len(sunspots)): o = 4 # offset p = sunspots[i] # g_number = groups.index(ws.iloc[i]['group_number']) group = img_cont[int(p[1]) - o:int(p[1]) + o, int(p[0]) - o:int(p[0]) + o] low = np.where(group == np.amin(group)) center = (img_cont.shape[0] / 2, img_cont.shape[1] / 2) distance = np.linalg.norm(tuple(j - k for j, k in zip(center, p))) cosine_amplifier = math.cos(math.radians(1) * distance / center[0]) norm_num_px = cosine_amplifier * ws.iloc[i]['projected_whole_spot'] ss_num_px = 8.6 * norm_num_px * disk_mask_num_px / 10e6 new = set([(p[1] - o + low[1][0], p[0] - o + low[0][0])]) whole_spot = set() candidates = set() expansion_rate = 3 while len(whole_spot) < ss_num_px: expand = {(n[0] + i, n[1] + j) for i in [-1, 0, 1] for j in [-1, 0, 1] for n in new} for e in set(expand - whole_spot): candidates.add(e) new = heapq.nsmallest(expansion_rate, candidates, key=lambda k: img_cont[k]) for n in new: candidates.remove(n) whole_spot.update(set(new)) whole_spot_mask.update(whole_spot) for c in set.intersection(whole_spot_mask, disk_mask): mask[c] = 1 # show_mask(img_cont, mask) remove_if_exists(continuum_file) remove_if_exists(magnetic_file) return {"img": inputs.astype(np.float32), "mask": mask}
import pandas import pytest import astropy.units as u from astropy.time import TimeDelta from sunpy import timeseries from sunpy.data.test import rootdir from sunpy.instr import lyra from sunpy.time import is_time_equal, parse_time # Define location for test LYTAF database files TEST_DATA_PATH = rootdir # Define some test data for test_remove_lytaf_events() TIME = parse_time(np.array([datetime.datetime(2013, 2, 1) + datetime.timedelta(minutes=i) for i in range(120)])) CHANNELS = [np.zeros(len(TIME)) + 0.4, np.zeros(len(TIME)) + 0.1] EMPTY_LYTAF = np.empty((0,), dtype=[("insertion_time", object), ("begin_time", object), ("reference_time", object), ("end_time", object), ("event_type", object), ("event_definition", object)]) LYTAF_TEST = np.append( EMPTY_LYTAF, np.array([(parse_time(datetime.datetime.utcfromtimestamp(1371459961)), parse_time(datetime.datetime.utcfromtimestamp(1359677220)), parse_time(datetime.datetime.utcfromtimestamp(1359677250)), parse_time(datetime.datetime.utcfromtimestamp(1359677400)), "LAR", "Large Angle Rotation.")], dtype=EMPTY_LYTAF.dtype))
def testDirectoryObsPattern(): s = Scraper('%y%m%d/{observatory}_%Y%m%d.fits', observatory='SDO') testpath = '140305/SDO_20140305.fits' d = parse_time((2014, 3, 5)) assert s.matches(testpath, d)
def testDirectoryDatePatternFalse(): s = Scraper('%Y/%m/%d/%Y%m%d_%H%M%S_59.fit.gz') testpath = '2013/03/05/20140305_013000_59.fit.gz' d = parse_time((2014, 3, 5, 1, 30)) assert not s.matches(testpath, d)
def peek(self, title="GOES Xray Flux"): """Plots GOES XRS light curve is the usual manner. An example is shown below. .. plot:: import sunpy.timeseries import sunpy.data.sample ts_goes = sunpy.timeseries.TimeSeries(sunpy.data.sample.GOES_XRS_TIMESERIES, source='XRS') ts_goes.peek() Parameters ---------- title : `str` The title of the plot. **kwargs : `dict` Any additional plot arguments that should be used when plotting. """ # noqa # Check we have a timeseries valid for plotting self._validate_data_for_ploting() figure = plt.figure() axes = plt.gca() dates = matplotlib.dates.date2num(parse_time(self.data.index).datetime) axes.plot_date(dates, self.data['xrsa'], '-', label=r'0.5--4.0 $\AA$', color='blue', lw=2) axes.plot_date(dates, self.data['xrsb'], '-', label=r'1.0--8.0 $\AA$', color='red', lw=2) axes.set_yscale("log") axes.set_ylim(1e-9, 1e-2) axes.set_title(title) axes.set_ylabel('Watts m$^{-2}$') axes.set_xlabel(datetime.datetime.isoformat(self.data.index[0])[0:10]) ax2 = axes.twinx() ax2.set_yscale("log") ax2.set_ylim(1e-9, 1e-2) ax2.set_yticks((1e-9, 1e-8, 1e-7, 1e-6, 1e-5, 1e-4, 1e-3, 1e-2)) ax2.set_yticklabels((' ', 'A', 'B', 'C', 'M', 'X', ' ')) axes.yaxis.grid(True, 'major') axes.xaxis.grid(False, 'major') axes.legend() # @todo: display better tick labels for date range (e.g. 06/01 - 06/05) formatter = matplotlib.dates.DateFormatter('%H:%M') axes.xaxis.set_major_formatter(formatter) axes.fmt_xdata = matplotlib.dates.DateFormatter('%H:%M') figure.autofmt_xdate() figure.show()
def solar_rotate_coordinate(coordinate, new_observer_time, new_observer_location="earth", **diff_rot_kwargs): """ Given a coordinate on the Sun, calculate where that coordinate maps to at some later or earlier time, given the solar rotation profile. Note that if the new observer location is defined using a BaseCoordinateFrame or SkyCoord, then it is assumed that the new observer location is correct for the new observer time that was also passed in. Parameters ---------- coordinate : `~astropy.coordinates.SkyCoord` Any valid coordinate which is transformable to Heliographic Stonyhurst. new_observer_time : sunpy-compatible time date/time at which the input co-ordinate will be rotated to. new_observer_location : `str`, `~astropy.coordinates.BaseCoordinateFrame`, `~astropy.coordinates.SkyCoord` The solar-system body for which to calculate observer locations. Note that spacecraft are not explicitly supported as yet. Instruments in Earth orbit can be approximated by using the default setting. If a BaseCoordinateFrame or SkyCoord are passed in, it is assumed that this observer location is correct for the observer time that was also passed in. **diff_rot_kwargs : keyword arguments Keyword arguments are passed on as keyword arguments to `~sunpy.physics.differential_rotation.diff_rot`. Returns ------- coordinate : `~astropy.coordinates.SkyCoord`` The locations of the input coordinates after the application of solar rotation in the input coordinate frame. Examples -------- >>> import astropy.units as u >>> from astropy.coordinates import SkyCoord >>> from sunpy.coordinates import frames >>> from sunpy.physics.differential_rotation import solar_rotate_coordinate >>> from sunpy.coordinates.ephemeris import get_earth >>> obstime = '2010-09-10 12:34:56' >>> c = SkyCoord(-570*u.arcsec, 120*u.arcsec, obstime=obstime, observer=get_earth(obstime), frame=frames.Helioprojective) >>> solar_rotate_coordinate(c, '2010-09-10 13:34:56') # doctest: +FLOAT_CMP <SkyCoord (Helioprojective: obstime=2010-09-10 13:34:56, rsun=695508.0 km, observer=<HeliographicStonyhurst Coordinate (obstime=2010-09-10 13:34:56): (lon, lat, radius) in (deg, deg, AU) ( 0., 7.24822784, 1.00695436)>): (Tx, Ty, distance) in (arcsec, arcsec, km) (-562.37689548, 119.26840368, 1.50083152e+08)> """ # Calculate the interval between the start and end time interval = (parse_time(new_observer_time) - parse_time(coordinate.obstime)).total_seconds() * u.s # Compute Stonyhurst Heliographic co-ordinates - returns (longitude, # latitude). Points off the limb are returned as nan. heliographic_coordinate = coordinate.transform_to( 'heliographic_stonyhurst') # Compute the differential rotation drot = diff_rot(interval, heliographic_coordinate.lat.to(u.degree), **diff_rot_kwargs) # Rotate the input co-ordinate and update the observer heliographic_rotated = SkyCoord(heliographic_coordinate.lon + drot, heliographic_coordinate.lat, obstime=new_observer_time, observer=new_observer_location, frame=frames.HeliographicStonyhurst) # Return the rotated coordinates to the input coordinate frame return heliographic_rotated.transform_to(coordinate.frame.name)
def __init__(self, start, end): self.start = parse_time(start) self.end = parse_time(end) self.inverted = False vso_attrs._Range.__init__(self, start, end, self.__class__)
def get_body_heliographic_stonyhurst(body, time='now', observer=None, *, include_velocity=False): """ Return a `~sunpy.coordinates.frames.HeliographicStonyhurst` frame for the location of a solar-system body at a specified time. The location can be corrected for light travel time to an observer. Parameters ---------- body : `str` The solar-system body for which to calculate positions time : {parse_time_types} Time to use in a parse_time-compatible format observer : `~astropy.coordinates.SkyCoord` If None, the returned coordinate is the instantaneous or "true" location. If not None, the returned coordinate is the astrometric location (i.e., accounts for light travel time to the specified observer) include_velocity : `bool`, optional If True, include the body's velocity in the output coordinate. Defaults to False. Returns ------- out : `~sunpy.coordinates.frames.HeliographicStonyhurst` Location of the solar-system body in the `~sunpy.coordinates.HeliographicStonyhurst` frame Notes ----- There is no correction for aberration due to observer motion. For a body close to the Sun in angular direction relative to the observer, the correction can be negligible because the apparent location of the body will shift in tandem with the Sun. Examples -------- >>> from sunpy.coordinates.ephemeris import get_body_heliographic_stonyhurst Obtain the location of Venus >>> get_body_heliographic_stonyhurst('venus', '2012-06-06 04:07:29') <HeliographicStonyhurst Coordinate (obstime=2012-06-06T04:07:29.000, rsun=695700.0 km): (lon, lat, radius) in (deg, deg, AU) (0.07349535, 0.05223575, 0.72605496)> Obtain the location of Venus as seen from Earth when adjusted for light travel time >>> earth = get_body_heliographic_stonyhurst('earth', '2012-06-06 04:07:29') >>> get_body_heliographic_stonyhurst('venus', '2012-06-06 04:07:29', observer=earth) INFO: Apparent body location accounts for 144.07 seconds of light travel time [sunpy.coordinates.ephemeris] <HeliographicStonyhurst Coordinate (obstime=2012-06-06T04:07:29.000, rsun=695700.0 km): (lon, lat, radius) in (deg, deg, AU) (0.07084926, 0.0520573, 0.72605477)> Obtain the location and velocity of Mars >>> mars = get_body_heliographic_stonyhurst('mars', '2001-02-03', include_velocity=True) >>> mars <HeliographicStonyhurst Coordinate (obstime=2001-02-03T00:00:00.000, rsun=695700.0 km): (lon, lat, radius) in (deg, deg, AU) (63.03105777, -5.20656151, 1.6251161) (d_lon, d_lat, d_radius) in (arcsec / s, arcsec / s, km / s) (-0.02323686, 0.00073376, -1.4798387)> Transform that same location and velocity of Mars to a different frame using `~astropy.coordinates.SkyCoord`. >>> from astropy.coordinates import SkyCoord >>> from sunpy.coordinates import Helioprojective >>> SkyCoord(mars).transform_to(Helioprojective(observer=earth)) <SkyCoord (Helioprojective: obstime=2001-02-03T00:00:00.000, rsun=695700.0 km, observer=<HeliographicStonyhurst Coordinate (obstime=2012-06-06T04:07:29.000, rsun=695700.0 km): (lon, lat, radius) in (deg, deg, AU) (6.2686056e-15, -0.00766698, 1.01475668)>): (Tx, Ty, distance) in (arcsec, arcsec, AU) (-298654.73268523, -21726.6154073, 1.40134156) (d_Tx, d_Ty, d_distance) in (arcsec / s, arcsec / s, km / s) (-0.01663438, -0.00058027, -15.08908184)> """ obstime = parse_time(time) if observer is None: # If there is no observer, there is not adjustment for light travel time emitted_time = obstime else: observer_icrs = SkyCoord(observer).icrs.cartesian # This implementation is modeled after Astropy's `_get_apparent_body_position` light_travel_time = 0. * u.s emitted_time = obstime delta_light_travel_time = 1. * u.s # placeholder value while np.any(np.fabs(delta_light_travel_time) > 1.0e-8 * u.s): body_icrs = get_body_barycentric(body, emitted_time) distance = (body_icrs - observer_icrs).norm() delta_light_travel_time = light_travel_time - distance / speed_of_light light_travel_time = distance / speed_of_light emitted_time = obstime - light_travel_time if light_travel_time.isscalar: ltt_string = f"{light_travel_time.to_value('s'):.2f}" else: ltt_string = f"{light_travel_time.to_value('s')}" log.info( f"Apparent body location accounts for {ltt_string} seconds of light travel time" ) if include_velocity: pos, vel = get_body_barycentric_posvel(body, emitted_time) body_icrs = pos.with_differentials( vel.represent_as(CartesianDifferential)) else: body_icrs = get_body_barycentric(body, emitted_time) body_hgs = ICRS(body_icrs).transform_to( HeliographicStonyhurst(obstime=obstime)) return body_hgs
def test_attrs_time(): times = a.Time("2020/10/01T00:00", "2020/10/01T00:00") times.start == parse_time("2020/10/01T00:00") times.end == parse_time("2020/10/01T00:00")
def testNoDirectory(): s = Scraper('files/%Y%m%d_%H%M.dat') startdate = parse_time((2010, 1, 10, 20, 30)) enddate = parse_time((2010, 1, 20, 20, 30)) timerange = TimeRange(startdate, enddate) assert len(s.range(timerange)) == 1
def _get_new_observer(initial_obstime, observer, time): """ Helper function that interprets the possible ways of specifying the input to the solar coordinate rotation function. If the "observer" argument is not `None`, it is used to specify the location of the new observer in space and time. If the "time" argument is not `None`, it is used to calculate the duration over which to the amount of solar rotation is calculated. Note that using the "time" keyword assumes that the new observer is on the Earth. This may be a reasonable assumption depending on the application. Either the "observer" or "time" argument must be specified, but both cannot be specified at the same time and both cannot be None. Parameters ---------- initial_obstime : `~astropy.time.Time` The initial time before solar rotation has been applied. observer : `~astropy.coordinates.BaseCoordinateFrame`, `~astropy.coordinates.SkyCoord`, None The location of the new observer in space and time (the observer must have an interpretable obstime property). time : `~astropy.time.Time`, `~astropy.time.TimeDelta`, `~astropy.units.Quantity`, None Used to define the duration over which the amount of solar rotation is calculated. If 'time' is an `~astropy.time.Time` then the time interval is "time - initial_obstime"; if 'time' is `~astropy.time.TimeDelta` or `~astropy.units.Quantity` then the calculation is "initial_obstime + time". Returns ------- new_observer : `~astropy.coordinates.SkyCoord`, `~astropy.coordinates.BaseCoordinateFrame` The position of the observer in space and time. If the "time" keyword is used the output is an `~astropy.coordinates.SkyCoord`. If the "observer" keyword is not None the output has the same type as the "observer" keyword. In all cases the output is specified in the heliographic Stonyhurst coordinate system. """ # Check the input and create the new observer if (observer is not None) and (time is not None): raise ValueError( "Either the 'observer' or the 'time' keyword must be specified, but not both simultaneously." ) elif observer is not None: # Check that the new_observer is specified correctly. if not (isinstance(observer, (BaseCoordinateFrame, SkyCoord))): raise ValueError( "The 'observer' must be an astropy.coordinates.BaseCoordinateFrame or an astropy.coordinates.SkyCoord." ) if observer.obstime is None: raise ValueError( "The observer 'obstime' property must not be None.") new_observer = observer elif time is not None: warnings.warn("Using 'time' assumes an Earth-based observer.") if isinstance(time, TimeDelta) or isinstance(time, u.Quantity): new_observer_time = initial_obstime + time else: new_observer_time = parse_time(time) new_observer = get_body("earth", new_observer_time) else: raise ValueError( "Either the 'observer' or the 'time' keyword must not be None.") return new_observer
def test_roi_times_list_one_element(): region = roi(times=['2012-06-20 05:00']) expected_time = parse_time((2012, 6, 20, 5, 0)) assert (region.start_time == expected_time) assert (region.end_time == expected_time)
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: # 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']}") 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 _warp_sun_coordinates(xy, smap, new_observer, **diff_rot_kwargs): """ This function takes pixel coordinates in the warped image (`xy`) and calculates the pixel locations of those pixels in the map. To do this it converts the input pixel coordinates to helioprojective coordinates as seen by new_observer, then transforms them to heliographic Stonyhurst, adds the differential rotation correction and then transforms them back to helioprojective coordinates as seen by the map observer and then calculates their corresponding pixel coordinates in the input map. This is an inverse function needed by `skimage.transform.warp`. Parameters ---------- xy : `numpy.ndarray` Pixel coordinates in the warped image. smap : `~sunpy.map.GenericMap` Original map that we want to transform. Returns ------- xy2 : `numpy.ndarray` Pixel coordinates in the map corresponding to the input pixels in the warped image. """ # Suppress NaN warnings in coordinate transforms with warnings.catch_warnings(): warnings.simplefilter('ignore') # The time interval between the new observer time and the map observation time. interval = (parse_time(new_observer.obstime) - parse_time(smap.date)).to(u.s) # We need to get the input pixel coordinates into the OUTPUT HPC frame. # To save us having to construct a WCS etc, we do the transformation # using the output map, and then replace the observer in place before # transforming to HGS. This is acceptable because the pixel -> world # transformation is independent of the observer. input_pixels = xy.T * u.pix map_coord = smap.pixel_to_world(*input_pixels) output_hpc_coords = SkyCoord(map_coord.Tx, map_coord.Ty, map_coord.distance, obstime=new_observer.obstime, observer=new_observer, frame=Helioprojective) heliographic_coordinate = output_hpc_coords.transform_to( HeliographicStonyhurst) # Now transform the HGS coordinates to the obstime of the input map (to account for movement of Earth) heliographic_coordinate = heliographic_coordinate.transform_to( HeliographicStonyhurst(obstime=smap.date)) # Compute the differential rotation. drot = diff_rot(interval, heliographic_coordinate.lat.to(u.degree), **diff_rot_kwargs) # The change in longitude is negative because we are mapping from the # new coordinates to the old. rotated_coord = SkyCoord(heliographic_coordinate.lon - drot, heliographic_coordinate.lat, heliographic_coordinate.radius, obstime=heliographic_coordinate.obstime, frame=HeliographicStonyhurst) # As seen from the map observer, which coordinates are on disk and which are behind the Sun. where_off_disk_from_map_observer = rotated_coord.transform_to( Heliocentric(observer=smap.observer_coordinate)).z.value < 0 # Re-project the pixels which are on disk back to location of the original observer coordinates_at_map_observer = rotated_coord.transform_to( smap.coordinate_frame) # Go back to pixel co-ordinates x2, y2 = smap.world_to_pixel(coordinates_at_map_observer) # Re-stack the data to make it correct output form xy2 = np.dstack([x2.T.value.flat, y2.T.value.flat])[0] # Set the off disk coordinates to NaN so they are not included in the output image. xy2[where_off_disk_from_map_observer.flat] = np.nan return xy2
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)
# equator: area = 0.0 for i, response in enumerate(responses): if response['area_atdiskcenter'] > area and np.abs( response['hgc_y']) < 60.0: area = response['area_atdiskcenter'] response_index = i ############################################################################## # Now let's get the boundary of the coronal hole ch = responses[response_index] p1 = ch["hpc_boundcc"][9:-2] p2 = p1.split(',') p3 = [v.split(" ") for v in p2] ch_boundary = np.asarray([(eval(v[0]), eval(v[1])) for v in p3]) ch_date = parse_time(ch['event_starttime']) ############################################################################## # The coronal hole was detected at a certain time. To plot it on a map, we # need to rotate it to the map observation time. rotated_boundary = np.zeros_like(ch_boundary) n = ch_boundary.shape[0] for i in range(0, n): new_coords = rot_hpc(ch_boundary[i, 0] * u.arcsec, ch_boundary[i, 1] * u.arcsec, ch_date, aia_map.date) rotated_boundary[i, 0] = new_coords[0].value rotated_boundary[i, 1] = new_coords[1].value ############################################################################## # Now let's plot the rotated coronal hole boundary on the AIA map, and fill # it with some matplotlib hatching.
def testDirectoryRange_single(): s = Scraper('%Y%m%d/%H_%M.csv') startdate = parse_time((2010, 10, 10, 5, 0)) enddate = parse_time((2010, 10, 10, 7, 0)) timerange = TimeRange(startdate, enddate) assert len(s.range(timerange)) == 1
def plot(self, gamma=None, annotate=True, axes=None, **imshow_args): """ Plots the map object using matplotlib, in a method equivalent to plt.imshow() using nearest neighbour interpolation. Parameters ---------- gamma : float Gamma value to use for the color map annotate : bool If true, the data is plotted at it's natural scale; with title and axis labels. axes: matplotlib.axes object or None If provided the image will be plotted on the given axes. Else the current matplotlib axes will be used. **imshow_args : dict Any additional imshow arguments that should be used when plotting the image. Examples -------- #Simple Plot with color bar plt.figure() aiamap.plot() plt.colorbar() #Add a limb line and grid aia.plot() aia.draw_limb() aia.draw_grid() """ #Get current axes if not axes: axes = plt.gca() # Normal plot if annotate: axes.set_title("%s %s" % (self.name, parse_time( self.date).strftime("%Y-%m-%d %H:%M:%S.%f"))) # x-axis label if self.coordinate_system['x'] == 'HG': xlabel = 'Longitude [%s]' % self.units['x'] else: xlabel = 'X-position [%s]' % self.units['x'] # y-axis label if self.coordinate_system['y'] == 'HG': ylabel = 'Latitude [%s]' % self.units['y'] else: ylabel = 'Y-position [%s]' % self.units['y'] axes.set_xlabel(xlabel) axes.set_ylabel(ylabel) # Determine extent extent = self.xrange + self.yrange cmap = deepcopy(self.cmap) if gamma is not None: cmap.set_gamma(gamma) #make imshow kwargs a dict kwargs = { 'origin': 'lower', 'cmap': cmap, 'norm': self.mpl_color_normalizer, 'extent': extent, 'interpolation': 'nearest' } kwargs.update(imshow_args) ret = axes.imshow(self.data, **kwargs) #Set current image (makes colorbar work) plt.sci(ret) return ret
results = Fido.search(tr, a.Instrument.xrs & a.goes.SatelliteNumber(15) | a.hek.FL & (a.hek.FRM.Name == 'SWPC')) # NOQA ############################################################################### # Then download the XRS data and load it into a TimeSeries. files = Fido.fetch(results) goes = TimeSeries(files) ############################################################################### # Next let's retrieve `~sunpy.net.hek.HEKTable` from the Fido result # and then load the first row from HEK results into ``flares_hek``. hek_results = results['hek'] flares_hek = hek_results[0] ############################################################################### # Lets plot everything together. plt.figure() goes.plot() plt.axvline(parse_time(flares_hek['event_peaktime']).datetime) plt.axvspan(parse_time(flares_hek['event_starttime']).datetime, parse_time(flares_hek['event_endtime']).datetime, alpha=0.2, label=flares_hek['fl_goescls']) plt.legend(loc=2) plt.yscale('log') plt.show()