|
RAVE
|
To accomodate for a more general way of handling file I/O a new concept of file objects has been introduced that will be able to support different structures without creating separate data objects just to handle a specific data file.
These objects are not intended for use when working with the different data structures but should be seen as a layer that can be used between the I/O layer and the data objects used within rave.
Note, these objects does not care about conforming to a specific file format. Instead that is up to the actual file writing to enable / disable. Currently the file object will allow almost anything and can create ODIM H5 file that are not compatible with the ODIM H5 specification and as such is up to the user to ensure that the file object that is saved follows the requirements.
The idea behind the file objects is that it should be possible to map the actual file I/O like ODIM H5 or FM-301 into a file object that will be mapped into the correct data object. The file object in turn will be mapped into a general structure that is internal for rave so that we don't need to adjust the internals just due to a different version of a file format. This mapping could then be done using a simple text-based file like json or something similar.
However, this is work in progress and for now the file objects will just be containers for reading/writing ODIM H5 files.
The first thing to do when creating a HDF5 file from scratch is to define some data to be written. The syntax is quite simple
and will not require a lot of work to understand. The saving is done like always when using the _raveio api so that hasn't changed. The object to use is _fileobject .
import _raveio, _fileobject, _rave
fileobj = _fileobject.new()
fileobj.attributes["Conventions"]="ODIM_H5/V2_2"
fileobj["/what"].attributes["source"]="NOD:setst"
fileobj["/what"].attributes["date"]="20200414"
fileobj["/what"].attributes["time"]="160000"
fileobj["/what"].attributes["object"]="SCAN"
fileobj["/what"].attributes["version"]="H5rad 2.2"
fileobj["/where"].attributes["height"]=99
fileobj["/where"].attributes["lat"]=61.1
fileobj["/where"].attributes["lon"]=10.2
fileobj["/dataset1/what"].attributes["product"]="SCAN"
fileobj["/dataset1/where"].attributes["elangle"]=0.5
fileobj["/dataset1/where"].attributes["nbins"]=480
fileobj["/dataset1/where"].attributes["nrays"]=360
fileobj["/dataset1/where"].attributes["rstart"]=0.0
fileobj["/dataset1/where"].attributes["rscale"]=500.0
fileobj["/dataset1/data1/what"].attributes["quantity"]="DBZH"
fileobj["/dataset1/data1/what"].attributes["gain"]=0.5
fileobj["/dataset1/data1/what"].attributes["nodata"]=255
fileobj["/dataset1/data1/what"].attributes["offset"]=-32.0
fileobj["/dataset1/data1/what"].attributes["undetect"]=0.0
fileobj["/dataset1/data1/data"].data = numpy.zeros((360,480), numpy.uint8)
rio = _raveio.new()
rio.object = fileobj
rio.save("test.h5")
It is also possible to load a ODIM H5 file into the general file object format regardless if it is a known type like SCAN, PVOL, .. or not.
>>> obj = _raveio.openFileObject("test.h5").object
The simplest way to display the content of the file object is to use the built in string representation.
>>> print(str(obj))
GROUP '/' {
Conventions = ODIM_H5/V2_2
GROUP 'dataset1' {
GROUP 'data1' {
DATASET 'data' {
DIMENSIONS = 480 x 360
DATATYPE = UCHAR
LOADED
}
GROUP 'what' {
undetect = 0
nodata = 255
gain = 0.5
offset = -32
quantity = DBZH
}
}
GROUP 'what' {
product = SCAN
}
GROUP 'where' {
nbins = 480
elangle = 0.5
rscale = 500
rstart = 0
nrays = 360
}
}
GROUP 'what' {
time = 160000
date = 20200414
object = SCAN
version = H5rad 2.2
source = NOD:setst
}
GROUP 'where' {
lat = 61.1
lon = 10.2
height = 99
}
}