Skip to content

Commit d2521ff

Browse files
D-arioSpaceceb8
authored andcommitted
remote tests
1 parent f8619d3 commit d2521ff

File tree

10 files changed

+264
-242
lines changed

10 files changed

+264
-242
lines changed

astroquery/esa/neocc/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
European Space Agency (ESA)
77
88
Created on 16 Jun. 2021
9-
Last update 02 Nov. 2021
9+
Last update 01 Mar. 2022
1010
1111
"""
1212
import os

astroquery/esa/neocc/core.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
* Property: European Space Agency (ESA)
1010
* Developed by: Elecnor Deimos
1111
* Author: C. Álvaro Arroyo Parejo
12-
* Issue: 1.4.0
13-
* Date: 02-11-2021
12+
* Issue: 2.1.0
13+
* Date: 01-03-2021
1414
* Purpose: Main module which gets NEAs data from https://neo.ssa.esa.int/
1515
* Module: core.py
1616
* History:
@@ -35,10 +35,10 @@
3535
1.4.0 29-10-2021 Adding new docstrings.\n
3636
Change method for obtaining physical
3737
properties
38-
======== =========== ============================================
39-
38+
2.0.0 21-01-2022 Prepare module for Astroquery integration
39+
2.1.0 01-03-2022 Remove *parse* dependency
4040
41-
© Copyright [European Space Agency][2021]
41+
© Copyright [European Space Agency][2022]
4242
All rights reserved
4343
"""
4444

astroquery/esa/neocc/lists.py

Lines changed: 45 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
* Property: European Space Agency (ESA)
88
* Developed by: Elecnor Deimos
99
* Author: C. Álvaro Arroyo Parejo
10-
* Issue: 1.4.0
11-
* Date: 02-11-2021
10+
* Issue: 2.1.0
11+
* Date: 01-03-2021
1212
* Purpose: Module which request and parse list data from ESA NEOCC
1313
* Module: lists.py
1414
* History:
@@ -29,16 +29,19 @@
2929
1.4.0 29-10-2021 Adding Catalogue of NEAS (current date
3030
and middle arc).\n
3131
Update docstrings.
32+
2.0.0 21-01-2022 Prepare module for Astroquery integration
33+
2.1.0 01-03-2022 Remove *parse* dependency
3234
======== =========== ==========================================
3335
34-
© Copyright [European Space Agency][2021]
36+
© Copyright [European Space Agency][2022]
3537
All rights reserved
3638
"""
3739

3840
import io
3941
from datetime import timedelta
42+
from astropy.table import Table
43+
from astropy.time import Time
4044
import pandas as pd
41-
from parse import parse
4245
import requests
4346
from astroquery.esa.neocc import conf
4447

@@ -82,7 +85,7 @@ def get_list_url(list_name):
8285
"priority_list": 'esa_priority_neo_list',
8386
"priority_list_faint": 'esa_faint_neo_list',
8487
"close_encounter" : 'close_encounter2.txt',
85-
"impacted_objects" : 'impactedObjectsList.txt',
88+
"impacted_objects" : 'past_impactors_list',
8689
"neo_catalogue_current" : 'neo_kc.cat',
8790
"neo_catalogue_middle" : 'neo_km.cat'
8891
}
@@ -230,10 +233,11 @@ def parse_risk(data_byte_d):
230233
neocc_lst = neocc_lst.drop(neocc_lst.columns[-1], axis=1)
231234

232235
# Convert column with date to datetime variable
233-
neocc_lst['Date/Time'] = pd.to_datetime(neocc_lst['Date/Time'])
236+
neocc_lst['Date/Time'] = pd.to_datetime(neocc_lst['Date/Time'],
237+
errors='ignore')
234238
# Split Years into 2 columns to avoid dashed between integers
235-
# Check dataframe is not empty (for special list)
236-
if len(neocc_lst.index.values) != 0:
239+
# Check dataframe column length is differnt from 8 (for special risk)
240+
if len(neocc_lst.columns) != 8:
237241
neocc_lst[['First year', 'Last year']] = neocc_lst['Years']\
238242
.str.split("-",
239243
expand=True)\
@@ -467,17 +471,25 @@ def parse_impacted(data_byte_d):
467471
Decoded StringIO object.
468472
Returns
469473
-------
470-
neocc_lst : *pandas.DataFrame*
471-
Data frame with impacted objects list data parsed.
474+
neocc_table : *astropy.table.table.Table*
475+
Astropy table with impacted objects list data parsed.
472476
"""
473-
# Read data as csv
474-
neocc_lst = pd.read_csv(data_byte_d, header=None,
475-
delim_whitespace=True)
476-
477-
# Convert column with date to datetime variable
478-
neocc_lst[1] = pd.to_datetime(neocc_lst[1])
479-
480-
return neocc_lst
477+
# Read data as csv using astropy.table
478+
neocc_table = Table.read(data_byte_d, format='pandas.csv',
479+
delimiter=r'\s+\|\s+|\s+\|',
480+
engine='python', header=1,
481+
dtype={'Object designator': str,
482+
'Diameter in m': str,
483+
'Impact date/time in UTC': str,
484+
'Impact Velocity in km/s': float,
485+
'Estimated energy in Mt': float,
486+
'Measured energy in Mt': float})
487+
neocc_table.remove_column('Unnamed: 6')
488+
# Convert column with date to astropy.time ISO format variable
489+
neocc_table['Impact date/time in UTC'] =\
490+
Time(neocc_table['Impact date/time in UTC'], scale='utc')
491+
492+
return neocc_table
481493

