py_artecs.modelDb

DEPRECATED

  1"""
  2   **DEPRECATED** 
  3"""
  4
  5class modelDb :
  6   """
  7   **DEPRECATED** 
  8   
  9Class to handle a local version of the ARTECS DB.
 10
 11It takes in input a csv file generated from a query of ARTECS and saved in csv format.
 12
 13See the example in the introductory page.
 14
 15This module is kept for compatibility with early releases of py_artecs, but it is not maintained so its use is DEPRECATED.
 16
 17   """
 18   def __init__(self,project_name,project_path,csv_name,Verbose=True,csv_sep='!',csv_comment='#',csv_index_col='index',figures_path='png',filterBad=True,new=False,query=None) :
 19      import time
 20      from collections import OrderedDict
 21      from matplotlib import pyplot as plt
 22      import numpy as np
 23      import pandas
 24      import astropy
 25      #
 26      self.reset()
 27      self.reset_plot_status()
 28      #
 29      self._project_name=project_name
 30      self._project_path=project_path
 31      self._csv_name=csv_name
 32      self._figures_path=figures_path
 33      #
 34      if new : return
 35      #
 36      print()
 37      print("Reading from csv file ",self._csv_name)
 38      tic=time.time()
 39      csv=pandas.read_csv(self._project_path+'/'+self._csv_name,sep=csv_sep,comment=csv_comment,index_col=csv_index_col)
 40      if not 'TSTART' in csv.keys() : 
 41         csv['TSTART']=np.zeros(len(csv))
 42         print ("TSTART not found, replaced by a DUMMY")
 43      csv['Natm']=csv['p_surface']/csv['GRAV']
 44      csv['iclass']=np.array([self.classification_string2numeric(k.strip().lower()) for k in csv.CLASS])
 45      csv['peri']=(1-csv.ECC)*csv.SMA
 46      csv['aphe']=(1+csv.ECC)*csv.SMA
 47      self.flagBad=np.array(csv['iclass']==self._string_class_notfound)*8+np.array(csv.iclass<0)*4+np.array(np.isnan(csv.TMGLOB))*2+np.array(csv.TSTART<0)
 48      tic=time.time()-tic
 49      print("%d lines in %e sec"%(len(csv),tic))
 50      #
 51      if not 'SOURCE' in csv.keys() :
 52         csv['SOURCE']=np.zeros(len(csv))-1
 53      #
 54      if filterBad :
 55         self.TABLE=csv[self.flagBad==0]
 56      else :
 57         self.TABLE=csv
 58      #
 59      if query != None and query!='' :
 60         self.TABLE=self.TABLE.query(query)
 61      #
 62      if Verbose :
 63         print()
 64         print("In %s, containind %d models, the number of models with "%(csv_name,len(csv)))
 65         print("  CLASS  == UNKNOWN                    ",(csv.iclass==-200).sum())
 66         print("  CLASS  == SNOWBALL                   ",(csv.iclass==1).sum())
 67         print("  CLASS  == WATERBELT                  ",(csv.iclass==2).sum())
 68         print("  CLASS  == WARM                       ",(csv.iclass==3).sum())
 69         print("  CLASS  == WARM_HOT                   ",(csv.iclass==4).sum())
 70         print("  INVALID STRING IN CLASS              ",((self.flagBad>=8)).sum())
 71         print()
 72         for k in np.unique(csv['SOURCE']) :
 73            print("  SOURCE == %d                          %d"%(k,(csv.SOURCE==0).sum()))
 74         #print("  SOURCE == 1                          ",(csv.SOURCE==1).sum())
 75         print()
 76         print("  TMGLOB == NaN                        ",np.isnan(csv.TMGLOB).sum())
 77         print("  TSTART<0                             ",(csv.TSTART<0).sum())
 78         print("  TMGLOB == NaN and TSTART<0           ",((csv.TSTART<0)&np.isnan(csv.TMGLOB)).sum())
 79         print("  TMGLOB == NaN and ZCD == NaN         ",(np.isnan(csv.TMGLOB)&np.isnan(csv.zenithal_column_density)).sum())
 80         print("  TMGLOB == NaN and CLASS == UNDEFINED ",(np.isnan(csv.TMGLOB)&(csv.iclass==0)).sum())
 81         print()
 82      #
 83      del csv 
 84   def to_csv(self,outFile,COMMENT='') :
 85      print("Writing csv into ",outFile)
 86      open(outFile,'w').write('#\n#'+outFile+'\n#elaboration of '+self._csv_name+'\n#'+str(COMMENT)+'\n#!BEGIN\n')
 87      open(outFile,'a').write(self.TABLE.to_csv(None,sep='!',index_column='index'))
 88      open(outFile,'a').write('#!END\n')
 89      print("written")
 90   def reset(self) :
 91      from collections import OrderedDict
 92      for k in ['_project_name','_project_path','_csv_name','_figures_path','_project_name','_project_path','TABLE','flagBad','classTable'] :
 93         self.__dict__[k]=None
 94      self._numeric_classification=OrderedDict()
 95      self._numeric_classification['---']=-400
 96      self._numeric_classification['unknown']=-200
 97      self._numeric_classification['snowball']=1
 98      self._numeric_classification['waterbelt']=2
 99      self._numeric_classification['warm']=3
