Get SPoCA results from the ROB EPN-TAP service

SPoCA

The [web interface](https://vo-tap.oma.be/rob_spoca_ch/q/spoca_ch_dr/form) allows to do some simple search on the time of detection of the Coronal Hole. For a programming interface, it is recommended to use the [TAP protocol](https://vo-tap.oma.be/tap). Below we give some examples on how to achieve this in Python using the [PyVO library](https://pyvo.readthedocs.io/en/latest/). ### Example 1 : Find the size of 10 random coronal holes ``` from pyvo.dal import tap TAP_SERVICE_URL = 'https://vo-tap.oma.be/tap' query = 'SELECT TOP 10 * FROM rob_spoca_ch.epn_core' results = tap.search(TAP_SERVICE_URL, query) # Print the number of results returned print(len(results)) # Print the size of the CH in arcsec² for result in results: print(result['ch_area_projected']) ``` ### Example 2: Find coronal holes between 2 dates ``` from pyvo.dal import tap from astropy.time import Time TAP_SERVICE_URL = 'https://vo-tap.oma.be/tap' # The columns time_min and time_max are in Julian days, so we must convert the dates start_date = Time('2020-01-01 00:00:00Z') end_date = Time('2020-01-01 12:00:00Z') query = 'SELECT time_min FROM rob_spoca_ch.epn_core WHERE time_min >= %s AND time_max < %s' % (start_date.to_value('jd'), end_date.to_value('jd')) results = tap.search(TAP_SERVICE_URL, query) # Print the time of detection of the CH # In TAP, times are are specified in Julian Day, so convert it to datetime for result in results: print(Time(result['time_min'], format='jd').datetime) ``` ### Example 3: Find the Carrington longitude of the centroid of a specific coronal hole through time ``` from pyvo.dal import tap from astropy.time import Time from astropy import units as u from sunpy.coordinates import HeliographicStonyhurst, Helioprojective, frames TAP_SERVICE_URL = 'https://vo-tap.oma.be/tap' # Find all the detections for the Coronal hole with granule_gid 3770 query = "SELECT * from rob_spoca_ch.epn_core WHERE granule_gid = 'spoca_coronalhole_3770' ORDER BY time_min" results = tap.search(TAP_SERVICE_URL, query) # In TAP, the coordinates of the centroid are specified in Helioprojective # so convert them to Heliographic coordinates for result in results: obstime = Time(result["time_min"], format="jd").to_datetime() observer = HeliographicStonyhurst( result["subobserver_longitude_min"] * u.deg, result["subobserver_latitude_min"] * u.deg, result["target_distance_min"] * u.km, obstime=obstime, ) centroid_in_helioprojective = Helioprojective( result['ch_c1_centroid'] * u.deg, result['ch_c2_centroid'] * u.deg, observer=observer, ) centroid_in_heliographic = centroid_in_helioprojective.transform_to( frames.HeliographicCarrington(obstime=obstime, observer='earth') ) print(centroid_in_heliographic.lon.deg) ``` ### Example 4: Plot a a specific coronal hole through time The ROB SPoCA Coronal Hole Maps contains all the Coronal Holes (CH) detected, to isolate a specific one, the number in the granule_uid of the CH corrersponds to the value of the pixels of that CH in the map. For example the CH with granule_uid "spoca_coronalhole_3770" have pixels value 3770. ``` from pyvo.dal import tap from sunpy.map import Map from matplotlib import pyplot, colors TAP_SERVICE_URL = 'https://vo-tap.oma.be/tap' # Find all the detections for the Coronal hole with granule_gid 3770 query = "SELECT * from rob_spoca_ch.epn_core WHERE granule_gid = 'spoca_coronalhole_3770' ORDER BY time_min" results = tap.search(TAP_SERVICE_URL, query) color_map = colors.LinearSegmentedColormap.from_list('SPoCA', ['black', 'orange']) figure = pyplot.figure(figsize=(6 * len(results), 6), dpi=150, constrained_layout=True) for i, result in enumerate(results, start=1): # SPoCA CH maps can be easily opened and analyzed using SunPy maps ch_map = Map(result['access_url']) # Erase all other CH from the map by setting their pixel values to 0 ( 0 is the value of background pixels ) ch_map.data[ch_map.data != 3770] = 0 axes = figure.add_subplot(1, len(results), i, projection=ch_map) ch_map.plot(axes=axes, cmap=color_map, title=ch_map.date.strftime("%Y-%m-%d %H:%M:%S")) ch_map.draw_limb(axes=axes, color='white') figure.savefig("/tmp/spoca_coronalhole_3770.png") ``` Note that in the figure below we have limited the results to 5 for conciseness
Image representing 5 white circles corresponding to the limb of the sun, and inside each an orange patch corresponding to the coronal hole shape