user19316680
user19316680

Reputation:

How to extract list of all zones in a CGNS file?

I am trying to use "PyCGNS" python package in conda to extract the list of all the "zones" in a CGNS file. Attached is the snapshot view of the opened file.

Here is what I want:

zone_list = [zone1, zone2, ..., zone51]

I would appreciate your help..cgns


Hint:

Here is the print(tree) value:

['CGNSTree', None, [['CGNSLibraryVersion', array([3.21], dtype=float32), [], 'CGNSLibraryVersion_t'], ['Base', array([3, 3]), [['zone41', array([[ 77,  76,   0],
       [113, 112,   0],
       [ 49,  48,   0]], dtype=int64), [['ZoneType', array([b'S', b't', b'r', b'u', b'c', b't', b'u', b'r', b'e', b'd'],
      dtype='|S1'), [], 'ZoneType_t'], ['GridCoordinates', None, [['CoordinateX', array(....

Upvotes: 0

Views: 284

Answers (2)

kcw78
kcw78

Reputation: 8026

I'm not a PyCGNS guy, but I understand HDF5 data schema, so will give it a try. :)

The docs recommend (tree,links,paths)=CGNS.MAP.load("your.hdf") Did you try that? It returns tree which is a Python list with the CGNS tree info. As I understand, the tree describes the node structure (aka schema). Per the documentation, the node structure looks like this:

Attribute type
Name string
Value numpy array
Children list of CGNS/Python nodes
Type string

You could print(tree), but I think you will be swamped with output. You can interrogate the tree to find nodes named "zone*". Based on your image, I suspect all zone nodes are all children of a Node with named "Base". If so, the code will look something like this (educated guess):

import CGNS.MAP
(tree,links,paths) = CGNS.MAP.load("your.hdf")
# print(f'Tree has {len(tree[2])} child nodes')
level_1_nodes = tree[2]
# print(f'Level 1 Node List has {len(level_1_nodes)} child nodes') 
base_node = level_1_nodes[1]
# print(f'Base Node List has {len(base_node[2])} child nodes') 
zone_nodes = base_node[2]
print(f'Zone Node List has {len(zone_nodes)} child nodes') 
zones = [] 
for zone in zone_nodes:
    print(f'Checking on child node: {zone[0]}')
    if 'zone' in zone[0]:
        # print(f'Zone: {zone[0]} node has {len(zone[2])} child nodes') 
        zones.append(zone[0])                       

If you are familiar with List Comprehension, the last 4 lines can be simplified to:

zones = [ z[0] for z in zone_nodes if "zone" in z[0] ] 

Give that a try and see if solves your problem. If it's not exactly right, it should get you close.

Upvotes: 0

user19316680
user19316680

Reputation:

Here is the answer I was finally looking for (thank for the help from kcw78)

def zone_extractor(fname: str) -> List:
    """This function extracts all the zones in a CGNS file

    Args:
        fname (str): _description_

    Returns:
        List: _description_
    """
    (tree, links, paths) = CGM.load(Path(FILE_DIR) / fname)
    zones = []
    for node in tree:
        if (node is not None) and isinstance(node, list) and (node[1][0] == 'Base'):
            zones = [child[0] for child in node[1][2] if child[0].startswith('zone')]
    return sorted_nicely(zones)

Upvotes: 0

Related Questions