Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
C
CTDAS
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Deploy
Releases
Package registry
Container registry
Model registry
Operate
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
NearRealTimeCTDAS
CTDAS
Commits
ad278492
Commit
ad278492
authored
12 years ago
by
karolina
Browse files
Options
Downloads
Patches
Plain Diff
No commit message
No commit message
parent
98e0e626
Branches
Branches containing commit
No related tags found
No related merge requests found
Changes
3
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
da/tools/io.py
+121
-326
121 additions, 326 deletions
da/tools/io.py
da/tools/io4.py
+118
-402
118 additions, 402 deletions
da/tools/io4.py
da/tools/io_cdf.py
+84
-103
84 additions, 103 deletions
da/tools/io_cdf.py
with
323 additions
and
831 deletions
da/tools/io.py
+
121
−
326
View file @
ad278492
...
...
@@ -9,403 +9,198 @@ File created on 15 Oct 2008.
File modified for CT data assimilation system in July 2010, Wouter Peters
"""
import
standardvariables
import
pycdf
as
CDF
import
datetime
as
dt
from
numpy
import
array
import
os
disclaimer
=
"
This data belongs to the CarbonTracker project
"
email
=
"
wouter.peters@wur.nl
"
url
=
"
http://carbontracker.wur.nl
"
disclaimer
=
"
This data belongs to the CarbonTracker project
"
email
=
"
wouter.peters@wur.nl
"
url
=
"
http://carbontracker.wur.nl
"
institution
=
"
Wageningen University and Research Center
"
source
=
"
CarbonTracker release 2.0
"
source
=
"
CarbonTracker release 2.0
"
conventions
=
"
CF-1.1
"
historytext
=
'
Created on
'
+
dt
.
datetime
.
now
().
strftime
(
'
%B %d, %Y
'
)
+
'
by %s
'
%
os
.
environ
[
'
USER
'
]
historytext
=
'
Created on
'
+
dt
.
datetime
.
now
().
strftime
(
'
%B %d, %Y
'
)
+
'
by %s
'
%
os
.
environ
[
'
USER
'
]
std_savedict
=
{
'
name
'
:
'
unknown
'
,
'
values
'
:
None
,
'
dims
'
:
None
,
'
units
'
:
''
,
'
long_name
'
:
''
,
'
_FillValue
'
:
float
(
-
999.
),
'
comment
'
:
''
}
class
CT_CDF
(
object
):
"""
The CT_CDF object is a wrapper around the NIO functionality offered by NCAR
'
s Nio library. It can read+write data in many formats, including
NetCDF, HDF, and GRIB. The CT_CDF class is able to make an instance of an Nio file object, and automatically add (meta)data to it in
a format that complies with CF-1.1 conventions.
The user can specify a filename when creating an instance of the CT_CDF object, as well as all arguments used by the Nio.open_file function.
An object is returned that holds the Nio file handle in self.file, as well as some global attributes we want in each file coming out of
this data assimilation system.
The methods of the CT_CDF object are:
AddCTHeader() : Adds a standard header to the file with information about date, user, system, contact person, and a disclaimer.
AddParamsDim() : Add a dimension called
'
nparams
'
AddLatLonDim() : Add two dimension called
'
latitude
'
and
'
longitude
'
AddMembersDim() : Add a dimension called
'
nmembers
'
AddObsDim() : Add a dimension called
'
nobs
'
AddLagDim() : Add a dimension called
'
nlag
'
, this one can be unlimited
AddDateDim() : Add a dimension called
'
date
'
, this one can be unlimited
AddDateDimFormat() : Add a dimension called
'
datedimformat
'
, this is a 6-integer format as in yyyy,mm,dd,HH,MM,SS
GetVariable() : return a variable from the dataset by name
StandardVar() : return a dictionary with precooked CF-1.1 information for a dataset to be written
inquire_unlimited() : get the length of the unlimited dimension
AddData() : Add data from a dictionary to the file
close() : close the file
"""
def
__init__
(
self
,
filename
,
method
=
'
create
'
,
*
arguments
):
import
Nio
import
os
if
method
not
in
[
'
read
'
,
'
write
'
,
'
create
'
]:
raise
ValueError
,
'
Method %s is not defined for a CarbonTracker NetCDF file object
'
%
method
std_savedict
=
{
'
name
'
:
'
unknown
'
,
'
values
'
:[],
'
dims
'
:(
0
,
0
,),
'
units
'
:
''
,
'
long_name
'
:
''
,
'
_FillValue
'
:
float
(
-
999.
),
'
comment
'
:
''
}
class
CT_CDF
(
CDF
.
CDF
):
"""
function opens a NetCDF/HDF/GRIB file for writing of output
"""
def
__init__
(
self
,
filename
,
method
=
'
read
'
):
if
method
not
in
[
'
read
'
,
'
write
'
,
'
create
'
]:
raise
ValueError
,
'
Method %s is not defined for a CarbonTracker NetCDF file object
'
%
method
if
method
==
'
read
'
:
self
.
file
=
Nio
.
open_file
(
filename
,
mode
=
'
r
'
,
*
arguments
)
print
'
Reading from file
'
super
(
CDF
.
CDF
,
self
).
__init__
(
filename
,
CDF
.
NC
.
NOWRITE
)
elif
method
==
'
write
'
:
self
.
file
=
Nio
.
open_file
(
filename
,
mode
=
method
,
*
arguments
)
#print 'Adding to existing file'
super
(
CT_CDF
,
self
).
__init__
(
filename
,
CDF
.
NC
.
WRITE
|
CDF
.
NC
.
CREATE
)
self
.
AddCTHeader
()
elif
method
==
'
create
'
:
if
os
.
path
.
exists
(
filename
):
os
.
remove
(
filename
)
s
elf
.
file
=
Nio
.
open_file
(
filename
,
mode
=
method
,
*
arguments
)
#print 'Creating new file'
s
uper
(
CT_CDF
,
self
).
__init__
(
filename
,
CDF
.
NC
.
WRITE
|
CDF
.
NC
.
TRUNC
|
CDF
.
NC
.
CREATE
)
self
.
AddCTHeader
()
if
method
!=
'
read
'
:
self
.
AddCTHeader
()
def
AddCTHeader
(
self
):
self
.
automode
()
#
setattr
(
self
.
file
,
'
Institution
'
,
institution
)
setattr
(
self
.
file
,
'
Contact
'
,
email
)
setattr
(
self
.
file
,
'
URL
'
,
url
)
setattr
(
self
.
file
,
'
Source
'
,
source
)
setattr
(
self
.
file
,
'
Convention
'
,
conventions
)
setattr
(
self
.
file
,
'
Disclaimer
'
,
disclaimer
)
setattr
(
self
,
'
History
'
,
historytext
)
def
AddParamsDim
(
self
,
nparams
):
dimparams
=
self
.
file
.
create_dimension
(
'
nparameters
'
,
nparams
)
return
(
'
nparameters
'
,)
def
AddMembersDim
(
self
,
nmembers
):
dimmembers
=
self
.
file
.
create_dimension
(
'
nmembers
'
,
nmembers
)
return
(
'
nmembers
'
,)
def
AddLagDim
(
self
,
nlag
=
0
,
unlimited
=
True
):
setattr
(
self
,
'
Institution
'
,
institution
)
setattr
(
self
,
'
Contact
'
,
email
)
setattr
(
self
,
'
URL
'
,
url
)
setattr
(
self
,
'
Source
'
,
source
)
setattr
(
self
,
'
Convention
'
,
conventions
)
setattr
(
self
,
'
Disclaimer
'
,
disclaimer
)
setattr
(
self
,
'
History
'
,
historytext
)
def
AddParamsDim
(
self
,
nparams
):
self
.
automode
()
dimparams
=
self
.
def_dim
(
'
nparameters
'
,
nparams
)
return
(
dimparams
,)
def
AddMembersDim
(
self
,
nmembers
):
self
.
automode
()
dimmembers
=
self
.
def_dim
(
'
nmembers
'
,
nmembers
)
return
(
dimmembers
,)
def
AddLagDim
(
self
,
nlag
,
unlimited
=
True
):
self
.
automode
()
if
unlimited
:
dimlag
=
self
.
file
.
create_dimension
(
'
nlag
'
,
None
)
dimlag
=
self
.
def_dim
(
'
nlag
'
,
CDF
.
NC
.
UNLIMITED
)
else
:
dimlag
=
self
.
file
.
create_dimension
(
'
nlag
'
,
nlag
)
dimlag
=
(
'
nlag
'
,)
# Also create the variable of the same name so it can be queried for length
var
=
self
.
file
.
create_variable
(
'
nlag
'
,
'
i
'
,
dimlag
)
return
(
'
nlag
'
,)
dimlag
=
self
.
def_dim
(
'
nlag
'
,
nlag
)
return
(
dimlag
,)
def
AddObsDim
(
self
,
nobs
):
dimobs
=
self
.
file
.
create_dimension
(
'
nobs
'
,
nobs
)
return
(
'
nobs
'
,)
def
AddLatLonDim
(
self
,
istart
=
0
,
iend
=
360
,
jstart
=
0
,
jend
=
180
):
"""
Add dimensions + data for latitude and longitude values of a rectangular 1x1 grid, the
scope of the arrays can be limited by using the istart,...,jend integers
"""
def
AddObsDim
(
self
,
nobs
):
self
.
automode
()
dimobs
=
self
.
def_dim
(
'
nobs
'
,
nobs
)
return
(
dimobs
,)
def
AddLatLonDim
(
self
,
istart
=
0
,
iend
=
360
,
jstart
=
0
,
jend
=
180
):
from
numpy
import
arange
,
float64
if
'
latitude
'
in
self
.
file
.
dimensions
.
keys
():
return
(
'
latitude
'
,
'
longitude
'
,)
# already exists
if
'
latitude
'
in
self
.
dimensions
():
return
(
self
.
dim
(
'
latitude
'
),
self
.
dim
(
'
longitude
'
))
# already exists
lons
=
-
180
+
arange
(
360
)
*
1.0
+
0.5
lats
=-
90
+
arange
(
180
)
*
1.0
+
0.5
lons
=
-
180
+
arange
(
360
)
*
1.0
+
0.5
lats
=
-
90
+
arange
(
180
)
*
1.0
+
0.5
#
lats
=
lats
[
jstart
:
jend
]
lons
=
lons
[
istart
:
iend
]
lats
=
lats
[
jstart
:
jend
]
lons
=
lons
[
istart
:
iend
]
#
dimlon
=
self
.
file
.
create_dimension
(
'
longitude
'
,
lons
.
shape
[
0
])
dimlon
=
(
'
longitude
'
,)
dimlat
=
self
.
file
.
create_dimension
(
'
latitude
'
,
lats
.
shape
[
0
])
dimlat
=
(
'
latitude
'
,)
savedict
=
self
.
StandardVar
(
varname
=
'
latitude
'
)
savedict
[
'
values
'
]
=
lats
.
tolist
()
savedict
[
'
actual_range
'
]
=
(
float
(
lats
[
0
]),
float
(
lats
[
-
1
]))
savedict
[
'
dims
'
]
=
dimlat
self
.
automode
()
dimlon
=
self
.
def_dim
(
'
longitude
'
,
lons
.
shape
[
0
])
dimlat
=
self
.
def_dim
(
'
latitude
'
,
lats
.
shape
[
0
])
savedict
=
self
.
StandardVar
(
varname
=
'
latitude
'
)
savedict
[
'
values
'
]
=
lats
.
tolist
()
savedict
[
'
actual_range
'
]
=
(
float
(
lats
[
0
]),
float
(
lats
[
-
1
]))
savedict
[
'
dims
'
]
=
(
dimlat
,)
self
.
AddData
(
savedict
)
savedict
=
self
.
StandardVar
(
varname
=
'
longitude
'
)
savedict
[
'
values
'
]
=
lons
.
tolist
()
savedict
[
'
actual_range
'
]
=
(
float
(
lons
[
0
]),
float
(
lons
[
-
1
]))
savedict
[
'
dims
'
]
=
dimlon
savedict
=
self
.
StandardVar
(
varname
=
'
longitude
'
)
savedict
[
'
values
'
]
=
lons
.
tolist
()
savedict
[
'
actual_range
'
]
=
(
float
(
lons
[
0
]),
float
(
lons
[
-
1
]))
savedict
[
'
dims
'
]
=
(
dimlon
,)
self
.
AddData
(
savedict
)
return
dimlat
+
dimlon
def
AddDateDim
(
self
,
ndate
=
0
,
unlimited
=
True
):
"""
Add a date dimension, give it the unlimited length if requested
"""
if
unlimited
:
dimdate
=
self
.
file
.
create_dimension
(
'
date
'
,
None
)
else
:
dimdate
=
self
.
file
.
create_dimension
(
'
date
'
,
ndate
)
dimdate
=
(
'
date
'
,)
return
(
dimlat
,
dimlon
)
# Also create the variable of the same name so it can be queried for length
var
=
self
.
file
.
create_variable
(
'
date
'
,
'
d
'
,
dimdate
)
return
dimdate
def
AddDateDim
(
self
):
self
.
automode
()
if
'
date
'
in
self
.
dimensions
():
return
(
self
.
dim
(
'
date
'
),)
return
(
self
.
def_dim
(
'
date
'
,
CDF
.
NC
.
UNLIMITED
),)
def
AddDateDimFormat
(
self
):
"""
Add a dimension representing a date format as yyyy/mm/dd/HH/MM/SS
"""
if
'
yyyymmddhhmmss
'
in
self
.
file
.
dimensions
.
keys
():
pass
else
:
dummy
=
self
.
file
.
create_dimension
(
'
yyyymmddhhmmss
'
,
6
)
# already exists
dimdateformat
=
(
'
yyyymmddhhmmss
'
,)
return
dimdateformat
def
AddDim
(
self
,
dimname
,
dimsize
):
if
dimname
in
self
.
file
.
dimensions
.
keys
():
pass
else
:
newdim
=
self
.
file
.
create_dimension
(
dimname
,
dimsize
)
return
(
dimname
,)
def
has_date
(
self
,
dd
):
"""
Check if a passed date (dd) is already present in the dates included in a file
"""
if
self
.
file
.
variables
[
'
date
'
].
shape
[
0
]
>
0
:
if
dd
in
self
.
file
.
variables
[
'
date
'
][:].
tolist
():
self
.
automode
()
if
'
yyyymmddhhmmss
'
in
self
.
dimensions
():
return
(
self
.
dim
(
'
yyyymmddhhmmss
'
),)
# already exists
return
(
self
.
def_dim
(
'
yyyymmddhhmmss
'
,
6
),)
def
AddDim
(
self
,
dimname
,
dimsize
):
if
dimname
not
in
self
.
dimensions
():
newdim
=
self
.
def_dim
(
dimname
,
dimsize
)
return
(
newdim
,)
def
has_date
(
self
,
dd
):
if
self
.
inq_unlimlen
()
>
0
:
if
dd
in
self
.
GetVariable
(
'
date
'
).
tolist
():
return
True
else
:
return
False
else
:
return
False
def
GetVariable
(
self
,
varname
):
def
GetVariable
(
self
,
varname
):
"""
get variable from ncf file
"""
return
self
.
file
.
variables
[
varname
][:]
return
array
(
self
.
var
(
varname
).
get
())
def
StandardVar
(
self
,
varname
):
def
StandardVar
(
self
,
varname
):
"""
return properties of standard variables
"""
import
standardvariables
if
varname
in
standardvariables
.
standard_variables
.
keys
():
return
standardvariables
.
standard_variables
[
varname
]
else
:
var
=
std_savedict
.
copy
()
var
[
'
name
'
]
=
varname
return
var
def
inquire_unlimited
(
self
):
"""
Get the index and name of the unlimited dimension
"""
try
:
index
=
self
.
file
.
dimensions
.
values
().
index
(
None
)
unlimname
=
self
.
file
.
dimensions
.
keys
()[
index
]
unlimlen
=
self
.
file
.
variables
[
unlimname
].
shape
[
0
]
except
:
unlimlen
=
-
1
unlimname
=
'
None
'
return
(
unlimname
,
unlimlen
,)
def
AddData
(
self
,
datadict
,
silent
=
True
):
"""
Add data to the Nio file object. This is achieved by passing a data dictionary to this routine that holds all metadata plus
the real data values. For example:
savedict=std_savedict.copy()
savedict[
'
name
'
] =
'
testarray
'
savedict[
'
dims
'
] = (
'
date
'
,
'
latitude
'
,)
savedict[
'
count
'
] = unlimlen+n
savedict[
'
values
'
] = np.arange(180)+n*1.5
ncf.AddData(savedict,silent=False)
this makes a copy of a standard variable dictionary first, and then populates it with (meta)data. The conventions are that
return
standardvariables
.
standard_variables
[
'
unknown
'
]
[
'
dims
'
] = a tuple with names of the dimensions
[
'
count
'
] = an integer number that represents the first dimension along which to write (usually the unlimited dim)
[
'
values
'
] = a list or array that holds the data values to be written. Note that one cannot pass any other object.
The counter for the unlimited dimension is needed because multiple datasets might be added with unlimited dimensions and
we don
'
t want the unlimited counter to increase everytime. To get the value of the counter (needed when appending data for instance)
use
unlimname,unlim_count = ncf.inquire_unlimited()
where an integer value is returned for the length, and -1 indicates there is no unlimited dimension
Note that there are special pre-cooked data dictionaries available in the module standardvariables, with many attributes
already specified. For instance:
savedict=ncf.StandardVar(varname=
'
date
'
)
savedict[
'
values
'
]= [100.0+n]
savedict[
'
count
'
] = unlimlen+n
savedict[
'
dims
'
]=(
'
date
'
,)
ncf.AddData(savedict,silent=False)
has long_names, comments, and data ranges pre-specified.
"""
import
numpy
as
np
# Make sure the passed dictionary has proper values for the important entries
if
None
==
datadict
[
'
values
'
]:
raise
IOError
,
"
The passed data dictionary does not contain values, please provide data to write
"
if
None
==
datadict
[
'
dims
'
]:
raise
IOError
,
"
The passed data dictionary does not contain valid dimensions, please provide names of dimensions for the dataset
"
if
not
isinstance
(
datadict
[
'
values
'
],(
list
,
np
.
ndarray
,)):
raise
IOError
,
"
Please pass a list or array to the AddData() method, not a %s object
"
%
datadict
[
'
values
'
].
__class__
# First, try to get the requested dataset number to place next in file. Note that this is an attribute of the
# savedict and has to be specified by the user. If not specified, the 'next' dataset is number 0
def
AddData
(
self
,
datadict
,
nsets
=
1
,
silent
=
True
):
"""
add fields to file, at end of unlimited dimension
"""
existing_vars
=
self
.
variables
()
try
:
next
=
datadict
[
'
count
'
]
except
:
next
=
0
# Check if the requested variable already exists in the file, if so, get a variable handle directly
existing_vars
=
self
.
file
.
variables
.
keys
()
if
datadict
[
'
name
'
]
in
existing_vars
:
var
=
self
.
file
.
variables
[
datadict
[
'
name
'
]]
# If the variable name is new, create a new dataset
next
=
0
if
existing_vars
.
has_key
(
datadict
[
'
name
'
]):
var
=
self
.
var
(
datadict
[
'
name
'
])
var
[
next
:
next
+
nsets
]
=
datadict
[
'
values
'
]
else
:
if
not
silent
:
print
'
Creating new dataset:
'
+
datadict
[
'
name
'
]
if
datadict
.
has_key
(
'
dtype
'
):
# datatype is part of the data dictionary passed
if
not
silent
:
print
'
Creating new dataset:
'
+
datadict
[
'
name
'
]
if
datadict
.
has_key
(
'
dtype
'
):
if
datadict
[
'
dtype
'
]
==
'
int
'
:
var
=
self
.
file
.
create_variable
(
datadict
[
'
name
'
],
'
i
'
,
datadict
[
'
dims
'
])
var
=
self
.
def_var
(
datadict
[
'
name
'
],
CDF
.
NC
.
INT
,
datadict
[
'
dims
'
])
elif
datadict
[
'
dtype
'
]
==
'
char
'
:
var
=
self
.
file
.
create_variable
(
datadict
[
'
name
'
],
'
s1
'
,
datadict
[
'
dims
'
])
var
=
self
.
def_var
(
datadict
[
'
name
'
],
CDF
.
NC
.
CHAR
,
datadict
[
'
dims
'
])
elif
datadict
[
'
dtype
'
]
==
'
double
'
:
var
=
self
.
file
.
create_variable
(
datadict
[
'
name
'
],
'
d
'
,
datadict
[
'
dims
'
])
var
=
self
.
def_var
(
datadict
[
'
name
'
],
CDF
.
NC
.
DOUBLE
,
datadict
[
'
dims
'
])
else
:
var
=
self
.
file
.
create_variable
(
datadict
[
'
name
'
],
'
f
'
,
datadict
[
'
dims
'
])
else
:
var
=
self
.
file
.
create_variable
(
datadict
[
'
name
'
],
'
d
'
,
datadict
[
'
dims
'
])
# default is 'double'
# All other keys in the datadict are assumed to be variable attributes, except for a few reserved ones
for
k
,
v
in
datadict
.
iteritems
():
if
k
not
in
[
'
name
'
,
'
dims
'
,
'
values
'
,
'
_FillValue
'
,
'
count
'
]:
setattr
(
var
,
k
,
v
)
# Now that the variable instance is returned, start to add the data. First figure out if we are dealing with an unlimited dimension
unlimname
,
unlimlen
=
self
.
inquire_unlimited
()
has_unlimited_dim
=
(
unlimname
!=
'
None
'
)
# If so, check if the first dimension of the passed dataset corresponds to the unlimited dimension
if
has_unlimited_dim
and
var
.
dimensions
[
0
]
==
unlimname
:
# Add the data to the unlimited dim, note the special occassion for passing only one value (a record)
if
len
(
datadict
[
'
values
'
])
==
1
:
var
[
next
]
=
datadict
[
'
values
'
][
0
]
var
=
self
.
def_var
(
datadict
[
'
name
'
],
CDF
.
NC
.
FLOAT
,
datadict
[
'
dims
'
])
else
:
var
[
next
,:]
=
datadict
[
'
values
'
]
# Add the data , note the special occassion for passing only one value (a record)
else
:
if
len
(
datadict
[
'
values
'
])
==
1
:
var
.
assign_value
(
datadict
[
'
values
'
][
0
])
var
=
self
.
def_var
(
datadict
[
'
name
'
],
CDF
.
NC
.
FLOAT
,
datadict
[
'
dims
'
])
for
k
,
v
in
datadict
.
iteritems
():
if
k
not
in
[
'
name
'
,
'
dims
'
,
'
values
'
,
'
_FillValue
'
,
'
count
'
]:
setattr
(
var
,
k
,
v
)
if
var
.
isrecord
():
var
[
next
:
next
+
nsets
]
=
datadict
[
'
values
'
]
else
:
var
[:]
=
datadict
[
'
values
'
]
def
close
(
self
):
"""
close the file object
"""
return
self
.
file
.
close
()
var
[:]
=
datadict
[
'
values
'
]
def
CreateDirs
(
rundat
,
dirname
):
def
GetVariable
(
file
,
varname
):
"""
get variable from HDF file
"""
return
array
(
file
.
select
(
varname
).
get
())
dirname
=
os
.
path
.
join
(
rundat
.
outputdir
,
dirname
)
def
CreateDirs
(
rundat
,
dirname
):
dirname
=
os
.
path
.
join
(
rundat
.
outputdir
,
dirname
)
if
not
os
.
path
.
exists
(
dirname
):
print
"
Creating new output directory
"
+
dirname
print
"
Creating new output directory
"
+
dirname
os
.
makedirs
(
dirname
)
else
:
print
'
Writing files to directory: %s
'
%
(
dirname
,)
print
'
Writing files to directory: %s
'
%
(
dirname
,)
return
dirname
if
__name__
==
'
__main__
'
:
import
sys
import
os
import
numpy
as
np
sys
.
path
.
append
(
'
../../
'
)
import
da.tools.standardvariables
try
:
os
.
remove
(
'
test.nc
'
)
except
:
pass
ncf
=
CT_CDF
(
'
test.nc
'
,
'
w
'
)
dimgrid
=
ncf
.
AddLatLonDim
()
dimdate
=
ncf
.
AddDateDim
(
unlimited
=
True
)
#dimlag=ncf.AddLagDim(unlimited=True)
#dimidate=ncf.AddDateDimFormat()
unlimname
,
unlimlen
=
ncf
.
inquire_unlimited
()
if
unlimlen
<
0
:
unlimlen
=
0
for
n
in
range
(
100
):
savedict
=
ncf
.
StandardVar
(
varname
=
'
testarray
'
)
savedict
[
'
dims
'
]
=
(
'
date
'
,
'
latitude
'
,)
savedict
[
'
count
'
]
=
unlimlen
+
n
savedict
[
'
values
'
]
=
np
.
arange
(
180
)
+
n
*
1.5
ncf
.
AddData
(
savedict
,
silent
=
False
)
savedict
=
ncf
.
StandardVar
(
varname
=
'
testarray2
'
)
savedict
[
'
dims
'
]
=
(
'
date
'
,
'
latitude
'
,)
savedict
[
'
count
'
]
=
unlimlen
+
n
savedict
[
'
values
'
]
=
np
.
arange
(
180
)
-
n
*
1.5
ncf
.
AddData
(
savedict
,
silent
=
False
)
savedict
=
ncf
.
StandardVar
(
varname
=
'
date
'
)
savedict
[
'
values
'
]
=
[
100.0
+
n
]
savedict
[
'
count
'
]
=
unlimlen
+
n
savedict
[
'
dims
'
]
=
dimdate
ncf
.
AddData
(
savedict
,
silent
=
False
)
#savedict=ncf.StandardVar(varname='testfail')
#savedict['values']=range(5)
#ncf.AddData(savedict,silent=False)
print
ncf
.
inquire_unlimited
()
ncf
.
file
.
close
()
ncf
=
CT_CDF
(
'
test.nc
'
,
'
create
'
)
dimgrid
=
ncf
.
AddLatLonDim
()
dimdate
=
ncf
.
AddDateDim
()
dimidate
=
ncf
.
AddDateDimFormat
()
This diff is collapsed.
Click to expand it.
da/tools/io4.py
+
118
−
402
View file @
ad278492
This diff is collapsed.
Click to expand it.
da/tools/io_cdf.py
+
84
−
103
View file @
ad278492
...
...
@@ -15,131 +15,117 @@ import datetime as dt
from
numpy
import
array
import
os
disclaimer
=
"
This data belongs to the CarbonTracker project
"
email
=
"
wouter.peters@wur.nl
"
url
=
"
http://carbontracker.wur.nl
"
disclaimer
=
"
This data belongs to the CarbonTracker project
"
email
=
"
wouter.peters@wur.nl
"
url
=
"
http://carbontracker.wur.nl
"
institution
=
"
Wageningen University and Research Center
"
source
=
"
CarbonTracker release 2.0
"
source
=
"
CarbonTracker release 2.0
"
conventions
=
"
CF-1.1
"
historytext
=
'
Created on
'
+
dt
.
datetime
.
now
().
strftime
(
'
%B %d, %Y
'
)
+
'
by %s
'
%
os
.
environ
[
'
USER
'
]
historytext
=
'
Created on
'
+
dt
.
datetime
.
now
().
strftime
(
'
%B %d, %Y
'
)
+
'
by %s
'
%
os
.
environ
[
'
USER
'
]
std_savedict
=
{
'
name
'
:
'
unknown
'
,
'
values
'
:[],
'
dims
'
:(
0
,
0
,),
'
units
'
:
''
,
'
long_name
'
:
''
,
'
_FillValue
'
:
float
(
-
999.
),
'
comment
'
:
''
}
std_savedict
=
{
'
name
'
:
'
unknown
'
,
'
values
'
:[],
'
dims
'
:(
0
,
0
,),
'
units
'
:
''
,
'
long_name
'
:
''
,
'
_FillValue
'
:
float
(
-
999.
),
'
comment
'
:
''
}
class
CT_CDF
(
CDF
.
CDF
):
"""
function opens a NetCDF/HDF/GRIB file for writing of output
"""
def
__init__
(
self
,
filename
,
method
=
'
read
'
):
if
method
not
in
[
'
read
'
,
'
write
'
,
'
create
'
]:
def
__init__
(
self
,
filename
,
method
=
'
read
'
):
if
method
not
in
[
'
read
'
,
'
write
'
,
'
create
'
]:
raise
ValueError
,
'
Method %s is not defined for a CarbonTracker NetCDF file object
'
%
method
if
method
==
'
read
'
:
print
'
Reading from file
'
super
(
CDF
.
CDF
,
self
).
__init__
(
filename
,
CDF
.
NC
.
NOWRITE
)
super
(
CDF
.
CDF
,
self
).
__init__
(
filename
,
CDF
.
NC
.
NOWRITE
)
elif
method
==
'
write
'
:
#print 'Adding to existing file'
super
(
CT_CDF
,
self
).
__init__
(
filename
,
CDF
.
NC
.
WRITE
|
CDF
.
NC
.
CREATE
)
super
(
CT_CDF
,
self
).
__init__
(
filename
,
CDF
.
NC
.
WRITE
|
CDF
.
NC
.
CREATE
)
self
.
AddCTHeader
()
elif
method
==
'
create
'
:
#print 'Creating new file'
super
(
CT_CDF
,
self
).
__init__
(
filename
,
CDF
.
NC
.
WRITE
|
CDF
.
NC
.
TRUNC
|
CDF
.
NC
.
CREATE
)
super
(
CT_CDF
,
self
).
__init__
(
filename
,
CDF
.
NC
.
WRITE
|
CDF
.
NC
.
TRUNC
|
CDF
.
NC
.
CREATE
)
self
.
AddCTHeader
()
def
AddCTHeader
(
self
):
self
.
automode
()
#
setattr
(
self
,
'
Institution
'
,
institution
)
setattr
(
self
,
'
Contact
'
,
email
)
setattr
(
self
,
'
URL
'
,
url
)
setattr
(
self
,
'
Source
'
,
source
)
setattr
(
self
,
'
Convention
'
,
conventions
)
setattr
(
self
,
'
Disclaimer
'
,
disclaimer
)
setattr
(
self
,
'
History
'
,
historytext
)
def
AddParamsDim
(
self
,
nparams
):
setattr
(
self
,
'
Institution
'
,
institution
)
setattr
(
self
,
'
Contact
'
,
email
)
setattr
(
self
,
'
URL
'
,
url
)
setattr
(
self
,
'
Source
'
,
source
)
setattr
(
self
,
'
Convention
'
,
conventions
)
setattr
(
self
,
'
Disclaimer
'
,
disclaimer
)
setattr
(
self
,
'
History
'
,
historytext
)
def
AddParamsDim
(
self
,
nparams
):
self
.
automode
()
dimparams
=
self
.
def_dim
(
'
nparameters
'
,
nparams
)
dimparams
=
self
.
def_dim
(
'
nparameters
'
,
nparams
)
return
(
dimparams
,)
def
AddMembersDim
(
self
,
nmembers
):
def
AddMembersDim
(
self
,
nmembers
):
self
.
automode
()
dimmembers
=
self
.
def_dim
(
'
nmembers
'
,
nmembers
)
dimmembers
=
self
.
def_dim
(
'
nmembers
'
,
nmembers
)
return
(
dimmembers
,)
def
AddLagDim
(
self
,
nlag
,
unlimited
=
True
):
def
AddLagDim
(
self
,
nlag
,
unlimited
=
True
):
self
.
automode
()
if
unlimited
:
dimlag
=
self
.
def_dim
(
'
nlag
'
,
CDF
.
NC
.
UNLIMITED
)
dimlag
=
self
.
def_dim
(
'
nlag
'
,
CDF
.
NC
.
UNLIMITED
)
else
:
dimlag
=
self
.
def_dim
(
'
nlag
'
,
nlag
)
dimlag
=
self
.
def_dim
(
'
nlag
'
,
nlag
)
return
(
dimlag
,)
def
AddObsDim
(
self
,
nobs
):
def
AddObsDim
(
self
,
nobs
):
self
.
automode
()
dimobs
=
self
.
def_dim
(
'
nobs
'
,
nobs
)
dimobs
=
self
.
def_dim
(
'
nobs
'
,
nobs
)
return
(
dimobs
,)
def
AddLatLonDim
(
self
,
istart
=
0
,
iend
=
360
,
jstart
=
0
,
jend
=
180
):
def
AddLatLonDim
(
self
,
istart
=
0
,
iend
=
360
,
jstart
=
0
,
jend
=
180
):
from
numpy
import
arange
,
float64
if
'
latitude
'
in
self
.
dimensions
():
return
(
self
.
dim
(
'
latitude
'
),
self
.
dim
(
'
longitude
'
),)
# already exists
if
'
latitude
'
in
self
.
dimensions
():
return
(
self
.
dim
(
'
latitude
'
),
self
.
dim
(
'
longitude
'
))
# already exists
lons
=
-
180
+
arange
(
360
)
*
1.0
+
0.5
lats
=-
90
+
arange
(
180
)
*
1.0
+
0.5
lons
=
-
180
+
arange
(
360
)
*
1.0
+
0.5
lats
=
-
90
+
arange
(
180
)
*
1.0
+
0.5
#
lats
=
lats
[
jstart
:
jend
]
lons
=
lons
[
istart
:
iend
]
lats
=
lats
[
jstart
:
jend
]
lons
=
lons
[
istart
:
iend
]
#
self
.
automode
()
dimlon
=
self
.
def_dim
(
'
longitude
'
,
lons
.
shape
[
0
])
dimlat
=
self
.
def_dim
(
'
latitude
'
,
lats
.
shape
[
0
])
dimlon
=
self
.
def_dim
(
'
longitude
'
,
lons
.
shape
[
0
])
dimlat
=
self
.
def_dim
(
'
latitude
'
,
lats
.
shape
[
0
])
savedict
=
self
.
StandardVar
(
varname
=
'
latitude
'
)
savedict
[
'
values
'
]
=
lats
.
tolist
()
savedict
[
'
actual_range
'
]
=
(
float
(
lats
[
0
]),
float
(
lats
[
-
1
]))
savedict
[
'
dims
'
]
=
(
dimlat
,)
savedict
=
self
.
StandardVar
(
varname
=
'
latitude
'
)
savedict
[
'
values
'
]
=
lats
.
tolist
()
savedict
[
'
actual_range
'
]
=
(
float
(
lats
[
0
]),
float
(
lats
[
-
1
]))
savedict
[
'
dims
'
]
=
(
dimlat
,)
self
.
AddData
(
savedict
)
savedict
=
self
.
StandardVar
(
varname
=
'
longitude
'
)
savedict
[
'
values
'
]
=
lons
.
tolist
()
savedict
[
'
actual_range
'
]
=
(
float
(
lons
[
0
]),
float
(
lons
[
-
1
]))
savedict
[
'
dims
'
]
=
(
dimlon
,)
savedict
=
self
.
StandardVar
(
varname
=
'
longitude
'
)
savedict
[
'
values
'
]
=
lons
.
tolist
()
savedict
[
'
actual_range
'
]
=
(
float
(
lons
[
0
]),
float
(
lons
[
-
1
]))
savedict
[
'
dims
'
]
=
(
dimlon
,)
self
.
AddData
(
savedict
)
return
(
dimlat
,
dimlon
,
)
return
(
dimlat
,
dimlon
)
def
AddDateDim
(
self
):
self
.
automode
()
if
'
date
'
in
self
.
dimensions
():
return
(
self
.
dim
(
'
date
'
),)
return
(
self
.
def_dim
(
'
date
'
,
CDF
.
NC
.
UNLIMITED
),)
if
'
date
'
in
self
.
dimensions
():
return
(
self
.
dim
(
'
date
'
),)
return
(
self
.
def_dim
(
'
date
'
,
CDF
.
NC
.
UNLIMITED
),)
def
AddDateDimFormat
(
self
):
self
.
automode
()
if
'
yyyymmddhhmmss
'
in
self
.
dimensions
():
return
(
self
.
dim
(
'
yyyymmddhhmmss
'
),)
# already exists
return
(
self
.
def_dim
(
'
yyyymmddhhmmss
'
,
6
),)
if
'
yyyymmddhhmmss
'
in
self
.
dimensions
():
return
(
self
.
dim
(
'
yyyymmddhhmmss
'
),)
# already exists
return
(
self
.
def_dim
(
'
yyyymmddhhmmss
'
,
6
),)
def
AddDim
(
self
,
dimname
,
dimsize
):
if
dimname
in
self
.
dimensions
():
pass
else
:
newdim
=
self
.
def_dim
(
dimname
,
dimsize
)
def
AddDim
(
self
,
dimname
,
dimsize
):
if
dimname
not
in
self
.
dimensions
():
newdim
=
self
.
def_dim
(
dimname
,
dimsize
)
return
(
newdim
,)
def
has_date
(
self
,
dd
):
def
has_date
(
self
,
dd
):
if
self
.
inq_unlimlen
()
>
0
:
if
dd
in
self
.
GetVariable
(
'
date
'
).
tolist
():
return
True
...
...
@@ -148,11 +134,11 @@ class CT_CDF(CDF.CDF):
else
:
return
False
def
GetVariable
(
self
,
varname
):
def
GetVariable
(
self
,
varname
):
"""
get variable from ncf file
"""
return
array
(
self
.
var
(
varname
).
get
())
def
StandardVar
(
self
,
varname
):
def
StandardVar
(
self
,
varname
):
"""
return properties of standard variables
"""
import
standardvariables
...
...
@@ -161,65 +147,60 @@ class CT_CDF(CDF.CDF):
else
:
return
standardvariables
.
standard_variables
[
'
unknown
'
]
def
AddData
(
self
,
datadict
,
nsets
=
1
,
silent
=
True
):
def
AddData
(
self
,
datadict
,
nsets
=
1
,
silent
=
True
):
"""
add fields to file, at end of unlimited dimension
"""
existing_vars
=
self
.
variables
()
existing_vars
=
self
.
variables
()
try
:
next
=
datadict
[
'
count
'
]
except
:
next
=
0
next
=
0
if
existing_vars
.
has_key
(
datadict
[
'
name
'
]):
var
=
self
.
var
(
datadict
[
'
name
'
])
var
[
next
:
next
+
nsets
]
=
datadict
[
'
values
'
]
var
[
next
:
next
+
nsets
]
=
datadict
[
'
values
'
]
else
:
if
not
silent
:
print
'
Creating new dataset:
'
+
datadict
[
'
name
'
]
if
not
silent
:
print
'
Creating new dataset:
'
+
datadict
[
'
name
'
]
if
datadict
.
has_key
(
'
dtype
'
):
if
datadict
[
'
dtype
'
]
==
'
int
'
:
var
=
self
.
def_var
(
datadict
[
'
name
'
],
CDF
.
NC
.
INT
,
datadict
[
'
dims
'
])
var
=
self
.
def_var
(
datadict
[
'
name
'
],
CDF
.
NC
.
INT
,
datadict
[
'
dims
'
])
elif
datadict
[
'
dtype
'
]
==
'
char
'
:
var
=
self
.
def_var
(
datadict
[
'
name
'
],
CDF
.
NC
.
CHAR
,
datadict
[
'
dims
'
])
var
=
self
.
def_var
(
datadict
[
'
name
'
],
CDF
.
NC
.
CHAR
,
datadict
[
'
dims
'
])
elif
datadict
[
'
dtype
'
]
==
'
double
'
:
var
=
self
.
def_var
(
datadict
[
'
name
'
],
CDF
.
NC
.
DOUBLE
,
datadict
[
'
dims
'
])
var
=
self
.
def_var
(
datadict
[
'
name
'
],
CDF
.
NC
.
DOUBLE
,
datadict
[
'
dims
'
])
else
:
var
=
self
.
def_var
(
datadict
[
'
name
'
],
CDF
.
NC
.
FLOAT
,
datadict
[
'
dims
'
])
var
=
self
.
def_var
(
datadict
[
'
name
'
],
CDF
.
NC
.
FLOAT
,
datadict
[
'
dims
'
])
else
:
var
=
self
.
def_var
(
datadict
[
'
name
'
],
CDF
.
NC
.
FLOAT
,
datadict
[
'
dims
'
])
for
k
,
v
in
datadict
.
iteritems
():
if
k
not
in
[
'
name
'
,
'
dims
'
,
'
values
'
,
'
_FillValue
'
,
'
count
'
]:
setattr
(
var
,
k
,
v
)
var
=
self
.
def_var
(
datadict
[
'
name
'
],
CDF
.
NC
.
FLOAT
,
datadict
[
'
dims
'
])
for
k
,
v
in
datadict
.
iteritems
():
if
k
not
in
[
'
name
'
,
'
dims
'
,
'
values
'
,
'
_FillValue
'
,
'
count
'
]:
setattr
(
var
,
k
,
v
)
if
var
.
isrecord
():
var
[
next
:
next
+
nsets
]
=
datadict
[
'
values
'
]
var
[
next
:
next
+
nsets
]
=
datadict
[
'
values
'
]
else
:
var
[:]
=
datadict
[
'
values
'
]
var
[:]
=
datadict
[
'
values
'
]
def
GetVariable
(
file
,
varname
):
def
GetVariable
(
file
,
varname
):
"""
get variable from HDF file
"""
return
array
(
file
.
select
(
varname
).
get
())
def
CreateDirs
(
rundat
,
dirname
):
dirname
=
os
.
path
.
join
(
rundat
.
outputdir
,
dirname
)
def
CreateDirs
(
rundat
,
dirname
):
dirname
=
os
.
path
.
join
(
rundat
.
outputdir
,
dirname
)
if
not
os
.
path
.
exists
(
dirname
):
print
"
Creating new output directory
"
+
dirname
print
"
Creating new output directory
"
+
dirname
os
.
makedirs
(
dirname
)
else
:
print
'
Writing files to directory: %s
'
%
(
dirname
,)
print
'
Writing files to directory: %s
'
%
(
dirname
,)
return
dirname
if
__name__
==
'
__main__
'
:
try
:
os
.
remove
(
'
test.nc
'
)
except
:
pass
ncf
=
CT_CDF
(
'
test.nc
'
,
'
create
'
)
dimgrid
=
ncf
.
AddLatLonDim
()
dimdate
=
ncf
.
AddDateDim
()
dimidate
=
ncf
.
AddDateDimFormat
()
ncf
=
CT_CDF
(
'
test.nc
'
,
'
create
'
)
dimgrid
=
ncf
.
AddLatLonDim
()
dimdate
=
ncf
.
AddDateDim
()
dimidate
=
ncf
.
AddDateDimFormat
()
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment