Skip to content

Commit 739466c

Browse files
author
Stéphane Sénési
committed
Merge branch 'project'
Conflicts: doc/conf.py
2 parents a31a530 + 7a2773f commit 739466c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+8428
-8786
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,4 @@ examples/.ipynb_checkpoints
99
/doc/_build
1010
/README.html
1111
/doc/climaf.log
12+
climaf.log

bin/climaf

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#!/bin/bash
2+
3+
# Wrapper for launching Python while letting it import climaf.api
4+
# either interactively or on a series of files
5+
6+
# No python launch flag is allowed
7+
8+
# We assume this script is located in a subdir of climaf installation dir
9+
cdir=$(cd ..; pwd)
10+
11+
export PYTHONPATH=$PYTHONPATH:$cdir
12+
13+
if [ "$*" ] ; then
14+
(echo 'from climaf.api import *'; cat $*) | python
15+
else
16+
python -i -c 'from climaf.api import *'
17+
fi
18+

climaf/api.py

Lines changed: 73 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,46 @@
33
44
It also imports a few functions from other modules, and declares a number of 'CliMAF standard operators'
55
6-
Main functions are ``dataloc``, ``ds``, ``cdataset``, ``cdef``, ``cscript``, ``cfile``, ``cMA`` :
6+
Main functions are :
7+
8+
- for data definition and access :
9+
10+
- ``cproject``: declare a project and its non-standard attributes/facets
11+
712
- ``dataloc`` : set data locations for a series of experiments
13+
814
- ``cdef`` : define some default values for datasets attributes
9-
- ``ds`` : define a dataset object
10-
- ``cscript`` : define a new CliMAF operator (this also defines a new Pyhton fucntion)
11-
- ``cfile`` : get the file value of a CliMAF object (compute it)
15+
16+
- ``ds`` : define a dataset object (actually a front-end for ``cdataset``)
17+
18+
- ``derive`` : define a variable as computed from other variables
19+
20+
- for processing the data
21+
22+
- ``cscript`` : define a new CliMAF operator (this also defines a new Python function)
23+
1224
- ``cMA`` : get the Masked Array value of a CliMAF object (compute it)
1325
26+
- for managing/viewing results :
27+
28+
- ``cfile`` : get the file value of a CliMAF object (compute it)
29+
30+
- ``cshow`` : display a result of type 'figure'
1431
15-
Utility functions are ``clog``, ``cdump``, ``craz``, ``csave``:
16-
- ``clog`` : tune verbosity
1732
- ``cdump`` : tell what's in cache
33+
34+
- ``cdrop`` : delete the cached file for an object
35+
1836
- ``craz`` : reset cache
19-
- ``csave`` : save cache index to disk
37+
38+
- ``csync`` : save cache index to disk
39+
40+
41+
- utility functions :
42+
43+
- ``clog`` : tune verbosity
44+
45+
- ``clog_file`` : tune verbosity for log file
2046
2147
"""
2248
# Created : S.Senesi - 2014
@@ -25,22 +51,44 @@
2551
import os, os.path, shutil, logging
2652

2753
import climaf, climaf.cache
28-
from climaf.classes import cdefault as cdef,cdataset,ds #,cperiod
29-
from climaf.driver import ceval,varOf #,cfile,cobj
54+
from climaf.classes import cdef,cdataset,ds,cproject,cprojects
55+
from climaf.driver import ceval,varOf
3056
from climaf.dataloc import dataloc
3157
from climaf.operators import cscript, scripts as cscripts, derive
32-
from climaf.cache import creset as craz, csync as csave , cdump, cdrop
58+
from climaf.cache import craz, csync as csave , cdump, cdrop
3359
from clogging import clogger, clog, clog_file
3460
import climaf.standard_operators
61+
import climaf.standard_projects
62+
63+
#########################
64+
# CliMAF init phase
65+
#########################
66+
67+
Climaf_version="0.5"
3568

36-
clog(logging.ERROR)
37-
clog_file(logging.ERROR)
3869
#: Path for the CliMAF package. From here, can write e.g. ``cpath+"../scripts"``. The value shown in the doc is not meaningful for your own CliMAF install
3970
cpath=os.path.abspath(climaf.__path__[0])
40-
climaf.cache.setNewUniqueCache("~/tmp/climaf_cache")
71+
72+
# Set default logging levels
73+
clog(os.getenv("CLIMAF_LOG_LEVEL","error"))
74+
clog_file(os.getenv("CLIMAF_LOGFILE_LEVEL","info"))
75+
4176
climaf.standard_operators.load_standard_operators()
77+
climaf.standard_projects.init_standard_projects()
78+
from climaf.site_settings import onCiclad, atCNRM
79+
80+
# Read user config file
81+
conf_file=os.path.expanduser("~/.climaf")
82+
if os.path.isfile(conf_file) : execfile(conf_file, {"Climaf_version":Climaf_version })
83+
84+
# Decide for cache location
85+
climaf.cache.setNewUniqueCache(os.getenv("CLIMAF_CACHE","~/tmp/climaf_cache"))
86+
4287

88+
#########################
4389
# Commodity functions
90+
#########################
91+
4492
def cfile(object,target=None,ln=None,deep=None) :
4593
"""
4694
Provide the filename for a CliMAF object, or copy this file to target. Launch computation if needed.
@@ -49,21 +97,28 @@ def cfile(object,target=None,ln=None,deep=None) :
4997
object (CliMAF object) : either a dataset or a 'compound' object (e.g. the result of a CliMAF operator)
5098
target (str, optional) : name of the destination file or link; CliMAF will anyway store the result
5199
in its cache;
100+
52101
ln (logical, optional) : if True, target is created as a symlink to the CLiMAF cache file
53-
deep (logical, optional) : governs the use of cached values when computing the object
102+
103+
deep (logical, optional) : governs the use of cached values when computing the object:
54104
55105
- if missing, or None : use cache as much as possible (speed up the computation)
106+
56107
- False : make a shallow computation, i.e. do not use cached values for the
57108
top level operation
109+
58110
- True : make a deep computation, i.e. do not use any cached value
59111
60112
Returns:
61-
- if 'target' is provided : returns this filename if computation is successful ('target' contains the result), and None otherwise;
113+
114+
- if 'target' is provided : returns this filename (or linkname) if computation is
115+
successful ('target' contains the result), and None otherwise;
116+
62117
- else : returns the filename in CliMAF cache, which contains the result (and None if failure)
63118
64119
65120
"""
66-
clogger.debug("cfile called on"+str(object))
121+
clogger.debug("cfile called on "+str(object))
67122
result=climaf.driver.ceval(object,format='file',deep=deep)
68123
if target is None : return result
69124
else :
@@ -81,7 +136,7 @@ def cshow(obj) :
81136
For a figure object, this will lead to display it
82137
( launch computation if needed. )
83138
"""
84-
clogger.debug("cshow called on"+str(obj)) #LV
139+
clogger.debug("cshow called on "+str(obj))
85140
return climaf.driver.ceval(obj,format='MaskedArray')
86141

