A Python3 library to handle contents of ARTECS: Archive of terrestrial-type climate simulations
+
+
http://wwwuser.oats.inaf.it/exobio/climates/
+
+
+
through TAP and the PYVO services.
+
+
Authors: Michele Maris (1), Marco Molinaro (1)
+
+
(1) INAF/Trieste Astronomical Observatory
+
+
+
First Issue: 2019 Nov 20
+
+
Dependencies:
+
+
This package needs:
+ numpy, scipy, pandas, pyvo
+
+
Installation
+
+
For the latest release:
+
+
+
>>> pip3installpy_artecs
+
+
+
+
for the dev version clone this GitLab repository.
+
+
Files in py_artecs
+
+
__init__.py : the init file
+
+
tap.py : the file with the TAP library
+
+
artecs_map.py : a utility class to handle a local fits file with a Temperature MAP downloaded from the archive
+
+
modelDB.py : a utility class to handle a local csv file with the result of a query, this module is kept for backward compatibility, but its use is deprecated
+
+
Example of session:
+
+
The archive is accessed from the exop_pubblic_tap in py_artecs:
+
+
+
>>> fromartecsimportexop_pubblic_tap
+
+
+
+
Then instantiate a database object
+
+
+
>>> atap=exop_pubblic_tap()
+
+
+
+
all the queries to ARTECS are made through the methods in atap.
+
+
Queries follows the Astronomical Data Query Language (ADQL) format
+
+
+
>>> ptab=atap.search('power(SMA,1.5)>0.87');
+
+
+
+
see the appendix for further references on the ADQL.
+
+
To know wether the search is successfull:
+
+
+
>>> atap.success()
+True
+
+
+
+
The result of a query is stored in ptab as a PANDAS data_frame.
+
+
In order to save the table as a csv file use the "to_csv" method of pandas data frame:
+
+
+
>>> ptab.to_csv('result.csv',sep=' ')
+
+
+
+
In order to get a map corresponding to the first entry in the ptab use:
+
+
+
>>> TMAP=atap.get_map(ptab.URL[0])
+
+
+
+
the command creates a fits file to rercover the fits filename
TMAP is an object of class artecs_map, so it contains the temperature MAP in the ARTECS fits file, as well as the other keywords in the original fits file.
+
+
Note that the artecs_map class can be used also local copies of the ARTECS temperature maps.
+
+
At last, to perform a new query reset the old one with:
+
+
+
>>> atap.clear()
+
+
+
+
Appendix A: ADQL Queries
+
+
A query is a string
+ . SELECTION set of data to be selected
+ . HOW_MANY elements to select
+ . WHICH_FIELDS fields to select
+ . FROM which table
+ . WHERE condition for selection is true
+
+
Examples of query strings:
+
+
+
Download all the data:
+
+
+
SELECT * FROM exo.EXO
+
+
Download only the first 10 elements:
+
+
+
SELECT TOP 10 * FROM exo.EXO
+
+
Download only the first 10 elements with SMA in the range 0.9 to 1.1:
+
+
+
SELECT TOP 10 * FROM exo.EXO WHERE SMA BETWEEN 0.9 AND 1.1
+
+
+
alternativelly
+
+
+
SELECT TOP 10 * FROM exo.EXO WHERE (0.9 <= SMA) AND (SMA <= 1.1)
+
+
Download only the first 10 elements with SMA in the range 0.9 to 1.1 and CONTHAB>=0.5
+
+
+
SELECT TOP 10 * FROM exo.EXO WHERE SMA BETWEEN 0.9 AND 1.1 AND CONTHAB>=0.5
+
+
Arithmetic calculations are allowed if needed for selection so to download the first 10 elements with SMA^1.5 > 0.87
+
+
+
SELECT TOP 10 * FROM exo.EXO WHERE power(SMA,1.5)> 0.87
+
+
returns just columns SMA and CONTHAB from previous example:
+
+
+
SELECT TOP 10 SMA,CONTHAB FROM exo.EXO WHERE power(SMA,1.5)> 0.87
+
+
+
+
Note that the query string is not sensitive to uppercase or lowercase.
1classartecs_map:
+ 2"""
+ 3A class to handle a temperature map from ARTECS.
+ 4
+ 5It reads the artecs_map from a fits file.
+ 6
+ 7 >>> AMAP=artecs_map("artecs_map.fits")
+ 8
+ 9Keywords in the map are returned as members of the class or using the method "parameter".
+ 10
+ 11Example:
+ 12
+ 13 >>> AMAP.temp
+ 14
+ 15returns the temperature map,
+ 16
+ 17 >>> AMAP.parameter('temp')
+ 18
+ 19returns the temperature map.
+ 20
+ 21
+ 22 >>> AMAP.shape
+ 23
+ 24returns the shape of the map (rows, columns)
+ 25
+ 26
+ 27 """
+ 28@property
+ 29deffilename(self):
+ 30""" parameter: the filename """
+ 31returnself._filename
+ 32
+ 33@property
+ 34defp(self):
+ 35""" the fits file pointer, normally closed.
+ 36 """
+ 37returnself._p
+ 38
+ 39@property
+ 40deflst_lat(self):
+ 41""" list of latitude bands """
+ 42returnself._lst_lat
+ 43
+ 44@property
+ 45deflst_year(self):
+ 46""" list of time intervals """
+ 47returnself._lst_year
+ 48
+ 49@property
+ 50defshape(self):
+ 51""" the shape of the 2D maps """
+ 52returnself._shape
+ 53
+ 54@property
+ 55defTMGLOB(self):
+ 56""" the mean surface temperature """
+ 57returnself._TMGLOB
+ 58
+ 59def__init__(self,filename,closeFits=True,verbose=False):
+ 60""" To instantiate the class pass the filename from which to load the Temperature map
+ 61
+ 62 >Keywords:
+ 63
+ 64 >>`verbose`: if True verbose output
+ 65
+ 66 >>`closeFits`: if True the fits file is closed after reading
+ 67 """
+ 68importnumpy
+ 69try:
+ 70importpyfits
+ 71except:
+ 72fromastropy.ioimportfitsaspyfits
+ 73self._filename=filename
+ 74self._p=pyfits.open(filename)
+ 75self._key=[]
+ 76self._value=[]
+ 77self._descr=[]
+ 78mkd=True
+ 79forccinself.p[0].header.cards:
+ 80ifcc[0]!='COMMENT':
+ 81self._key.append(cc[0])
+ 82self._value.append(cc[1])
+ 83self._descr.append(cc[2])
+ 84else:
+ 85ifmkd:
+ 86self._key.append(cc[0])
+ 87self._value.append('\n'.join(self.p[0].header['COMMENT']))
+ 88self._descr.append(None)
+ 89mkd=False
+ 90
+ 91#: N of year intervals
+ 92self.N=self.parameter('N')
+ 93
+ 94#: NS number of latitude bands
+ 95self.NS=self.parameter('NS')
+ 96
+ 97#: the shape
+ 98self._shape=(self.NS,self.N)
+ 99
+100self.year=self.p[1].data['year']
+101self.lat=self.p[1].data['lat']
+102self.temp=self.p[1].data['temp']
+103self.year.shape=self.shape
+104self.lat.shape=self.shape
+105self.temp.shape=self.shape
+106
+107#: the mean surfscr temperature
+108self._TMGLOB=self.temp.mean()
+109
+110self._lst_lat=self.lat[0]
+111self._lst_year=self.year[:,0].T
+112
+113ifverbose:
+114print('Successfully opened and readed ',filename)
+115
+116ifcloseFits:
+117self._p.close()
+118ifverbose:
+119print('fits file closed ',filename)
+120
+121
+122defkeys(self,maps=False):
+123"""
+124returns the list of quantities in the map
+125
+126Keywords:
+127
+128>`maps` (default False), if True returns just the list of of elements which are 2D maps
+129 """
+130ifmaps:
+131return['year','lat','temp']
+132else:
+133returnself._key
+134defhas_key(self,key):
+135"""True if required `key` is in the map"""
+136returnkeyinself._key
+137defparameter(self,key):
+138"""returns a parameter from the fits file from its `key'"""
+139returnself._value[self._key.index(key)]
+140defdescription(self,key):
+141"""returns the description of a parameter in the fits file from its `key'"""
+142returnself._descr[self._key.index(key)]
+143#def bilinear_interpolation(self,lat,year) :
+144#"""returns bilinear interpolation of the map (not implemeted yet) """
+145#raise Exception(
+
+
+
+
+
+
+
+
+ class
+ artecs_map:
+
+
+
+
+
+
2classartecs_map:
+ 3"""
+ 4A class to handle a temperature map from ARTECS.
+ 5
+ 6It reads the artecs_map from a fits file.
+ 7
+ 8 >>> AMAP=artecs_map("artecs_map.fits")
+ 9
+ 10Keywords in the map are returned as members of the class or using the method "parameter".
+ 11
+ 12Example:
+ 13
+ 14 >>> AMAP.temp
+ 15
+ 16returns the temperature map,
+ 17
+ 18 >>> AMAP.parameter('temp')
+ 19
+ 20returns the temperature map.
+ 21
+ 22
+ 23 >>> AMAP.shape
+ 24
+ 25returns the shape of the map (rows, columns)
+ 26
+ 27
+ 28 """
+ 29@property
+ 30deffilename(self):
+ 31""" parameter: the filename """
+ 32returnself._filename
+ 33
+ 34@property
+ 35defp(self):
+ 36""" the fits file pointer, normally closed.
+ 37 """
+ 38returnself._p
+ 39
+ 40@property
+ 41deflst_lat(self):
+ 42""" list of latitude bands """
+ 43returnself._lst_lat
+ 44
+ 45@property
+ 46deflst_year(self):
+ 47""" list of time intervals """
+ 48returnself._lst_year
+ 49
+ 50@property
+ 51defshape(self):
+ 52""" the shape of the 2D maps """
+ 53returnself._shape
+ 54
+ 55@property
+ 56defTMGLOB(self):
+ 57""" the mean surface temperature """
+ 58returnself._TMGLOB
+ 59
+ 60def__init__(self,filename,closeFits=True,verbose=False):
+ 61""" To instantiate the class pass the filename from which to load the Temperature map
+ 62
+ 63 >Keywords:
+ 64
+ 65 >>`verbose`: if True verbose output
+ 66
+ 67 >>`closeFits`: if True the fits file is closed after reading
+ 68 """
+ 69importnumpy
+ 70try:
+ 71importpyfits
+ 72except:
+ 73fromastropy.ioimportfitsaspyfits
+ 74self._filename=filename
+ 75self._p=pyfits.open(filename)
+ 76self._key=[]
+ 77self._value=[]
+ 78self._descr=[]
+ 79mkd=True
+ 80forccinself.p[0].header.cards:
+ 81ifcc[0]!='COMMENT':
+ 82self._key.append(cc[0])
+ 83self._value.append(cc[1])
+ 84self._descr.append(cc[2])
+ 85else:
+ 86ifmkd:
+ 87self._key.append(cc[0])
+ 88self._value.append('\n'.join(self.p[0].header['COMMENT']))
+ 89self._descr.append(None)
+ 90mkd=False
+ 91
+ 92#: N of year intervals
+ 93self.N=self.parameter('N')
+ 94
+ 95#: NS number of latitude bands
+ 96self.NS=self.parameter('NS')
+ 97
+ 98#: the shape
+ 99self._shape=(self.NS,self.N)
+100
+101self.year=self.p[1].data['year']
+102self.lat=self.p[1].data['lat']
+103self.temp=self.p[1].data['temp']
+104self.year.shape=self.shape
+105self.lat.shape=self.shape
+106self.temp.shape=self.shape
+107
+108#: the mean surfscr temperature
+109self._TMGLOB=self.temp.mean()
+110
+111self._lst_lat=self.lat[0]
+112self._lst_year=self.year[:,0].T
+113
+114ifverbose:
+115print('Successfully opened and readed ',filename)
+116
+117ifcloseFits:
+118self._p.close()
+119ifverbose:
+120print('fits file closed ',filename)
+121
+122
+123defkeys(self,maps=False):
+124"""
+125returns the list of quantities in the map
+126
+127Keywords:
+128
+129>`maps` (default False), if True returns just the list of of elements which are 2D maps
+130 """
+131ifmaps:
+132return['year','lat','temp']
+133else:
+134returnself._key
+135defhas_key(self,key):
+136"""True if required `key` is in the map"""
+137returnkeyinself._key
+138defparameter(self,key):
+139"""returns a parameter from the fits file from its `key'"""
+140returnself._value[self._key.index(key)]
+141defdescription(self,key):
+142"""returns the description of a parameter in the fits file from its `key'"""
+143returnself._descr[self._key.index(key)]
+144#def bilinear_interpolation(self,lat,year) :
+145#"""returns bilinear interpolation of the map (not implemeted yet) """
+146#raise Exception(
+
+
+
+
A class to handle a temperature map from ARTECS.
+
+
It reads the artecs_map from a fits file.
+
+
+
>>> AMAP=artecs_map("artecs_map.fits")
+
+
+
+
Keywords in the map are returned as members of the class or using the method "parameter".
60def__init__(self,filename,closeFits=True,verbose=False):
+ 61""" To instantiate the class pass the filename from which to load the Temperature map
+ 62
+ 63 >Keywords:
+ 64
+ 65 >>`verbose`: if True verbose output
+ 66
+ 67 >>`closeFits`: if True the fits file is closed after reading
+ 68 """
+ 69importnumpy
+ 70try:
+ 71importpyfits
+ 72except:
+ 73fromastropy.ioimportfitsaspyfits
+ 74self._filename=filename
+ 75self._p=pyfits.open(filename)
+ 76self._key=[]
+ 77self._value=[]
+ 78self._descr=[]
+ 79mkd=True
+ 80forccinself.p[0].header.cards:
+ 81ifcc[0]!='COMMENT':
+ 82self._key.append(cc[0])
+ 83self._value.append(cc[1])
+ 84self._descr.append(cc[2])
+ 85else:
+ 86ifmkd:
+ 87self._key.append(cc[0])
+ 88self._value.append('\n'.join(self.p[0].header['COMMENT']))
+ 89self._descr.append(None)
+ 90mkd=False
+ 91
+ 92#: N of year intervals
+ 93self.N=self.parameter('N')
+ 94
+ 95#: NS number of latitude bands
+ 96self.NS=self.parameter('NS')
+ 97
+ 98#: the shape
+ 99self._shape=(self.NS,self.N)
+100
+101self.year=self.p[1].data['year']
+102self.lat=self.p[1].data['lat']
+103self.temp=self.p[1].data['temp']
+104self.year.shape=self.shape
+105self.lat.shape=self.shape
+106self.temp.shape=self.shape
+107
+108#: the mean surfscr temperature
+109self._TMGLOB=self.temp.mean()
+110
+111self._lst_lat=self.lat[0]
+112self._lst_year=self.year[:,0].T
+113
+114ifverbose:
+115print('Successfully opened and readed ',filename)
+116
+117ifcloseFits:
+118self._p.close()
+119ifverbose:
+120print('fits file closed ',filename)
+
+
+
+
To instantiate the class pass the filename from which to load the Temperature map
+
+
+
Keywords:
+
+
+
+
+
verbose: if True verbose output
+
+
+
+
+
+
closeFits: if True the fits file is closed after reading
+
+
+
+
+
+
+
+
+ filename
+
+
+
+
+
+
parameter: the filename
+
+
+
+
+
+
+ p
+
+
+
+
+
+
the fits file pointer, normally closed.
+
+
+
+
+
+
+ lst_lat
+
+
+
+
+
+
list of latitude bands
+
+
+
+
+
+
+ lst_year
+
+
+
+
+
+
list of time intervals
+
+
+
+
+
+
+ shape
+
+
+
+
+
+
the shape of the 2D maps
+
+
+
+
+
+
+ TMGLOB
+
+
+
+
+
+
the mean surface temperature
+
+
+
+
+
+
+
+
+ def
+ keys(self, maps=False):
+
+
+
+
+
+
123defkeys(self,maps=False):
+124"""
+125returns the list of quantities in the map
+126
+127Keywords:
+128
+129>`maps` (default False), if True returns just the list of of elements which are 2D maps
+130 """
+131ifmaps:
+132return['year','lat','temp']
+133else:
+134returnself._key
+
+
+
+
returns the list of quantities in the map
+
+
Keywords:
+
+
+
maps (default False), if True returns just the list of of elements which are 2D maps
+
+
+
+
+
+
+
+
+
+ def
+ has_key(self, key):
+
+
+
+
+
+
135defhas_key(self,key):
+136"""True if required `key` is in the map"""
+137returnkeyinself._key
+
+
+
+
True if required key is in the map
+
+
+
+
+
+
+
+
+ def
+ parameter(self, key):
+
+
+
+
+
+
138defparameter(self,key):
+139"""returns a parameter from the fits file from its `key'"""
+140returnself._value[self._key.index(key)]
+
+
+
+
returns a parameter from the fits file from its `key'
+
+
+
+
+
+
+
+
+ def
+ description(self, key):
+
+
+
+
+
+
141defdescription(self,key):
+142"""returns the description of a parameter in the fits file from its `key'"""
+143returnself._descr[self._key.index(key)]
+144#def bilinear_interpolation(self,lat,year) :
+145#"""returns bilinear interpolation of the map (not implemeted yet) """
+146#raise Exception(
+
+
+
+
returns the description of a parameter in the fits file from its `key'
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/py_artecs/modelDb.html b/docs/py_artecs/modelDb.html
new file mode 100644
index 0000000..b421a6d
--- /dev/null
+++ b/docs/py_artecs/modelDb.html
@@ -0,0 +1,1765 @@
+
+
+
+
+
+
+ py_artecs.modelDb API documentation
+
+
+
+
+
+
+
+
+
+
+
+
229defreset_plot_status(self):
+230"""resets the self._last_plot dictionary where handles from the last plot generated are stored"""
+231fromcollectionsimportOrderedDict
+232self._last_plot=OrderedDict()
+233self._last_plot['fig']=None
+234self._last_plot['xlabel']=None
+235self._last_plot['ylabel']=None
+236self._last_plot['axe']=None
+237self._last_plot['legend']=None
+238self._last_plot['curves']=[]
+
+
+
+
resets the self._last_plot dictionary where handles from the last plot generated are stored
296defset_iceTOT_threshold(self,iceTOT_threshold):
+297""" set iceTOT_threshold : the ice coverage over which the planet is considered a snowball
+298suggested values 0.95 or 0.99
+299 """
+300self.iceTOT_threshold=iceTOT_threshold
+
+
+
+
set iceTOT_threshold : the ice coverage over which the planet is considered a snowball
+suggested values 0.95 or 0.99
+
+
+
+
+
+
+
+
+ def
+ flag_class_warm(self):
+
+
+
+
+
+
302defflag_class_warm(self):
+303"""returns Murante's classifications for warm calculated from scratch
+304iceTOT_threshold is the ice coverage over which the planet is considered a snowball
+305suggested values 0.95 or 0.99
+306 """
+307importnumpyasnp
+308ifnotself.iceTOT_threshold():return
+309return(self.TABLE['TMGLOB']>self.TABLE['Tice'])*(self.TABLE['TMGLOB']<self.TABLE['Tvap'])
+
+
+
+
returns Murante's classifications for warm calculated from scratch
+iceTOT_threshold is the ice coverage over which the planet is considered a snowball
+suggested values 0.95 or 0.99
+
+
+
+
+
+
+
+
+ def
+ flag_class_warm_hot(self):
+
+
+
+
+
+
311defflag_class_warm_hot(self):
+312"""returns Murante's classifications for warm_hot calculated from scratch
+313iceTOT_threshold is the ice coverage over which the planet is considered a snowball
+314suggested values 0.95 or 0.99
+315 """
+316importnumpyasnp
+317ifnotself.iceTOT_threshold():return
+318return(self.TABLE['TMGLOB']>=self.TABLE['Tvap'])
+
+
+
+
returns Murante's classifications for warm_hot calculated from scratch
+iceTOT_threshold is the ice coverage over which the planet is considered a snowball
+suggested values 0.95 or 0.99
+
+
+
+
+
+
+
+
+ def
+ flag_class_snowball(self):
+
+
+
+
+
+
320defflag_class_snowball(self):
+321"""returns Murante's classifications for warm_hot calculated from scratch
+322iceTOT_threshold is the ice coverage over which the planet is considered a snowball
+323suggested values 0.95 or 0.99
+324 """
+325importnumpyasnp
+326ifnotself.iceTOT_threshold():return
+327return(self.TABLE['ICE']>self.iceTOT_threshold)
+
+
+
+
returns Murante's classifications for warm_hot calculated from scratch
+iceTOT_threshold is the ice coverage over which the planet is considered a snowball
+suggested values 0.95 or 0.99
+
+
+
+
+
+
+
+
+ def
+ flag_class_waterbelt(self):
+
+
+
+
+
+
329defflag_class_waterbelt(self):
+330"""returns Murante's classifications for warm_hot calculated from scratch
+331iceTOT_threshold is the ice coverage over which the planet is considered a snowball
+332suggested values 0.95 or 0.99
+333 """
+334importnumpyasnp
+335ifnotself.iceTOT_threshold():return
+336return(self.TABLE['TMGLOB']<=self.TABLE['Tice'])*(self.TABLE['ICE']<=self.iceTOT_threshold)
+
+
+
+
returns Murante's classifications for warm_hot calculated from scratch
+iceTOT_threshold is the ice coverage over which the planet is considered a snowball
+suggested values 0.95 or 0.99
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/py_artecs/tap.html b/docs/py_artecs/tap.html
new file mode 100644
index 0000000..dfb4d84
--- /dev/null
+++ b/docs/py_artecs/tap.html
@@ -0,0 +1,1187 @@
+
+
+
+
+
+
+ py_artecs.tap API documentation
+
+
+
+
+
+
+
+
+
+
+
+
1__DESCRIPTION__="""
+ 2
+ 3TAP services for ARTECS
+ 4
+ 5By M.Maris 1.1 - 2019 Nov 15 -
+ 6Ported to python3
+ 7Needs pyvo
+ 8
+ 9
+ 10
+ 11Example:
+ 12 >>> import artecs
+ 13 >>> atap=artecs.exop_pubblic_tap()
+ 14
+ 15 >>> atap.EXPLAIN()
+ 16
+ 17 >>> atap.keys()
+ 18
+ 19
+ 20 >>> tab=atap.search('(0.7 <= SMA) and (SMA <=3.)')
+ 21
+ 22 >>> tab.FO_CONST.unique()
+ 23
+ 24 >>> tab.to_csv('/tmp/pippo.csv',sep=' ')
+ 25
+ 26 >>> MAP=atap.get_map(tab.URL[0])
+ 27
+ 28"""
+ 29
+ 30try:
+ 31importpyvo
+ 32BAD=False
+ 33except:
+ 34print("PYVO not found, to install pyvo : \n\t>sudo pip install pyvo\n%s EXOP_TAP class will not work properly"%("/".join(__file__.split('/')[-2:])))
+ 35BAD=True
+ 36
+ 37#if BAD :
+ 38#import sys
+ 39#sys.exit(1)
+ 40#del BAD
+ 41
+ 42classEXOP_TAP:
+ 43def__init__(self,tap_url="http://archives.ia2.inaf.it/vo/tap/exo",table_name="exo.EXO",temporary_files_path='/tmp'):
+ 44importpyvo
+ 45#
+ 46#creates empty object
+ 47self._empty()
+ 48#
+ 49self._temporary_files_path=temporary_files_path+'/'iftemporary_files_path!=''andtemporary_files_path!=Noneelse''
+ 50#
+ 51#connects to db
+ 52self._url=tap_url
+ 53self._table_name=table_name
+ 54#
+ 55#template for query_string, two fields: <QUERY> <FIELDS>
+ 56self._template_query="SELECT %s%s FROM "+self._table_name
+ 57#
+ 58try:
+ 59self._tap_service=pyvo.dal.TAPService(tap_url)
+ 60except:
+ 61print("Error, unable to connect to TAP_URL '"+tap_url+"'")
+ 62#
+ 63#from db gets fields description
+ 64self._get_field_description()
+ 65#
+ 66def_empty(self):
+ 67self._url=None
+ 68self._table_name=None
+ 69self._tap_service=None
+ 70self._elapsed_time=0.
+ 71self._search_result=None
+ 72self._field_description=None
+ 73self._field_names=None
+ 74self._search_success=None
+ 75self._template_query=None
+ 76self._download_success=None
+ 77#
+ 78def_get_field_description(self):
+ 79self.adql_search('SELECT TOP 1 * FROM '+self._table_name)
+ 80self._field_description=self._search_result.fielddescs
+ 81self._field_names=self._search_result.fieldnames
+ 82self.clean()
+ 83#
+ 84defkeys(self):
+ 85"""list of fields in the database"""
+ 86returnself._field_names
+ 87#
+ 88defhas_key(self,this):
+ 89"""has_key"""
+ 90returnthisinself._field_names
+ 91#
+ 92def__include__(self,this):
+ 93"""this in object"""
+ 94returnthisinself._field_names
+ 95#
+ 96defsuccess(self):
+ 97"""returns True if last search was successfull"""
+ 98returnself._search_success==True
+ 99#
+100defclean(self):
+101"""cleans information from last search"""
+102self._search_success=None
+103self._search_result=None
+104#
+105defadql_search(self,adql_string):
+106"""search on database using ADQL string """
+107importtime
+108self.clean()
+109self._search_success=False
+110self._elapsed_time=time.time()
+111self._search_result=self._tap_service.search(adql_string)
+112self._elapsed_time=time.time()-self._elapsed_time
+113self._search_success=True
+114#
+115defsearch_string(self,SELECTION,TOP,FIELDS,WHERE,SORT):
+116"""creates a properly formatted adql query_string"""
+117adql='SELECT'
+118adql+=''iftype(SELECTION)==type(None)else' '+SELECT
+119adql+=' TOP %d'%TOPiftype(TOP)==type(1)else''
+120adql+=' *'iftype(FIELDS)==type(None)else' '+FIELDS
+121adql+=' FROM '+self._table_name
+122adql+=''ifWHERE==''orWHERE==Noneelse' WHERE '+WHERE
+123adql+=''ifSORT==''orSORT==Noneelse' SORT BY '+SORT
+124returnadql
+125#
+126defsearch(self,WHERE,SELECTION=None,FIELDS=None,TOP=None,SORT=None,as_astropy=False,as_votable=False):
+127"""download a table from the database
+128 search('') or search(WHERE='') returns all the data in the database
+129
+130 the table can be returned as :
+131 pandas dataframe (default)
+132 astropy table (as_astropy = True)
+133 votable (as_votable=True)
+134 """
+135importtime
+136#
+137adql=self.search_string(SELECTION,TOP,FIELDS,WHERE,SORT)
+138self.adql_search(adql)
+139#
+140ifas_astropy:
+141returnself._search_result.table
+142elifas_votable:
+143returnself._search_result.votable
+144else:
+145returnself._search_result.table.to_pandas()
+146#
+147defget_map(self,_URL,outfile=None):
+148"""gets a map """
+149importnumpyasnp
+150importtime
+151from.artecs_mapimportartecs_map
+152try:
+153fromurllib2importurlopen
+154except:
+155fromurllib.requestimporturlopen
+156importrequests
+157importgzip
+158importos
+159try:
+160fromStringIOimportStringIO
+161except:
+162fromioimportStringIO
+163iftype(_URL)==type(""):
+164URL=_URL+''
+165else:
+166URL=_URL.decode("utf-8")
+167#
+168iftype(outfile)!=type(''):
+169#if out file not specified creates a unique temporary name and reserves it
+170flag=True
+171whileflag:
+172tmp=URL+' '+time.asctime()
+173tmp=tmp+' '+str(np.random.randint(1000000))
+174tmp=abs(hash(tmp))
+175tmp=hex(tmp)[2:]
+176_o=self._temporary_files_path+'artecs_download_file_'+tmp+'.fits'
+177flag=os.path.isfile(_o)
+178open(_o,'w').write('a')#this is to reserve the file name
+179else:
+180_o=outfile
+181#
+182tic=time.time()
+183request=requests.Request(URL)
+184#response = urlopen(request)
+185try:
+186response=urlopen(URL)
+187except:
+188print("URL %s not found"%URL)
+189iftype(outfile)!=type(''):
+190os.remove(_o)
+191self._download_success=False
+192return
+193#buf = StringIO(response.read())
+194buf=response
+195f=gzip.GzipFile(fileobj=buf)
+196data=f.read()
+197open(_o,'wb').write(data)
+198tic=time.time()-tic
+199#
+200amap=artecs_map(_o)
+201amap.url=URL
+202iftype(outfile)!=type(''):
+203os.remove(_o)
+204self._download_success=True
+205returnamap
+206#
+207defdownload_map(self,URL,outfile=None,path=None):
+208"""download the fits file corresponding at a given URL
+209 if outfile is not specified the fits file name from the URL is used
+210 if path is not specified the current file is stored in the current path
+211 """
+212_path=''iftype(path)!=type('')elsepath+'/'
+213iftype(outfile)!=type(''):
+214_o=URL.split('/')[-1].split('.gz')[0]
+215_o=_path+_o
+216else:
+217_o=outfile
+218self.get_map(URL,outfile=_o)
+219#
+220defEXPLAIN(self):
+221"""print a short introduction on the query language"""
+222print("""
+223ADQL = Astronomical Data Query Language
+224
+225A query is a string
+226- SELECTION set of data to be selected
+227- HOW_MANY elements to select
+228- WHICH_FIELDS fields to select
+229- FROM which table
+230- WHERE condition for selection is true
+231
+232Example:
+233
+2341. Download all the data
+235 SELECT * FROM exo.EXO
+236
+2372. Download only the first 10 elements
+238 SELECT TOP 10 * FROM exo.EXO
+239
+2403. Download only the first 10 elements with SMA in the range 0.9 to 1.1
+241 SELECT TOP 10 * FROM exo.EXO WHERE SMA BETWEEN 0.9 AND 1.1
+242
+243 alternativelly
+244
+245 SELECT TOP 10 * FROM exo.EXO WHERE (0.9 <= SMA) AND (SMA <= 1.1)
+246
+2474. Download only the first 10 elements with SMA in the range 0.9 to 1.1 and CONTHAB>=0.5
+248 SELECT TOP 10 * FROM exo.EXO WHERE SMA BETWEEN 0.9 AND 1.1 AND CONTHAB>=0.5
+249
+2505. Arithmetic calculations are allowed if needed for selection so to download the first 10 elements with SMA^1.5 > 0.87
+251 SELECT TOP 10 * FROM exo.EXO WHERE power(SMA,1.5)> 0.87
+252
+2536. returns just columns SMA and CONTHAB from previous example:
+254 SELECT TOP 10 SMA,CONTHAB FROM exo.EXO WHERE power(SMA,1.5)> 0.87
+255
+256Note that the query is not sensitive to uppercase or lowercase.
+257
+258Tutorials:
+259 http://www.g-vo.org/tutorials/gaia-mock-tap.pdf
+260 http://www.ivoa.net/documents/REC/ADQL/ADQL-20081030.pdf
+261 http://www.ivoa.net/documents/
+262
+263""")
+264
+265
+
+
+
+
+
+
+
+
+ class
+ EXOP_TAP:
+
+
+
+
+
+
43classEXOP_TAP:
+ 44def__init__(self,tap_url="http://archives.ia2.inaf.it/vo/tap/exo",table_name="exo.EXO",temporary_files_path='/tmp'):
+ 45importpyvo
+ 46#
+ 47#creates empty object
+ 48self._empty()
+ 49#
+ 50self._temporary_files_path=temporary_files_path+'/'iftemporary_files_path!=''andtemporary_files_path!=Noneelse''
+ 51#
+ 52#connects to db
+ 53self._url=tap_url
+ 54self._table_name=table_name
+ 55#
+ 56#template for query_string, two fields: <QUERY> <FIELDS>
+ 57self._template_query="SELECT %s%s FROM "+self._table_name
+ 58#
+ 59try:
+ 60self._tap_service=pyvo.dal.TAPService(tap_url)
+ 61except:
+ 62print("Error, unable to connect to TAP_URL '"+tap_url+"'")
+ 63#
+ 64#from db gets fields description
+ 65self._get_field_description()
+ 66#
+ 67def_empty(self):
+ 68self._url=None
+ 69self._table_name=None
+ 70self._tap_service=None
+ 71self._elapsed_time=0.
+ 72self._search_result=None
+ 73self._field_description=None
+ 74self._field_names=None
+ 75self._search_success=None
+ 76self._template_query=None
+ 77self._download_success=None
+ 78#
+ 79def_get_field_description(self):
+ 80self.adql_search('SELECT TOP 1 * FROM '+self._table_name)
+ 81self._field_description=self._search_result.fielddescs
+ 82self._field_names=self._search_result.fieldnames
+ 83self.clean()
+ 84#
+ 85defkeys(self):
+ 86"""list of fields in the database"""
+ 87returnself._field_names
+ 88#
+ 89defhas_key(self,this):
+ 90"""has_key"""
+ 91returnthisinself._field_names
+ 92#
+ 93def__include__(self,this):
+ 94"""this in object"""
+ 95returnthisinself._field_names
+ 96#
+ 97defsuccess(self):
+ 98"""returns True if last search was successfull"""
+ 99returnself._search_success==True
+100#
+101defclean(self):
+102"""cleans information from last search"""
+103self._search_success=None
+104self._search_result=None
+105#
+106defadql_search(self,adql_string):
+107"""search on database using ADQL string """
+108importtime
+109self.clean()
+110self._search_success=False
+111self._elapsed_time=time.time()
+112self._search_result=self._tap_service.search(adql_string)
+113self._elapsed_time=time.time()-self._elapsed_time
+114self._search_success=True
+115#
+116defsearch_string(self,SELECTION,TOP,FIELDS,WHERE,SORT):
+117"""creates a properly formatted adql query_string"""
+118adql='SELECT'
+119adql+=''iftype(SELECTION)==type(None)else' '+SELECT
+120adql+=' TOP %d'%TOPiftype(TOP)==type(1)else''
+121adql+=' *'iftype(FIELDS)==type(None)else' '+FIELDS
+122adql+=' FROM '+self._table_name
+123adql+=''ifWHERE==''orWHERE==Noneelse' WHERE '+WHERE
+124adql+=''ifSORT==''orSORT==Noneelse' SORT BY '+SORT
+125returnadql
+126#
+127defsearch(self,WHERE,SELECTION=None,FIELDS=None,TOP=None,SORT=None,as_astropy=False,as_votable=False):
+128"""download a table from the database
+129 search('') or search(WHERE='') returns all the data in the database
+130
+131 the table can be returned as :
+132 pandas dataframe (default)
+133 astropy table (as_astropy = True)
+134 votable (as_votable=True)
+135 """
+136importtime
+137#
+138adql=self.search_string(SELECTION,TOP,FIELDS,WHERE,SORT)
+139self.adql_search(adql)
+140#
+141ifas_astropy:
+142returnself._search_result.table
+143elifas_votable:
+144returnself._search_result.votable
+145else:
+146returnself._search_result.table.to_pandas()
+147#
+148defget_map(self,_URL,outfile=None):
+149"""gets a map """
+150importnumpyasnp
+151importtime
+152from.artecs_mapimportartecs_map
+153try:
+154fromurllib2importurlopen
+155except:
+156fromurllib.requestimporturlopen
+157importrequests
+158importgzip
+159importos
+160try:
+161fromStringIOimportStringIO
+162except:
+163fromioimportStringIO
+164iftype(_URL)==type(""):
+165URL=_URL+''
+166else:
+167URL=_URL.decode("utf-8")
+168#
+169iftype(outfile)!=type(''):
+170#if out file not specified creates a unique temporary name and reserves it
+171flag=True
+172whileflag:
+173tmp=URL+' '+time.asctime()
+174tmp=tmp+' '+str(np.random.randint(1000000))
+175tmp=abs(hash(tmp))
+176tmp=hex(tmp)[2:]
+177_o=self._temporary_files_path+'artecs_download_file_'+tmp+'.fits'
+178flag=os.path.isfile(_o)
+179open(_o,'w').write('a')#this is to reserve the file name
+180else:
+181_o=outfile
+182#
+183tic=time.time()
+184request=requests.Request(URL)
+185#response = urlopen(request)
+186try:
+187response=urlopen(URL)
+188except:
+189print("URL %s not found"%URL)
+190iftype(outfile)!=type(''):
+191os.remove(_o)
+192self._download_success=False
+193return
+194#buf = StringIO(response.read())
+195buf=response
+196f=gzip.GzipFile(fileobj=buf)
+197data=f.read()
+198open(_o,'wb').write(data)
+199tic=time.time()-tic
+200#
+201amap=artecs_map(_o)
+202amap.url=URL
+203iftype(outfile)!=type(''):
+204os.remove(_o)
+205self._download_success=True
+206returnamap
+207#
+208defdownload_map(self,URL,outfile=None,path=None):
+209"""download the fits file corresponding at a given URL
+210 if outfile is not specified the fits file name from the URL is used
+211 if path is not specified the current file is stored in the current path
+212 """
+213_path=''iftype(path)!=type('')elsepath+'/'
+214iftype(outfile)!=type(''):
+215_o=URL.split('/')[-1].split('.gz')[0]
+216_o=_path+_o
+217else:
+218_o=outfile
+219self.get_map(URL,outfile=_o)
+220#
+221defEXPLAIN(self):
+222"""print a short introduction on the query language"""
+223print("""
+224ADQL = Astronomical Data Query Language
+225
+226A query is a string
+227- SELECTION set of data to be selected
+228- HOW_MANY elements to select
+229- WHICH_FIELDS fields to select
+230- FROM which table
+231- WHERE condition for selection is true
+232
+233Example:
+234
+2351. Download all the data
+236 SELECT * FROM exo.EXO
+237
+2382. Download only the first 10 elements
+239 SELECT TOP 10 * FROM exo.EXO
+240
+2413. Download only the first 10 elements with SMA in the range 0.9 to 1.1
+242 SELECT TOP 10 * FROM exo.EXO WHERE SMA BETWEEN 0.9 AND 1.1
+243
+244 alternativelly
+245
+246 SELECT TOP 10 * FROM exo.EXO WHERE (0.9 <= SMA) AND (SMA <= 1.1)
+247
+2484. Download only the first 10 elements with SMA in the range 0.9 to 1.1 and CONTHAB>=0.5
+249 SELECT TOP 10 * FROM exo.EXO WHERE SMA BETWEEN 0.9 AND 1.1 AND CONTHAB>=0.5
+250
+2515. Arithmetic calculations are allowed if needed for selection so to download the first 10 elements with SMA^1.5 > 0.87
+252 SELECT TOP 10 * FROM exo.EXO WHERE power(SMA,1.5)> 0.87
+253
+2546. returns just columns SMA and CONTHAB from previous example:
+255 SELECT TOP 10 SMA,CONTHAB FROM exo.EXO WHERE power(SMA,1.5)> 0.87
+256
+257Note that the query is not sensitive to uppercase or lowercase.
+258
+259Tutorials:
+260 http://www.g-vo.org/tutorials/gaia-mock-tap.pdf
+261 http://www.ivoa.net/documents/REC/ADQL/ADQL-20081030.pdf
+262 http://www.ivoa.net/documents/
+263
+264""")
+
127defsearch(self,WHERE,SELECTION=None,FIELDS=None,TOP=None,SORT=None,as_astropy=False,as_votable=False):
+128"""download a table from the database
+129 search('') or search(WHERE='') returns all the data in the database
+130
+131 the table can be returned as :
+132 pandas dataframe (default)
+133 astropy table (as_astropy = True)
+134 votable (as_votable=True)
+135 """
+136importtime
+137#
+138adql=self.search_string(SELECTION,TOP,FIELDS,WHERE,SORT)
+139self.adql_search(adql)
+140#
+141ifas_astropy:
+142returnself._search_result.table
+143elifas_votable:
+144returnself._search_result.votable
+145else:
+146returnself._search_result.table.to_pandas()
+
+
+
+
download a table from the database
+search('') or search(WHERE='') returns all the data in the database
+
+
the table can be returned as :
+ pandas dataframe (default)
+ astropy table (as_astropy = True)
+ votable (as_votable=True)
208defdownload_map(self,URL,outfile=None,path=None):
+209"""download the fits file corresponding at a given URL
+210 if outfile is not specified the fits file name from the URL is used
+211 if path is not specified the current file is stored in the current path
+212 """
+213_path=''iftype(path)!=type('')elsepath+'/'
+214iftype(outfile)!=type(''):
+215_o=URL.split('/')[-1].split('.gz')[0]
+216_o=_path+_o
+217else:
+218_o=outfile
+219self.get_map(URL,outfile=_o)
+
+
+
+
download the fits file corresponding at a given URL
+if outfile is not specified the fits file name from the URL is used
+if path is not specified the current file is stored in the current path
+
+
+
+
+
+
+
+
+ def
+ EXPLAIN(self):
+
+
+
+
+
+
221defEXPLAIN(self):
+222"""print a short introduction on the query language"""
+223print("""
+224ADQL = Astronomical Data Query Language
+225
+226A query is a string
+227- SELECTION set of data to be selected
+228- HOW_MANY elements to select
+229- WHICH_FIELDS fields to select
+230- FROM which table
+231- WHERE condition for selection is true
+232
+233Example:
+234
+2351. Download all the data
+236 SELECT * FROM exo.EXO
+237
+2382. Download only the first 10 elements
+239 SELECT TOP 10 * FROM exo.EXO
+240
+2413. Download only the first 10 elements with SMA in the range 0.9 to 1.1
+242 SELECT TOP 10 * FROM exo.EXO WHERE SMA BETWEEN 0.9 AND 1.1
+243
+244 alternativelly
+245
+246 SELECT TOP 10 * FROM exo.EXO WHERE (0.9 <= SMA) AND (SMA <= 1.1)
+247
+2484. Download only the first 10 elements with SMA in the range 0.9 to 1.1 and CONTHAB>=0.5
+249 SELECT TOP 10 * FROM exo.EXO WHERE SMA BETWEEN 0.9 AND 1.1 AND CONTHAB>=0.5
+250
+2515. Arithmetic calculations are allowed if needed for selection so to download the first 10 elements with SMA^1.5 > 0.87
+252 SELECT TOP 10 * FROM exo.EXO WHERE power(SMA,1.5)> 0.87
+253
+2546. returns just columns SMA and CONTHAB from previous example:
+255 SELECT TOP 10 SMA,CONTHAB FROM exo.EXO WHERE power(SMA,1.5)> 0.87
+256
+257Note that the query is not sensitive to uppercase or lowercase.
+258
+259Tutorials:
+260 http://www.g-vo.org/tutorials/gaia-mock-tap.pdf
+261 http://www.ivoa.net/documents/REC/ADQL/ADQL-20081030.pdf
+262 http://www.ivoa.net/documents/
+263
+264""")
+
+
+
+
print a short introduction on the query language
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/search.js b/docs/search.js
new file mode 100644
index 0000000..9acf963
--- /dev/null
+++ b/docs/search.js
@@ -0,0 +1,46 @@
+window.pdocSearch = (function(){
+/** elasticlunr - http://weixsong.github.io * Copyright (C) 2017 Oliver Nightingale * Copyright (C) 2017 Wei Song * MIT Licensed */!function(){function e(e){if(null===e||"object"!=typeof e)return e;var t=e.constructor();for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n]);return t}var t=function(e){var n=new t.Index;return n.pipeline.add(t.trimmer,t.stopWordFilter,t.stemmer),e&&e.call(n,n),n};t.version="0.9.5",lunr=t,t.utils={},t.utils.warn=function(e){return function(t){e.console&&console.warn&&console.warn(t)}}(this),t.utils.toString=function(e){return void 0===e||null===e?"":e.toString()},t.EventEmitter=function(){this.events={}},t.EventEmitter.prototype.addListener=function(){var e=Array.prototype.slice.call(arguments),t=e.pop(),n=e;if("function"!=typeof t)throw new TypeError("last argument must be a function");n.forEach(function(e){this.hasHandler(e)||(this.events[e]=[]),this.events[e].push(t)},this)},t.EventEmitter.prototype.removeListener=function(e,t){if(this.hasHandler(e)){var n=this.events[e].indexOf(t);-1!==n&&(this.events[e].splice(n,1),0==this.events[e].length&&delete this.events[e])}},t.EventEmitter.prototype.emit=function(e){if(this.hasHandler(e)){var t=Array.prototype.slice.call(arguments,1);this.events[e].forEach(function(e){e.apply(void 0,t)},this)}},t.EventEmitter.prototype.hasHandler=function(e){return e in this.events},t.tokenizer=function(e){if(!arguments.length||null===e||void 0===e)return[];if(Array.isArray(e)){var n=e.filter(function(e){return null===e||void 0===e?!1:!0});n=n.map(function(e){return t.utils.toString(e).toLowerCase()});var i=[];return n.forEach(function(e){var n=e.split(t.tokenizer.seperator);i=i.concat(n)},this),i}return e.toString().trim().toLowerCase().split(t.tokenizer.seperator)},t.tokenizer.defaultSeperator=/[\s\-]+/,t.tokenizer.seperator=t.tokenizer.defaultSeperator,t.tokenizer.setSeperator=function(e){null!==e&&void 0!==e&&"object"==typeof e&&(t.tokenizer.seperator=e)},t.tokenizer.resetSeperator=function(){t.tokenizer.seperator=t.tokenizer.defaultSeperator},t.tokenizer.getSeperator=function(){return t.tokenizer.seperator},t.Pipeline=function(){this._queue=[]},t.Pipeline.registeredFunctions={},t.Pipeline.registerFunction=function(e,n){n in t.Pipeline.registeredFunctions&&t.utils.warn("Overwriting existing registered function: "+n),e.label=n,t.Pipeline.registeredFunctions[n]=e},t.Pipeline.getRegisteredFunction=function(e){return e in t.Pipeline.registeredFunctions!=!0?null:t.Pipeline.registeredFunctions[e]},t.Pipeline.warnIfFunctionNotRegistered=function(e){var n=e.label&&e.label in this.registeredFunctions;n||t.utils.warn("Function is not registered with pipeline. This may cause problems when serialising the index.\n",e)},t.Pipeline.load=function(e){var n=new t.Pipeline;return e.forEach(function(e){var i=t.Pipeline.getRegisteredFunction(e);if(!i)throw new Error("Cannot load un-registered function: "+e);n.add(i)}),n},t.Pipeline.prototype.add=function(){var e=Array.prototype.slice.call(arguments);e.forEach(function(e){t.Pipeline.warnIfFunctionNotRegistered(e),this._queue.push(e)},this)},t.Pipeline.prototype.after=function(e,n){t.Pipeline.warnIfFunctionNotRegistered(n);var i=this._queue.indexOf(e);if(-1===i)throw new Error("Cannot find existingFn");this._queue.splice(i+1,0,n)},t.Pipeline.prototype.before=function(e,n){t.Pipeline.warnIfFunctionNotRegistered(n);var i=this._queue.indexOf(e);if(-1===i)throw new Error("Cannot find existingFn");this._queue.splice(i,0,n)},t.Pipeline.prototype.remove=function(e){var t=this._queue.indexOf(e);-1!==t&&this._queue.splice(t,1)},t.Pipeline.prototype.run=function(e){for(var t=[],n=e.length,i=this._queue.length,o=0;n>o;o++){for(var r=e[o],s=0;i>s&&(r=this._queue[s](r,o,e),void 0!==r&&null!==r);s++);void 0!==r&&null!==r&&t.push(r)}return t},t.Pipeline.prototype.reset=function(){this._queue=[]},t.Pipeline.prototype.get=function(){return this._queue},t.Pipeline.prototype.toJSON=function(){return this._queue.map(function(e){return t.Pipeline.warnIfFunctionNotRegistered(e),e.label})},t.Index=function(){this._fields=[],this._ref="id",this.pipeline=new t.Pipeline,this.documentStore=new t.DocumentStore,this.index={},this.eventEmitter=new t.EventEmitter,this._idfCache={},this.on("add","remove","update",function(){this._idfCache={}}.bind(this))},t.Index.prototype.on=function(){var e=Array.prototype.slice.call(arguments);return this.eventEmitter.addListener.apply(this.eventEmitter,e)},t.Index.prototype.off=function(e,t){return this.eventEmitter.removeListener(e,t)},t.Index.load=function(e){e.version!==t.version&&t.utils.warn("version mismatch: current "+t.version+" importing "+e.version);var n=new this;n._fields=e.fields,n._ref=e.ref,n.documentStore=t.DocumentStore.load(e.documentStore),n.pipeline=t.Pipeline.load(e.pipeline),n.index={};for(var i in e.index)n.index[i]=t.InvertedIndex.load(e.index[i]);return n},t.Index.prototype.addField=function(e){return this._fields.push(e),this.index[e]=new t.InvertedIndex,this},t.Index.prototype.setRef=function(e){return this._ref=e,this},t.Index.prototype.saveDocument=function(e){return this.documentStore=new t.DocumentStore(e),this},t.Index.prototype.addDoc=function(e,n){if(e){var n=void 0===n?!0:n,i=e[this._ref];this.documentStore.addDoc(i,e),this._fields.forEach(function(n){var o=this.pipeline.run(t.tokenizer(e[n]));this.documentStore.addFieldLength(i,n,o.length);var r={};o.forEach(function(e){e in r?r[e]+=1:r[e]=1},this);for(var s in r){var u=r[s];u=Math.sqrt(u),this.index[n].addToken(s,{ref:i,tf:u})}},this),n&&this.eventEmitter.emit("add",e,this)}},t.Index.prototype.removeDocByRef=function(e){if(e&&this.documentStore.isDocStored()!==!1&&this.documentStore.hasDoc(e)){var t=this.documentStore.getDoc(e);this.removeDoc(t,!1)}},t.Index.prototype.removeDoc=function(e,n){if(e){var n=void 0===n?!0:n,i=e[this._ref];this.documentStore.hasDoc(i)&&(this.documentStore.removeDoc(i),this._fields.forEach(function(n){var o=this.pipeline.run(t.tokenizer(e[n]));o.forEach(function(e){this.index[n].removeToken(e,i)},this)},this),n&&this.eventEmitter.emit("remove",e,this))}},t.Index.prototype.updateDoc=function(e,t){var t=void 0===t?!0:t;this.removeDocByRef(e[this._ref],!1),this.addDoc(e,!1),t&&this.eventEmitter.emit("update",e,this)},t.Index.prototype.idf=function(e,t){var n="@"+t+"/"+e;if(Object.prototype.hasOwnProperty.call(this._idfCache,n))return this._idfCache[n];var i=this.index[t].getDocFreq(e),o=1+Math.log(this.documentStore.length/(i+1));return this._idfCache[n]=o,o},t.Index.prototype.getFields=function(){return this._fields.slice()},t.Index.prototype.search=function(e,n){if(!e)return[];e="string"==typeof e?{any:e}:JSON.parse(JSON.stringify(e));var i=null;null!=n&&(i=JSON.stringify(n));for(var o=new t.Configuration(i,this.getFields()).get(),r={},s=Object.keys(e),u=0;u0&&t.push(e);for(var i in n)"docs"!==i&&"df"!==i&&this.expandToken(e+i,t,n[i]);return t},t.InvertedIndex.prototype.toJSON=function(){return{root:this.root}},t.Configuration=function(e,n){var e=e||"";if(void 0==n||null==n)throw new Error("fields should not be null");this.config={};var i;try{i=JSON.parse(e),this.buildUserConfig(i,n)}catch(o){t.utils.warn("user configuration parse failed, will use default configuration"),this.buildDefaultConfig(n)}},t.Configuration.prototype.buildDefaultConfig=function(e){this.reset(),e.forEach(function(e){this.config[e]={boost:1,bool:"OR",expand:!1}},this)},t.Configuration.prototype.buildUserConfig=function(e,n){var i="OR",o=!1;if(this.reset(),"bool"in e&&(i=e.bool||i),"expand"in e&&(o=e.expand||o),"fields"in e)for(var r in e.fields)if(n.indexOf(r)>-1){var s=e.fields[r],u=o;void 0!=s.expand&&(u=s.expand),this.config[r]={boost:s.boost||0===s.boost?s.boost:1,bool:s.bool||i,expand:u}}else t.utils.warn("field name in user configuration not found in index instance fields");else this.addAllFields2UserConfig(i,o,n)},t.Configuration.prototype.addAllFields2UserConfig=function(e,t,n){n.forEach(function(n){this.config[n]={boost:1,bool:e,expand:t}},this)},t.Configuration.prototype.get=function(){return this.config},t.Configuration.prototype.reset=function(){this.config={}},lunr.SortedSet=function(){this.length=0,this.elements=[]},lunr.SortedSet.load=function(e){var t=new this;return t.elements=e,t.length=e.length,t},lunr.SortedSet.prototype.add=function(){var e,t;for(e=0;e1;){if(r===e)return o;e>r&&(t=o),r>e&&(n=o),i=n-t,o=t+Math.floor(i/2),r=this.elements[o]}return r===e?o:-1},lunr.SortedSet.prototype.locationFor=function(e){for(var t=0,n=this.elements.length,i=n-t,o=t+Math.floor(i/2),r=this.elements[o];i>1;)e>r&&(t=o),r>e&&(n=o),i=n-t,o=t+Math.floor(i/2),r=this.elements[o];return r>e?o:e>r?o+1:void 0},lunr.SortedSet.prototype.intersect=function(e){for(var t=new lunr.SortedSet,n=0,i=0,o=this.length,r=e.length,s=this.elements,u=e.elements;;){if(n>o-1||i>r-1)break;s[n]!==u[i]?s[n]u[i]&&i++:(t.add(s[n]),n++,i++)}return t},lunr.SortedSet.prototype.clone=function(){var e=new lunr.SortedSet;return e.elements=this.toArray(),e.length=e.elements.length,e},lunr.SortedSet.prototype.union=function(e){var t,n,i;this.length>=e.length?(t=this,n=e):(t=e,n=this),i=t.clone();for(var o=0,r=n.toArray();oA Python3 library to handle contents of ARTECS: Archive of terrestrial-type climate simulations
\n\n
http://wwwuser.oats.inaf.it/exobio/climates/\n
\n\n
through TAP and the PYVO services.
\n\n
Authors: Michele Maris (1), Marco Molinaro (1)
\n\n
(1) INAF/Trieste Astronomical Observatory\n
\n\n
First Issue: 2019 Nov 20
\n\n
Dependencies:
\n\n
This package needs: \n numpy, scipy, pandas, pyvo
\n\n
Installation
\n\n
For the latest release:
\n\n
\n
>>> pip3installpy_artecs\n
\n
\n\n
for the dev version clone this GitLab repository.
\n\n
Files in py_artecs
\n\n
__init__.py : the init file
\n\n
tap.py : the file with the TAP library
\n\n
artecs_map.py : a utility class to handle a local fits file with a Temperature MAP downloaded from the archive
\n\n
modelDB.py : a utility class to handle a local csv file with the result of a query, this module is kept for backward compatibility, but its use is deprecated
\n\n
Example of session:
\n\n
The archive is accessed from the exop_pubblic_tap in py_artecs:
\n\n
\n
>>> fromartecsimportexop_pubblic_tap\n
\n
\n\n
Then instantiate a database object
\n\n
\n
>>> atap=exop_pubblic_tap()\n
\n
\n\n
all the queries to ARTECS are made through the methods in atap.
\n\n
Queries follows the Astronomical Data Query Language (ADQL) format
\n\n
\n
>>> ptab=atap.search('power(SMA,1.5)>0.87');\n
\n
\n\n
see the appendix for further references on the ADQL.
\n\n
To know wether the search is successfull:
\n\n
\n
>>> atap.success()\nTrue\n
\n
\n\n
The result of a query is stored in ptab as a PANDAS data_frame.
\n\n
In order to save the table as a csv file use the \"to_csv\" method of pandas data frame:
\n\n
\n
>>> ptab.to_csv('result.csv',sep=' ')\n
\n
\n\n
In order to get a map corresponding to the first entry in the ptab use:
\n\n
\n
>>> TMAP=atap.get_map(ptab.URL[0])\n
\n
\n\n
the command creates a fits file to rercover the fits filename
TMAP is an object of class artecs_map, so it contains the temperature MAP in the ARTECS fits file, as well as the other keywords in the original fits file.
\n\n
Note that the artecs_map class can be used also local copies of the ARTECS temperature maps.
\n\n
At last, to perform a new query reset the old one with:
\n\n
\n
>>> atap.clear()\n
\n
\n\n
Appendix A: ADQL Queries
\n\n
A query is a string \n . SELECTION set of data to be selected\n . HOW_MANY elements to select\n . WHICH_FIELDS fields to select\n . FROM which table\n . WHERE condition for selection is true
\n\n
Examples of query strings:
\n\n\n
Download all the data:
\n\n
\n
SELECT * FROM exo.EXO
\n
\n
Download only the first 10 elements:
\n\n
\n
SELECT TOP 10 * FROM exo.EXO
\n
\n
Download only the first 10 elements with SMA in the range 0.9 to 1.1:
\n\n
\n
SELECT TOP 10 * FROM exo.EXO WHERE SMA BETWEEN 0.9 AND 1.1
\n
\n\n
alternativelly
\n\n
\n
SELECT TOP 10 * FROM exo.EXO WHERE (0.9 <= SMA) AND (SMA <= 1.1)
\n
\n
Download only the first 10 elements with SMA in the range 0.9 to 1.1 and CONTHAB>=0.5
\n\n
\n
SELECT TOP 10 * FROM exo.EXO WHERE SMA BETWEEN 0.9 AND 1.1 AND CONTHAB>=0.5
\n
\n
Arithmetic calculations are allowed if needed for selection so to download the first 10 elements with SMA^1.5 > 0.87
\n\n
\n
SELECT TOP 10 * FROM exo.EXO WHERE power(SMA,1.5)> 0.87
\n
\n
returns just columns SMA and CONTHAB from previous example:
\n\n
\n
SELECT TOP 10 SMA,CONTHAB FROM exo.EXO WHERE power(SMA,1.5)> 0.87
\n
\n\n\n
Note that the query string is not sensitive to uppercase or lowercase.
returns Murante's classifications for warm calculated from scratch\niceTOT_threshold is the ice coverage over which the planet is considered a snowball\nsuggested values 0.95 or 0.99
returns Murante's classifications for warm_hot calculated from scratch\niceTOT_threshold is the ice coverage over which the planet is considered a snowball\nsuggested values 0.95 or 0.99
returns Murante's classifications for warm_hot calculated from scratch\niceTOT_threshold is the ice coverage over which the planet is considered a snowball\nsuggested values 0.95 or 0.99
returns Murante's classifications for warm_hot calculated from scratch\niceTOT_threshold is the ice coverage over which the planet is considered a snowball\nsuggested values 0.95 or 0.99
download the fits file corresponding at a given URL\nif outfile is not specified the fits file name from the URL is used\nif path is not specified the current file is stored in the current path