.. ====================================================================== CHLone - CGNS HDF5 LIBRARY only node edition See license.txt in the root directory of this source release ====================================================================== .. _pythonCHLone: Python module ============= .. sidebar:: CGNS.MAP documentation The quick start here gives some basic functions use, more detailled examples are in `CGNS.MAP <http://pycgns.sourceforge.net/MAP/readme.html>`_ documentation. As a matter of fact, CGNS.MAP is no more than an import and a rename of the `CHLone <http://chlone.sourceforge.net>`_ Python module, but actual use of *CGNS/Python* trees requires Python functions for examples. Then the actual use would be find in these `CGNS.MAP <http://pycgns.sourceforge.net/MAP/readme.html>`_ pages. The CHLone python module is the mapper. It has been moved from the CGNS.MAP module of pyCGNS to have a self-contained service for HDF5 and Python translation of CGNS trees. Now you can use the CGNS/Python interface to CHLone without pyCGNS. Quick start ----------- The mapper is a module implementing the :ref:`SIDS-to-Python <reference_sids_to_python>` mapping, a CGNS/Python translation of the CGNS/HDF5 files, including links. There are only two functions in the module: the **load** and the **save**, the behavior of these function is driven by their arguments. Defaults arguments insure a simple load/save of CGNS/HDF5 files. A simple exemple to load a *CGNS/HDF5* file as a *CGNS/Python* tree:: import CHLone T=CHLone.load("naca012.cgns") The returned ``T`` is a tuple ``(tree,links,paths)``, the ``load`` argument is the file name, all other parameters are then set to their default value. The ``tree`` value contains the actual CGNS/Python tree with linked-to files included (because the ``S2P_FOLLOWLINKS`` flag is *on*) and the ``links`` value is a list of links found during the *HDF5* file parse. The last value of a link entry is the status of the link (see :ref:`flags <lkflags>`). The ``paths`` contains read time information about incomplete nodes, for example no data had been retrieved for this node (if the max data size is reached). Saving a file is also quite easy:: import CHLone CHLone.save("naca012.cgns",tree) The ``tree`` value contains the actual CGNS/Python tree, for example the one you had with the ``load``. These two simple functions behaviors can be modified using ``flags`` and other parameters, see below the *user interface* for a reference of these arguments and the `examples <http://pycgns.sourceforge.net/MAP/examples.html>`_ for a rather practical use. User interface -------------- It is a lightweight module, its purpose is to be as small as possible in order to be embedded separatly in an application . There are two functions: the ``load`` and the ``save``, an exception class ``CHLoneException`` and a set of constants. All other Python manipulations can be performed using `pyCGNS <http://pycgns.sourceforge.net/index.html>`_ that provides a very large set of features on *CGNS/Python* trees. Functions ~~~~~~~~~ The ``load`` reads a *CGNS/HDF5* file and produces a *CGNS/Python* tree. The ``save`` takes a *CGNS/Python* tree and writes the contents in a *CGNS/HDF5* file:: (tree,links,paths)=CHLone.load(filename,flags,depth,subtree,linkpaths,updatedict,maxdata) status=CHLone.save(filename,tree,links,flags,depth,updatedict) The default values are set to provide the simple interface if you have *usual* files without links:: (tree,links,paths)=CHLone.load(filename) status=CHLone.save(filename,tree) The `S2P` prefix stands for *SIDS-to-Python*. The complete interface of the load and the save are:: (tree,links,paths) <- load(filename, flags = S2P_FDEFAULT, depth = 0, subtree = '', linkpaths = [], update = {}, maxdata = -1, linkfull = False) None <- save(filename, tree, links = [], flags = S2P_FDEFAULT, depth = 0, linkpaths = [], update = {}, skip = {}, linkfull = False) The arguments and the return values are: * **tree** (input/output): The ``tree`` is the list representing the *CGNS/Python* tree. The structure of a ``tree`` list is detailled in :ref:`SIDS-to-Python <reference_sids_to_python>`. There is no link information in this tree either for *load* or for *save*. During the *load*, the links are silently replaced by the linked-to tree they are referring. The ``links`` value keeps track of these link references found while parsing the *CGNS/HDF5* file. During the *save*, the sub-trees of the argument tree that refer to other files by means of links are discarged. It is up to the user application to save these sub-trees by an subsequent call to the API. * **links** (input/output): The ``links`` is a list with the link node information. It is returned by a *load* and used as command parameters during the *save*. You can write your own ``links`` list or change the list you obtain after a *load*. The structure of a ``links`` list is detailled in :ref:`SIDS-to-Python <reference_sids_to_python>` but *CHLone* adds a flag at the end of each link entry list. These :ref:`flags <lkflags>` indicate wether the link has been found or if the file was found but not the target node or any other issue related to this link entry. * **linkfull** (input/output): A flag that sets the input/output format of a link entry in the list. An entry is a sequence of two filenames (source, destination), the directories where the files where found, wrt to the link search path, and finally the nodes paths (source, destination). The status is a integer that indicates wetehr the link has been found or not, and the reason why it was not found. The ``linkfull`` flag is a boolean. ``False`` sets the old format, that is, for each link input or output entry: ``[ destdir, destfile, destnode, srcnode, status ]`` (with ``status`` optional). The new format helps to handle links-to-links and keeps tracks of the actual directories used during all the link traversals. The entry format is then: `` [ srcdir, srcfile, srcnode, destdir, destfile, destnode, status ]``. * **paths** (output): A list of ``( node-path, status )`` entries. The status indicates why the node is in this returned list. So far, the only reason is because the ``maxdata`` threshold and the ``NODATA`` flag have been set. * **filename** (input): The name of the target file, to read or to write. The ``filename`` can be absolute or relative, it should be accessible in read/write depending on the action you perform on it. The file extension is unused. * **flags** (input): You can control the behavior of a load/save using the :ref:`flags <mapflags>`. You have to look a these carefully, the same tree can load/save in a completely different way depending on these ``flags``. * **depth** (input): This positive integer value sets the level of children the load/save takes into account. For example, a depth of 2 would stop load/save the CGNS tree once the children of the children of the start node is reached. This level two child is used, its children are not. If you want to have all the children, use a 0 ``depth`` which means no limit on depth. * **subtree** (input): The ``subtree`` defines the start node of the load/save. It should be an absolute path of an existing node in the argument filename. All the nodes along this path are taken into account for load/save actions. * **linkpaths** (input): The load may need a *link files search path* if your linked-to files are not in the current directory. The ``linkpath`` argument is a list of strings, during the load *CHLone* will look for linked-to files using this list: it is parsed from the first element to the last, the selected file is the first found in this directory list. * **updatedict** (input): A dictionnary of paths (string) as keys and *CGNS/Python* nodes as values. When the load reaches a node with the path in the keys, the numpy value is updated instead of creating a new array. You can pass your own array with an already allocated memory zone or update and already loaded numpy. * **maxdata** (input): Set the maxmimum size of node data array to be read. To be used with the ``NODATA`` flag. If a node has a data size above this max, the node data type is set to ``MT`` (no data) and its path is stored into the returned ``paths`` list to keep traceability on it. * **skip** (input): A list of *CGNS/Python* nodes paths (string) to skip at save time. This list is used when you skp large data and you do not want the save to overwrite the actual data you have on the disk. The ''paths'' list you get with the load is the good candidate for this parameter. This parameter is **only** used for an update, not for a new file save. .. warning:: The current directory is **not** in the link search path. So if your linked-to file is in current directory, you should add `.` in the link search path list. This is to avoid side effect while you are running tools that create local copies. .. warning:: If the filename is an absolute path name (not recommended !) then you should add and empty path in the search path list. .. _mapflags: Flags ~~~~~ The interface choice was to reduce the number of functions and to tune function call parameters to change the behavior or the ``load`` and ``save``. This actually leads to a quite tricky flags manipulation The flags are integers that can be OR-ed or XOR-ed to set/unset specific parts in the read/write loops. Some falgs combinations are impossible, however the irrelevant falgs are silently ignored and you may limit your combinations to the examples hereafter. The boolean operators are used for the flag settings:: flags=CHLone.FFOLLOWLINKS|CHLone.FTRACE flags =flags&~CHLone.FTRACE flags&=~CHLone.FTRACE The table below gives all the `CHLone` flags. +--------------------+------------------------------------------------------+ | *Flag variable* | *Function* | +====================+======================================================+ | ``FNONE`` | Clear all flags, set to zero. | +--------------------+------------------------------------------------------+ | ``FALL`` | Set all flags, set to one. | +--------------------+------------------------------------------------------+ | ``FTRACE`` | Set the trace on, messages are sent to 'stdout' | +--------------------+------------------------------------------------------+ | ``FFOLLOWLINKS`` | Continue to parse the linked-to tree \(1) | +--------------------+------------------------------------------------------+ | ``FNODATA`` | Do not load large 'DataArray_t' \(1) \(3) | +--------------------+------------------------------------------------------+ | ``FIGNORELINKS`` | Forget all link specifications. \(2) | +--------------------+------------------------------------------------------+ | ``FCOMPRESS`` | Force chunking/compress \(8) | +--------------------+------------------------------------------------------+ | ``FREVERSEDIMS`` | Reserved \(5) | +--------------------+------------------------------------------------------+ | ``FOWNDATA`` | Forces the `numpy` flag ``\~NPY_OWNDATA`` \(1) | +--------------------+------------------------------------------------------+ | ``FUPDATE`` | Save updates existing file \(6) \(2) | +--------------------+------------------------------------------------------+ | ``FDELETEMISSING`` | Remove nodes not in input CGNS/Python tree \(2) | +--------------------+------------------------------------------------------+ | ``FALTERNATESIDS`` | Changes some node types \(4) | +--------------------+------------------------------------------------------+ | ``FUPDATEONLY`` | Create/update nodes only from update list \(1) | +--------------------+------------------------------------------------------+ | ``FFORTRANFLAG`` | Forces the `numpy` flag ``\~NPY_FCONTIGUOUS`` \(1) | +--------------------+------------------------------------------------------+ | ``FREADONLY`` | Reserved \(5) | +--------------------+------------------------------------------------------+ | ``FNEW`` | Reserved \(5) | +--------------------+------------------------------------------------------+ | ``FPROPAGATE`` | Force linked-to file write \(2) \(7) | +--------------------+------------------------------------------------------+ | ``FDEBUG`` | Low level debug trace | +--------------------+------------------------------------------------------+ The ``FDEFAULT`` flag corresponds to ``( (FFOLLOWLINKS|FDELETEMISSING|FOWNDATA) & ~FREVERSEDIMS)`` There is no requirements or check on which flag can or cannot be associated with another flag. **Remarks:** (1) Only when you are *loading* a tree. (2) Only when you are *saving* a tree. (3) Which means all ``DataArray_t`` actual memory zones will **NOT** be released by Python. (3) The term `large` has to be defined using the threshold parameter ``maxdata``. The *save* will **NOT** check if the CGNS/Python tree was performed with the ``FNODATA`` flag on, then you have to check by yourself that your *save* will not overwrite an existing file with empty data! The last returned argument of the ``load``, the ``paths`` gives the list of the nodata nodes. (4) The alternate types are not CGNS/SIDS types. See :ref:`CGNS/Python <legacytypes>` mapping. (5) Internal flag (6) The file should exist, all new nodes are added, thus modifying the children list of their parents. Existing nodes are updated only in the case of value change. There no children removal, name or label change. (7) Not implemented yet or incompletely implemented. (8) Compression is with a chunk size of 1024 for 1D and takes the last N-1 dimensions axis as chunk size for others (first axis is then size 1). **Examples:** Without any flag, the default load gets all the tree in the CGNS/HDF5 file, follows the linked-to files as far as they are in the **current** directory. See the link flags hereafter for details about bad link diagnostics:: import CHLone (t,l,p)=CHLone.load('124Disk.hdf') print t,l,p The flag ``FFOLLOWLINKS`` is in the default flags, if we unset it the read of the file will return the status ``LKIGNORED`` (see link flags). The linked-to files are not parsed. The ``FFOLLOWLINKS`` is used for the load, while the ``FIGNORELINKS`` is for the save. It says that the link list passed as argument to the save has to be ignored:: import CHLone flags=CHLone.FDEFAULT&~CHLone.FFOLLOWLINKS (t,l,p)=CHLone.load('124Disk.hdf',flags=flags) print t,l,p The CGNS/SIDS standard defines node types with the pattern ``<TYPE>_t`` for most of the nodes. Some special nodes do have, for historical reasons, a weird type name, for example ``"int[IndexDimension]"``. With the ``FALTERNATESIDS`` flag, you change the weird types with their ``<TYPE>_t`` as defined in the CGNS/Python mapping. This is not CGNS/SIDS compliant, the flag is not set as default:: import CHLone import CGNS.PAT.cgnsutils as CGU flags=CHLone.FDEFAULT|CHLone.FALTERNATESIDS (t,l,p)=CHLone.load('124Disk.hdf',flags=flags) print 'load 1', CGU.getPathsByTypeSet(t,['Transform_t']) (t,l,p)=CHLone.load('124Disk.hdf') print 'load 2', CGU.getPathsByTypeSet(t,['Transform_t']) print 'load 2', CGU.getPathsByTypeSet(t,['"int[IndexDimension]"']) The ``FNODATA`` is one of the most useful flag, it allows to load the file skeletton without the actual data. The falg has to be used with the ``maxdata`` parameter. If you define ``maxdata`` without ``FNODATA`` this parameter is ignored. The third value of the load return is the list of paths of nodes having their data incomplete. Then you actually have the node in the tree, but the data is ``None`` if its size is more than ``maxdata``. The size is the ``ndarray.size`` as returned by *numpy*:: import CHLone import CGNS.PAT.cgnsutils as CGU flags=CHLone.FDEFAULT|CHLone.FNODATA (t,l,p)=CHLone.load('124Disk.hdf',flags=flags,maxdata=30) print t,l,p print 'value:',CGU.getValueByPath(t,'/Disk/zone3/GridCoordinates/CoordinateX') More examples can be found in the CGNS.MAP `examples <http://pycgns.sourceforge.net/MAP/examples.html>`_. The use of *pyCGNS* is helpful for paths manipulation, data search and parse and so on. .. _lkflags: Link flags ~~~~~~~~~~ The link flags can be OR-ed, this is required when the link fails, the actual reason of the failure is described by another flag. The flags are defined as a bitfield so that first value (in parenthesis) is 0, second is 1, then 2... +-------------------+------------------------------------------------------+ | *Flag variable* | *Function* | +===================+======================================================+ | S2P_LKOK | Link has been found and is OK (0) | +-------------------+------------------------------------------------------+ | S2P_LKFAIL | Link has failed, check flags to get the error (1) | +-------------------+------------------------------------------------------+ | S2P_LKNOFILE | Linked-to file not found (2) | +-------------------+------------------------------------------------------+ | S2P_LKFILENOREAD | Linked-to file found but not readable (4) | +-------------------+------------------------------------------------------+ | S2P_LKNONODE | Linked-to file found but linked-to node not found (8)| +-------------------+------------------------------------------------------+ | S2P_LKLOOP | Linked-to file and node found, but loop detected (16)| +-------------------+------------------------------------------------------+ | S2P_LKIGNORED | Link ignored by user request (64) | +-------------------+------------------------------------------------------+ The flags ar OR-ed on failure, for example if you retrieve a link list from a load with a status of 5, this means you have a failure on a file not found (``S2P_LKFAIL`` and ``S2P_LKNOFILE``). Links management ~~~~~~~~~~~~~~~~ The CGNS/HDF5 implementation defines the links as a symbolic link from one node to another node. Both nodes can be in the same file or not. In the case of a local link (a node that refers to another node in the same file), the link entry has no directory/file. The ``load`` parses all the links (it follows links) unless you unset the ``S2P_FOLLOWLINKS``. The ``save`` stops its actual file save when it encounters a link. Then the user has to insure the save of the rest of the *CGNS/Python** tree by himself (see `examples <http://pycgns.sourceforge.net/MAP/examples.html>`_. SIDS-to-Python Mapping ---------------------- .. toctree:: sids-to-python .. warning:: The *root* node of an *HDF5* file is the ``/`` group with an attribute name of ``HDF5 MotherNode``. This is an exception in the *CGNS/HDF5* tree, all other nodes have the same *group name* as the value of the ``name`` attribute. Then, if you want to use ``h5dump`` on a *CGNS/HDF5* tree, keep in mind that the name ``HDF5 MotherNode`` is an internal name and this should *not* be used by applications. .. -------------------------------------------------------------------------