482494

483495
def parse_neo_catalogue(data_byte_d):
@@ -505,29 +517,22 @@ def parse_neo_catalogue(data_byte_d):
505517
data_byte_d.seek(0)
506518
# Read the header
507519
neocc_head = pd.read_fwf(data_byte_d, header=None, nrows=4)
508-
# Template for format data
509-
parse_format = "format = '{format}' ! file format"
510-
# Parse required data for attributes
511-
format_txt = parse(parse_format, neocc_head.iloc[0][0])
512-
neocc_lst.form = format_txt['format']
513-
# Template for record type
514-
parse_rectype = "rectype = '{rectype}' !"\
515-
" record type (1L/ML)"
516-
# Parse required data for attributes
517-
rectype = parse(parse_rectype, neocc_head.iloc[1][0])
518-
neocc_lst.rectype = rectype['rectype']
520+
# Template for format data:
521+
# format = '{format}' ! file format
522+
format_txt = neocc_head.iloc[0][0].split("'")[1].strip()
523+
neocc_lst.form = format_txt
524+
# Template for record type:
525+
# rectype = '{rectype}' ! record type (1L/ML)
526+
rectype = neocc_head.iloc[1][0].split("'")[1].strip()
527+
neocc_lst.rectype = rectype
519528
# Template for type of orbital element
520-
parse_elem = "elem = '{elem}' ! "\
521-
"type of orbital elements"
522-
# Parse required data for attributes
523-
elem = parse(parse_elem, neocc_head.iloc[2][0])
524-
neocc_lst.elem = elem['elem']
529+
# elem = '{elem}' ! type of orbital elements
530+
elem = neocc_head.iloc[2][0].split("'")[1].strip()
531+
neocc_lst.elem = elem
525532
# Template for reference system
526-
parse_refsys = "refsys = {refsys} !"\
527-
" default reference system"
528-
# Parse required data for attributes
529-
refsys = parse(parse_refsys, neocc_head.iloc[3][0])
530-
neocc_lst.refsys = refsys['refsys']
533+
# refsys = {refsys} ! default reference system
534+
refsys = neocc_head.iloc[3][0].split("=")[1].split("!")[0].strip()
535+
neocc_lst.refsys = refsys
531536
neocc_lst.help = ('These catalogues represent the list of '
532537
'Keplerian orbit for each asteroid in the '
533538
'input list at mean epoch and at current epoch.'
@@ -546,3 +551,4 @@ def parse_neo_catalogue(data_byte_d):
546551

547552

548553
return neocc_lst
554+

astroquery/esa/neocc/tabs.py

Lines changed: 59 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010
* Property: European Space Agency (ESA)
1111
* Developed by: Elecnor Deimos
1212
* Author: C. Álvaro Arroyo Parejo
13-
* Issue: 1.4.0
14-
* Date: 02-11-2021
13+
* Issue: 2.1.0
14+
* Date: 01-03-2021
1515
* Purpose: Module which request and parse list data from ESA NEOCC
1616
* Module: tabs.py
1717
* History:
@@ -48,9 +48,10 @@
4848
Orb_type attribute added in tab *orbit_properties*.\n
4949
Bug fix in tab *observations*.\n
5050
Adding redundancy for tab *summary* parsing.
51-
======== =========== =====================================================
51+
2.0.0 21-01-2022 Prepare module for Astroquery integration
52+
2.1.0 01-03-2022 Remove *parse* dependency
5253
53-
© Copyright [European Space Agency][2021]
54+
© Copyright [European Space Agency][2022]
5455
All rights reserved
5556
"""
5657

@@ -60,7 +61,6 @@
6061
import re
6162
from datetime import datetime, timedelta
6263
import pandas as pd
63-
from parse import parse
6464
import requests
6565
from bs4 import BeautifulSoup
6666
from astroquery.esa.neocc import conf
@@ -299,16 +299,21 @@ def _get_footer(data_obj):
299299

300300
# Drop NaN values if necessary
301301
df_txt = df_txt.dropna(how='all')
302-
# Template for observations data
303-
parse_txt_obs = "Based on {total} optical observations "\
304-
"(of which {rejected} are rejected as "\
305-
"outliers)"
306-
# Parse required data for attributes
307-
obs = parse(parse_txt_obs, df_txt.iloc[-7-j][0].split(' and')[0])
308-
# Template for date of observations
309-
parse_txt_arc = 'from {start} to {end}.'
310-
# Parse required data for attributes
311-
arc = parse(parse_txt_arc, df_txt.iloc[-6-j][0])
302+
# Template for observations data:
303+
# Based on {total} optical observations (of which {rejected}
304+
# are rejected as outliers)
305+
obs_total = df_txt.iloc[-7-j][0].split('on ')[1].\
306+
split('optical')[0].strip()
307+
obs_rejected = df_txt.iloc[-7-j][0].split('which ')[1].\
308+
split('are')[0].strip()
309+
obs = [obs_total, obs_rejected]
310+
# Template for date of observations: from {start} to {end}.
311+
arc_start = df_txt.iloc[-6-j][0].split('from ')[1].\
312+
split('to ')[0].strip()
313+
arc_end = df_txt.iloc[-6-j][0].split('to ')[1].\
314+
split('.')[0] + '.' + df_txt.iloc[-6-j][0].\
315+
split('to ')[1].split('.')[1]
316+
arc = [arc_start, arc_end]
312317
# Computation date
313318
comp = df_txt.iloc[-1-j][0].split('=')[2].strip()
314319
# Get information text
@@ -429,18 +434,18 @@ def _impacts_parser(self, data_obj):
429434
footer = self._get_footer(data_obj)
430435
# Assign parsed data to attributes
431436
# Change format to datetime and show in isoformat()
432-
arc_start = footer[1]['start'].split('.')
437+
arc_start = footer[1][0].split('.')
433438
arc_start = datetime.strptime(arc_start[0], '%Y/%m/%d') +\
434439
timedelta(float(arc_start[1])/1e3)
435440
self.arc_start = arc_start.isoformat()
436441
# Change format to datetime and show in isoformat()
437-
arc_end = footer[1]['end'].split('.')
442+
arc_end = footer[1][1].split('.')
438443
arc_end = datetime.strptime(arc_end[0], '%Y/%m/%d') +\
439444
timedelta(float(arc_end[1])/1e3)
440445
self.arc_end = arc_end.isoformat()
441-
self.observation_accepted = int(footer[0]['total']) - \
442-
int(footer[0]['rejected'])
443-
self.observation_rejected = int(footer[0]['rejected'])
446+
self.observation_accepted = int(footer[0][0]) - \
447+
int(footer[0][1])
448+
self.observation_rejected = int(footer[0][1])
444449
self.computation = footer[2]
445450
self.additional_note = footer[4]
446451
# Assign info text from pandas
@@ -614,7 +619,6 @@ def _phys_prop_parser(self, data_obj):
614619
# Initialize index
615620
index = 0
616621
if len(df_check.columns) > 4:
617-
# rest = len(df_check.columns) - 4
618622
# Iterate over each element in last col to find
619623
# rows with additional elements separated by commas
620624
for element in df_check.iloc[:, -1]:
@@ -732,29 +736,21 @@ def _get_head_obs(df_d):
732736
Root Mean Square for magnitude.
733737
"""
734738
df_head = pd.read_csv(df_d, nrows=4, header=None)
735-
# Template for version
736-
parse_ver = 'version = {ver}'
737-
# Parse required data for attributes
738-
ver = parse(parse_ver, df_head[0][0])
739-
ver = float(ver['ver'])
740-
# Template for errmod
741-
parse_err = "errmod = '{err}'"
742-
# Parse required data for attributes
743-
err = parse(parse_err, df_head[0][1])
744-
err = err['err']
745-
# Template for RMSast
746-
parse_ast = "RMSast = {ast}"
747-
# Parse required data for attributes
748-
ast = parse(parse_ast, df_head[0][2])
749-
ast = float(ast['ast'])
750-
# Template for RMSast
751-
parse_mag = "RMSmag = {mag}"
752-
# Parse required data for attributes
753-
mag = parse(parse_mag, df_head[0][3])
754-
if mag is None:
739+
# Template for version: version = {ver}
740+
ver = df_head.iloc[0][0].split('=')[1].strip()
741+
ver = float(ver)
742+
# Template for errmod: errmod = '{err}'
743+
err = df_head.iloc[1][0].split("'")[1].strip()
744+
# Template for RMSast: RMSast = {ast}
745+
ast = df_head.iloc[2][0].split('=')[1].strip()
746+
ast = float(ast)
747+
# Template for RMSast: RMSmag = {mag}
748+
mag = df_head.iloc[3][0]
749+
if mag == 'END_OF_HEADER':
755750
mag = 'No data for RMSmag'
756751
else:
757-
mag = float(mag['mag'])
752+
mag = float(df_head.iloc[3][0].split('=')[1].strip())
753+
758754

759755
return ver, err, ast, mag
760756

@@ -1351,23 +1347,16 @@ def _get_head_orb(data_obj):
13511347
df_info_d = io.StringIO(data_obj.decode('utf-8'))
13521348
# Read as txt file
13531349
df_info = pd.read_fwf(df_info_d, nrows=3, header=None)
1354-
# Template for format data
1355-
parse_format = "format = '{format}' ! file format"
1356-
# Parse required data for attributes
1357-
format_txt = parse(parse_format, df_info.iloc[0][0])
1358-
form = format_txt['format']
1359-
# Template for record type
1360-
parse_rectype = "rectype = '{rectype}' !"\
1361-
" record type (1L/ML)"
1362-
# Parse required data for attributes
1363-
rectype = parse(parse_rectype, df_info.iloc[1][0])
1364-
rectype = rectype['rectype']
1365-
# Template for reference system
1366-
parse_refsys = "refsys = {refsys} !"\
1367-
" default reference system"
1368-
# Parse required data for attributes
1369-
refsys = parse(parse_refsys, df_info.iloc[2][0])
1370-
refsys = refsys['refsys']
1350+
# Template for format data:
1351+
# format = '{format}' ! file format
1352+
format_txt = df_info.iloc[0][0].split("'")[1].strip()
1353+
form = format_txt
1354+
# Template for record type:
1355+
# rectype = '{rectype}' ! record type (1L/ML)
1356+
rectype = df_info.iloc[1][0].split("'")[1].strip()
1357+
# Template for reference system:
1358+
# refsys = {refsys} ! default reference system"
1359+
refsys = df_info.iloc[2][0].split("=")[1].split("!")[0].strip()
13711360

13721361
return form, rectype, refsys
13731362

@@ -1827,26 +1816,17 @@ def _get_head_ephem(data_obj):
18271816
"""
18281817
data_d = io.StringIO(data_obj.decode('utf-8'))
18291818
head_ephe = pd.read_fwf(data_d, nrows=5, header=None)
1830-
# Template for observatory
1831-
parse_obs = 'Observatory: {observatory}'
1832-
# Parse required data for attributes
1833-
obs = parse(parse_obs, head_ephe[0][1])
1834-
obs = obs['observatory']
1835-
# Template for initial date
1836-
parse_idate = 'Initial Date: {init_date}'
1837-
# Parse required data for attributes
1838-
idate = parse(parse_idate, head_ephe[0][2])
1839-
idate = idate['init_date']
1840-
# Template for initial date
1841-
parse_fdate = 'Final Date: {final_date}'
1842-
# Parse required data for attributes
1843-
fdate = parse(parse_fdate, head_ephe[0][3])
1844-
fdate = fdate['final_date']
1845-
# Template for initial date
1846-
parse_step = 'Time step: {step}'
1847-
# Parse required data for attributes
1848-
tstep = parse(parse_step, head_ephe[0][4])
1849-
tstep = tstep['step']
1819+
# Template for observatory: Observatory: {observatory}
1820+
obs = head_ephe.iloc[1][0].split(':')[1].strip()
1821+
# Template for initial date: Initial Date: {init_date}
1822+
idate = head_ephe.iloc[2][0].split(':')[1].strip() + ':' +\
1823+
head_ephe.iloc[2][0].split(':')[2].strip()
1824+
# Template for initial date: Final Date: {final_date}
1825+
fdate = head_ephe.iloc[3][0].split(':')[1].strip() + ':' +\
1826+
head_ephe.iloc[3][0].split(':')[2].strip()
1827+
# Template for initial date: Time step: {step}
1828+
tstep = head_ephe.iloc[4][0].split(':')[1].strip()
1829+
18501830

18511831
return obs, idate, fdate, tstep
18521832

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
Last Update: 2021-10-04 05:49 UTC
1+
Last Update: 2022-08-19 08:03 UTC
22
Object | Diameter | VI Max |
33
Num/des. Name | m | *=Y | Date/Time | IP max | PS max |TS | Vel km/s |
44
AAAAAAAAA AAAAAAAAAAAAAAAA | NNNN | A | YYYY-MM-DD HH:MM | EEEEEEEE | NNN.NN | NN | NNN.NN |
5+
101955 Bennu | 484 | | 2182-09-24 20:24 | 3.70E-4 | -1.59 | | 12.68 |
6+
29075 1950DA | 1300 | | 2880-03-16 23:48 | 1.96E-5 | -2.13 | | 17.99 |

0 commit comments

Comments
 (0)