h5rdmtoolbox 0.8.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of h5rdmtoolbox might be problematic. Click here for more details.

Files changed (115) hide show
  1. h5rdmtoolbox/__init__.py +174 -0
  2. h5rdmtoolbox/_cfg.py +102 -0
  3. h5rdmtoolbox/_cli.py +211 -0
  4. h5rdmtoolbox/_repr.py +480 -0
  5. h5rdmtoolbox/_user.py +105 -0
  6. h5rdmtoolbox/_version.py +6 -0
  7. h5rdmtoolbox/cache.py +3 -0
  8. h5rdmtoolbox/consts.py +3 -0
  9. h5rdmtoolbox/conventions/__init__.py +28 -0
  10. h5rdmtoolbox/conventions/cfg.py +2 -0
  11. h5rdmtoolbox/conventions/consts.py +22 -0
  12. h5rdmtoolbox/conventions/core.py +484 -0
  13. h5rdmtoolbox/conventions/errors.py +34 -0
  14. h5rdmtoolbox/conventions/html/template.html +17 -0
  15. h5rdmtoolbox/conventions/layout/__init__.py +35 -0
  16. h5rdmtoolbox/conventions/layout/core.py +236 -0
  17. h5rdmtoolbox/conventions/layout/tbx.py +123 -0
  18. h5rdmtoolbox/conventions/layout/utils.py +25 -0
  19. h5rdmtoolbox/conventions/layout/validation.py +501 -0
  20. h5rdmtoolbox/conventions/layout/validators.py +229 -0
  21. h5rdmtoolbox/conventions/references.py +66 -0
  22. h5rdmtoolbox/conventions/standard_attributes.py +252 -0
  23. h5rdmtoolbox/conventions/standard_names/__init__.py +6 -0
  24. h5rdmtoolbox/conventions/standard_names/accessor.py +130 -0
  25. h5rdmtoolbox/conventions/standard_names/affixes.py +306 -0
  26. h5rdmtoolbox/conventions/standard_names/cache.py +3 -0
  27. h5rdmtoolbox/conventions/standard_names/consts.py +17 -0
  28. h5rdmtoolbox/conventions/standard_names/h5interface.py +167 -0
  29. h5rdmtoolbox/conventions/standard_names/name.py +114 -0
  30. h5rdmtoolbox/conventions/standard_names/table.py +916 -0
  31. h5rdmtoolbox/conventions/standard_names/transformation.py +267 -0
  32. h5rdmtoolbox/conventions/standard_names/utils.py +67 -0
  33. h5rdmtoolbox/conventions/standard_names/validator.py +88 -0
  34. h5rdmtoolbox/conventions/utils.py +153 -0
  35. h5rdmtoolbox/conventions/validator_management.py +2 -0
  36. h5rdmtoolbox/conventions/validators.py +381 -0
  37. h5rdmtoolbox/conventions/warnings.py +5 -0
  38. h5rdmtoolbox/data/__init__.py +9 -0
  39. h5rdmtoolbox/data/fluid-v1.yml +36 -0
  40. h5rdmtoolbox/data/h5tbx_convention.yaml +21 -0
  41. h5rdmtoolbox/data/piv-v1.yml +35 -0
  42. h5rdmtoolbox/data/style.css +199 -0
  43. h5rdmtoolbox/data/tutorial_convention.yaml +98 -0
  44. h5rdmtoolbox/data/tutorial_standard_name_table.yaml +89 -0
  45. h5rdmtoolbox/database/__init__.py +72 -0
  46. h5rdmtoolbox/database/file.py +497 -0
  47. h5rdmtoolbox/database/files.py +142 -0
  48. h5rdmtoolbox/database/lazy.py +151 -0
  49. h5rdmtoolbox/database/mongo.py +291 -0
  50. h5rdmtoolbox/database/parallel.py +57 -0
  51. h5rdmtoolbox/database/results.py +0 -0
  52. h5rdmtoolbox/database/tutorial.py +6 -0
  53. h5rdmtoolbox/errors.py +4 -0
  54. h5rdmtoolbox/extensions/__init__.py +0 -0
  55. h5rdmtoolbox/extensions/dataset.py +0 -0
  56. h5rdmtoolbox/extensions/ipyvolume.py +176 -0
  57. h5rdmtoolbox/extensions/magnitude.py +77 -0
  58. h5rdmtoolbox/extensions/normalize.py +93 -0
  59. h5rdmtoolbox/extensions/scatterhist.py +100 -0
  60. h5rdmtoolbox/extensions/units.py +23 -0
  61. h5rdmtoolbox/extensions/vector.py +85 -0
  62. h5rdmtoolbox/hdfgui.py +39 -0
  63. h5rdmtoolbox/orcid.py +139 -0
  64. h5rdmtoolbox/plotting.py +166 -0
  65. h5rdmtoolbox/protected_attributes.py +9 -0
  66. h5rdmtoolbox/tutorial.py +318 -0
  67. h5rdmtoolbox/utils.py +481 -0
  68. h5rdmtoolbox/wrapper/__init__.py +9 -0
  69. h5rdmtoolbox/wrapper/accessory.py +74 -0
  70. h5rdmtoolbox/wrapper/core.py +2140 -0
  71. h5rdmtoolbox/wrapper/ds_decoder.py +109 -0
  72. h5rdmtoolbox/wrapper/h5attr.py +239 -0
  73. h5rdmtoolbox/wrapper/h5ext.py +20 -0
  74. h5rdmtoolbox/wrapper/h5utils.py +32 -0
  75. h5rdmtoolbox/wrapper/h5yaml.py +78 -0
  76. h5rdmtoolbox/wrapper/xr2hdf.py +101 -0
  77. h5rdmtoolbox-0.8.1.dist-info/LICENSE +674 -0
  78. h5rdmtoolbox-0.8.1.dist-info/METADATA +223 -0
  79. h5rdmtoolbox-0.8.1.dist-info/RECORD +115 -0
  80. h5rdmtoolbox-0.8.1.dist-info/WHEEL +5 -0
  81. h5rdmtoolbox-0.8.1.dist-info/entry_points.txt +2 -0
  82. h5rdmtoolbox-0.8.1.dist-info/top_level.txt +2 -0
  83. tests/__init__.py +0 -0
  84. tests/conventions/__init__.py +0 -0
  85. tests/conventions/standard_attributes/__init__.py +0 -0
  86. tests/conventions/standard_attributes/standard_names/__init__.py +0 -0
  87. tests/conventions/standard_attributes/standard_names/test_interface.py +131 -0
  88. tests/conventions/standard_attributes/standard_names/test_provenance.py +95 -0
  89. tests/conventions/standard_attributes/standard_names/test_snt.py +238 -0
  90. tests/conventions/standard_attributes/standard_names/test_transformations_and_affixes.py +268 -0
  91. tests/conventions/standard_attributes/test_standard_attributes.py +481 -0
  92. tests/conventions/standard_attributes/test_standard_names.py +296 -0
  93. tests/conventions/test_conventions.py +285 -0
  94. tests/conventions/test_layout.py +513 -0
  95. tests/conventions/test_utils.py +48 -0
  96. tests/conventions/test_validators.py +27 -0
  97. tests/database/__init__.py +0 -0
  98. tests/database/test_filequery.py +474 -0
  99. tests/database/test_mongo.py +252 -0
  100. tests/test_config.py +79 -0
  101. tests/test_extensions.py +160 -0
  102. tests/test_logger.py +31 -0
  103. tests/test_orcid.py +32 -0
  104. tests/test_potting.py +155 -0
  105. tests/test_repr.py +79 -0
  106. tests/test_user.py +56 -0
  107. tests/test_utils.py +94 -0
  108. tests/test_version.py +19 -0
  109. tests/wrapper/__init__.py +0 -0
  110. tests/wrapper/test_core.py +696 -0
  111. tests/wrapper/test_dump.py +21 -0
  112. tests/wrapper/test_file.py +503 -0
  113. tests/wrapper/test_find.py +36 -0
  114. tests/wrapper/test_h5ext.py +22 -0
  115. tests/wrapper/test_xr2df.py +41 -0
