diff --git a/src/lgdo/cli.py b/src/lgdo/cli.py index 16fee6c8..6563fd66 100644 --- a/src/lgdo/cli.py +++ b/src/lgdo/cli.py @@ -52,6 +52,11 @@ def lh5ls(args=None): default=None, help="""Maximum tree depth of groups to print""", ) + parser.add_argument( + "--detail", + action="store_true", + help="""Print details about datasets""", + ) args = parser.parse_args(args) @@ -66,7 +71,13 @@ def lh5ls(args=None): print(__version__) # noqa: T201 sys.exit() - lh5.show(args.lh5_file, args.lh5_group, attrs=args.attributes, depth=args.depth) + lh5.show( + args.lh5_file, + args.lh5_group, + attrs=args.attributes, + depth=args.depth, + detail=args.detail, + ) def lh5concat(args=None): diff --git a/src/lgdo/lh5/tools.py b/src/lgdo/lh5/tools.py index b9eb2f38..ff526d42 100644 --- a/src/lgdo/lh5/tools.py +++ b/src/lgdo/lh5/tools.py @@ -87,6 +87,7 @@ def show( indent: str = "", header: bool = True, depth: int | None = None, + detail: bool = False, ) -> None: """Print a tree of LH5 file contents with LGDO datatype. @@ -104,6 +105,8 @@ def show( print `lh5_group` at the top of the diagram. depth maximum tree depth of groups to print + detail + whether to print additional information about how the data is stored Examples -------- @@ -171,6 +174,26 @@ def show( print(f"{indent}{char} \033[1m{key}\033[0m ยท {dtype} {_attrs}") # noqa: T201 + if detail and isinstance(val, h5py.Dataset): + char = "| " + if killme: + char = " " + toprint = f"{indent}{char}" + try: + toprint += f"\033[3mdtype\033[0m={val.dtype}" + toprint += f", \033[3mshape\033[0m={val.shape}" + toprint += f", \033[3mnbytes\033[0m={utils.fmtbytes(val.nbytes)}" + if (chunkshape := val.chunks) is None: + toprint += ", \033[3mnumchunks\033[0m=contiguous" + else: + toprint += f", \033[3mnumchunks\033[0m={val.id.get_num_chunks()}" + toprint += f", \033[3mchunkshape\033[0m={chunkshape}" + toprint += f", \033[3mcompression\033[0m={val.compression}" + except TypeError: + toprint += "(scalar)" + + print(toprint) # noqa: T201 + # if it's a group, call this function recursively if isinstance(val, h5py.Group): show( @@ -179,6 +202,7 @@ def show( header=False, attrs=attrs, depth=depth - 1 if depth else None, + detail=detail, ) # break or move to next key diff --git a/src/lgdo/lh5/utils.py b/src/lgdo/lh5/utils.py index ef139398..cf1fed04 100644 --- a/src/lgdo/lh5/utils.py +++ b/src/lgdo/lh5/utils.py @@ -221,3 +221,13 @@ def expand_path( return paths[0] return paths + + +# https://stackoverflow.com/a/1094933 +def fmtbytes(num, suffix="B"): + """Returns formatted f-string for printing human-readable number of bytes.""" + for unit in ("", "k", "M", "G", "T", "P", "E", "Z"): + if abs(num) < 1024.0: + return f"{num:3.1f} {unit}{suffix}" + num /= 1024.0 + return f"{num:.1f} Y{suffix}"