100      self._numeric_classification['warm_hot']=4
101      self._string_class_notfound=-100000
102      #
103      self._classification_labels=self._numeric_classification.keys()
104      self._ClassNames=['SNOWBALL','WATERBELT','WARM','WARM_HOT']
105      self._ClassColor={'SNOWBALL':'b','WATERBELT':'g','WARM':'r','WARM_HOT':'y'}
106      self._ClassMarker={'SNOWBALL':'o:12','WATERBELT':'v:16','WARM':'d:8','WARM_HOT':'s:6'}
107      #
108      self.iceTOT_threshold=None
109   #
110   def __len__(self) : return len(self.TABLE)
111   #
112   def __getitem__(self,this) : return self.TABLE[this]
113   #
114   def __setitem__(self,this,that) : self.TABLE[this]=that
115   #
116   def copy(self) :
117      import copy
118      out=modelDb('slice of '+self._project_name,self._project_path,None,new=True)
119      out._project_name=self._project_name
120      out._project_path=self._project_path
121      out._csv_name=None
122      out._figures_path=self._figures_path
123      out.classTable=copy.deepcopy(self.classTable)
124      return out
125   #
126   def unique_values(self) :
127      import numpy as np
128      from collections import OrderedDict
129      import pandas
130      out=OrderedDict()
131      for k in self.keys() :
132         out[k]=np.unique(self.TABLE[k].values)
133      return out
134   #
135   def list_unique_values(self) :
136      out=self.unique_values()
137      for k in out.keys() :
138         print("%s (%d) ="%(k,len(out[k])))
139      #
140   def classification_indexes(self,*arg,**karg) :
141      import numpy as np
142      from collections import OrderedDict
143      if len(arg) == 0 : 
144         _arg=['CLASS','OBLIQ','ECC','SMA','PRESS','SOURCE','GEO','FO_CONST','PROT','P_CO2']
145      else :
146         _arg=arg
147      ipfx=karg['index_pfx'] if karg.has_key('index_pfx') else 'i_'
148      for k in _arg : 
149         quit=False
150         if not k in self.keys() :
151            print("%s not found "%k)
152            quit=True
153      if quit : 
154         return
155      classTable=OrderedDict()
156      for k in arg :
157         u=self.unique(k)
158         iu=np.zeros(len(self))
159         classTable[k]=OrderedDict()
160         for cu,u in enumerate(self.unique(k)) :
161            idx=np.where(np.array(self.TABLE[k]==u))[0]
162            iu[idx]=cu
163            classTable[k][u]=[cu,len(idx)]
164         self.TABLE[ipfx+k]=iu
165      self.classTable=classTable.copy()
166      return classTable
167   #
168   def show_classTable(self) :
169      for k in DB.classTable.keys() :
170         print('%10s : %3d = '%(k,len(DB.classTable[k])),end='')
171         for ij,j in enumerate(DB.classTable[k].keys()) : 
172            if ij>0 : print ('|',end='')
173            print('%3d#'%ij,end='')
174            print('%12s'%str(j),':',end='')
175            print("%6d "%len(DB.query('i_'+k+'=='+str(ij))),end='')
176         print()
177   #
178   def unique(self,key) : 
179      import numpy as np
180      return np.sort(self.TABLE[key].unique())
181   #
182   def sort(self,sort_by) :
183      self.TABLE=self.TABLE.sort(sort_by)
184   #
185   def sorted_query(self,sort_by,qstr) :
186      out=self.copy()
187      if type(qstr) == type('') :
188         out.TABLE=self.TABLE.query(qstr)
189      else :
190         out.TABLE=self.TABLE[qstr]
191      out.TABLE=out.TABLE.sort(sort_by)
192      return out
193   #
194   def query(self,qstr) :
195      out=self.copy()
196      if type(qstr) == type('') :
197         out.TABLE=self.TABLE.query(qstr)
198      else :
199         out.TABLE=self.TABLE[qstr]
200      return out
201   #
202   def select_by_loc(self,loc_argument) :
203      out=self.copy()
204      out.TABLE=self.TABLE.loc[loc_argument]
205      return out
206   #
207   def select_by_iloc(self,iloc_argument) :
208      out=self.copy()
209      out.TABLE=self.TABLE.iloc[iloc_argument]
210      return out
211   #
212   def classification_string2numeric(self,strg) :
213      try :
214         return self._numeric_classification[strg.lower().strip()]
215      except :
216         print("bad strng ",strg)
217         return self._string_class_notfound
218   #
219   def calc_iclass(self,string_classification_array) :
220      return np.array([self._numeric_classification[k.strip().lower()] for k in string_classification_array])
221   #
222   def keys(self) : return list(self.TABLE.keys())
223   #
224   def has_key(self,this) : return (this in self.TABLE.keys())
225   #
226   def __include__(self,this) : return (this in self.TABLE.keys())
227   #
228   def reset_plot_status(self) :
229      """resets the self._last_plot dictionary where handles from the last plot generated are stored"""
230      from collections import OrderedDict
231      self._last_plot=OrderedDict()
232      self._last_plot['fig']=None
233      self._last_plot['xlabel']=None
234      self._last_plot['ylabel']=None
235      self._last_plot['axe']=None
236      self._last_plot['legend']=None
237      self._last_plot['curves']=[]
238   #
239   def plot2(self,x,y='MolecularDepth',ylog=True,xlog=False,newfig=True,legend_loc=3,xylim=None,savefig=None,one2one_line=False) :
240      """creates a 2 axis plot, the handles for the plot objects are stored in self._last_plot"""
241      from collections import OrderedDict
242      from matplotlib import pyplot as plt
243      import numpy as np
244      import pandas
245      import astropy
246      #
247      self.reset_plot_status()
248      #
249      if newfig : 
250         self._last_plot['fig']=plt.figure()
251      else :
252         self._last_plot['fig']=plt.gcf()
253      #
254      for k in self._ClassNames :  
255         smp=self.TABLE.query('CLASS=="%s"'%k)
256         self._last_plot['curves'].append(plt.plot(smp[x],smp[y],self._ClassColor[k]+self._ClassMarker[k][0],label=k,mew=0,markersize=int(self._ClassMarker[k][2:])))
257      plt.gca().set_xscale('linear' if xlog==False else 'log')
258      plt.gca().set_yscale('linear' if ylog==False else 'log')
259      plt.title(self._project_name,fontsize=20)
260      if xylim != None : plt.axis(xylim)
261      #
262      if one2one_line==True :
263         a=plt.axis()
264         x121=np.arange(0,1+0.01,0.01)
265         x121=a[0]*x121+a[1]*(1-x121)
266         self._last_plot['1:1']=plt.plot(x121,x121,'k-',lw=1)
267         self._last_plot['1:1'][0].set_zorder(-10)
268      #
269      if x=='Natm' :
270         a=plt.axis()
271         self._last_plot['STARTNATMLINES']=[plt.plot(k*np.ones(2),[a[2],a[3]],'k-',lw=2) for k in np.unique(self.TABLE['PRESS']/self.TABLE['GRAV'])]
272         for k in self._last_plot['STARTNATMLINES'] : k[0].set_zorder(-10)
273      #
274      if x=='p_surface' :
275         a=plt.axis()
276         self._last_plot['PRESS_LINES']=[plt.plot(k*np.ones(2),[a[2],a[3]],'k-',lw=2) for k in np.unique(self.TABLE['PRESS'])]
277         for k in self._last_plot['PRESS_LINES'] : k[0].set_zorder(-10)
278      #
279      self._last_plot['axe']=plt.gca()
280      if legend_loc > 0 :
281         self._last_plot['legend']=plt.legend(loc=legend_loc)
282      self._last_plot['xlabel']=plt.xlabel(x,fontsize=20)
283      self._last_plot['ylabel']=plt.ylabel(y,fontsize=20)
284      plt.gcf().set_figwidth(18.)
285      plt.gcf().set_figheight(plt.gcf().get_figwidth()*3./4.)
286      if savefig != None and savefig != False:
287         if type(savefig)==type('') and savefig!='' :
288            _savefig=savefig
289         else :
290            _savefig=self._project_name+'/'+self._figures_path+'/'+y+'_vz_'+x+'.pdf'
291         print("Saving in ",_savefig)
292         plt.savefig(_savefig,dpi=plt.gcf().get_dpi())
293      plt.show()
294   #
295   def set_iceTOT_threshold(self,iceTOT_threshold) :
296      """ set iceTOT_threshold : the ice coverage over which the planet is considered a snowball
297suggested values 0.95 or 0.99
298      """
299      self.iceTOT_threshold=iceTOT_threshold
300   #
301   def flag_class_warm(self) :
302      """returns Murante's classifications for warm calculated from scratch
303iceTOT_threshold is the ice coverage over which the planet is considered a snowball
304suggested values 0.95 or 0.99
305      """
306      import numpy as np
307      if not self.iceTOT_threshold() : return
308      return (self.TABLE['TMGLOB'] > self.TABLE['Tice']) * (self.TABLE['TMGLOB'] < self.TABLE['Tvap'])
309      
310   def flag_class_warm_hot(self) :
311      """returns Murante's classifications for warm_hot calculated from scratch
312iceTOT_threshold is the ice coverage over which the planet is considered a snowball
313suggested values 0.95 or 0.99
314      """
315      import numpy as np
316      if not self.iceTOT_threshold() : return
317      return (self.TABLE['TMGLOB'] >= self.TABLE['Tvap'])
318      
319   def flag_class_snowball(self) :
320      """returns Murante's classifications for warm_hot calculated from scratch
321iceTOT_threshold is the ice coverage over which the planet is considered a snowball
322suggested values 0.95 or 0.99
323      """
324      import numpy as np
325      if not self.iceTOT_threshold() : return
326      return (self.TABLE['ICE'] > self.iceTOT_threshold)
327      
328   def flag_class_waterbelt(self) :
329      """returns Murante's classifications for warm_hot calculated from scratch
330iceTOT_threshold is the ice coverage over which the planet is considered a snowball
331suggested values 0.95 or 0.99
332      """
333      import numpy as np
334      if not self.iceTOT_threshold() : return
335      return (self.TABLE['TMGLOB'] <= self.TABLE['Tice'])*(self.TABLE['ICE'] <= self.iceTOT_threshold)
336   
337   def _testIceTot(self) :
338      if self.iceTOT_threshold == None :
339         raise Exception("iceTOT_threshold not set, Set iceTOT_threshold with .set_iceTOT_threshold(x) before")
340         return False
341      return True
class modelDb:
  6class modelDb :
  7   """
  8   **DEPRECATED** 
  9   
 10Class to handle a local version of the ARTECS DB.
 11
 12It takes in input a csv file generated from a query of ARTECS and saved in csv format.
 13
 14See the example in the introductory page.
 15
 16This module is kept for compatibility with early releases of py_artecs, but it is not maintained so its use is DEPRECATED.
 17
 18   """
 19   def __init__(self,project_name,project_path,csv_name,Verbose=True,csv_sep='!',csv_comment='#',csv_index_col='index',figures_path='png',filterBad=True,new=False,query=None) :
 20      import time
 21      from collections import OrderedDict
 22      from matplotlib import pyplot as plt
 23      import numpy as np
 24      import pandas
 25      import astropy
 26      #
 27      self.reset()
 28      self.reset_plot_status()
 29      #
 30      self._project_name=project_name
 31      self._project_path=project_path
 32      self._csv_name=csv_name
 33      self._figures_path=figures_path
 34      #
 35      if new : return
 36      #
 37      print()
 38      print("Reading from csv file ",self._csv_name)
 39      tic=time.time()
 40      csv=pandas.read_csv(self._project_path+'/'+self._csv_name,sep=csv_sep,comment=csv_comment,index_col=csv_index_col)
 41      if not 'TSTART' in csv.keys() : 
 42         csv['TSTART']=np.zeros(len(csv))
 43         print ("TSTART not found, replaced by a DUMMY")
 44      csv['Natm']=csv['p_surface']/csv['GRAV']
 45      csv['iclass']=np.array([self.classification_string2numeric(k.strip().lower()) for k in csv.CLASS])
 46      csv['peri']=(1-csv.ECC)*csv.SMA
 47      csv['aphe']=(1+csv.ECC)*csv.SMA
 48      self.flagBad=np.array(csv['iclass']==self._string_class_notfound)*8+np.array(csv.iclass<0)*4+np.array(np.isnan(csv.TMGLOB))*2+np.array(csv.TSTART<0)
 49      tic=time.time()-tic
 50      print("%d lines in %e sec"%(len(csv),tic))
 51      #
 52      if not 'SOURCE' in csv.keys() :
 53         csv['SOURCE']=np.zeros(len(csv))-1
 54      #
 55      if filterBad :
 56         self.TABLE=csv[self.flagBad==0]
 57      else :
 58         self.TABLE=csv
 59      #
 60      if query != None and query!='' :
 61         self.TABLE=self.TABLE.query(query)
 62      #
 63      if Verbose :
 64         print()
 65         print("In %s, containind %d models, the number of models with "%(csv_name,len(csv)))
 66         print("  CLASS  == UNKNOWN                    ",(csv.iclass==-200).sum())
 67         print("  CLASS  == SNOWBALL                   ",(csv.iclass==1).sum())
 68         print("  CLASS  == WATERBELT                  ",(csv.iclass==2).sum())
 69         print("  CLASS  == WARM                       ",(csv.iclass==3).sum())
 70         print("  CLASS  == WARM_HOT                   ",(csv.iclass==4).sum())
 71         print("  INVALID STRING IN CLASS              ",((self.flagBad>=8)).sum())
 72         print()
 73         for k in np.unique(csv['SOURCE']) :
 74            print("  SOURCE == %d                          %d"%(k,(csv.SOURCE==0).sum()))
 75         #print("  SOURCE == 1                          ",(csv.SOURCE==1).sum())
 76         print()
 77         print("  TMGLOB == NaN                        ",np.isnan(csv.TMGLOB).sum())
 78         print("  TSTART<0                             ",(csv.TSTART<0).sum())
 79         print("  TMGLOB == NaN and TSTART<0           ",((csv.TSTART<0)&np.isnan(csv.TMGLOB)).sum())
 80         print("  TMGLOB == NaN and ZCD == NaN         ",(np.isnan(csv.TMGLOB)&np.isnan(csv.zenithal_column_density)).sum())
 81         print("  TMGLOB == NaN and CLASS == UNDEFINED ",(np.isnan(csv.TMGLOB)&(csv.iclass==0)).sum())
 82         print()
 83      #
 84      del csv 
 85   def to_csv(self,outFile,COMMENT='') :
 86      print("Writing csv into ",outFile)
 87      open(outFile,'w').write('#\n#'+outFile+'\n#elaboration of '+self._csv_name+'\n#'+str(COMMENT)+'\n#!BEGIN\n')
 88      open(outFile,'a').write(self.TABLE.to_csv(None,sep='!',index_column='index'))
 89      open(outFile,'a').write('#!END\n')
 90      print("written")
 91   def reset(self) :
 92      from collections import OrderedDict
 93      for k in ['_project_name','_project_path','_csv_name','_figures_path','_project_name','_project_path','TABLE','flagBad','classTable'] :
 94         self.__dict__[k]=None
 95      self._numeric_classification=OrderedDict()
 96      self._numeric_classification['---']=-400
 97      self._numeric_classification['unknown']=-200
 98      self._numeric_classification['snowball']=1
 99      self._numeric_classification['waterbelt']=2