@@ -0,0 +1,174 @@
1
+ """h5rdtoolbox repository"""
2
+ import atexit
3
+ import pathlib
4
+ # noinspection PyUnresolvedReferences
5
+ import pint_xarray
6
+ import shutil
7
+ import xarray as xr
8
+ from typing import Union, Callable
9
+
10
+ from h5rdmtoolbox._cfg import set_config, get_config, get_ureg
11
+
12
+ pint_xarray.unit_registry = get_ureg()
13
+
14
+ from . import conventions
15
+ from .conventions.core import Convention
16
+ from . import plotting
17
+ from . import wrapper
18
+ from ._user import UserDir
19
+ from ._version import __version__
20
+ from . import database
21
+ from . import utils
22
+ from .wrapper.core import lower, Lower, File, Group, Dataset
23
+ from . import errors
24
+
25
+ from .wrapper.accessory import register_special_dataset
26
+
27
+ name = 'h5rdmtoolbox'
28
+ __this_dir__ = pathlib.Path(__file__).parent
29
+ __author__ = 'Matthias Probst'
30
+ __author_orcid__ = 'https://orcid.org/0000-0001-8729-0482'
31
+
32
+ logger = utils.create_tbx_logger('h5rdmtoolbox')
33
+
34
+ logger.setLevel(get_config()['init_logger_level'])
35
+
36
+ cv_h5py = conventions.Convention('h5py',
37
+ contact=__author_orcid__)
38
+ cv_h5py.register()
39
+
40
+ cv_h5tbx = conventions.Convention.from_yaml(__this_dir__ / 'data/h5tbx_convention.yaml')
41
+
42
+ use = conventions.core.use
43
+
44
+ use(get_config()['default_convention'])
45
+
46
+
47
+ class FileDB:
48
+ """User-friendly interface to database.Folder, database.File or database.Files"""
49
+
50
+ def __new__(cls, path, rec=False, **kwargs):
51
+ if isinstance(path, (list, tuple)):
52
+ filenames = []
53
+ for p in [pathlib.Path(_p) for _p in path]:
54
+ if p.is_file():
55
+ filenames.append(p)
56
+ elif p.is_dir():
57
+ if rec:
58
+ for f in p.rglob('*.hdf'):
59
+ filenames.append(f)
60
+ else:
61
+ for f in p.glob('*.hdf'):
62
+ filenames.append(f)
63
+ return database.Files(filenames, **kwargs)
64
+
65
+ path = pathlib.Path(path)
66
+ if path.is_dir():
67
+ return database.Folder(path, rec=rec, **kwargs)
68
+ return database.File(path, **kwargs)
69
+
70
+
71
+ def dump(src: Union[str, File, pathlib.Path]) -> None:
72
+ """Call h5.dump() on the provided HDF5 file
73
+
74
+ Parameters
75
+ ----------
76
+ src : str, File, pathlib.Path
77
+ the HDF5 file or filename to dump
78
+ """
79
+ if isinstance(src, File):
80
+ with File(src.hdf_filename) as h5:
81
+ return h5.dump()
82
+ with File(src) as h5:
83
+ return h5.dump()
84
+
85
+
86
+ def dumps(src: Union[str, File, pathlib.Path]):
87
+ """Call h5.dumps() on the provided HDF5 file"""
88
+ if isinstance(src, File):
89
+ with File(src.hdf_filename) as h5:
90
+ return h5.dumps()
91
+ with File(src) as h5:
92
+ return h5.dumps()
93
+
94
+
95
+ def register_dataset_decoder(decoder: Callable, decoder_name: str = None, overwrite: bool = False):
96
+ """A decoder function takes a xarray.DataArray and a dataset as input and returns a xarray.DataArray
97
+ It is called after the dataset is loaded into memory and before being returned to the user. Be careful:
98
+ Multiple decoders can be registered and they are called in the order of registration. Hence, your decoder
99
+ may behave unexpectedly!
100
+ """
101
+ from .wrapper import ds_decoder
102
+ if decoder_name is None:
103
+ decoder_name = decoder.__name__
104
+ registered_decorators = ds_decoder.registered_dataset_decoders
105
+ if decoder_name in registered_decorators or decoder in registered_decorators.values():
106
+ if not overwrite:
107
+ raise ValueError(f'decoder "{decoder_name}" already registered. Name and function must be unique.')
108
+ ds_decoder.registered_dataset_decoders[decoder_name] = decoder
109
+
110
+
111
+ atexit_verbose = False
112
+
113
+
114
+ @atexit.register
115
+ def clean_temp_data(full: bool = False):
116
+ """cleaning up the tmp directory"""
117
+ from ._user import _user_root_dir
118
+
119
+ failed_dirs = []
120
+ failed_dirs_file = UserDir['tmp'] / 'failed.txt'
121
+ if full:
122
+ root_tmp = _user_root_dir / 'tmp'
123
+ if root_tmp.exists():
124
+ try:
125
+ shutil.rmtree(root_tmp)
126
+ root_tmp.mkdir(exist_ok=True, parents=True)
127
+ except PermissionError as e:
128
+ print(f'removing tmp folder "{root_tmp}" failed due to "{e}".')
129
+ return
130
+
131
+ for _tmp_session_dir in [UserDir['tmp'], ]:
132
+ if atexit_verbose:
133
+ print(f'cleaning up tmp directory "{_tmp_session_dir}"')
134
+ if _tmp_session_dir.exists():
135
+ try:
136
+ if atexit_verbose:
137
+ print(f'try deleting tmp in session dir: {_tmp_session_dir}')
138
+ shutil.rmtree(_tmp_session_dir)
139
+ except PermissionError as e:
140
+ if atexit_verbose:
141
+ print(f'[!] failed deleting tmp session dir: {_tmp_session_dir}')
142
+ failed_dirs.append(UserDir['tmp'])
143
+ if atexit_verbose:
144
+ print(f'removing tmp folder "{_tmp_session_dir}" failed due to "{e}". Best is you '
145
+ f'manually delete the directory.')
146
+ finally:
147
+ lines = []
148
+ if failed_dirs_file.exists():
149
+ with open(failed_dirs_file, 'r') as f:
150
+ lines = f.readlines()
151
+ for line in lines:
152
+ try:
153
+ shutil.rmtree(line.strip())
154
+ except Exception:
155
+ if pathlib.Path(line).exists():
156
+ failed_dirs.append(line)
157
+
158
+ if lines or failed_dirs:
159
+ with open(failed_dirs_file, 'w') as f:
160
+ for fd in failed_dirs:
161
+ f.writelines(f'{fd}\n')
162
+ else:
163
+ failed_dirs_file.unlink(missing_ok=True)
164
+ else:
165
+ logger.debug(f'No user tmp dir not found: {_tmp_session_dir}')
166
+
167
+
168
+ xr.set_options(display_expand_data=False)
169
+
170
+ __all__ = ('__version__', '__author__', '__author_orcid__', 'UserDir', 'use',
171
+ 'File', 'Group', 'Dataset',
172
+ 'dump', 'dumps', 'cv_h5py', 'lower', 'Lower',
173
+ 'set_config', 'get_config', 'get_ureg',
174
+ 'Convention')
h5rdmtoolbox/_cfg.py ADDED
@@ -0,0 +1,102 @@
1
+ """package configuration. largely based on xarray's configuration concept. no credits taken!"""
2
+ from pint import UnitRegistry
3
+ from typing import Dict, Union
4
+
5
+ ureg = UnitRegistry(force_ndarray_like=True)
6
+
7
+
8
+ def is_valid_logger_level(level: Union[str, int]):
9
+ """Check if the logger level is valid."""
10
+ if not isinstance(level, (str, int)):
11
+ # raise TypeError(f'Invalid type for the logger: {type(logger_value)}')
12
+ return False
13
+ if isinstance(level, str):
14
+ return level.lower() in ('error', 'debug', 'critical', 'warning', 'info', 'fatal', 'warning', 'warn')
15
+ # 0: NOTSET, 10: DEBUG, 20: INFO, 30: WARNING, 40: ERROR, 50: CRITICAL
16
+ return level in (0, 10, 20, 30, 40, 50)
17
+
18
+
19
+ CONFIG = {'return_xarray': True,
20
+ 'advanced_shape_repr': True,
21
+ 'natural_naming': True,
22
+ 'hdf_compression': 'gzip',
23
+ 'hdf_compression_opts': 5,
24
+ 'xarray_unit_repr_in_plots': 'in',
25
+ 'plotting_name_order': ('plot_name', 'long_name', 'standard_name'),
26
+ 'require_unit': True, # datasets require units
27
+ 'ureg_format': 'C~',
28
+ 'default_convention': 'h5tbx',
29
+ 'init_logger_level': 'ERROR',
30
+ 'dtime_fmt': '%Y%m%d%H%M%S%f',
31
+ 'expose_user_prop_to_attrs': True,
32
+ 'scale_attribute_name': 'scale',
33
+ 'offset_attribute_name': 'offset',
34
+ 'add_provenance': True,
35
+ 'ignore_standard_attribute_errors': False,
36
+ 'allow_deleting_standard_attributes': False,
37
+ 'parallel_find': True, }
38
+
39
+ _VALIDATORS = {
40
+ 'return_xarray': lambda x: isinstance(x, bool),
41
+ 'advanced_shape_repr': lambda x: isinstance(x, bool),
42
+ 'natural_naming': lambda x: isinstance(x, bool),
43
+ 'hdf_compression': lambda x: isinstance(x, str),
44
+ 'hdf_compression_opts': lambda x: isinstance(x, int),
45
+ 'xarray_unit_repr_in_plots': lambda x: x in ('/', '()', '(', '[]', '[', '//', 'in'),
46
+ 'plotting_name_order': lambda x: isinstance(x, (tuple, list)) and [xx in ('plot_name', 'long_name', 'standard_name')
47
+ for xx in x],
48
+ 'require_unit': lambda x: isinstance(x, bool),
49
+ 'ureg_format': lambda x: isinstance(x, str),
50
+ 'default_convention': lambda x: str(x) in ('h5py', 'h5tbx', 'None'),
51
+ 'init_logger_level': lambda x: is_valid_logger_level(x),
52
+ 'dtime_fmt': lambda x: isinstance(x, str),
53
+ 'expose_user_prop_to_attrs': lambda x: isinstance(x, bool),
54
+ 'scale_attribute_name': lambda x: isinstance(x, str),
55
+ 'offset_attribute_name': lambda x: isinstance(x, str),
56
+ 'add_provenance': lambda x: isinstance(x, bool),
57
+ 'ignore_standard_attribute_errors': lambda x: isinstance(x, bool),
58
+ 'parallel_find': lambda x: isinstance(x, bool),
59
+ }
60
+
61
+
62
+ class set_config:
63
+ """Set the configuration parameters."""
64
+
65
+ def __init__(self, **kwargs):
66
+ self.old = {}
67
+ for k, v in kwargs.items():
68
+ if k in _VALIDATORS and not _VALIDATORS[k](v):
69
+ raise ValueError(f'Config parameter "{k}" has invalid value: "{v}"')
70
+ if k not in CONFIG:
71
+ raise KeyError(f'Not a configuration key: "{k}"')
72
+ self.old[k] = CONFIG[k]
73
+ if k == 'ureg_format':
74
+ get_ureg().default_format = str(v)
75
+ self._update(kwargs)
76
+
77
+ def __enter__(self):
78
+ return
79
+
80
+ def __exit__(self, *args, **kwargs):
81
+ self._update(self.old)
82
+
83
+ def _update(self, options_dict: Dict):
84
+ CONFIG.update(options_dict)
85
+
86
+
87
+ # set_config = ConfigSetter()
88
+
89
+
90
+ def get_config(key=None):
91
+ """Return the configuration parameters."""
92
+ if key is None:
93
+ return CONFIG
94
+ return CONFIG[key]
95
+
96
+
97
+ def get_ureg() -> UnitRegistry:
98
+ """get unit registry"""
99
+ return ureg
100
+
101
+
102
+ set_config(ureg_format=CONFIG['ureg_format'])
h5rdmtoolbox/_cli.py ADDED
@@ -0,0 +1,211 @@
1
+ """collection of command line interface functions"""
2
+
3
+ import argparse
4
+ import h5py
5
+ import webbrowser
6
+ from pprint import pprint
7
+
8
+ from . import File
9
+ from ._version import __version__
10
+
11
+
12
+ def main():
13
+ """main command line interface function"""
14
+ parser = argparse.ArgumentParser(description='h5RDMtoolbox command line interface')
15
+ parser.add_argument('-V', '--version',
16
+ action='version', version=f'%(prog)s {__version__}')
17
+ parser.add_argument('-D', dest='documentation',
18
+ action='store_true',
19
+ help="Opens documentation in browser")
20
+ parser.add_argument('-u', '--user-dirs',
21
+ action='store_true',
22
+ default=False,
23
+ help='Print user directories.')
24
+ parser.add_argument('-d', '--dump',
25
+ type=str,
26
+ required=False,
27
+ default=None,
28
+ help='Dump file content.')
29
+ subparsers = parser.add_subparsers(help='sub-commands help')
30
+
31
+ # LAYOUT
32
+ sp_layout = subparsers.add_parser('layout', help='layout menu')
33
+ sp_layout.set_defaults(cmd='layout')
34
+ sp_layout.add_argument('--list-registered', action='store_true',
35
+ help='List all registered layouts.')
36
+ sp_layout.add_argument('-l', '--layout',
37
+ type=str,
38
+ required=False,
39
+ default=None,
40
+ help='Registered layout name or filename of a layout.')
41
+ sp_layout.add_argument('-c', '--check',
42
+ type=str,
43
+ required=False,
44
+ default=None,
45
+ help='Filename to run check on.')
46
+ sp_layout.add_argument('-r', '--register',
47
+ type=str,
48
+ required=False,
49
+ default=None,
50
+ help='Register the passed HDF file as a layout.')
51
+
52
+ # STANDARD NAME
53
+ sp_standard_name = subparsers.add_parser('standard_name', help='standard name menu')
54
+ sp_standard_name.set_defaults(cmd='standard_name')
55
+ sp_standard_name.add_argument('--list-registered', action='store_true',
56
+ help='List all registered standard name tables.')
57
+ sp_standard_name.add_argument('-t', '--table',
58
+ type=str,
59
+ required=False,
60
+ default=None,
61
+ help='Registered standard name or filename of a standard table.')
62
+ sp_standard_name.add_argument('-f', '--file',
63
+ type=str,
64
+ required=False,
65
+ default=None,
66
+ help='Filename to run check on.')
67
+ # MONGODB
68
+ sp_mongo = subparsers.add_parser('mongodb', help='mongodb menu')
69
+ sp_mongo.set_defaults(cmd='mongodb')
70
+ # sp_mongo.add_argument('list_dbs', nargs='?', default=False, help='List all available databases')
71
+ # sp_mongo.add_argument('list_collections', nargs='?', default=False, help='List all available collections of the '
72
+ # 'selected database')
73
+ sp_mongo.add_argument('--list-dbs', action='store_true')
74
+ sp_mongo.add_argument('--list-collections', action='store_true')
75
+ sp_mongo.add_argument('-i', '--ip',
76
+ type=str,
77
+ required=False,
78
+ default='localhost',
79
+ help='IP address. Default is localhost')
80
+ sp_mongo.add_argument('-p', '--port',
81
+ type=int,
82
+ required=False,
83
+ default=27017,
84
+ help='Port. Default is 27017')
85
+ sp_mongo.add_argument('-d', '--db',
86
+ type=str,
87
+ required=False,
88
+ help='Database')
89
+ sp_mongo.add_argument('-c', '--collection',
90
+ type=str,
91
+ required=False,
92
+ default=False,
93
+ help='Collection')
94
+ sp_mongo.add_argument('-a', '--add',
95
+ type=str,
96
+ required=False,
97
+ default=False,
98
+ help='Add HDF file to database')
99
+
100
+ args = parser.parse_args()
101
+ if args.documentation:
102
+ webbrowser.open('https://matthiasprobst.github.io/h5RDMtoolbox/')
103
+ return
104
+ if args.user_dirs:
105
+ from ._user import UserDir
106
+ pprint(UserDir)
107
+ return
108
+ if args.dump:
109
+ with File(args.dump) as h5:
110
+ h5.sdump()
111
+ arg_vars = vars(args)
112
+
113
+ if 'cmd' in arg_vars:
114
+ if args.cmd == 'mongodb':
115
+ from pymongo import MongoClient
116
+ db = None
117
+ collection = None
118
+
119
+ print(f'\n > Current connection: {args.ip}:{args.port}')
120
+ client = MongoClient(args.ip, args.port)
121
+ list_of_databases = client.list_database_names()
122
+
123
+ if args.db:
124
+ if len(list_of_databases) == 0:
125
+ print(' > No connection to a client found')
126
+ return
127
+ db = client[args.db]
128
+
129
+ if args.collection:
130
+ # list_of_collections = db.list_collection_names()
131
+ # if len(list_of_collections) == 0:
132
+ # print(f' ! No collections found')
133
+ # return
134
+ collection = db[args.collection]
135
+ print(f' > Selected collection: {collection}')
136
+
137
+ if args.list_dbs:
138
+ pprint(list_of_databases)
139
+ return
140
+
141
+ if args.list_collections:
142
+ print(' > Listing collections for ')
143
+ if db is None:
144
+ print(' ! No database selected')
145
+ return
146
+ print(db)
147
+ list_of_collections = db.list_collection_names()
148
+ print(' > List of collections:\n--------------------')
149
+ pprint(list_of_collections)
150
+ return
151
+
152
+ if args.add:
153
+ if collection is None:
154
+ print('No collection selected or found')
155
+ return
156
+ try:
157
+ with h5py.File(args.add):
158
+ pass
159
+ except OSError:
160
+ print(' ! Unable to open the HDF file. Make sure it is an HDF file and that it can be '
161
+ 'opened/is not corrupt')
162
+ return
163
+ print(f' > Adding hdf file: {args.add} to collection {collection.name} of database {db.name}')
164
+ with File(args.add) as h5:
165
+ # noinspection PyUnresolvedReferences
166
+ from h5rdmtoolbox.database import mongo
167
+ h5.mongo.insert(collection=collection, recursive=True, update=True)
168
+ return
169
+ if args.cmd == 'standard_name':
170
+ from .conventions.tbx import StandardNameTable
171
+ import pathlib
172
+ if args.list_registered:
173
+ StandardNameTable.print_registered()
174
+ return
175
+ if args.table:
176
+ snt_filename = pathlib.Path(args.table)
177
+ if snt_filename.exists():
178
+ snt = StandardNameTable.from_yaml(args.table)
179
+ else:
180
+ snt = StandardNameTable.load_registered(args.table)
181
+ print(f' > Checking file "{args.file}" with standard name table "{snt.versionname}"')
182
+ with File(args.file) as h5:
183
+ snt.check_hdf_group(h5, recursive=True, raise_error=False)
184
+ return
185
+ if args.cmd == 'layout':
186
+ from .conventions import layout
187
+ import pathlib
188
+ if args.list_registered:
189
+ for k in layout.File.Registry().layouts.keys():
190
+ print(k)
191
+ return
192
+ hdf_filename = None
193
+ if args.check:
194
+ hdf_filename = pathlib.Path(args.check)
195
+ if args.layout:
196
+ layout_filename = pathlib.Path(args.layout)
197
+ if layout_filename.exists():
198
+ h5lay = layout.File(layout_filename)
199
+ else:
200
+ h5lay = layout.File.load_registered(args.layout, h5repr=None)
201
+ if hdf_filename is None:
202
+ print('No hdf filename. Provide by -f <my_file.hdf>')
203
+ return
204
+ print(f'Checking {hdf_filename} with layout {args.layout}')
205
+ with h5py.File(hdf_filename) as h5:
206
+ h5lay.check(h5)
207
+ return
208
+ if args.register:
209
+ hdf_filename = pathlib.Path(args.register)
210
+ h5lay = layout.File(hdf_filename)
211
+ h5lay.register()