87142
def cMA(obj,deep=None) :
@@ -106,7 +161,7 @@ def cexport(*args,**kwargs) :
106161
""" Alias for climaf.driver.ceval. Create synonyms for arg 'format'
107162
108163
"""
109-
clogger.debug("cexport called with arguments"+str(args)) #LV
164+
clogger.debug("cexport called with arguments"+str(args))
110165
if "format" in kwargs :
111166
if (kwargs['format']=="NetCDF" or kwargs['format']=="netcdf" or kwargs['format']=="nc") :
112167
kwargs['format']="file"

climaf/cache.py

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
1-
""" CliMAF cache module : stores and retrieves CliMAF objects from their CRS expression.
1+
"""
2+
3+
CliMAF cache module : stores and retrieves CliMAF objects from their CRS expression.
4+
5+
26
37
"""
48
# Created : S.Senesi - 2014
59

610
import sys, os, os.path, re, time
7-
from climaf.classes import compare_trees
11+
from climaf.classes import compare_trees, cobject, ctree, cdataset
812

913
from clogging import clogger
1014

@@ -24,7 +28,7 @@ def setNewUniqueCache(path) :
2428
crs2filename=dict() # The index associating filenames to CRS expressions
2529
cacheIndexFileName = cachedirs[0]+"/index" # The place to write the index
2630
currentCache=cachedirs[0]
27-
creset(hideError=True)
31+
craz(hideError=True)
2832

2933
#def generateUniqueFileName(expression, operator=climaf.classes.firstGenericDataSet):
3034
def generateUniqueFileName(expression, operator=None, format="nc"):
@@ -68,7 +72,7 @@ def generateUniqueFileName(expression, operator=None, format="nc"):
6872
exit
6973
guess=full[0 : number - 1 ]
7074
existing=searchFile(prefix+stringToPath(guess, directoryNameLength )+"."+format)
71-
readCRS=getCRS(existing)
75+
if existing : readCRS=getCRS(existing)
7276
rep=currentCache+"/"+prefix+stringToPath(full[0 : number - 1 ], directoryNameLength )+"."+format
7377
rep=os.path.expanduser(rep)
7478
# Create the relevant directory, so that user scripts don't have to care
@@ -174,7 +178,7 @@ def hasMatchingObject(cobject,ds_func) :
174178
if len(crs2filename.keys()) == 0 : cload()
175179
def op_squeezes_time(operator):
176180
import operators
177-
return operators.scripts[operator].flags.doSqueezeTime
181+
return not operators.scripts[operator].flags.commuteWithTimeConcatenation
178182
#
179183
for crs in crs2filename :
180184
co=eval(crs, sys.modules['__main__'].__dict__)
@@ -221,10 +225,34 @@ def complement(crsb, crse, crs) :
221225
register(filet,crs)
222226
return filet
223227

224-
def cdrop(crs, rm=True) :
225-
""" Deletes a cached file for a given CliMAF Reference Syntax expression, if it exists
228+
def cdrop(obj, rm=True) :
229+
"""
230+
Deletes the cached file for a CliMAF object, if it exists
226231
227-
Returns None if it does not exists, False if delete is unsuccessful, True if OK """
232+
Args :
233+
obj (cobject or string) : object to delete, or its string representation (CRS)
234+
rm (bool) : for advanced use only; should we actually delete (rm) the file, or
235+
just forget it in CliMAF cache index ?
236+
237+
Returns : None if object does not exists, False if failing to delete, True if OK
238+
239+
Example ::
240+
241+
>>> dg=ds(project='example', experiment='AMIPV6ALB2G', variable='tas', period='1980-1981')
242+
>>> dg
243+
>>> cfile(dg)
244+
'/home/senesi/tmp/climaf_cache/da/c.nc'
245+
>>> os.system('ls -al '+f)
246+
>>> cdrop(dg)
247+
"""
248+
if (type(obj) is ctree ) :
249+
crs=cobject.crs
250+
if (type(obj) is cdataset ) :
251+
crs="select("+crs+")"
252+
elif type(obj) is str : crs=obj
253+
else :
254+
clogger.error("%s is not a CliMAF object"%`obj`)
255+
return
228256
if crs in crs2filename :
229257
clogger.info("discarding cached value for "+crs)
230258
try :
@@ -260,7 +288,7 @@ def cload() :
260288
except:
261289
clogger.debug("no index file yet")
262290

263-
def creset(hideError=False) :
291+
def craz(hideError=False) :
264292
"""
265293
Clear CliMAF cache : erase existing files content, reset in-memory index
266294

0 commit comments

Comments
 (0)