100      self._numeric_classification['warm']=3
101      self._numeric_classification['warm_hot']=4
102      self._string_class_notfound=-100000
103      #
104      self._classification_labels=self._numeric_classification.keys()
105      self._ClassNames=['SNOWBALL','WATERBELT','WARM','WARM_HOT']
106      self._ClassColor={'SNOWBALL':'b','WATERBELT':'g','WARM':'r','WARM_HOT':'y'}
107      self._ClassMarker={'SNOWBALL':'o:12','WATERBELT':'v:16','WARM':'d:8','WARM_HOT':'s:6'}
108      #
109      self.iceTOT_threshold=None
110   #
111   def __len__(self) : return len(self.TABLE)
112   #
113   def __getitem__(self,this) : return self.TABLE[this]
114   #
115   def __setitem__(self,this,that) : self.TABLE[this]=that
116   #
117   def copy(self) :
118      import copy
119      out=modelDb('slice of '+self._project_name,self._project_path,None,new=True)
120      out._project_name=self._project_name
121      out._project_path=self._project_path
122      out._csv_name=None
123      out._figures_path=self._figures_path
124      out.classTable=copy.deepcopy(self.classTable)
125      return out
126   #
127   def unique_values(self) :
128      import numpy as np
129      from collections import OrderedDict
130      import pandas
131      out=OrderedDict()
132      for k in self.keys() :
133         out[k]=np.unique(self.TABLE[k].values)
134      return out
135   #
136   def list_unique_values(self) :
137      out=self.unique_values()
138      for k in out.keys() :
139         print("%s (%d) ="%(k,len(out[k])))
140      #
141   def classification_indexes(self,*arg,**karg) :
142      import numpy as np
143      from collections import OrderedDict
144      if len(arg) == 0 : 
145         _arg=['CLASS','OBLIQ','ECC','SMA','PRESS','SOURCE','GEO','FO_CONST','PROT','P_CO2']
146      else :
147         _arg=arg
148      ipfx=karg['index_pfx'] if karg.has_key('index_pfx') else 'i_'
149      for k in _arg : 
150         quit=False
151         if not k in self.keys() :
152            print("%s not found "%k)
153            quit=True
154      if quit : 
155         return
156      classTable=OrderedDict()
157      for k in arg :
158         u=self.unique(k)
159         iu=np.zeros(len(self))
160         classTable[k]=OrderedDict()
161         for cu,u in enumerate(self.unique(k)) :
162            idx=np.where(np.array(self.TABLE[k]==u))[0]
163            iu[idx]=cu
164            classTable[k][u]=[cu,len(idx)]
165         self.TABLE[ipfx+k]=iu
166      self.classTable=classTable.copy()
167      return classTable
168   #
169   def show_classTable(self) :
170      for k in DB.classTable.keys() :
171         print('%10s : %3d = '%(k,len(DB.classTable[k])),end='')
172         for ij,j in enumerate(DB.classTable[k].keys()) : 
173            if ij>0 : print ('|',end='')
174            print('%3d#'%ij,end='')
175            print('%12s'%str(j),':',end='')
176            print("%6d "%len(DB.query('i_'+k+'=='+str(ij))),end='')
177         print()
178   #
179   def unique(self,key) : 
180      import numpy as np
181      return np.sort(self.TABLE[key].unique())
182   #
183   def sort(self,sort_by) :
184      self.TABLE=self.TABLE.sort(sort_by)
185   #
186   def sorted_query(self,sort_by,qstr) :
187      out=self.copy()
188      if type(qstr) == type('') :
189         out.TABLE=self.TABLE.query(qstr)
190      else :
191         out.TABLE=self.TABLE[qstr]
192      out.TABLE=out.TABLE.sort(sort_by)
193      return out
194   #
195   def query(self,qstr) :
196      out=self.copy()
197      if type(qstr) == type('') :
198         out.TABLE=self.TABLE.query(qstr)
199      else :
200         out.TABLE=self.TABLE[qstr]
201      return out
202   #
203   def select_by_loc(self,loc_argument) :
204      out=self.copy()
205      out.TABLE=self.TABLE.loc[loc_argument]
206      return out
207   #
208   def select_by_iloc(self,iloc_argument) :
209      out=self.copy()
210      out.TABLE=self.TABLE.iloc[iloc_argument]
211      return out
212   #
213   def classification_string2numeric(self,strg) :
214      try :
215         return self._numeric_classification[strg.lower().strip()]
216      except :
217         print("bad strng ",strg)
218         return self._string_class_notfound
219   #
220   def calc_iclass(self,string_classification_array) :
221      return np.array([self._numeric_classification[k.strip().lower()] for k in string_classification_array])
222   #
223   def keys(self) : return list(self.TABLE.keys())
224   #
225   def has_key(self,this) : return (this in self.TABLE.keys())
226   #
227   def __include__(self,this) : return (this in self.TABLE.keys())
228   #
229   def reset_plot_status(self) :
230      """resets the self._last_plot dictionary where handles from the last plot generated are stored"""
231      from collections import OrderedDict
232      self._last_plot=OrderedDict()
233      self._last_plot['fig']=None
234      self._last_plot['xlabel']=None
235      self._last_plot['ylabel']=None
236      self._last_plot['axe']=None
237      self._last_plot['legend']=None
238      self._last_plot['curves']=[]
239   #
240   def plot2(self,x,y='MolecularDepth',ylog=True,xlog=False,newfig=True,legend_loc=3,xylim=None,savefig=None,one2one_line=False) :
241      """creates a 2 axis plot, the handles for the plot objects are stored in self._last_plot"""
242      from collections import OrderedDict
243      from matplotlib import pyplot as plt
244      import numpy as np
245      import pandas
246      import astropy
247      #
248      self.reset_plot_status()
249      #
250      if newfig : 
251         self._last_plot['fig']=plt.figure()
252      else :
253         self._last_plot['fig']=plt.gcf()
254      #
255      for k in self._ClassNames :  
256         smp=self.TABLE.query('CLASS=="%s"'%k)
257         self._last_plot['curves'].append(plt.plot(smp[x],smp[y],self._ClassColor[k]+self._ClassMarker[k][0],label=k,mew=0,markersize=int(self._ClassMarker[k][2:])))
258      plt.gca().set_xscale('linear' if xlog==False else 'log')
259      plt.gca().set_yscale('linear' if ylog==False else 'log')
260      plt.title(self._project_name,fontsize=20)
261      if xylim != None : plt.axis(xylim)
262      #
263      if one2one_line==True :
264         a=plt.axis()
265         x121=np.arange(0,1+0.01,0.01)
266         x121=a[0]*x121+a[1]*(1-x121)
267         self._last_plot['1:1']=plt.plot(x121,x121,'k-',lw=1)
268         self._last_plot['1:1'][0].set_zorder(-10)
269      #
270      if x=='Natm' :
271         a=plt.axis()
272         self._last_plot['STARTNATMLINES']=[plt.plot(k*np.ones(2),[a[2],a[3]],'k-',lw=2) for k in np.unique(self.TABLE['PRESS']/self.TABLE['GRAV'])]
273         for k in self._last_plot['STARTNATMLINES'] : k[0].set_zorder(-10)
274      #
275      if x=='p_surface' :
276         a=plt.axis()
277         self._last_plot['PRESS_LINES']=[plt.plot(k*np.ones(2),[a[2],a[3]],'k-',lw=2) for k in np.unique(self.TABLE['PRESS'])]
278         for k in self._last_plot['PRESS_LINES'] : k[0].set_zorder(-10)
279      #
280      self._last_plot['axe']=plt.gca()
281      if legend_loc > 0 :
282         self._last_plot['legend']=plt.legend(loc=legend_loc)
283      self._last_plot['xlabel']=plt.xlabel(x,fontsize=20)
284      self._last_plot['ylabel']=plt.ylabel(y,fontsize=20)
285      plt.gcf().set_figwidth(18.)
286      plt.gcf().set_figheight(plt.gcf().get_figwidth()*3./4.)
287      if savefig != None and savefig != False:
288         if type(savefig)==type('') and savefig!='' :
289            _savefig=savefig
290         else :
291            _savefig=self._project_name+'/'+self._figures_path+'/'+y+'_vz_'+x+'.pdf'
292         print("Saving in ",_savefig)
293         plt.savefig(_savefig,dpi=plt.gcf().get_dpi())
294      plt.show()
295   #
296   def set_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      """
300      self.iceTOT_threshold=iceTOT_threshold
301   #
302   def flag_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      """
307      import numpy as np
308      if not self.iceTOT_threshold() : return
309      return (self.TABLE['TMGLOB'] > self.TABLE['Tice']) * (self.TABLE['TMGLOB'] < self.TABLE['Tvap'])
310      
311   def flag_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      """
316      import numpy as np
317      if not self.iceTOT_threshold() : return
318      return (self.TABLE['TMGLOB'] >= self.TABLE['Tvap'])
319      
320   def flag_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      """
325      import numpy as np
326      if not self.iceTOT_threshold() : return
327      return (self.TABLE['ICE'] > self.iceTOT_threshold)
328      
329   def flag_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      """
334      import numpy as np
335      if not self.iceTOT_threshold() : return
336      return (self.TABLE['TMGLOB'] <= self.TABLE['Tice'])*(self.TABLE['ICE'] <= self.iceTOT_threshold)
337   
338   def _testIceTot(self) :
339      if self.iceTOT_threshold == None :
340         raise Exception("iceTOT_threshold not set, Set iceTOT_threshold with .set_iceTOT_threshold(x) before")
341         return False
342      return True

DEPRECATED

Class to handle a local version of the ARTECS DB.

It takes in input a csv file generated from a query of ARTECS and saved in csv format.

See the example in the introductory page.

This module is kept for compatibility with early releases of py_artecs, but it is not maintained so its use is DEPRECATED.

modelDb( project_name, project_path, csv_name, Verbose=True, csv_sep='!', csv_comment='#', csv_index_col='index', figures_path='png', filterBad=True, new=False, query=None)
19   def __init__(self,project_name,project_path,csv_name,Verbose=True,csv_sep='!',csv_comment='#',csv_index_col='index',figures_path='png',filterBad=True,new=False,query=None) :
20      import time
21      from collections import OrderedDict
22      from matplotlib import pyplot as plt
23      import numpy as np
24      import pandas
25      import astropy
26      #
27      self.reset()
28      self.reset_plot_status()
29      #
30      self._project_name=project_name
31      self._project_path=project_path
32      self._csv_name=csv_name
33      self._figures_path=figures_path
34      #
35      if new : return
36      #
37      print()
38      print("Reading from csv file ",self._csv_name)
39      tic=time.time()
40      csv=pandas.read_csv(self._project_path+'/'+self._csv_name,sep=csv_sep,comment=csv_comment,index_col=csv_index_col)
41      if not 'TSTART' in csv.keys() : 
42         csv['TSTART']=np.zeros(len(csv))
43         print ("TSTART not found, replaced by a DUMMY")
44      csv['Natm']=csv['p_surface']/csv['GRAV']
45      csv['iclass']=np.array([self.classification_string2numeric(k.strip().lower()) for k in csv.CLASS])
46      csv['peri']=(1-csv.ECC)*csv.SMA
47      csv['aphe']=(1+csv.ECC)*csv.SMA
48      self.flagBad=np.array(csv['iclass']==self._string_class_notfound)*8+np.array(csv.iclass<0)*4+np.array(np.isnan(csv.TMGLOB))*2+np.array(csv.TSTART<0)
49      tic=time.time()-tic
50      print("%d lines in %e sec"%(len(csv),tic))
51      #
52      if not 'SOURCE' in csv.keys() :
53         csv['SOURCE']=np.zeros(len(csv))-1
54      #
55      if filterBad :
56         self.TABLE=csv[self.flagBad==0]
57      else :
58         self.TABLE=csv
59      #
60      if query != None and query!='' :
61         self.TABLE=self.TABLE.query(query)
62      #
63      if Verbose :
64         print()
65         print("In %s, containind %d models, the number of models with "%(csv_name,len(csv)))
66         print("  CLASS  == UNKNOWN                    ",(csv.iclass==-200).sum())
67         print("  CLASS  == SNOWBALL                   ",(csv.iclass==1).sum())
68         print("  CLASS  == WATERBELT                  ",(csv.iclass==2).sum())
69         print("  CLASS  == WARM                       ",(csv.iclass==3).sum())
70         print("  CLASS  == WARM_HOT                   ",(csv.iclass==4).sum())
71         print("  INVALID STRING IN CLASS              ",((self.flagBad>=8)).sum())
72         print()
73         for k in np.unique(csv['SOURCE']) :
74            print("  SOURCE == %d                          %d"%(k,(csv.SOURCE==0).sum()))
75         #print("  SOURCE == 1                          ",(csv.SOURCE==1).sum())
76         print()
77         print("  TMGLOB == NaN                        ",np.isnan(csv.TMGLOB).sum())
78         print("  TSTART<0                             ",(csv.TSTART<0).sum())
79         print("  TMGLOB == NaN and TSTART<0           ",((csv.TSTART<0)&np.isnan(csv.TMGLOB)).sum())
80         print("  TMGLOB == NaN and ZCD == NaN         ",(np.isnan(csv.TMGLOB)&np.isnan(csv.zenithal_column_density)).sum())
81         print("  TMGLOB == NaN and CLASS == UNDEFINED ",(np.isnan(csv.TMGLOB)&(csv.iclass==0)).sum())
82         print()
83      #
84      del csv 
def to_csv(self, outFile, COMMENT=''):
85   def to_csv(self,outFile,COMMENT='') :
86      print("Writing csv into ",outFile)
87      open(outFile,'w').write('#\n#'+outFile+'\n#elaboration of '+self._csv_name+'\n#'+str(COMMENT)+'\n#!BEGIN\n')
88      open(outFile,'a').write(self.TABLE.to_csv(None,sep='!',index_column='index'))
89      open(outFile,'a').write('#!END\n')
90      print("written")
def reset(self):
 91   def reset(self) :
 92      from collections import OrderedDict
 93      for k in ['_project_name','_project_path','_csv_name','_figures_path','_project_name','_project_path','TABLE','flagBad','classTable'] :
 94         self.__dict__[k]=None
 95      self._numeric_classification=OrderedDict()
 96      self._numeric_classification['---']=-400
 97      self._numeric_classification['unknown']=-200
 98      self._numeric_classification['snowball']=1
 99      self._numeric_classification['waterbelt']=2
100      self._numeric_classification['warm']=3
101      self._numeric_classification['warm_hot']=4
102      self._string_class_notfound=-100000
103      #
104      self._classification_labels=self._numeric_classification.keys()
105      self._ClassNames=['SNOWBALL','WATERBELT','WARM','WARM_HOT']
106      self._ClassColor={'SNOWBALL':'b','WATERBELT':'g','WARM':'r','WARM_HOT':'y'}
107      self._ClassMarker={'SNOWBALL':'o:12','WATERBELT':'v:16','WARM':'d:8','WARM_HOT':'s:6'}
108      #
109      self.iceTOT_threshold=None
def copy(self):
117   def copy(self) :
118      import copy
119      out=modelDb('slice of '+self._project_name,self._project_path,None,new=True)
120      out._project_name=self._project_name
121      out._project_path=self._project_path
122      out._csv_name=None
123      out._figures_path=self._figures_path
124      out.classTable=copy.deepcopy(self.classTable)
125      return out
def unique_values(self):
127   def unique_values(self) :
128      import numpy as np
129      from collections import OrderedDict
130      import pandas
131      out=OrderedDict()
132      for k in self.keys() :
133         out[k]=np.unique(self.TABLE[k].values)
134      return out
def list_unique_values(self):
136   def list_unique_values(self) :
137      out=self.unique_values()
138      for k in out.keys() :
139         print("%s (%d) ="%(k,len(out[k])))
140      #
def classification_indexes(self, *arg, **karg):
141   def classification_indexes(self,*arg,**karg) :
142      import numpy as np
143      from collections import OrderedDict
144      if len(arg) == 0 : 
145         _arg=['CLASS','OBLIQ','ECC','SMA','PRESS','SOURCE','GEO','FO_CONST','PROT','P_CO2']
146      else :
147         _arg=arg
148      ipfx=karg['index_pfx'] if karg.has_key('index_pfx') else 'i_'
149      for k in _arg : 
150         quit=False
151         if not k in self.keys() :
152            print("%s not found "%k)
153            quit=True
154      if quit : 
155         return
156      classTable=OrderedDict()
157      for k in arg :
158         u=self.unique(k)
159         iu=np.zeros(len(self))
160         classTable[k]=OrderedDict()
161         for cu,u in enumerate(self.unique(k)) :
162            idx=np.where(np.array(self.TABLE[k]==u))[0]
163            iu[idx]=cu
164            classTable[k][u]=[cu,len(idx)]
165         self.TABLE[ipfx+k]=iu
166      self.classTable=classTable.copy()
167      return classTable
def show_classTable(self):
169   def show_classTable(self) :
170      for k in DB.classTable.keys() :
171         print('%10s : %3d = '%(k,len(DB.classTable[k])),end='')
172         for ij,j in enumerate(DB.classTable[k].keys()) : 
173            if ij>0 : print ('|',end='')
174            print('%3d#'%ij,end='')
175            print('%12s'%str(j),':',end='')
176            print("%6d "%len(DB.query('i_'+k+'=='+str(ij))),end='')
177         print()
def unique(self, key):
179   def unique(self,key) : 
180      import numpy as np
181      return np.sort(self.TABLE[key].unique())
def sort(self, sort_by):
183   def sort(self,sort_by) :
184      self.TABLE=self.TABLE.sort(sort_by)
def sorted_query(self, sort_by, qstr):
186   def sorted_query(self,sort_by,qstr) :
187      out=self.copy()
188      if type(qstr) == type('') :
189         out.TABLE=self.TABLE.query(qstr)
190      else :
191         out.TABLE=self.TABLE[qstr]
192      out.TABLE=out.TABLE.sort(sort_by)
193      return out
def query(self, qstr):
195   def query(self,qstr) :
196      out=self.copy()
197      if type(qstr) == type('') :
198         out.TABLE=self.TABLE.query(qstr)
199      else :
200         out.TABLE=self.TABLE[qstr]
201      return out
def select_by_loc(self, loc_argument):
203   def select_by_loc(self,loc_argument) :
204      out=self.copy()
205      out.TABLE=self.TABLE.loc[loc_argument]
206      return out
def select_by_iloc(self, iloc_argument):
208   def select_by_iloc(self,iloc_argument) :
209      out=self.copy()
210      out.TABLE=self.TABLE.iloc[iloc_argument]
211      return out
def classification_string2numeric(self, strg):
213   def classification_string2numeric(self,strg) :
214      try :
215         return self._numeric_classification[strg.lower().strip()]
216      except :
217         print("bad strng ",strg)
218         return self._string_class_notfound
def calc_iclass(self, string_classification_array):
220   def calc_iclass(self,string_classification_array) :
221      return np.array([self._numeric_classification[k.strip().lower()] for k in string_classification_array])
def keys(self):
223   def keys(self) : return list(self.TABLE.keys())
def has_key(self, this):
225   def has_key(self,this) : return (this in self.TABLE.keys())
def reset_plot_status(self):
229   def reset_plot_status(self) :
230      """resets the self._last_plot dictionary where handles from the last plot generated are stored"""
231      from collections import OrderedDict
232      self._last_plot=OrderedDict()
233      self._last_plot['fig']=None
234      self._last_plot['xlabel']=None
235      self._last_plot['ylabel']=None
236      self._last_plot['axe']=None
237      self._last_plot['legend']=None
238      self._last_plot['curves']=[]

resets the self._last_plot dictionary where handles from the last plot generated are stored

def plot2( self, x, y='MolecularDepth', ylog=True, xlog=False, newfig=True, legend_loc=3, xylim=None, savefig=None, one2one_line=False):
240   def plot2(self,x,y='MolecularDepth',ylog=True,xlog=False,newfig=True,legend_loc=3,xylim=None,savefig=None,one2one_line=False) :
241      """creates a 2 axis plot, the handles for the plot objects are stored in self._last_plot"""
242      from collections import OrderedDict
243      from matplotlib import pyplot as plt
244      import numpy as np
245      import pandas
246      import astropy
247      #
248      self.reset_plot_status()
249      #
250      if newfig : 
251         self._last_plot['fig']=plt.figure()
252      else :
253         self._last_plot['fig']=plt.gcf()
254      #
255      for k in self._ClassNames :  
256         smp=self.TABLE.query('CLASS=="%s"'%k)
257         self._last_plot['curves'].append(plt.plot(smp[x],smp[y],self._ClassColor[k]+self._ClassMarker[k][0],label=k,mew=0,markersize=int(self._ClassMarker[k][2:])))
258      plt.gca().set_xscale('linear' if xlog==False else 'log')
259      plt.gca().set_yscale('linear' if ylog==False else 'log')
260      plt.title(self._project_name,fontsize=20)
261      if xylim != None : plt.axis(xylim)
262      #
263      if one2one_line==True :
264         a=plt.axis()
265         x121=np.arange(0,1+0.01,0.01)
266         x121=a[0]*x121+a[1]*(1-x121)
267         self._last_plot['1:1']=plt.plot(x121,x121,'k-',lw=1)
268         self._last_plot['1:1'][0].set_zorder(-10)
269      #
270      if x=='Natm' :
271         a=plt.axis()
272         self._last_plot['STARTNATMLINES']=[plt.plot(k*np.ones(2),[a[2],a[3]],'k-',lw=2) for k in np.unique(self.TABLE['PRESS']/self.TABLE['GRAV'])]
273         for k in self._last_plot['STARTNATMLINES'] : k[0].set_zorder(-10)
274      #
275      if x=='p_surface' :
276         a=plt.axis()
277         self._last_plot['PRESS_LINES']=[plt.plot(k*np.ones(2),[a[2],a[3]],'k-',lw=2) for k in np.unique(self.TABLE['PRESS'])]
278         for k in self._last_plot['PRESS_LINES'] : k[0].set_zorder(-10)
279      #
280      self._last_plot['axe']=plt.gca()
281      if legend_loc > 0 :
282         self._last_plot['legend']=plt.legend(loc=legend_loc)
283      self._last_plot['xlabel']=plt.xlabel(x,fontsize=20)
284      self._last_plot['ylabel']=plt.ylabel(y,fontsize=20)
285      plt.gcf().set_figwidth(18.)
286      plt.gcf().set_figheight(plt.gcf().get_figwidth()*3./4.)
287      if savefig != None and savefig != False:
288         if type(savefig)==type('') and savefig!='' :
289            _savefig=savefig
290         else :
291            _savefig=self._project_name+'/'+self._figures_path+'/'+y+'_vz_'+x+'.pdf'
292         print("Saving in ",_savefig)
293         plt.savefig(_savefig,dpi=plt.gcf().get_dpi())
294      plt.show()

creates a 2 axis plot, the handles for the plot objects are stored in self._last_plot

def set_iceTOT_threshold(self, iceTOT_threshold):
296   def set_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      """
300      self.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):
302   def flag_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      """
307      import numpy as np
308      if not self.iceTOT_threshold() : return
309      return (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):
311   def flag_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      """
316      import numpy as np
317      if not self.iceTOT_threshold() : return
318      return (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):
320   def flag_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      """
325      import numpy as np
326      if not self.iceTOT_threshold() : return
327      return (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):
329   def flag_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      """
334      import numpy as np
335      if not self.iceTOT_threshold() : return
336      return (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