pyhdf5_handler.src.hdf5_handler
1from __future__ import annotations 2 3import os 4import h5py 5import numpy as np 6import numbers 7import pandas as pd 8import datetime 9import time 10 11from ..src import object_handler 12import gc 13 14 15def close_all_hdf5_file(): 16 """ 17 Close all hdf5 file opened in the current session 18 """ 19 20 for obj in gc.get_objects(): # Browse through ALL objects 21 if isinstance(obj, h5py.File): # Just HDF5 files 22 try: 23 print(f"try closing {obj}") 24 obj.close() 25 except: 26 pass # Was already closed 27 28 29def open_hdf5(path, read_only=False, replace=False, wait_time=0): 30 """ 31 32 Open or create an HDF5 file. 33 34 Parameters 35 ---------- 36 37 path : str 38 The file path. 39 40 read_only : boolean 41 If true the access to the hdf5 fil is in read-only mode. Multi process can read the same hdf5 file simulteneously. This is not possible when access mode are append 'a' or write 'w'. 42 43 replace: Boolean 44 If true, the existing hdf5file is erased 45 46 wait_time: int 47 If the hdf5 is unavailable, the function will try to access serveral time and will wait wait_time seconds maximum. If this time is elapsed, the file won't be opened. This parameter is usefull if several program or threads need to read/write simultaneously in the same hdf5 database. 48 49 Returns 50 ------- 51 52 f : 53 A h5py object. 54 55 Examples 56 -------- 57 58 >>> hdf5=pyhdf5_handler.open_hdf5("./my_hdf5.hdf5") 59 >>> hdf5.keys() 60 >>> hdf5.attrs.keys() 61 62 """ 63 f = None 64 wait = 0 65 while wait <= wait_time: 66 67 f = None 68 exist_file = True 69 70 try: 71 72 if read_only: 73 if os.path.isfile(path): 74 f = h5py.File(path, "r") 75 76 else: 77 exist_file = False 78 raise ValueError(f"File {path} does not exist.") 79 80 else: 81 if replace: 82 f = h5py.File(path, "w") 83 84 else: 85 if os.path.isfile(path): 86 f = h5py.File(path, "a") 87 88 else: 89 f = h5py.File(path, "w") 90 except: 91 pass 92 93 if f is None: 94 if not exist_file: 95 print(f"File {path} does not exist.") 96 return f 97 else: 98 print(f"The file {path} is unvailable, waiting {wait}/{wait_time}s") 99 100 wait = wait + 1 101 102 if wait_time > 0: 103 time.sleep(1) 104 105 else: 106 break 107 108 return f 109 110 111def add_hdf5_sub_group(hdf5, subgroup=None): 112 """ 113 Create a new subgroup in a HDF5 object 114 115 Parameters 116 ---------- 117 118 hdf5 : h5py.File 119 An hdf5 object opened with open_hdf5() 120 121 subgroup: str 122 Path to a subgroub that must be created 123 124 Returns 125 ------- 126 127 hdf5 : 128 the h5py object. 129 130 Examples 131 -------- 132 133 >>> hdf5=pyhdf5_handler.open_hdf5("./model_subgroup.hdf5", replace=True) 134 >>> hdf5=pyhdf5_handler.add_hdf5_sub_group(hdf5, subgroup="mygroup") 135 >>> hdf5.keys() 136 >>> hdf5.attrs.keys() 137 138 """ 139 if subgroup is not None: 140 if subgroup == "": 141 subgroup = "./" 142 143 hdf5.require_group(subgroup) 144 145 return hdf5 146 147 148def _dump_object_to_hdf5_from_list_attribute(hdf5, instance, list_attr): 149 """ 150 dump a object to a hdf5 file from a list of attributes 151 152 Parameters 153 ---------- 154 hdf5 : h5py.File 155 an hdf5 object 156 157 instance : object 158 a custom python object. 159 160 list_attr : list 161 a list of attribute 162 163 """ 164 if isinstance(list_attr, list): 165 for attr in list_attr: 166 if isinstance(attr, str): 167 _dump_object_to_hdf5_from_str_attribute(hdf5, instance, attr) 168 169 elif isinstance(attr, list): 170 _dump_object_to_hdf5_from_list_attribute(hdf5, instance, attr) 171 172 elif isinstance(attr, dict): 173 _dump_object_to_hdf5_from_dict_attribute(hdf5, instance, attr) 174 175 else: 176 raise ValueError( 177 f"inconsistent {attr} in {list_attr}. {attr} must be a an instance of dict, list or str" 178 ) 179 180 else: 181 raise ValueError(f"{list_attr} must be a instance of list.") 182 183 184def _dump_object_to_hdf5_from_dict_attribute(hdf5, instance, dict_attr): 185 """ 186 dump a object to a hdf5 file from a dictionary of attributes 187 188 Parameters 189 ---------- 190 191 hdf5 : h5py.File 192 an hdf5 object 193 194 instance : object 195 a custom python object. 196 197 dict_attr : dict 198 a dictionary of attribute 199 200 """ 201 if isinstance(dict_attr, dict): 202 for attr, value in dict_attr.items(): 203 hdf5 = add_hdf5_sub_group(hdf5, subgroup=attr) 204 205 try: 206 sub_instance = getattr(instance, attr) 207 208 except: 209 if isinstance(instance, dict): 210 sub_instance = instance[attr] 211 else: 212 sub_instance = instance 213 214 if isinstance(value, dict): 215 _dump_object_to_hdf5_from_dict_attribute(hdf5[attr], sub_instance, value) 216 217 elif isinstance(value, list): 218 _dump_object_to_hdf5_from_list_attribute(hdf5[attr], sub_instance, value) 219 220 elif isinstance(value, str): 221 _dump_object_to_hdf5_from_str_attribute(hdf5[attr], sub_instance, value) 222 223 else: 224 225 raise ValueError( 226 f"inconsistent '{attr}' in '{dict_attr}'. Dict({attr}) must be a instance of dict, list or str" 227 ) 228 229 else: 230 raise ValueError(f"{dict_attr} must be a instance of dict.") 231 232 233def _dump_object_to_hdf5_from_str_attribute(hdf5, instance, str_attr): 234 """ 235 dump a object to a hdf5 file from a string attribute 236 237 Parameters 238 ---------- 239 240 hdf5 : h5py.File 241 an hdf5 object 242 243 instance : object 244 a custom python object. 245 246 str_attr : str 247 a string attribute 248 249 """ 250 251 if isinstance(str_attr, str): 252 253 try: 254 value = getattr(instance, str_attr) 255 256 except: 257 if isinstance(instance, dict): 258 value = instance[str_attr] 259 else: 260 value = instance 261 262 try: 263 264 attribute_name = str(str_attr) 265 for character in "/ ": 266 attribute_name = attribute_name.replace(character, "_") 267 268 if isinstance(value, dict): 269 270 # print("---> dictionary: ", str_attr, value) 271 272 hdf5 = add_hdf5_sub_group(hdf5, subgroup=attribute_name) 273 save_dict_to_hdf5(hdf5[attribute_name], value) 274 275 else: 276 277 hdf5_dataset_creator(hdf5, attribute_name, value) 278 279 except: 280 raise ValueError( 281 f"Unable to dump attribute {str_attr} with value {value} from {instance}" 282 ) 283 284 else: 285 raise ValueError(f"{str_attr} must be a instance of str.") 286 287 288def _dump_object_to_hdf5_from_iteratable(hdf5, instance, iteratable=None): 289 """ 290 dump a object to a hdf5 file from a iteratable object list or dict 291 292 Parameters 293 ---------- 294 295 hdf5 : h5py.File 296 an hdf5 object 297 instance : object 298 a custom python object. 299 iteratable : list | dict 300 a list or a dict of attribute 301 302 Examples 303 -------- 304 305 >>> setup, mesh = smash.load_dataset("cance") 306 >>> model = smash.Model(setup, mesh) 307 >>> model.run(inplace=True) 308 >>> 309 >>> hdf5=pyhdf5_handler.open_hdf5("./model.hdf5", replace=True) 310 >>> hdf5=pyhdf5_handler.add_hdf5_sub_group(hdf5, subgroup="model1") 311 pyhdf5_handler._dump_object_to_hdf5_from_iteratable(hdf5["model1"], model) 312 313 """ 314 if isinstance(iteratable, list): 315 _dump_object_to_hdf5_from_list_attribute(hdf5, instance, iteratable) 316 317 elif isinstance(iteratable, dict): 318 _dump_object_to_hdf5_from_dict_attribute(hdf5, instance, iteratable) 319 320 else: 321 raise ValueError(f"{iteratable} must be a instance of list or dict.") 322 323 324def _hdf5_handle_str(name, value): 325 326 dataset = { 327 "name": name, 328 "attr_value": str(type(value)), 329 "dataset_value": value, 330 "shape": 1, 331 "dtype": h5py.string_dtype(encoding="utf-8"), 332 } 333 334 return dataset 335 336 337def _hdf5_handle_numbers(name: str, value: numbers.Number): 338 339 arr = np.array([value]) 340 dataset = { 341 "name": name, 342 "attr_value": str(type(value)), 343 "dataset_value": arr, 344 "shape": arr.shape, 345 "dtype": arr.dtype, 346 } 347 348 return dataset 349 350 351def _hdf5_handle_none(name: str, value: None): 352 353 dataset = { 354 "name": name, 355 "attr_value": "_None_", 356 "dataset_value": "_None_", 357 "shape": 1, 358 "dtype": h5py.string_dtype(encoding="utf-8"), 359 } 360 361 return dataset 362 363 364def _hdf5_handle_timestamp( 365 name: str, value: pd.Timestamp | np.datetime64 | datetime.date 366): 367 368 dtype = type(value) 369 370 if isinstance(value, (np.datetime64)): 371 value = value.tolist() 372 373 dataset = { 374 "name": name, 375 "attr_value": str(dtype), 376 "dataset_value": value.strftime("%Y-%m-%d %H:%M"), 377 "shape": 1, 378 "dtype": h5py.string_dtype(encoding="utf-8"), 379 } 380 381 return dataset 382 383 384def _hdf5_handle_DatetimeIndex(name: str, value: pd.DatetimeIndex): 385 386 dataset = _hdf5_handle_array(name, value) 387 388 return dataset 389 390 391def _hdf5_handle_list(name: str, value: list | tuple): 392 393 arr = np.array(value) 394 395 dataset = _hdf5_handle_array(name, arr) 396 397 return dataset 398 399 400def _hdf5_handle_array(name: str, value: np.ndarray): 401 402 dtype_attr = type(value) 403 dtype = value.dtype 404 405 if value.dtype.char == "M": 406 407 ListDate = value.tolist() 408 ListDateStr = list() 409 for date in ListDate: 410 ListDateStr.append(date.strftime("%Y-%m-%d %H:%M")) 411 value = np.array(ListDateStr) 412 value = value.astype("O") 413 dtype = h5py.string_dtype(encoding="utf-8") 414 415 elif value.dtype == "object": 416 417 value = value.astype("S") 418 dtype = h5py.string_dtype(encoding="utf-8") 419 420 elif value.dtype.char == "U": 421 value = value.astype("S") 422 dtype = h5py.string_dtype(encoding="utf-8") 423 424 dataset = { 425 "name": name, 426 "attr_value": str(dtype_attr), 427 "dataset_value": value, 428 "shape": value.shape, 429 "dtype": dtype, 430 } 431 432 return dataset 433 434 435def _hdf5_handle_ndarray(hdf5: h5py.File, name: str, value: np.ndarray): 436 437 hdf5 = add_hdf5_sub_group(hdf5, subgroup=name) 438 _dump_ndarray_to_hdf5(hdf5[name], value) 439 440 441def _hdf5_create_dataset(hdf5: h5py.File, dataset: dict): 442 443 if dataset["name"] in hdf5.keys(): 444 del hdf5[dataset["name"]] 445 446 hdf5.create_dataset( 447 dataset["name"], 448 shape=dataset["shape"], 449 dtype=dataset["dtype"], 450 data=dataset["dataset_value"], 451 compression="gzip", 452 chunks=True, 453 ) 454 455 if "_" + dataset["name"] in list(hdf5.attrs.keys()): 456 del hdf5.attrs["_" + dataset["name"]] 457 458 hdf5.attrs["_" + dataset["name"]] = dataset["attr_value"] 459 460 461def hdf5_dataset_creator(hdf5: h5py.File, name: str, value): 462 """ 463 Write any value in an hdf5 object 464 465 Parameters 466 ---------- 467 468 hdf5 : h5py.File 469 an hdf5 object 470 471 name : str 472 name of the dataset 473 474 value : any 475 value to write in the hdf5 476 477 """ 478 # save ndarray datast 479 if isinstance(value, str): 480 dataset = _hdf5_handle_str(name, value) 481 482 elif isinstance(value, numbers.Number): 483 dataset = _hdf5_handle_numbers(name, value) 484 485 elif value is None: 486 dataset = _hdf5_handle_none(name, value) 487 488 elif isinstance(value, (pd.Timestamp, np.datetime64, datetime.date)): 489 dataset = _hdf5_handle_timestamp(name, value) 490 491 elif isinstance(value, pd.DatetimeIndex): 492 dataset = _hdf5_handle_DatetimeIndex(name, value) 493 494 elif isinstance(value, list): 495 dataset = _hdf5_handle_list(name, value) 496 497 elif isinstance(value, tuple): 498 dataset = _hdf5_handle_list(name, value) 499 500 elif isinstance(value, np.ndarray): 501 502 if len(value.dtype) > 0 and len(value.dtype.names) > 0: 503 _hdf5_handle_ndarray(hdf5, name, value) 504 return 505 else: 506 dataset = _hdf5_handle_array(name, value) 507 508 else: 509 510 hdf5 = add_hdf5_sub_group(hdf5, subgroup=name) 511 512 newdict = object_handler.read_object_as_dict(value) 513 514 save_dict_to_hdf5(hdf5[name], newdict) 515 516 _hdf5_create_dataset(hdf5, dataset) 517 518 519def _dump_ndarray_to_hdf5(hdf5, value): 520 """ 521 dump a ndarray data structure to an hdf5 file: this functions create a group ndarray_ds and store each component of the ndarray as a dataset. Plus it add 2 datasets which store the dtypes (ndarray_dtype) and labels (ndarray_indexes). 522 523 Parameters 524 ---------- 525 526 hdf5 : h5py.File 527 an hdf5 object 528 529 value : ndarray 530 an ndarray data structure with different datatype 531 532 """ 533 # save ndarray datastructure 534 535 hdf5 = add_hdf5_sub_group(hdf5, subgroup="ndarray_ds") 536 hdf5_data = hdf5["ndarray_ds"] 537 538 for item in value.dtype.names: 539 540 hdf5_dataset_creator(hdf5=hdf5_data, name=item, value=value[item]) 541 542 index = np.array(value.dtype.descr)[:, 0] 543 dtype = np.array(value.dtype.descr)[:, 1] 544 index = index.astype("O") 545 dtype = dtype.astype("O") 546 data_type = h5py.string_dtype(encoding="utf-8") 547 548 if "ndarray_dtype" in hdf5_data.keys(): 549 del hdf5_data["ndarray_dtype"] 550 551 hdf5_data.create_dataset( 552 "ndarray_dtype", 553 shape=dtype.shape, 554 dtype=data_type, 555 data=dtype, 556 compression="gzip", 557 chunks=True, 558 ) 559 560 if "ndarray_indexes" in hdf5_data.keys(): 561 del hdf5_data["ndarray_indexes"] 562 563 hdf5_data.create_dataset( 564 "ndarray_indexes", 565 shape=index.shape, 566 dtype=data_type, 567 data=index, 568 compression="gzip", 569 chunks=True, 570 ) 571 572 573def _read_ndarray_datastructure(hdf5): 574 """ 575 read a ndarray data structure from hdf5 file 576 577 Parameters 578 ---------- 579 580 hdf5 : h5py.File 581 an hdf5 object at the roots of the ndarray datastructure 582 583 Return 584 ------ 585 586 ndarray : the ndarray 587 588 """ 589 590 if "ndarray_ds" in list(hdf5.keys()): 591 592 decoded_item = list() 593 for it in hdf5["ndarray_ds/ndarray_dtype"][:]: 594 decoded_item.append(it.decode()) 595 list_dtypes = decoded_item 596 597 decoded_item = list() 598 for it in hdf5["ndarray_ds/ndarray_indexes"][:]: 599 decoded_item.append(it.decode()) 600 list_indexes = decoded_item 601 602 len_data = len(hdf5[f"ndarray_ds/{list_indexes[0]}"][:]) 603 604 list_datatype = list() 605 for i in range(len(list_indexes)): 606 list_datatype.append((list_indexes[i], list_dtypes[i])) 607 608 datatype = np.dtype(list_datatype) 609 610 ndarray = np.zeros(len_data, dtype=datatype) 611 612 for i in range(len(list_indexes)): 613 614 expected_type = list_dtypes[i] 615 616 values = hdf5_read_dataset( 617 hdf5[f"ndarray_ds/{list_indexes[i]}"], expected_type 618 ) 619 620 ndarray[list_indexes[i]] = values 621 622 return ndarray 623 624 625def save_dict_to_hdf5(hdf5, dictionary): 626 """ 627 628 dump a dictionary to an hdf5 file 629 630 Parameters 631 ---------- 632 633 hdf5 : h5py.File 634 an hdf5 object 635 636 dictionary : dict 637 a custom python dictionary 638 639 """ 640 if isinstance(dictionary, dict): 641 for attr, value in dictionary.items(): 642 # print("looping:",attr,value) 643 try: 644 645 attribute_name = str(attr) 646 for character in "/ ": 647 attribute_name = attribute_name.replace(character, "_") 648 649 if isinstance(value, dict): 650 # print("---> dictionary: ",attr, value) 651 652 hdf5 = add_hdf5_sub_group(hdf5, subgroup=attribute_name) 653 save_dict_to_hdf5(hdf5[attribute_name], value) 654 655 else: 656 657 hdf5_dataset_creator(hdf5, attribute_name, value) 658 659 except: 660 661 raise ValueError( 662 f"Unable to save attribute {str(attr)} with value {value}" 663 ) 664 665 else: 666 667 raise ValueError(f"{dictionary} must be a instance of dict.") 668 669 670def save_dict_to_hdf5file( 671 path_to_hdf5, dictionary=None, location="./", replace=False, wait_time=0 672): 673 """ 674 675 dump a dictionary to an hdf5 file 676 677 Parameters 678 ---------- 679 680 path_to_hdf5 : str 681 path to the hdf5 file 682 683 dictionary : dict | None 684 a dictionary containing the data to be saved 685 686 location : str 687 path location or subgroup where to write data in the hdf5 file 688 689 replace : Boolean 690 replace an existing hdf5 file. Default is False 691 692 wait_time: int 693 If the hdf5 is unavailable, the function will try to access serveral time and will wait wait_time seconds maximum. If this time is elapsed, the file won't be opened and the funciton will return None. This parameter is usefull if several program or threads need to read/write simultaneously in the same hdf5 database. 694 695 Examples 696 -------- 697 698 >>> dict={"a":1,"b":2} 699 >>> pyhdf5_handler.save_dict_to_hdf5("saved_dictionary.hdf5",dict) 700 701 """ 702 if isinstance(dictionary, dict): 703 hdf5 = open_hdf5(path_to_hdf5, replace=replace, wait_time=wait_time) 704 705 if hdf5 is None: 706 return 707 708 hdf5 = add_hdf5_sub_group(hdf5, subgroup=location) 709 save_dict_to_hdf5(hdf5[location], dictionary) 710 711 else: 712 raise ValueError(f"The input {dictionary} must be a instance of dict.") 713 714 hdf5.close() 715 716 717def save_object_to_hdf5( 718 hdf5, 719 instance, 720 keys_data=None, 721 location="./", 722 sub_data=None, 723 replace=False, 724 wait_time=0, 725): 726 """ 727 728 dump an object to an hdf5 file 729 730 Parameters 731 ---------- 732 733 hdf5 : instance of h5py 734 An opened hdf5 file 735 736 instance : object 737 A custom python object to be saved into an hdf5 738 739 keys_data : list | dict 740 optional, a list or a dictionary of the attribute to be saved 741 742 location : str 743 path location or subgroup where to write data in the hdf5 file 744 745 sub_data : dict | None 746 optional, a extra dictionary containing extra-data to be saved along the object 747 748 replace : Boolean 749 replace an existing hdf5 file. Default is False 750 751 wait_time: int 752 If the hdf5 is unavailable, the function will try to access serveral time and will wait wait_time seconds maximum. If this time is elapsed, the file won't be opened and the funciton will return None. This parameter is usefull if several program or threads need to read/write simultaneously in the same hdf5 database. 753 754 """ 755 756 if keys_data is None: 757 keys_data = object_handler.generate_object_structure( 758 instance, include_method=False 759 ) 760 761 if hdf5 is None: 762 return None 763 764 hdf5 = add_hdf5_sub_group(hdf5, subgroup=location) 765 766 _dump_object_to_hdf5_from_iteratable(hdf5[location], instance, keys_data) 767 768 if isinstance(sub_data, dict): 769 save_dict_to_hdf5(hdf5[location], sub_data) 770 771 hdf5.close() 772 773 774def save_object_to_hdf5file( 775 path_to_hdf5, 776 instance, 777 keys_data=None, 778 location="./", 779 sub_data=None, 780 replace=False, 781 wait_time=0, 782): 783 """ 784 785 dump an object to an hdf5 file 786 787 Parameters 788 ---------- 789 790 path_to_hdf5 : str 791 path to the hdf5 file 792 793 instance : object 794 A custom python object to be saved into an hdf5 795 796 keys_data : list | dict 797 optional, a list or a dictionary of the attribute to be saved 798 799 location : str 800 path location or subgroup where to write data in the hdf5 file 801 802 sub_data : dict | None 803 optional, a extra dictionary containing extra-data to be saved along the object 804 805 replace : Boolean 806 replace an existing hdf5 file. Default is False 807 808 wait_time: int 809 If the hdf5 is unavailable, the function will try to access serveral time and will wait wait_time seconds maximum. If this time is elapsed, the file won't be opened and the funciton will return None. This parameter is usefull if several program or threads need to read/write simultaneously in the same hdf5 database. 810 811 """ 812 813 hdf5 = open_hdf5(path_to_hdf5, replace=replace, wait_time=wait_time) 814 815 save_object_to_hdf5( 816 hdf5, 817 instance, 818 keys_data=keys_data, 819 location=location, 820 sub_data=sub_data, 821 replace=replace, 822 wait_time=wait_time, 823 ) 824 825 826def read_hdf5file_as_dict( 827 path_to_hdf5, location="./", wait_time=0, read_attrs=True, read_dataset_attrs=False 828): 829 """ 830 831 Open, read and close an hdf5 file 832 833 Parameters 834 ---------- 835 836 path_to_hdf5 : str 837 path to the hdf5 file 838 839 location: str 840 place in the hdf5 from which we start reading the file 841 842 read_attrs : bool 843 read and import attributes in the dicitonnary. 844 845 read_dataset_attrs : bool 846 read and import special attributes linked to any dataset and created by pyhdf5_handler. These attributes only store the original dataype of the data stored in the dataset. 847 848 Return 849 -------- 850 851 dictionary : dict, a dictionary of all keys and attribute included in the hdf5 file 852 853 wait_time: int 854 If the hdf5 is unavailable, the function will try to access serveral time and will wait wait_time seconds maximum. If this time is elapsed, the file won't be opened and the funciton will return None. This parameter is usefull if several program or threads need to read/write simultaneously in the same hdf5 database. 855 856 Examples 857 -------- 858 859 read an hdf5 file 860 dictionary=hdf5_handler.read_hdf5file_as_dict(hdf5["model1"]) 861 """ 862 863 hdf5 = open_hdf5(path_to_hdf5, read_only=True, wait_time=wait_time) 864 865 if hdf5 is None: 866 return None 867 868 dictionary = read_hdf5_as_dict( 869 hdf5[location], read_attrs=read_attrs, read_dataset_attrs=read_dataset_attrs 870 ) 871 872 hdf5.close() 873 874 return dictionary 875 876 877def read_hdf5_as_dict(hdf5, read_attrs=True, read_dataset_attrs=False): 878 """ 879 Load an hdf5 file 880 881 Parameters 882 ---------- 883 884 hdf5 : h5py.File 885 an instance of hdf5, open with the function open_hdf5() 886 887 read_attrs : bool 888 read and import attributes in the dicitonnary. 889 890 read_dataset_attrs : bool 891 read and import special attributes linked to any dataset and created by pyhdf5_handler. These attributes only store the original dataype of the data stored in the dataset. 892 893 Return 894 -------- 895 896 dictionary : dict, a dictionary of all keys and attribute included in the hdf5 file 897 898 Examples 899 -------- 900 901 read only a part of an hdf5 file 902 >>> hdf5=hdf5_handler.open_hdf5("./multi_model.hdf5") 903 >>> dictionary=hdf5_handler.read_hdf5_as_dict(hdf5["model1"]) 904 >>> dictionary.keys() 905 906 """ 907 908 if not isinstance(hdf5, (h5py.File, h5py.Group, h5py.Dataset, h5py.Datatype)): 909 print("Error: input arg is not an instance of hdf5.File()") 910 return {} 911 912 dictionary = {} 913 914 for key, item in hdf5.items(): 915 916 if str(type(item)).find("group") != -1: 917 918 if key == "ndarray_ds": 919 920 # dictionary.update({key: _read_ndarray_datastructure(hdf5)}) 921 return _read_ndarray_datastructure(hdf5) 922 923 else: 924 925 dictionary.update({key: read_hdf5_as_dict(item)}) 926 927 if str(type(item)).find("dataset") != -1: 928 929 if "_" + key in hdf5.attrs.keys(): 930 expected_type = hdf5.attrs["_" + key] 931 values = hdf5_read_dataset(item, expected_type) 932 933 else: 934 935 values = item[:] 936 937 dictionary.update({key: values}) 938 939 list_attribute = [] 940 if read_attrs or read_dataset_attrs: 941 tmp_list_attribute = list(hdf5.attrs.keys()) 942 hdf5_item_matching_attributes = ["_" + element for element in list(hdf5.keys())] 943 944 if read_attrs: 945 946 list_attribute.extend( 947 list( 948 filter( 949 lambda l: l not in hdf5_item_matching_attributes, tmp_list_attribute 950 ) 951 ) 952 ) 953 954 if read_dataset_attrs: 955 956 list_attribute.extend( 957 list(filter(lambda l: l in hdf5_item_matching_attributes, tmp_list_attribute)) 958 ) 959 960 for key in list_attribute: 961 dictionary.update({key: hdf5.attrs[key]}) 962 963 return dictionary 964 965 966def hdf5_read_dataset(item, expected_type=None): 967 """ 968 Read a dataset stored in an hdf5 database 969 970 Parameters 971 ---------- 972 973 item : h5py.File 974 an hdf5 dataset/item 975 976 expected_type: str 977 the expected dtype as string str(type()) 978 979 Return 980 -------- 981 982 value : the value read from the hdf5, any type matching the expected type 983 984 985 """ 986 987 if expected_type == str(type("str")): 988 989 values = item[0].decode() 990 991 elif expected_type == str(type(1.0)): 992 993 values = item[0] 994 995 elif expected_type == "_None_": 996 997 values = None 998 999 elif expected_type in (str(pd.Timestamp), str(np.datetime64), str(datetime.datetime)): 1000 1001 if expected_type == str(pd.Timestamp): 1002 values = pd.Timestamp(item[0].decode()) 1003 1004 elif expected_type == str(np.datetime64): 1005 values = np.datetime64(item[0].decode()) 1006 1007 elif expected_type == str(datetime.datetime): 1008 values = datetime.datetime.fromisoformat(item[0].decode()) 1009 1010 else: 1011 values = item[0].decode() 1012 1013 else: 1014 1015 if item[:].dtype.char == "S": 1016 1017 values = item[:].astype("U") 1018 1019 elif item[:].dtype.char == "O": 1020 1021 # decode list if required 1022 decoded_item = list() 1023 for it in item[:]: 1024 1025 decoded_item.append(it.decode()) 1026 1027 values = decoded_item 1028 1029 else: 1030 values = item[:] 1031 1032 return values 1033 1034 1035def get_hdf5file_attribute( 1036 path_to_hdf5=str(), location="./", attribute=None, wait_time=0 1037): 1038 """ 1039 Get the value of an attribute in the hdf5file 1040 1041 Parameters 1042 ---------- 1043 1044 path_to_hdf5 : str 1045 the path to the hdf5file 1046 1047 location : str 1048 path inside the hdf5 where the attribute is stored 1049 1050 attribute: str 1051 attribute name 1052 1053 wait_time: int 1054 If the hdf5 is unavailable, the function will try to access serveral time and will wait wait_time seconds maximum. If this time is elapsed, the file won't be opened and the funciton will return None. This parameter is usefull if several program or threads need to read/write simultaneously in the same hdf5 database. 1055 1056 Return 1057 -------- 1058 1059 return_attribute : the value of the attribute 1060 1061 Examples 1062 -------- 1063 1064 get an attribute 1065 >>> attribute=hdf5_handler.get_hdf5_attribute("./multi_model.hdf5",attribute=my_attribute_name) 1066 1067 """ 1068 1069 hdf5_base = open_hdf5(path_to_hdf5, read_only=True, wait_time=wait_time) 1070 1071 if hdf5_base is None: 1072 return None 1073 1074 hdf5 = hdf5_base[location] 1075 1076 return_attribute = hdf5.attrs[attribute] 1077 1078 hdf5_base.close() 1079 1080 return return_attribute 1081 1082 1083def get_hdf5file_dataset(path_to_hdf5=str(), location="./", dataset=None, wait_time=0): 1084 """ 1085 Get the value of an attribute in the hdf5file 1086 1087 Parameters 1088 ---------- 1089 1090 path_to_hdf5 : str 1091 the path to the hdf5file 1092 1093 location : str 1094 path inside the hdf5 where the attribute is stored 1095 1096 dataset: str 1097 dataset name 1098 1099 wait_time: int 1100 If the hdf5 is unavailable, the function will try to access serveral time and will wait wait_time seconds maximum. If this time is elapsed, the file won't be opened and the funciton will return None. This parameter is usefull if several program or threads need to read/write simultaneously in the same hdf5 database. 1101 1102 Return 1103 -------- 1104 1105 return_dataset : the value of the attribute 1106 1107 Examples 1108 -------- 1109 1110 get a dataset 1111 >>> dataset=hdf5_handler.get_hdf5_dataset("./multi_model.hdf5",dataset=my_dataset_name) 1112 1113 """ 1114 1115 hdf5_base = open_hdf5(path_to_hdf5, read_only=True, wait_time=wait_time) 1116 1117 if hdf5_base is None: 1118 return None 1119 1120 hdf5 = hdf5_base[location] 1121 1122 if "_" + dataset in hdf5.attrs.keys(): 1123 expected_type = hdf5.attrs["_" + dataset] 1124 return_dataset = hdf5_read_dataset(hdf5[dataset], expected_type) 1125 1126 else: 1127 return_dataset = hdf5[dataset][:] 1128 1129 hdf5_base.close() 1130 1131 return return_dataset 1132 1133 1134def get_hdf5file_item( 1135 path_to_hdf5=str(), location="./", item=None, wait_time=0, search_attrs=False 1136): 1137 """ 1138 1139 Get a custom item in an hdf5file 1140 1141 Parameters 1142 ---------- 1143 1144 path_to_hdf5 : str 1145 the path to the hdf5file 1146 1147 location : str 1148 path inside the hdf5 where the attribute is stored. If item is None, item is set to basename(location) 1149 1150 item: str 1151 item name 1152 1153 wait_time: int 1154 If the hdf5 is unavailable, the function will try to access serveral time and will wait wait_time seconds maximum. If this time is elapsed, the file won't be opened and the funciton will return None. This parameter is usefull if several program or threads need to read/write simultaneously in the same hdf5 database. 1155 1156 search_attrs: bool 1157 Default is False. If True, the function will also search in the item in the attribute first. 1158 1159 Return 1160 -------- 1161 1162 return : custom value. can be an hdf5 object (group), an numpy array, a string, a float, an int ... 1163 1164 Examples 1165 -------- 1166 1167 get the dataset 'dataset' 1168 >>> dataset=hdf5_handler.get_hdf5_item("./multi_model.hdf5",location="path/in/hdf5/dataset") 1169 1170 """ 1171 1172 hdf5 = open_hdf5(path_to_hdf5, read_only=True, wait_time=wait_time) 1173 1174 if hdf5 is None: 1175 return None 1176 1177 hdf5_item = get_hdf5_item( 1178 hdf5_instance=hdf5, location=location, item=item, search_attrs=search_attrs 1179 ) 1180 1181 hdf5.close() 1182 1183 return hdf5_item 1184 1185 1186def get_hdf5_item(hdf5_instance=None, location="./", item=None, search_attrs=False): 1187 """ 1188 1189 Get a custom item in an hdf5file 1190 1191 Parameters 1192 ---------- 1193 1194 hdf5_instance : h5py.File 1195 an instance of an hdf5 1196 1197 location : str 1198 path inside the hdf5 where the attribute is stored. If item is None, item is set to basename(location) 1199 1200 item: str 1201 item name 1202 1203 search_attrs: bool 1204 Default is False. If True, the function will search in the item in the attribute first. 1205 1206 Return 1207 ------ 1208 1209 return : custom value. can be an hdf5 object (group), an numpy array, a string, a float, an int ... 1210 1211 Examples 1212 -------- 1213 1214 get the dataset 'dataset' 1215 >>> dataset=hdf5_handler.get_hdf5_item("./multi_model.hdf5",location="path/in/hdf5/dataset") 1216 1217 """ 1218 1219 if item is None and isinstance(location, str): 1220 head, tail = os.path.split(location) 1221 if len(tail) > 0: 1222 item = tail 1223 location = head 1224 1225 if not isinstance(item, str): 1226 print(f"Bad search item:{item}") 1227 return None 1228 1229 return None 1230 1231 # print(f"Getting item '{item}' at location '{location}'") 1232 hdf5 = hdf5_instance[location] 1233 1234 # first search in the attribute 1235 if search_attrs: 1236 list_attribute = hdf5.attrs.keys() 1237 if item in list_attribute: 1238 return hdf5.attrs[item] 1239 1240 # then search in groups and dataset 1241 list_keys = hdf5.keys() 1242 if item in list_keys: 1243 1244 hdf5_item = hdf5[item] 1245 1246 # print("Got Item ", hdf5_item) 1247 1248 if str(type(hdf5_item)).find("group") != -1: 1249 1250 if item == "ndarray_ds": 1251 1252 return _read_ndarray_datastructure(hdf5) 1253 1254 else: 1255 1256 returned_dict = read_hdf5_as_dict(hdf5_item) 1257 1258 return returned_dict 1259 1260 elif str(type(hdf5_item)).find("dataset") != -1: 1261 1262 if "_" + item in hdf5.attrs.keys(): 1263 expected_type = hdf5.attrs["_" + item] 1264 values = hdf5_read_dataset(hdf5_item, expected_type) 1265 else: 1266 values = hdf5_item[:] 1267 1268 return values 1269 1270 else: 1271 1272 return hdf5_item 1273 1274 else: 1275 1276 return None 1277 1278 1279def search_in_hdf5file( 1280 path_to_hdf5, key=None, location="./", wait_time=0, search_attrs=False 1281): 1282 """ 1283 1284 Search key in an hdf5 and return a list of [locations, datatype, key name, values]. Value and key are returned only if the key is an attribute or a dataset (None otherwise) 1285 1286 Parameters 1287 ---------- 1288 1289 path_to_hdf5 : str 1290 the path to the hdf5file 1291 1292 key: str 1293 key to search in the hdf5file 1294 1295 location : str 1296 path inside the hdf5 where to start the research 1297 1298 wait_time: int 1299 If the hdf5 is unavailable, the function will try to access serveral time and will wait wait_time seconds maximum. If this time is elapsed, the file won't be opened and the funciton will return None. This parameter is usefull if several program or threads need to read/write simultaneously in the same hdf5 database. 1300 1301 search_attrs : Bool 1302 Default false, search in the attributes 1303 1304 Return 1305 ------ 1306 1307 return_dataset : the value of the attribute 1308 1309 Examples 1310 -------- 1311 1312 search in a hdf5file 1313 >>> matchkey=hdf5_handler.search_in_hdf5file(hdf5filename, key='Nom_du_BV',location="./") 1314 1315 """ 1316 if key is None: 1317 print("Nothing to search, use key=") 1318 return [] 1319 1320 hdf5 = open_hdf5(path_to_hdf5, read_only=True, wait_time=wait_time) 1321 1322 if hdf5 is None: 1323 return None 1324 1325 results = search_in_hdf5(hdf5, key, location=location, search_attrs=search_attrs) 1326 1327 hdf5.close() 1328 1329 return results 1330 1331 1332def search_in_hdf5(hdf5_base, key=None, location="./", search_attrs=False): 1333 """ 1334 1335 Search key in an hdf5 and return a list of [locations, datatype, key name, values]. Value and key are returned only if the key is an attribute or a dataset (None otherwise) 1336 1337 Parameters 1338 ---------- 1339 1340 hdf5_base : h5py.File 1341 opened instance of the hdf5 1342 1343 key: str 1344 key to search in the hdf5file 1345 1346 location : str 1347 path inside the hdf5 where to start the research 1348 1349 search_attrs : Bool 1350 Default false, search in the attributes 1351 1352 Return 1353 ------ 1354 1355 return_dataset : the value of the attribute 1356 1357 Examples 1358 -------- 1359 1360 search in a hdf5 1361 >>> hdf5=hdf5_handler.open_hdf5(hdf5_file) 1362 >>> matchkey=hdf5_handler.search_in_hdf5(hdf5, key='Nom_du_BV',location="./") 1363 >>> hdf5.close() 1364 1365 """ 1366 if key is None: 1367 print("Nothing to search, use key=") 1368 return [] 1369 1370 result = [] 1371 1372 hdf5 = hdf5_base[location] 1373 1374 if search_attrs: 1375 list_attribute = hdf5.attrs.keys() 1376 1377 if key in list_attribute: 1378 result.append( 1379 { 1380 "path": location, 1381 "key": key, 1382 "datatype": "attribute", 1383 "value": hdf5.attrs[key], 1384 } 1385 ) 1386 1387 for hdf5_key, item in hdf5.items(): 1388 1389 if str(type(item)).find("group") != -1: 1390 1391 sub_location = os.path.join(location, hdf5_key) 1392 1393 # print(hdf5_key,sub_location,list(hdf5.keys())) 1394 1395 if hdf5_key == key: 1396 1397 if "ndarray_ds" in item.keys(): 1398 1399 result.append( 1400 { 1401 "path": sub_location, 1402 "key": None, 1403 "datatype": "ndarray", 1404 "value": _read_ndarray_datastructure(item), 1405 } 1406 ) 1407 1408 else: 1409 1410 result.append( 1411 { 1412 "path": sub_location, 1413 "key": None, 1414 "datatype": "group", 1415 "value": None, 1416 } 1417 ) 1418 1419 res = search_in_hdf5(hdf5_base, key, sub_location) 1420 1421 if len(res) > 0: 1422 for element in res: 1423 result.append(element) 1424 1425 if str(type(item)).find("dataset") != -1: 1426 1427 if hdf5_key == key: 1428 1429 if item[:].dtype.char == "S": 1430 1431 values = item[:].astype("U") 1432 1433 elif item[:].dtype.char == "O": 1434 1435 # decode list if required 1436 decoded_item = list() 1437 for it in item[:]: 1438 decoded_item.append(it.decode()) 1439 1440 values = decoded_item 1441 1442 else: 1443 1444 values = item[:] 1445 1446 result.append( 1447 {"path": location, "key": key, "datatype": "dataset", "value": values} 1448 ) 1449 1450 return result 1451 1452 1453def hdf5file_view( 1454 path_to_hdf5, 1455 location="./", 1456 max_depth=None, 1457 level_base=">", 1458 level_sep="--", 1459 depth=None, 1460 wait_time=0, 1461 list_attrs=True, 1462 list_dataset_attrs=False, 1463 return_view=False, 1464): 1465 """ 1466 1467 Search key in an hdf5 and return a list of [locations, datatype, key name, values]. Value and key are returned only if the key is an attribute or a dataset (None otherwise) 1468 1469 Parameters 1470 ---------- 1471 1472 1473 path_to_hdf5 : str 1474 Path to an hdf5 database 1475 1476 location : str 1477 path inside the hdf5 where to start the research 1478 1479 max_depth: str 1480 Max deph of the search in the hdf5 1481 1482 level_base: str 1483 string used as separator at the lower level (default '>') 1484 1485 level_sep: str 1486 string used as separator at higher level (default '--') 1487 1488 depth: int 1489 current depth level 1490 1491 list_attrs: bool 1492 default is True, list the attributes 1493 1494 list_dataset_attrs: bool 1495 default is False, list the special attributes defined for each dataset by pyhdf5_handler 1496 1497 return_view: bool 1498 retrun the object view in a dictionnary (do not print at screen) 1499 1500 wait_time: int 1501 If the hdf5 is unavailable, the function will try to access serveral time and will wait wait_time seconds maximum. If this time is elapsed, the file won't be opened and the funciton will return None. This parameter is usefull if several program or threads need to read/write simultaneously in the same hdf5 database. 1502 1503 Return 1504 -------- 1505 1506 dictionnary : optional, the view of the hdf5 1507 1508 Examples 1509 -------- 1510 1511 search in a hdf5file 1512 >>> matchkey=hdf5_handler.search_in_hdf5file(hdf5filename, key='Nom_du_BV',location="./") 1513 1514 """ 1515 1516 hdf5 = open_hdf5(path_to_hdf5, read_only=True, wait_time=wait_time) 1517 1518 if hdf5 is None: 1519 return None 1520 1521 results = hdf5_view( 1522 hdf5, 1523 location=location, 1524 max_depth=max_depth, 1525 level_base=level_base, 1526 level_sep=level_sep, 1527 depth=depth, 1528 list_attrs=list_attrs, 1529 list_dataset_attrs=list_dataset_attrs, 1530 return_view=return_view, 1531 ) 1532 1533 hdf5.close() 1534 1535 return results 1536 1537 1538def hdf5file_ls(path_to_hdf5, location="./"): 1539 """ 1540 List dataset in an hdf5file. 1541 1542 Parameters 1543 ---------- 1544 1545 path_to_hdf5 : str 1546 path to a hdf5file 1547 1548 location: str 1549 path inside the hdf5 where to start the research 1550 1551 Example 1552 ------- 1553 1554 >>> hdf5file_ls(test.hdf5) 1555 1556 """ 1557 1558 hdf5 = open_hdf5(path_to_hdf5, read_only=True) 1559 1560 hdf5_view( 1561 hdf5, 1562 location=location, 1563 max_depth=0, 1564 level_base=">", 1565 level_sep="--", 1566 list_attrs=False, 1567 return_view=False, 1568 ) 1569 1570 1571def hdf5_ls(hdf5): 1572 """ 1573 List dataset in an hdf5 instance. 1574 1575 Parameters 1576 ---------- 1577 1578 hdf5 : h5py.File 1579 hdf5 instance 1580 1581 location: str 1582 path inside the hdf5 where to start the research 1583 1584 Example 1585 ------- 1586 1587 >>> hdf5 = open_hdf5(path_to_hdf5, read_only=True) 1588 >>> hdf5_ls(hdf5) 1589 1590 """ 1591 1592 hdf5_view( 1593 hdf5, 1594 location="./", 1595 max_depth=0, 1596 level_base=">", 1597 level_sep="--", 1598 list_attrs=False, 1599 return_view=False, 1600 ) 1601 1602 1603def hdf5_view( 1604 hdf5_obj, 1605 location="./", 1606 max_depth=None, 1607 level_base=">", 1608 level_sep="--", 1609 depth=None, 1610 list_attrs=True, 1611 list_dataset_attrs=False, 1612 return_view=False, 1613): 1614 """ 1615 List recursively all dataset (and attributes) in an hdf5 object. 1616 1617 Parameters 1618 ---------- 1619 1620 hdf5_obj : h5py.File 1621 opened instance of the hdf5 1622 1623 location : str 1624 path inside the hdf5 where to start the research 1625 1626 max_depth: str 1627 Max deph of the search in the hdf5 1628 1629 level_base: str 1630 string used as separator at the lower level (default '>') 1631 1632 level_sep: str 1633 string used as separator at higher level (default '--') 1634 1635 depth: int 1636 current level depth 1637 1638 list_attrs: bool 1639 default is True, list the attributes 1640 1641 list_dataset_attrs: bool 1642 default is False, list the special attributes defined for each dataset by pyhdf5_handler 1643 1644 return_view: bool 1645 retrun the object view in a dictionnary 1646 1647 Return 1648 -------- 1649 1650 dictionnary : optional, the view of the hdf5 1651 1652 Examples 1653 -------- 1654 1655 search in a hdf5 1656 >>> hdf5=hdf5_handler.open_hdf5(hdf5_file) 1657 >>> matchkey=hdf5_handler.search_in_hdf5(hdf5, key='Nom_du_BV',location="./") 1658 >>> hdf5.close() 1659 1660 """ 1661 1662 result = [] 1663 1664 if max_depth is not None: 1665 1666 if depth is not None: 1667 depth = depth + 1 1668 else: 1669 depth = 0 1670 1671 if depth > max_depth: 1672 return result 1673 1674 hdf5 = hdf5_obj[location] 1675 1676 list_attribute = [] 1677 if list_attrs or list_dataset_attrs: 1678 tmp_list_attribute = list(hdf5.attrs.keys()) 1679 list_keys_matching_attributes = ["_" + element for element in list(hdf5.keys())] 1680 1681 if list_attrs: 1682 1683 list_attribute.extend( 1684 list( 1685 filter( 1686 lambda l: l not in list_keys_matching_attributes, tmp_list_attribute 1687 ) 1688 ) 1689 ) 1690 1691 if list_dataset_attrs: 1692 1693 list_attribute.extend( 1694 list(filter(lambda l: l in list_keys_matching_attributes, tmp_list_attribute)) 1695 ) 1696 1697 for key in list_attribute: 1698 values = hdf5.attrs[key] 1699 sub_location = os.path.join(location, key) 1700 if isinstance( 1701 values, (int, float, np.int64, np.float64, np.int32, np.float32, np.bool) 1702 ): 1703 result.append( 1704 f"{level_base}| {sub_location}, attribute, type={type(hdf5.attrs[key])}, value={values}" 1705 ) 1706 elif isinstance(values, (str)) and len(values) < 20: 1707 result.append( 1708 f"{level_base}| {sub_location}, attribute, type={type(hdf5.attrs[key])}, len={len(values)}, value={values}" 1709 ) 1710 else: 1711 result.append( 1712 f"{level_base}| {sub_location}, attribute, type={type(hdf5.attrs[key])}, len={len(values)}, value={values[0:20]}..." 1713 ) 1714 1715 for hdf5_key, item in hdf5.items(): 1716 1717 if str(type(item)).find("group") != -1: 1718 1719 sub_location = os.path.join(location, hdf5_key) 1720 1721 if "ndarray_ds" in item.keys(): 1722 result.append(f"{level_base}| {sub_location}, ndarray") 1723 else: 1724 result.append(f"{level_base}| {sub_location}, group") 1725 1726 res = hdf5_view( 1727 hdf5_obj, 1728 sub_location, 1729 max_depth=max_depth, 1730 level_base=level_base + level_sep, 1731 depth=depth, 1732 return_view=True, 1733 ) 1734 1735 # if len(res)>0: 1736 for key, item in enumerate(res): 1737 result.append(item) 1738 1739 if str(type(item)).find("dataset") != -1: 1740 1741 if item[:].dtype.char == "S": 1742 values = item[:].astype("U") 1743 else: 1744 values = item[:] 1745 1746 sub_location = os.path.join(location, hdf5_key) 1747 1748 result.append( 1749 f"{level_base}| {sub_location}, dataset, type={type(values)}, shape={values.shape}" 1750 ) 1751 1752 if return_view: 1753 return result 1754 else: 1755 for res in result: 1756 print(res)
16def close_all_hdf5_file(): 17 """ 18 Close all hdf5 file opened in the current session 19 """ 20 21 for obj in gc.get_objects(): # Browse through ALL objects 22 if isinstance(obj, h5py.File): # Just HDF5 files 23 try: 24 print(f"try closing {obj}") 25 obj.close() 26 except: 27 pass # Was already closed
Close all hdf5 file opened in the current session
30def open_hdf5(path, read_only=False, replace=False, wait_time=0): 31 """ 32 33 Open or create an HDF5 file. 34 35 Parameters 36 ---------- 37 38 path : str 39 The file path. 40 41 read_only : boolean 42 If true the access to the hdf5 fil is in read-only mode. Multi process can read the same hdf5 file simulteneously. This is not possible when access mode are append 'a' or write 'w'. 43 44 replace: Boolean 45 If true, the existing hdf5file is erased 46 47 wait_time: int 48 If the hdf5 is unavailable, the function will try to access serveral time and will wait wait_time seconds maximum. If this time is elapsed, the file won't be opened. This parameter is usefull if several program or threads need to read/write simultaneously in the same hdf5 database. 49 50 Returns 51 ------- 52 53 f : 54 A h5py object. 55 56 Examples 57 -------- 58 59 >>> hdf5=pyhdf5_handler.open_hdf5("./my_hdf5.hdf5") 60 >>> hdf5.keys() 61 >>> hdf5.attrs.keys() 62 63 """ 64 f = None 65 wait = 0 66 while wait <= wait_time: 67 68 f = None 69 exist_file = True 70 71 try: 72 73 if read_only: 74 if os.path.isfile(path): 75 f = h5py.File(path, "r") 76 77 else: 78 exist_file = False 79 raise ValueError(f"File {path} does not exist.") 80 81 else: 82 if replace: 83 f = h5py.File(path, "w") 84 85 else: 86 if os.path.isfile(path): 87 f = h5py.File(path, "a") 88 89 else: 90 f = h5py.File(path, "w") 91 except: 92 pass 93 94 if f is None: 95 if not exist_file: 96 print(f"File {path} does not exist.") 97 return f 98 else: 99 print(f"The file {path} is unvailable, waiting {wait}/{wait_time}s") 100 101 wait = wait + 1 102 103 if wait_time > 0: 104 time.sleep(1) 105 106 else: 107 break 108 109 return f
Open or create an HDF5 file.
Parameters
path : str The file path.
read_only : boolean If true the access to the hdf5 fil is in read-only mode. Multi process can read the same hdf5 file simulteneously. This is not possible when access mode are append 'a' or write 'w'.
replace: Boolean If true, the existing hdf5file is erased
wait_time: int If the hdf5 is unavailable, the function will try to access serveral time and will wait wait_time seconds maximum. If this time is elapsed, the file won't be opened. This parameter is usefull if several program or threads need to read/write simultaneously in the same hdf5 database.
Returns
f : A h5py object.
Examples
>>> hdf5=pyhdf5_handler.open_hdf5("./my_hdf5.hdf5")
>>> hdf5.keys()
>>> hdf5.attrs.keys()
112def add_hdf5_sub_group(hdf5, subgroup=None): 113 """ 114 Create a new subgroup in a HDF5 object 115 116 Parameters 117 ---------- 118 119 hdf5 : h5py.File 120 An hdf5 object opened with open_hdf5() 121 122 subgroup: str 123 Path to a subgroub that must be created 124 125 Returns 126 ------- 127 128 hdf5 : 129 the h5py object. 130 131 Examples 132 -------- 133 134 >>> hdf5=pyhdf5_handler.open_hdf5("./model_subgroup.hdf5", replace=True) 135 >>> hdf5=pyhdf5_handler.add_hdf5_sub_group(hdf5, subgroup="mygroup") 136 >>> hdf5.keys() 137 >>> hdf5.attrs.keys() 138 139 """ 140 if subgroup is not None: 141 if subgroup == "": 142 subgroup = "./" 143 144 hdf5.require_group(subgroup) 145 146 return hdf5
Create a new subgroup in a HDF5 object
Parameters
hdf5 : h5py.File An hdf5 object opened with open_hdf5()
subgroup: str Path to a subgroub that must be created
Returns
hdf5 : the h5py object.
Examples
>>> hdf5=pyhdf5_handler.open_hdf5("./model_subgroup.hdf5", replace=True)
>>> hdf5=pyhdf5_handler.add_hdf5_sub_group(hdf5, subgroup="mygroup")
>>> hdf5.keys()
>>> hdf5.attrs.keys()
462def hdf5_dataset_creator(hdf5: h5py.File, name: str, value): 463 """ 464 Write any value in an hdf5 object 465 466 Parameters 467 ---------- 468 469 hdf5 : h5py.File 470 an hdf5 object 471 472 name : str 473 name of the dataset 474 475 value : any 476 value to write in the hdf5 477 478 """ 479 # save ndarray datast 480 if isinstance(value, str): 481 dataset = _hdf5_handle_str(name, value) 482 483 elif isinstance(value, numbers.Number): 484 dataset = _hdf5_handle_numbers(name, value) 485 486 elif value is None: 487 dataset = _hdf5_handle_none(name, value) 488 489 elif isinstance(value, (pd.Timestamp, np.datetime64, datetime.date)): 490 dataset = _hdf5_handle_timestamp(name, value) 491 492 elif isinstance(value, pd.DatetimeIndex): 493 dataset = _hdf5_handle_DatetimeIndex(name, value) 494 495 elif isinstance(value, list): 496 dataset = _hdf5_handle_list(name, value) 497 498 elif isinstance(value, tuple): 499 dataset = _hdf5_handle_list(name, value) 500 501 elif isinstance(value, np.ndarray): 502 503 if len(value.dtype) > 0 and len(value.dtype.names) > 0: 504 _hdf5_handle_ndarray(hdf5, name, value) 505 return 506 else: 507 dataset = _hdf5_handle_array(name, value) 508 509 else: 510 511 hdf5 = add_hdf5_sub_group(hdf5, subgroup=name) 512 513 newdict = object_handler.read_object_as_dict(value) 514 515 save_dict_to_hdf5(hdf5[name], newdict) 516 517 _hdf5_create_dataset(hdf5, dataset)
Write any value in an hdf5 object
Parameters
hdf5 : h5py.File an hdf5 object
name : str name of the dataset
value : any value to write in the hdf5
626def save_dict_to_hdf5(hdf5, dictionary): 627 """ 628 629 dump a dictionary to an hdf5 file 630 631 Parameters 632 ---------- 633 634 hdf5 : h5py.File 635 an hdf5 object 636 637 dictionary : dict 638 a custom python dictionary 639 640 """ 641 if isinstance(dictionary, dict): 642 for attr, value in dictionary.items(): 643 # print("looping:",attr,value) 644 try: 645 646 attribute_name = str(attr) 647 for character in "/ ": 648 attribute_name = attribute_name.replace(character, "_") 649 650 if isinstance(value, dict): 651 # print("---> dictionary: ",attr, value) 652 653 hdf5 = add_hdf5_sub_group(hdf5, subgroup=attribute_name) 654 save_dict_to_hdf5(hdf5[attribute_name], value) 655 656 else: 657 658 hdf5_dataset_creator(hdf5, attribute_name, value) 659 660 except: 661 662 raise ValueError( 663 f"Unable to save attribute {str(attr)} with value {value}" 664 ) 665 666 else: 667 668 raise ValueError(f"{dictionary} must be a instance of dict.")
dump a dictionary to an hdf5 file
Parameters
hdf5 : h5py.File an hdf5 object
dictionary : dict a custom python dictionary
671def save_dict_to_hdf5file( 672 path_to_hdf5, dictionary=None, location="./", replace=False, wait_time=0 673): 674 """ 675 676 dump a dictionary to an hdf5 file 677 678 Parameters 679 ---------- 680 681 path_to_hdf5 : str 682 path to the hdf5 file 683 684 dictionary : dict | None 685 a dictionary containing the data to be saved 686 687 location : str 688 path location or subgroup where to write data in the hdf5 file 689 690 replace : Boolean 691 replace an existing hdf5 file. Default is False 692 693 wait_time: int 694 If the hdf5 is unavailable, the function will try to access serveral time and will wait wait_time seconds maximum. If this time is elapsed, the file won't be opened and the funciton will return None. This parameter is usefull if several program or threads need to read/write simultaneously in the same hdf5 database. 695 696 Examples 697 -------- 698 699 >>> dict={"a":1,"b":2} 700 >>> pyhdf5_handler.save_dict_to_hdf5("saved_dictionary.hdf5",dict) 701 702 """ 703 if isinstance(dictionary, dict): 704 hdf5 = open_hdf5(path_to_hdf5, replace=replace, wait_time=wait_time) 705 706 if hdf5 is None: 707 return 708 709 hdf5 = add_hdf5_sub_group(hdf5, subgroup=location) 710 save_dict_to_hdf5(hdf5[location], dictionary) 711 712 else: 713 raise ValueError(f"The input {dictionary} must be a instance of dict.") 714 715 hdf5.close()
dump a dictionary to an hdf5 file
Parameters
path_to_hdf5 : str path to the hdf5 file
dictionary : dict | None a dictionary containing the data to be saved
location : str path location or subgroup where to write data in the hdf5 file
replace : Boolean replace an existing hdf5 file. Default is False
wait_time: int If the hdf5 is unavailable, the function will try to access serveral time and will wait wait_time seconds maximum. If this time is elapsed, the file won't be opened and the funciton will return None. This parameter is usefull if several program or threads need to read/write simultaneously in the same hdf5 database.
Examples
>>> dict={"a":1,"b":2}
>>> pyhdf5_handler.save_dict_to_hdf5("saved_dictionary.hdf5",dict)
718def save_object_to_hdf5( 719 hdf5, 720 instance, 721 keys_data=None, 722 location="./", 723 sub_data=None, 724 replace=False, 725 wait_time=0, 726): 727 """ 728 729 dump an object to an hdf5 file 730 731 Parameters 732 ---------- 733 734 hdf5 : instance of h5py 735 An opened hdf5 file 736 737 instance : object 738 A custom python object to be saved into an hdf5 739 740 keys_data : list | dict 741 optional, a list or a dictionary of the attribute to be saved 742 743 location : str 744 path location or subgroup where to write data in the hdf5 file 745 746 sub_data : dict | None 747 optional, a extra dictionary containing extra-data to be saved along the object 748 749 replace : Boolean 750 replace an existing hdf5 file. Default is False 751 752 wait_time: int 753 If the hdf5 is unavailable, the function will try to access serveral time and will wait wait_time seconds maximum. If this time is elapsed, the file won't be opened and the funciton will return None. This parameter is usefull if several program or threads need to read/write simultaneously in the same hdf5 database. 754 755 """ 756 757 if keys_data is None: 758 keys_data = object_handler.generate_object_structure( 759 instance, include_method=False 760 ) 761 762 if hdf5 is None: 763 return None 764 765 hdf5 = add_hdf5_sub_group(hdf5, subgroup=location) 766 767 _dump_object_to_hdf5_from_iteratable(hdf5[location], instance, keys_data) 768 769 if isinstance(sub_data, dict): 770 save_dict_to_hdf5(hdf5[location], sub_data) 771 772 hdf5.close()
dump an object to an hdf5 file
Parameters
hdf5 : instance of h5py An opened hdf5 file
instance : object A custom python object to be saved into an hdf5
keys_data : list | dict optional, a list or a dictionary of the attribute to be saved
location : str path location or subgroup where to write data in the hdf5 file
sub_data : dict | None optional, a extra dictionary containing extra-data to be saved along the object
replace : Boolean replace an existing hdf5 file. Default is False
wait_time: int If the hdf5 is unavailable, the function will try to access serveral time and will wait wait_time seconds maximum. If this time is elapsed, the file won't be opened and the funciton will return None. This parameter is usefull if several program or threads need to read/write simultaneously in the same hdf5 database.
775def save_object_to_hdf5file( 776 path_to_hdf5, 777 instance, 778 keys_data=None, 779 location="./", 780 sub_data=None, 781 replace=False, 782 wait_time=0, 783): 784 """ 785 786 dump an object to an hdf5 file 787 788 Parameters 789 ---------- 790 791 path_to_hdf5 : str 792 path to the hdf5 file 793 794 instance : object 795 A custom python object to be saved into an hdf5 796 797 keys_data : list | dict 798 optional, a list or a dictionary of the attribute to be saved 799 800 location : str 801 path location or subgroup where to write data in the hdf5 file 802 803 sub_data : dict | None 804 optional, a extra dictionary containing extra-data to be saved along the object 805 806 replace : Boolean 807 replace an existing hdf5 file. Default is False 808 809 wait_time: int 810 If the hdf5 is unavailable, the function will try to access serveral time and will wait wait_time seconds maximum. If this time is elapsed, the file won't be opened and the funciton will return None. This parameter is usefull if several program or threads need to read/write simultaneously in the same hdf5 database. 811 812 """ 813 814 hdf5 = open_hdf5(path_to_hdf5, replace=replace, wait_time=wait_time) 815 816 save_object_to_hdf5( 817 hdf5, 818 instance, 819 keys_data=keys_data, 820 location=location, 821 sub_data=sub_data, 822 replace=replace, 823 wait_time=wait_time, 824 )
dump an object to an hdf5 file
Parameters
path_to_hdf5 : str path to the hdf5 file
instance : object A custom python object to be saved into an hdf5
keys_data : list | dict optional, a list or a dictionary of the attribute to be saved
location : str path location or subgroup where to write data in the hdf5 file
sub_data : dict | None optional, a extra dictionary containing extra-data to be saved along the object
replace : Boolean replace an existing hdf5 file. Default is False
wait_time: int If the hdf5 is unavailable, the function will try to access serveral time and will wait wait_time seconds maximum. If this time is elapsed, the file won't be opened and the funciton will return None. This parameter is usefull if several program or threads need to read/write simultaneously in the same hdf5 database.
827def read_hdf5file_as_dict( 828 path_to_hdf5, location="./", wait_time=0, read_attrs=True, read_dataset_attrs=False 829): 830 """ 831 832 Open, read and close an hdf5 file 833 834 Parameters 835 ---------- 836 837 path_to_hdf5 : str 838 path to the hdf5 file 839 840 location: str 841 place in the hdf5 from which we start reading the file 842 843 read_attrs : bool 844 read and import attributes in the dicitonnary. 845 846 read_dataset_attrs : bool 847 read and import special attributes linked to any dataset and created by pyhdf5_handler. These attributes only store the original dataype of the data stored in the dataset. 848 849 Return 850 -------- 851 852 dictionary : dict, a dictionary of all keys and attribute included in the hdf5 file 853 854 wait_time: int 855 If the hdf5 is unavailable, the function will try to access serveral time and will wait wait_time seconds maximum. If this time is elapsed, the file won't be opened and the funciton will return None. This parameter is usefull if several program or threads need to read/write simultaneously in the same hdf5 database. 856 857 Examples 858 -------- 859 860 read an hdf5 file 861 dictionary=hdf5_handler.read_hdf5file_as_dict(hdf5["model1"]) 862 """ 863 864 hdf5 = open_hdf5(path_to_hdf5, read_only=True, wait_time=wait_time) 865 866 if hdf5 is None: 867 return None 868 869 dictionary = read_hdf5_as_dict( 870 hdf5[location], read_attrs=read_attrs, read_dataset_attrs=read_dataset_attrs 871 ) 872 873 hdf5.close() 874 875 return dictionary
Open, read and close an hdf5 file
Parameters
path_to_hdf5 : str path to the hdf5 file
location: str place in the hdf5 from which we start reading the file
read_attrs : bool read and import attributes in the dicitonnary.
read_dataset_attrs : bool read and import special attributes linked to any dataset and created by pyhdf5_handler. These attributes only store the original dataype of the data stored in the dataset.
Return
dictionary : dict, a dictionary of all keys and attribute included in the hdf5 file
wait_time: int If the hdf5 is unavailable, the function will try to access serveral time and will wait wait_time seconds maximum. If this time is elapsed, the file won't be opened and the funciton will return None. This parameter is usefull if several program or threads need to read/write simultaneously in the same hdf5 database.
Examples
read an hdf5 file dictionary=hdf5_handler.read_hdf5file_as_dict(hdf5["model1"])
878def read_hdf5_as_dict(hdf5, read_attrs=True, read_dataset_attrs=False): 879 """ 880 Load an hdf5 file 881 882 Parameters 883 ---------- 884 885 hdf5 : h5py.File 886 an instance of hdf5, open with the function open_hdf5() 887 888 read_attrs : bool 889 read and import attributes in the dicitonnary. 890 891 read_dataset_attrs : bool 892 read and import special attributes linked to any dataset and created by pyhdf5_handler. These attributes only store the original dataype of the data stored in the dataset. 893 894 Return 895 -------- 896 897 dictionary : dict, a dictionary of all keys and attribute included in the hdf5 file 898 899 Examples 900 -------- 901 902 read only a part of an hdf5 file 903 >>> hdf5=hdf5_handler.open_hdf5("./multi_model.hdf5") 904 >>> dictionary=hdf5_handler.read_hdf5_as_dict(hdf5["model1"]) 905 >>> dictionary.keys() 906 907 """ 908 909 if not isinstance(hdf5, (h5py.File, h5py.Group, h5py.Dataset, h5py.Datatype)): 910 print("Error: input arg is not an instance of hdf5.File()") 911 return {} 912 913 dictionary = {} 914 915 for key, item in hdf5.items(): 916 917 if str(type(item)).find("group") != -1: 918 919 if key == "ndarray_ds": 920 921 # dictionary.update({key: _read_ndarray_datastructure(hdf5)}) 922 return _read_ndarray_datastructure(hdf5) 923 924 else: 925 926 dictionary.update({key: read_hdf5_as_dict(item)}) 927 928 if str(type(item)).find("dataset") != -1: 929 930 if "_" + key in hdf5.attrs.keys(): 931 expected_type = hdf5.attrs["_" + key] 932 values = hdf5_read_dataset(item, expected_type) 933 934 else: 935 936 values = item[:] 937 938 dictionary.update({key: values}) 939 940 list_attribute = [] 941 if read_attrs or read_dataset_attrs: 942 tmp_list_attribute = list(hdf5.attrs.keys()) 943 hdf5_item_matching_attributes = ["_" + element for element in list(hdf5.keys())] 944 945 if read_attrs: 946 947 list_attribute.extend( 948 list( 949 filter( 950 lambda l: l not in hdf5_item_matching_attributes, tmp_list_attribute 951 ) 952 ) 953 ) 954 955 if read_dataset_attrs: 956 957 list_attribute.extend( 958 list(filter(lambda l: l in hdf5_item_matching_attributes, tmp_list_attribute)) 959 ) 960 961 for key in list_attribute: 962 dictionary.update({key: hdf5.attrs[key]}) 963 964 return dictionary
Load an hdf5 file
Parameters
hdf5 : h5py.File an instance of hdf5, open with the function open_hdf5()
read_attrs : bool read and import attributes in the dicitonnary.
read_dataset_attrs : bool read and import special attributes linked to any dataset and created by pyhdf5_handler. These attributes only store the original dataype of the data stored in the dataset.
Return
dictionary : dict, a dictionary of all keys and attribute included in the hdf5 file
Examples
read only a part of an hdf5 file
>>> hdf5=hdf5_handler.open_hdf5("./multi_model.hdf5")
>>> dictionary=hdf5_handler.read_hdf5_as_dict(hdf5["model1"])
>>> dictionary.keys()
967def hdf5_read_dataset(item, expected_type=None): 968 """ 969 Read a dataset stored in an hdf5 database 970 971 Parameters 972 ---------- 973 974 item : h5py.File 975 an hdf5 dataset/item 976 977 expected_type: str 978 the expected dtype as string str(type()) 979 980 Return 981 -------- 982 983 value : the value read from the hdf5, any type matching the expected type 984 985 986 """ 987 988 if expected_type == str(type("str")): 989 990 values = item[0].decode() 991 992 elif expected_type == str(type(1.0)): 993 994 values = item[0] 995 996 elif expected_type == "_None_": 997 998 values = None 999 1000 elif expected_type in (str(pd.Timestamp), str(np.datetime64), str(datetime.datetime)): 1001 1002 if expected_type == str(pd.Timestamp): 1003 values = pd.Timestamp(item[0].decode()) 1004 1005 elif expected_type == str(np.datetime64): 1006 values = np.datetime64(item[0].decode()) 1007 1008 elif expected_type == str(datetime.datetime): 1009 values = datetime.datetime.fromisoformat(item[0].decode()) 1010 1011 else: 1012 values = item[0].decode() 1013 1014 else: 1015 1016 if item[:].dtype.char == "S": 1017 1018 values = item[:].astype("U") 1019 1020 elif item[:].dtype.char == "O": 1021 1022 # decode list if required 1023 decoded_item = list() 1024 for it in item[:]: 1025 1026 decoded_item.append(it.decode()) 1027 1028 values = decoded_item 1029 1030 else: 1031 values = item[:] 1032 1033 return values
Read a dataset stored in an hdf5 database
Parameters
item : h5py.File an hdf5 dataset/item
expected_type: str the expected dtype as string str(type())
Return
value : the value read from the hdf5, any type matching the expected type
1036def get_hdf5file_attribute( 1037 path_to_hdf5=str(), location="./", attribute=None, wait_time=0 1038): 1039 """ 1040 Get the value of an attribute in the hdf5file 1041 1042 Parameters 1043 ---------- 1044 1045 path_to_hdf5 : str 1046 the path to the hdf5file 1047 1048 location : str 1049 path inside the hdf5 where the attribute is stored 1050 1051 attribute: str 1052 attribute name 1053 1054 wait_time: int 1055 If the hdf5 is unavailable, the function will try to access serveral time and will wait wait_time seconds maximum. If this time is elapsed, the file won't be opened and the funciton will return None. This parameter is usefull if several program or threads need to read/write simultaneously in the same hdf5 database. 1056 1057 Return 1058 -------- 1059 1060 return_attribute : the value of the attribute 1061 1062 Examples 1063 -------- 1064 1065 get an attribute 1066 >>> attribute=hdf5_handler.get_hdf5_attribute("./multi_model.hdf5",attribute=my_attribute_name) 1067 1068 """ 1069 1070 hdf5_base = open_hdf5(path_to_hdf5, read_only=True, wait_time=wait_time) 1071 1072 if hdf5_base is None: 1073 return None 1074 1075 hdf5 = hdf5_base[location] 1076 1077 return_attribute = hdf5.attrs[attribute] 1078 1079 hdf5_base.close() 1080 1081 return return_attribute
Get the value of an attribute in the hdf5file
Parameters
path_to_hdf5 : str the path to the hdf5file
location : str path inside the hdf5 where the attribute is stored
attribute: str attribute name
wait_time: int If the hdf5 is unavailable, the function will try to access serveral time and will wait wait_time seconds maximum. If this time is elapsed, the file won't be opened and the funciton will return None. This parameter is usefull if several program or threads need to read/write simultaneously in the same hdf5 database.
Return
return_attribute : the value of the attribute
Examples
get an attribute
>>> attribute=hdf5_handler.get_hdf5_attribute("./multi_model.hdf5",attribute=my_attribute_name)
1084def get_hdf5file_dataset(path_to_hdf5=str(), location="./", dataset=None, wait_time=0): 1085 """ 1086 Get the value of an attribute in the hdf5file 1087 1088 Parameters 1089 ---------- 1090 1091 path_to_hdf5 : str 1092 the path to the hdf5file 1093 1094 location : str 1095 path inside the hdf5 where the attribute is stored 1096 1097 dataset: str 1098 dataset name 1099 1100 wait_time: int 1101 If the hdf5 is unavailable, the function will try to access serveral time and will wait wait_time seconds maximum. If this time is elapsed, the file won't be opened and the funciton will return None. This parameter is usefull if several program or threads need to read/write simultaneously in the same hdf5 database. 1102 1103 Return 1104 -------- 1105 1106 return_dataset : the value of the attribute 1107 1108 Examples 1109 -------- 1110 1111 get a dataset 1112 >>> dataset=hdf5_handler.get_hdf5_dataset("./multi_model.hdf5",dataset=my_dataset_name) 1113 1114 """ 1115 1116 hdf5_base = open_hdf5(path_to_hdf5, read_only=True, wait_time=wait_time) 1117 1118 if hdf5_base is None: 1119 return None 1120 1121 hdf5 = hdf5_base[location] 1122 1123 if "_" + dataset in hdf5.attrs.keys(): 1124 expected_type = hdf5.attrs["_" + dataset] 1125 return_dataset = hdf5_read_dataset(hdf5[dataset], expected_type) 1126 1127 else: 1128 return_dataset = hdf5[dataset][:] 1129 1130 hdf5_base.close() 1131 1132 return return_dataset
Get the value of an attribute in the hdf5file
Parameters
path_to_hdf5 : str the path to the hdf5file
location : str path inside the hdf5 where the attribute is stored
dataset: str dataset name
wait_time: int If the hdf5 is unavailable, the function will try to access serveral time and will wait wait_time seconds maximum. If this time is elapsed, the file won't be opened and the funciton will return None. This parameter is usefull if several program or threads need to read/write simultaneously in the same hdf5 database.
Return
return_dataset : the value of the attribute
Examples
get a dataset
>>> dataset=hdf5_handler.get_hdf5_dataset("./multi_model.hdf5",dataset=my_dataset_name)
1135def get_hdf5file_item( 1136 path_to_hdf5=str(), location="./", item=None, wait_time=0, search_attrs=False 1137): 1138 """ 1139 1140 Get a custom item in an hdf5file 1141 1142 Parameters 1143 ---------- 1144 1145 path_to_hdf5 : str 1146 the path to the hdf5file 1147 1148 location : str 1149 path inside the hdf5 where the attribute is stored. If item is None, item is set to basename(location) 1150 1151 item: str 1152 item name 1153 1154 wait_time: int 1155 If the hdf5 is unavailable, the function will try to access serveral time and will wait wait_time seconds maximum. If this time is elapsed, the file won't be opened and the funciton will return None. This parameter is usefull if several program or threads need to read/write simultaneously in the same hdf5 database. 1156 1157 search_attrs: bool 1158 Default is False. If True, the function will also search in the item in the attribute first. 1159 1160 Return 1161 -------- 1162 1163 return : custom value. can be an hdf5 object (group), an numpy array, a string, a float, an int ... 1164 1165 Examples 1166 -------- 1167 1168 get the dataset 'dataset' 1169 >>> dataset=hdf5_handler.get_hdf5_item("./multi_model.hdf5",location="path/in/hdf5/dataset") 1170 1171 """ 1172 1173 hdf5 = open_hdf5(path_to_hdf5, read_only=True, wait_time=wait_time) 1174 1175 if hdf5 is None: 1176 return None 1177 1178 hdf5_item = get_hdf5_item( 1179 hdf5_instance=hdf5, location=location, item=item, search_attrs=search_attrs 1180 ) 1181 1182 hdf5.close() 1183 1184 return hdf5_item
Get a custom item in an hdf5file
Parameters
path_to_hdf5 : str the path to the hdf5file
location : str path inside the hdf5 where the attribute is stored. If item is None, item is set to basename(location)
item: str item name
wait_time: int If the hdf5 is unavailable, the function will try to access serveral time and will wait wait_time seconds maximum. If this time is elapsed, the file won't be opened and the funciton will return None. This parameter is usefull if several program or threads need to read/write simultaneously in the same hdf5 database.
search_attrs: bool Default is False. If True, the function will also search in the item in the attribute first.
Return
return : custom value. can be an hdf5 object (group), an numpy array, a string, a float, an int ...
Examples
get the dataset 'dataset'
>>> dataset=hdf5_handler.get_hdf5_item("./multi_model.hdf5",location="path/in/hdf5/dataset")
1187def get_hdf5_item(hdf5_instance=None, location="./", item=None, search_attrs=False): 1188 """ 1189 1190 Get a custom item in an hdf5file 1191 1192 Parameters 1193 ---------- 1194 1195 hdf5_instance : h5py.File 1196 an instance of an hdf5 1197 1198 location : str 1199 path inside the hdf5 where the attribute is stored. If item is None, item is set to basename(location) 1200 1201 item: str 1202 item name 1203 1204 search_attrs: bool 1205 Default is False. If True, the function will search in the item in the attribute first. 1206 1207 Return 1208 ------ 1209 1210 return : custom value. can be an hdf5 object (group), an numpy array, a string, a float, an int ... 1211 1212 Examples 1213 -------- 1214 1215 get the dataset 'dataset' 1216 >>> dataset=hdf5_handler.get_hdf5_item("./multi_model.hdf5",location="path/in/hdf5/dataset") 1217 1218 """ 1219 1220 if item is None and isinstance(location, str): 1221 head, tail = os.path.split(location) 1222 if len(tail) > 0: 1223 item = tail 1224 location = head 1225 1226 if not isinstance(item, str): 1227 print(f"Bad search item:{item}") 1228 return None 1229 1230 return None 1231 1232 # print(f"Getting item '{item}' at location '{location}'") 1233 hdf5 = hdf5_instance[location] 1234 1235 # first search in the attribute 1236 if search_attrs: 1237 list_attribute = hdf5.attrs.keys() 1238 if item in list_attribute: 1239 return hdf5.attrs[item] 1240 1241 # then search in groups and dataset 1242 list_keys = hdf5.keys() 1243 if item in list_keys: 1244 1245 hdf5_item = hdf5[item] 1246 1247 # print("Got Item ", hdf5_item) 1248 1249 if str(type(hdf5_item)).find("group") != -1: 1250 1251 if item == "ndarray_ds": 1252 1253 return _read_ndarray_datastructure(hdf5) 1254 1255 else: 1256 1257 returned_dict = read_hdf5_as_dict(hdf5_item) 1258 1259 return returned_dict 1260 1261 elif str(type(hdf5_item)).find("dataset") != -1: 1262 1263 if "_" + item in hdf5.attrs.keys(): 1264 expected_type = hdf5.attrs["_" + item] 1265 values = hdf5_read_dataset(hdf5_item, expected_type) 1266 else: 1267 values = hdf5_item[:] 1268 1269 return values 1270 1271 else: 1272 1273 return hdf5_item 1274 1275 else: 1276 1277 return None
Get a custom item in an hdf5file
Parameters
hdf5_instance : h5py.File an instance of an hdf5
location : str path inside the hdf5 where the attribute is stored. If item is None, item is set to basename(location)
item: str item name
search_attrs: bool Default is False. If True, the function will search in the item in the attribute first.
Return
return : custom value. can be an hdf5 object (group), an numpy array, a string, a float, an int ...
Examples
get the dataset 'dataset'
>>> dataset=hdf5_handler.get_hdf5_item("./multi_model.hdf5",location="path/in/hdf5/dataset")
1280def search_in_hdf5file( 1281 path_to_hdf5, key=None, location="./", wait_time=0, search_attrs=False 1282): 1283 """ 1284 1285 Search key in an hdf5 and return a list of [locations, datatype, key name, values]. Value and key are returned only if the key is an attribute or a dataset (None otherwise) 1286 1287 Parameters 1288 ---------- 1289 1290 path_to_hdf5 : str 1291 the path to the hdf5file 1292 1293 key: str 1294 key to search in the hdf5file 1295 1296 location : str 1297 path inside the hdf5 where to start the research 1298 1299 wait_time: int 1300 If the hdf5 is unavailable, the function will try to access serveral time and will wait wait_time seconds maximum. If this time is elapsed, the file won't be opened and the funciton will return None. This parameter is usefull if several program or threads need to read/write simultaneously in the same hdf5 database. 1301 1302 search_attrs : Bool 1303 Default false, search in the attributes 1304 1305 Return 1306 ------ 1307 1308 return_dataset : the value of the attribute 1309 1310 Examples 1311 -------- 1312 1313 search in a hdf5file 1314 >>> matchkey=hdf5_handler.search_in_hdf5file(hdf5filename, key='Nom_du_BV',location="./") 1315 1316 """ 1317 if key is None: 1318 print("Nothing to search, use key=") 1319 return [] 1320 1321 hdf5 = open_hdf5(path_to_hdf5, read_only=True, wait_time=wait_time) 1322 1323 if hdf5 is None: 1324 return None 1325 1326 results = search_in_hdf5(hdf5, key, location=location, search_attrs=search_attrs) 1327 1328 hdf5.close() 1329 1330 return results
Search key in an hdf5 and return a list of [locations, datatype, key name, values]. Value and key are returned only if the key is an attribute or a dataset (None otherwise)
Parameters
path_to_hdf5 : str the path to the hdf5file
key: str key to search in the hdf5file
location : str path inside the hdf5 where to start the research
wait_time: int If the hdf5 is unavailable, the function will try to access serveral time and will wait wait_time seconds maximum. If this time is elapsed, the file won't be opened and the funciton will return None. This parameter is usefull if several program or threads need to read/write simultaneously in the same hdf5 database.
search_attrs : Bool Default false, search in the attributes
Return
return_dataset : the value of the attribute
Examples
search in a hdf5file
>>> matchkey=hdf5_handler.search_in_hdf5file(hdf5filename, key='Nom_du_BV',location="./")
1333def search_in_hdf5(hdf5_base, key=None, location="./", search_attrs=False): 1334 """ 1335 1336 Search key in an hdf5 and return a list of [locations, datatype, key name, values]. Value and key are returned only if the key is an attribute or a dataset (None otherwise) 1337 1338 Parameters 1339 ---------- 1340 1341 hdf5_base : h5py.File 1342 opened instance of the hdf5 1343 1344 key: str 1345 key to search in the hdf5file 1346 1347 location : str 1348 path inside the hdf5 where to start the research 1349 1350 search_attrs : Bool 1351 Default false, search in the attributes 1352 1353 Return 1354 ------ 1355 1356 return_dataset : the value of the attribute 1357 1358 Examples 1359 -------- 1360 1361 search in a hdf5 1362 >>> hdf5=hdf5_handler.open_hdf5(hdf5_file) 1363 >>> matchkey=hdf5_handler.search_in_hdf5(hdf5, key='Nom_du_BV',location="./") 1364 >>> hdf5.close() 1365 1366 """ 1367 if key is None: 1368 print("Nothing to search, use key=") 1369 return [] 1370 1371 result = [] 1372 1373 hdf5 = hdf5_base[location] 1374 1375 if search_attrs: 1376 list_attribute = hdf5.attrs.keys() 1377 1378 if key in list_attribute: 1379 result.append( 1380 { 1381 "path": location, 1382 "key": key, 1383 "datatype": "attribute", 1384 "value": hdf5.attrs[key], 1385 } 1386 ) 1387 1388 for hdf5_key, item in hdf5.items(): 1389 1390 if str(type(item)).find("group") != -1: 1391 1392 sub_location = os.path.join(location, hdf5_key) 1393 1394 # print(hdf5_key,sub_location,list(hdf5.keys())) 1395 1396 if hdf5_key == key: 1397 1398 if "ndarray_ds" in item.keys(): 1399 1400 result.append( 1401 { 1402 "path": sub_location, 1403 "key": None, 1404 "datatype": "ndarray", 1405 "value": _read_ndarray_datastructure(item), 1406 } 1407 ) 1408 1409 else: 1410 1411 result.append( 1412 { 1413 "path": sub_location, 1414 "key": None, 1415 "datatype": "group", 1416 "value": None, 1417 } 1418 ) 1419 1420 res = search_in_hdf5(hdf5_base, key, sub_location) 1421 1422 if len(res) > 0: 1423 for element in res: 1424 result.append(element) 1425 1426 if str(type(item)).find("dataset") != -1: 1427 1428 if hdf5_key == key: 1429 1430 if item[:].dtype.char == "S": 1431 1432 values = item[:].astype("U") 1433 1434 elif item[:].dtype.char == "O": 1435 1436 # decode list if required 1437 decoded_item = list() 1438 for it in item[:]: 1439 decoded_item.append(it.decode()) 1440 1441 values = decoded_item 1442 1443 else: 1444 1445 values = item[:] 1446 1447 result.append( 1448 {"path": location, "key": key, "datatype": "dataset", "value": values} 1449 ) 1450 1451 return result
Search key in an hdf5 and return a list of [locations, datatype, key name, values]. Value and key are returned only if the key is an attribute or a dataset (None otherwise)
Parameters
hdf5_base : h5py.File opened instance of the hdf5
key: str key to search in the hdf5file
location : str path inside the hdf5 where to start the research
search_attrs : Bool Default false, search in the attributes
Return
return_dataset : the value of the attribute
Examples
search in a hdf5
>>> hdf5=hdf5_handler.open_hdf5(hdf5_file)
>>> matchkey=hdf5_handler.search_in_hdf5(hdf5, key='Nom_du_BV',location="./")
>>> hdf5.close()
1454def hdf5file_view( 1455 path_to_hdf5, 1456 location="./", 1457 max_depth=None, 1458 level_base=">", 1459 level_sep="--", 1460 depth=None, 1461 wait_time=0, 1462 list_attrs=True, 1463 list_dataset_attrs=False, 1464 return_view=False, 1465): 1466 """ 1467 1468 Search key in an hdf5 and return a list of [locations, datatype, key name, values]. Value and key are returned only if the key is an attribute or a dataset (None otherwise) 1469 1470 Parameters 1471 ---------- 1472 1473 1474 path_to_hdf5 : str 1475 Path to an hdf5 database 1476 1477 location : str 1478 path inside the hdf5 where to start the research 1479 1480 max_depth: str 1481 Max deph of the search in the hdf5 1482 1483 level_base: str 1484 string used as separator at the lower level (default '>') 1485 1486 level_sep: str 1487 string used as separator at higher level (default '--') 1488 1489 depth: int 1490 current depth level 1491 1492 list_attrs: bool 1493 default is True, list the attributes 1494 1495 list_dataset_attrs: bool 1496 default is False, list the special attributes defined for each dataset by pyhdf5_handler 1497 1498 return_view: bool 1499 retrun the object view in a dictionnary (do not print at screen) 1500 1501 wait_time: int 1502 If the hdf5 is unavailable, the function will try to access serveral time and will wait wait_time seconds maximum. If this time is elapsed, the file won't be opened and the funciton will return None. This parameter is usefull if several program or threads need to read/write simultaneously in the same hdf5 database. 1503 1504 Return 1505 -------- 1506 1507 dictionnary : optional, the view of the hdf5 1508 1509 Examples 1510 -------- 1511 1512 search in a hdf5file 1513 >>> matchkey=hdf5_handler.search_in_hdf5file(hdf5filename, key='Nom_du_BV',location="./") 1514 1515 """ 1516 1517 hdf5 = open_hdf5(path_to_hdf5, read_only=True, wait_time=wait_time) 1518 1519 if hdf5 is None: 1520 return None 1521 1522 results = hdf5_view( 1523 hdf5, 1524 location=location, 1525 max_depth=max_depth, 1526 level_base=level_base, 1527 level_sep=level_sep, 1528 depth=depth, 1529 list_attrs=list_attrs, 1530 list_dataset_attrs=list_dataset_attrs, 1531 return_view=return_view, 1532 ) 1533 1534 hdf5.close() 1535 1536 return results
Search key in an hdf5 and return a list of [locations, datatype, key name, values]. Value and key are returned only if the key is an attribute or a dataset (None otherwise)
Parameters
path_to_hdf5 : str Path to an hdf5 database
location : str path inside the hdf5 where to start the research
max_depth: str Max deph of the search in the hdf5
level_base: str string used as separator at the lower level (default '>')
level_sep: str string used as separator at higher level (default '--')
depth: int current depth level
list_attrs: bool default is True, list the attributes
list_dataset_attrs: bool default is False, list the special attributes defined for each dataset by pyhdf5_handler
return_view: bool retrun the object view in a dictionnary (do not print at screen)
wait_time: int If the hdf5 is unavailable, the function will try to access serveral time and will wait wait_time seconds maximum. If this time is elapsed, the file won't be opened and the funciton will return None. This parameter is usefull if several program or threads need to read/write simultaneously in the same hdf5 database.
Return
dictionnary : optional, the view of the hdf5
Examples
search in a hdf5file
>>> matchkey=hdf5_handler.search_in_hdf5file(hdf5filename, key='Nom_du_BV',location="./")
1539def hdf5file_ls(path_to_hdf5, location="./"): 1540 """ 1541 List dataset in an hdf5file. 1542 1543 Parameters 1544 ---------- 1545 1546 path_to_hdf5 : str 1547 path to a hdf5file 1548 1549 location: str 1550 path inside the hdf5 where to start the research 1551 1552 Example 1553 ------- 1554 1555 >>> hdf5file_ls(test.hdf5) 1556 1557 """ 1558 1559 hdf5 = open_hdf5(path_to_hdf5, read_only=True) 1560 1561 hdf5_view( 1562 hdf5, 1563 location=location, 1564 max_depth=0, 1565 level_base=">", 1566 level_sep="--", 1567 list_attrs=False, 1568 return_view=False, 1569 )
List dataset in an hdf5file.
Parameters
path_to_hdf5 : str path to a hdf5file
location: str path inside the hdf5 where to start the research
Example
>>> hdf5file_ls(test.hdf5)
1572def hdf5_ls(hdf5): 1573 """ 1574 List dataset in an hdf5 instance. 1575 1576 Parameters 1577 ---------- 1578 1579 hdf5 : h5py.File 1580 hdf5 instance 1581 1582 location: str 1583 path inside the hdf5 where to start the research 1584 1585 Example 1586 ------- 1587 1588 >>> hdf5 = open_hdf5(path_to_hdf5, read_only=True) 1589 >>> hdf5_ls(hdf5) 1590 1591 """ 1592 1593 hdf5_view( 1594 hdf5, 1595 location="./", 1596 max_depth=0, 1597 level_base=">", 1598 level_sep="--", 1599 list_attrs=False, 1600 return_view=False, 1601 )
List dataset in an hdf5 instance.
Parameters
hdf5 : h5py.File hdf5 instance
location: str path inside the hdf5 where to start the research
Example
>>> hdf5 = open_hdf5(path_to_hdf5, read_only=True)
>>> hdf5_ls(hdf5)
1604def hdf5_view( 1605 hdf5_obj, 1606 location="./", 1607 max_depth=None, 1608 level_base=">", 1609 level_sep="--", 1610 depth=None, 1611 list_attrs=True, 1612 list_dataset_attrs=False, 1613 return_view=False, 1614): 1615 """ 1616 List recursively all dataset (and attributes) in an hdf5 object. 1617 1618 Parameters 1619 ---------- 1620 1621 hdf5_obj : h5py.File 1622 opened instance of the hdf5 1623 1624 location : str 1625 path inside the hdf5 where to start the research 1626 1627 max_depth: str 1628 Max deph of the search in the hdf5 1629 1630 level_base: str 1631 string used as separator at the lower level (default '>') 1632 1633 level_sep: str 1634 string used as separator at higher level (default '--') 1635 1636 depth: int 1637 current level depth 1638 1639 list_attrs: bool 1640 default is True, list the attributes 1641 1642 list_dataset_attrs: bool 1643 default is False, list the special attributes defined for each dataset by pyhdf5_handler 1644 1645 return_view: bool 1646 retrun the object view in a dictionnary 1647 1648 Return 1649 -------- 1650 1651 dictionnary : optional, the view of the hdf5 1652 1653 Examples 1654 -------- 1655 1656 search in a hdf5 1657 >>> hdf5=hdf5_handler.open_hdf5(hdf5_file) 1658 >>> matchkey=hdf5_handler.search_in_hdf5(hdf5, key='Nom_du_BV',location="./") 1659 >>> hdf5.close() 1660 1661 """ 1662 1663 result = [] 1664 1665 if max_depth is not None: 1666 1667 if depth is not None: 1668 depth = depth + 1 1669 else: 1670 depth = 0 1671 1672 if depth > max_depth: 1673 return result 1674 1675 hdf5 = hdf5_obj[location] 1676 1677 list_attribute = [] 1678 if list_attrs or list_dataset_attrs: 1679 tmp_list_attribute = list(hdf5.attrs.keys()) 1680 list_keys_matching_attributes = ["_" + element for element in list(hdf5.keys())] 1681 1682 if list_attrs: 1683 1684 list_attribute.extend( 1685 list( 1686 filter( 1687 lambda l: l not in list_keys_matching_attributes, tmp_list_attribute 1688 ) 1689 ) 1690 ) 1691 1692 if list_dataset_attrs: 1693 1694 list_attribute.extend( 1695 list(filter(lambda l: l in list_keys_matching_attributes, tmp_list_attribute)) 1696 ) 1697 1698 for key in list_attribute: 1699 values = hdf5.attrs[key] 1700 sub_location = os.path.join(location, key) 1701 if isinstance( 1702 values, (int, float, np.int64, np.float64, np.int32, np.float32, np.bool) 1703 ): 1704 result.append( 1705 f"{level_base}| {sub_location}, attribute, type={type(hdf5.attrs[key])}, value={values}" 1706 ) 1707 elif isinstance(values, (str)) and len(values) < 20: 1708 result.append( 1709 f"{level_base}| {sub_location}, attribute, type={type(hdf5.attrs[key])}, len={len(values)}, value={values}" 1710 ) 1711 else: 1712 result.append( 1713 f"{level_base}| {sub_location}, attribute, type={type(hdf5.attrs[key])}, len={len(values)}, value={values[0:20]}..." 1714 ) 1715 1716 for hdf5_key, item in hdf5.items(): 1717 1718 if str(type(item)).find("group") != -1: 1719 1720 sub_location = os.path.join(location, hdf5_key) 1721 1722 if "ndarray_ds" in item.keys(): 1723 result.append(f"{level_base}| {sub_location}, ndarray") 1724 else: 1725 result.append(f"{level_base}| {sub_location}, group") 1726 1727 res = hdf5_view( 1728 hdf5_obj, 1729 sub_location, 1730 max_depth=max_depth, 1731 level_base=level_base + level_sep, 1732 depth=depth, 1733 return_view=True, 1734 ) 1735 1736 # if len(res)>0: 1737 for key, item in enumerate(res): 1738 result.append(item) 1739 1740 if str(type(item)).find("dataset") != -1: 1741 1742 if item[:].dtype.char == "S": 1743 values = item[:].astype("U") 1744 else: 1745 values = item[:] 1746 1747 sub_location = os.path.join(location, hdf5_key) 1748 1749 result.append( 1750 f"{level_base}| {sub_location}, dataset, type={type(values)}, shape={values.shape}" 1751 ) 1752 1753 if return_view: 1754 return result 1755 else: 1756 for res in result: 1757 print(res)
List recursively all dataset (and attributes) in an hdf5 object.
Parameters
hdf5_obj : h5py.File opened instance of the hdf5
location : str path inside the hdf5 where to start the research
max_depth: str Max deph of the search in the hdf5
level_base: str string used as separator at the lower level (default '>')
level_sep: str string used as separator at higher level (default '--')
depth: int current level depth
list_attrs: bool default is True, list the attributes
list_dataset_attrs: bool default is False, list the special attributes defined for each dataset by pyhdf5_handler
return_view: bool retrun the object view in a dictionnary
Return
dictionnary : optional, the view of the hdf5
Examples
search in a hdf5
>>> hdf5=hdf5_handler.open_hdf5(hdf5_file)
>>> matchkey=hdf5_handler.search_in_hdf5(hdf5, key='Nom_du_BV',location="./")
>>> hdf5.close()