sdfr 1.0.0__py3-none-win_amd64.whl → 1.2.0__py3-none-win_amd64.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.
sdfr/SDF.py CHANGED
@@ -310,10 +310,8 @@ class BlockList:
310
310
  clib = sdf_lib
311
311
  self._clib = clib
312
312
  clib.sdf_open.restype = ct.POINTER(SdfFile)
313
- #clib.sdf_open.restype = ct.c_void_p
314
313
  clib.sdf_open.argtypes = [ct.c_char_p, ct.c_int, ct.c_int, ct.c_int]
315
314
  clib.sdf_stack_init.argtypes = [ct.c_void_p]
316
- #clib.sdf_read_blocklist.argtypes = [ct.POINTER(SdfFile)]
317
315
  clib.sdf_read_blocklist.argtypes = [ct.c_void_p]
318
316
  clib.sdf_read_blocklist_all.argtypes = [ct.c_void_p]
319
317
  clib.sdf_helper_read_data.argtypes = [ct.c_void_p, ct.POINTER(SdfBlock)]
@@ -336,35 +334,71 @@ class BlockList:
336
334
 
337
335
 
338
336
  block = h.contents.blocklist
337
+ self.Header = get_header(h.contents)
339
338
  meshes = []
340
339
  mesh_vars = []
340
+ self._block_ids = {}
341
+ self._block_names = {}
341
342
  for n in range(h.contents.nblocks):
342
343
  block = block.contents
343
344
  block._handle = h
345
+ block._blocklist = self
344
346
  blocktype = block.blocktype
347
+ newblock = None
345
348
  name = get_member_name(block.name)
346
- if blocktype == SdfBlockType.SDF_BLOCKTYPE_RUN_INFO:
347
- self.Run_info = get_run_info(block)
349
+ if blocktype == SdfBlockType.SDF_BLOCKTYPE_ARRAY:
350
+ newblock = BlockArray(block)
348
351
  elif blocktype == SdfBlockType.SDF_BLOCKTYPE_CONSTANT:
349
- self.__dict__[name] = BlockConstant(block)
350
- elif blocktype == SdfBlockType.SDF_BLOCKTYPE_PLAIN_VARIABLE:
351
- self.__dict__[name] = BlockPlainVariable(block)
352
- mesh_vars.append(self.__dict__[name])
353
- elif blocktype == SdfBlockType.SDF_BLOCKTYPE_POINT_VARIABLE:
354
- self.__dict__[name] = BlockPointVariable(block)
355
- mesh_vars.append(self.__dict__[name])
352
+ newblock = BlockConstant(block)
353
+ elif blocktype == SdfBlockType.SDF_BLOCKTYPE_CONTIGUOUS \
354
+ or blocktype == SdfBlockType.SDF_BLOCKTYPE_STITCHED:
355
+ if block.stagger == 10 or block.stagger == 12:
356
+ newblock = BlockStitchedPath(block)
357
+ else:
358
+ newblock = BlockStitched(block)
359
+ elif blocktype == SdfBlockType.SDF_BLOCKTYPE_CONTIGUOUS_MATERIAL \
360
+ or blocktype == SdfBlockType.SDF_BLOCKTYPE_STITCHED_MATERIAL:
361
+ newblock = BlockStitchedMaterial(block)
362
+ elif blocktype == SdfBlockType.SDF_BLOCKTYPE_CONTIGUOUS_MATVAR \
363
+ or blocktype == SdfBlockType.SDF_BLOCKTYPE_STITCHED_MATVAR:
364
+ newblock = BlockStitchedMatvar(block)
365
+ elif blocktype == SdfBlockType.SDF_BLOCKTYPE_CONTIGUOUS_SPECIES \
366
+ or blocktype == SdfBlockType.SDF_BLOCKTYPE_STITCHED_SPECIES:
367
+ newblock = BlockStitchedSpecies(block)
368
+ elif blocktype == SdfBlockType.SDF_BLOCKTYPE_CONTIGUOUS_TENSOR \
369
+ or blocktype == SdfBlockType.SDF_BLOCKTYPE_STITCHED_TENSOR:
370
+ newblock = BlockStitchedTensor(block)
371
+ elif blocktype == SdfBlockType.SDF_BLOCKTYPE_DATABLOCK:
372
+ newblock = BlockData(block)
373
+ elif blocktype == SdfBlockType.SDF_BLOCKTYPE_LAGRANGIAN_MESH:
374
+ newblock = BlockLagrangianMesh(block)
375
+ meshes.append(newblock)
376
+ elif blocktype == SdfBlockType.SDF_BLOCKTYPE_NAMEVALUE:
377
+ newblock = BlockNameValue(block)
378
+ elif blocktype == SdfBlockType.SDF_BLOCKTYPE_PLAIN_DERIVED \
379
+ or blocktype == SdfBlockType.SDF_BLOCKTYPE_PLAIN_VARIABLE:
380
+ newblock = BlockPlainVariable(block)
381
+ mesh_vars.append(newblock)
356
382
  elif blocktype == SdfBlockType.SDF_BLOCKTYPE_PLAIN_MESH:
357
- self.__dict__[name] = BlockPlainMesh(block)
358
- meshes.append(self.__dict__[name])
383
+ newblock = BlockPlainMesh(block)
384
+ meshes.append(newblock)
385
+ elif blocktype == SdfBlockType.SDF_BLOCKTYPE_POINT_DERIVED \
386
+ or blocktype == SdfBlockType.SDF_BLOCKTYPE_POINT_VARIABLE:
387
+ newblock = BlockPointVariable(block)
388
+ mesh_vars.append(newblock)
359
389
  elif blocktype == SdfBlockType.SDF_BLOCKTYPE_POINT_MESH:
360
- self.__dict__[name] = BlockPointMesh(block)
361
- meshes.append(self.__dict__[name])
362
- elif blocktype == SdfBlockType.SDF_BLOCKTYPE_NAMEVALUE:
363
- self.__dict__[name] = BlockNameValue(block)
364
- elif blocktype == SdfBlockType.SDF_BLOCKTYPE_ARRAY:
365
- self.__dict__[name] = BlockArray(block)
366
- #else:
367
- # print(name,SdfBlockType(blocktype).name)
390
+ newblock = BlockPointMesh(block)
391
+ meshes.append(newblock)
392
+ elif blocktype == SdfBlockType.SDF_BLOCKTYPE_RUN_INFO:
393
+ self.Run_info = get_run_info(block)
394
+ else:
395
+ # Block not supported
396
+ # print(name,SdfBlockType(blocktype).name)
397
+ pass
398
+ if newblock is not None:
399
+ self.__dict__[name] = newblock
400
+ self._block_ids.update({block.id.decode() : newblock})
401
+ self._block_names.update({block.name.decode() : newblock})
368
402
  block = block.next
369
403
 
370
404
  for var in mesh_vars:
@@ -380,6 +414,16 @@ class BlockList:
380
414
  self._clib.sdf_stack_destroy(self._handle)
381
415
  self._clib.sdf_close(self._handle)
382
416
 
417
+ @property
418
+ def name_dict(self):
419
+ """Dictionary of blocks using name field as key"""
420
+ return self._block_names
421
+
422
+ @property
423
+ def id_dict(self):
424
+ """Dictionary of blocks using id field as key"""
425
+ return self._block_ids
426
+
383
427
 
384
428
  class Block:
385
429
  """SDF block type
@@ -395,6 +439,8 @@ class Block:
395
439
  self._dims = tuple(block.dims[:block.ndims])
396
440
  self._contents = block
397
441
  self._owndata = True
442
+ self._blocklist = block._blocklist
443
+ self._data = None
398
444
 
399
445
  def __del__(self):
400
446
  if not self._owndata and self._data is not None:
@@ -413,6 +459,11 @@ class Block:
413
459
  self._owndata = False
414
460
  return np.frombuffer(buf, dtype)
415
461
 
462
+ @property
463
+ def blocklist(self):
464
+ """Blocklist"""
465
+ return self._blocklist
466
+
416
467
  @property
417
468
  def data(self):
418
469
  """Block data contents"""
@@ -446,7 +497,7 @@ class Block:
446
497
 
447
498
 
448
499
  class BlockConstant(Block):
449
- """Constant block class"""
500
+ """Constant block"""
450
501
  def __init__(self, block):
451
502
  super().__init__(block)
452
503
  offset = getattr(SdfBlock, 'const_value').offset
@@ -456,10 +507,7 @@ class BlockConstant(Block):
456
507
 
457
508
 
458
509
  class BlockPlainVariable(Block):
459
- def __init__(self, block):
460
- super().__init__(block)
461
- self._data = None
462
-
510
+ """Plain variable block"""
463
511
  @property
464
512
  def data(self):
465
513
  """Block data contents"""
@@ -500,6 +548,7 @@ class BlockPlainVariable(Block):
500
548
 
501
549
 
502
550
  class BlockPlainMesh(Block):
551
+ """Plain mesh block"""
503
552
  def __init__(self, block):
504
553
  super().__init__(block)
505
554
  self._data = None
@@ -508,7 +557,8 @@ class BlockPlainMesh(Block):
508
557
  self._mult = None
509
558
  if bool(block.dim_mults):
510
559
  self._mult = tuple(block.dim_mults[:block.ndims])
511
- self._extents = tuple(block.extents[:2*block.ndims])
560
+ if bool(block.extents):
561
+ self._extents = tuple(block.extents[:2*block.ndims])
512
562
 
513
563
  @property
514
564
  def data(self):
@@ -550,10 +600,28 @@ class BlockPlainMesh(Block):
550
600
  return self._units
551
601
 
552
602
 
553
- class BlockPointMesh(BlockPlainMesh):
554
- def __init__(self, block):
555
- super().__init__(block)
603
+ class BlockLagrangianMesh(BlockPlainMesh):
604
+ """Lagrangian mesh block"""
605
+ @property
606
+ def data(self):
607
+ """Block data contents"""
608
+ if self._data is None:
609
+ clib = self._handle._clib
610
+ clib.sdf_helper_read_data(self._handle, self._contents)
611
+ blen = np.dtype(self._datatype).itemsize
612
+ for d in self.dims:
613
+ blen *= d
614
+ grids = []
615
+ for i, d in enumerate(self.dims):
616
+ array = self._numpy_from_buffer(self._contents.grids[i], blen)
617
+ array = array.reshape(self.dims, order='F')
618
+ grids.append(array)
619
+ self._data = tuple(grids)
620
+ return self._data
621
+
556
622
 
623
+ class BlockPointMesh(BlockPlainMesh):
624
+ """Point mesh block"""
557
625
  @property
558
626
  def species_id(self):
559
627
  """Species ID"""
@@ -561,9 +629,7 @@ class BlockPointMesh(BlockPlainMesh):
561
629
 
562
630
 
563
631
  class BlockPointVariable(BlockPlainVariable):
564
- def __init__(self, block):
565
- super().__init__(block)
566
-
632
+ """Point variable block"""
567
633
  @property
568
634
  def species_id(self):
569
635
  """Species ID"""
@@ -571,6 +637,7 @@ class BlockPointVariable(BlockPlainVariable):
571
637
 
572
638
 
573
639
  class BlockNameValue(Block):
640
+ """Name/value block"""
574
641
  def __init__(self, block):
575
642
  super().__init__(block)
576
643
  self._dims = (block.ndims,)
@@ -590,10 +657,7 @@ class BlockNameValue(Block):
590
657
 
591
658
 
592
659
  class BlockArray(Block):
593
- def __init__(self, block):
594
- super().__init__(block)
595
- self._data = None
596
-
660
+ """Array block"""
597
661
  @property
598
662
  def data(self):
599
663
  """Block data contents"""
@@ -608,19 +672,112 @@ class BlockArray(Block):
608
672
  return self._data
609
673
 
610
674
 
675
+ class BlockData(Block):
676
+ """Data block"""
677
+ def __init__(self, block):
678
+ super().__init__(block)
679
+ self._checksum = block.checksum.decode()
680
+ self._checksum_type = block.checksum_type.decode()
681
+ self._mimetype = block.mimetype.decode()
682
+
683
+ @property
684
+ def data(self):
685
+ """Block data contents"""
686
+ if self._data is None:
687
+ clib = self._handle._clib
688
+ clib.sdf_helper_read_data(self._handle, self._contents)
689
+ blen = self._contents.data_length
690
+ _data = ct.cast(self._contents.data, ct.POINTER(ct.c_char * blen))
691
+ self._data = _data.contents[:]
692
+ return self._data
693
+
694
+ @property
695
+ def checksum(self):
696
+ """Block data checksum"""
697
+ return self._checksum
698
+
699
+ @property
700
+ def checksum_type(self):
701
+ """Block data checksum type"""
702
+ return self._checksum_type
703
+
704
+ @property
705
+ def mimetype(self):
706
+ """mimetype for Block data contents"""
707
+ return self._mimetype
708
+
709
+
710
+ class BlockStitched(Block):
711
+ """Stitched block"""
712
+ @property
713
+ def data(self):
714
+ """Block data contents"""
715
+ if self._data is None:
716
+ self._data = []
717
+ for i in range(self._contents.ndims):
718
+ vid = self._contents.variable_ids[i]
719
+ if len(vid) > 0:
720
+ vid = vid.decode()
721
+ self._data.append(self._blocklist._block_ids[vid])
722
+ return self._data
723
+
724
+
725
+ class BlockStitchedPath(BlockStitched):
726
+ """Stitched path block"""
727
+ pass
728
+
729
+
730
+ class BlockStitchedMaterial(BlockStitched):
731
+ """Stitched material block"""
732
+ pass
733
+
734
+
735
+ class BlockStitchedMatvar(BlockStitched):
736
+ """Stitched material variable block"""
737
+ pass
738
+
739
+
740
+ class BlockStitchedSpecies(BlockStitched):
741
+ """Stitched species block"""
742
+ pass
743
+
744
+
745
+ class BlockStitchedTensor(BlockStitched):
746
+ """Stitched tensor block"""
747
+ pass
748
+
749
+
750
+ def get_header(h):
751
+ d = {}
752
+ d['filename'] = h.filename.decode()
753
+ d['file_version'] = h.file_version
754
+ d['file_revision'] = h.file_revision
755
+ d['code_name'] = h.code_name.decode()
756
+ d['step'] = h.step
757
+ d['time'] = h.time
758
+ d['jobid1'] = h.jobid1
759
+ d['jobid2'] = h.jobid2
760
+ d['code_io_version'] = h.code_io_version
761
+ d['restart_flag'] = h.restart_flag
762
+ d['other_domains'] = h.other_domains
763
+ d['station_file'] = h.station_file
764
+ return d
765
+
766
+
611
767
  def get_run_info(block):
612
768
  from datetime import datetime
613
- r = ct.cast(block.data, ct.POINTER(RunInfo)).contents
614
- ri = {}
615
- ri['version'] = f"{r.version}.{r.revision}.{r.minor_rev}"
616
- ri['commit_id'] = r.commit_id.decode()
617
- ri['sha1sum'] = r.sha1sum.decode()
618
- ri['compile_machine'] = r.compile_machine.decode()
619
- ri['compile_flags'] = r.compile_flags.decode()
620
- ri['compile_date'] = datetime.utcfromtimestamp(r.compile_date).strftime('%c')
621
- ri['run_date'] = datetime.utcfromtimestamp(r.run_date).strftime('%c')
622
- ri['io_data'] = datetime.utcfromtimestamp(r.io_date).strftime('%c')
623
- return ri
769
+ h = ct.cast(block.data, ct.POINTER(RunInfo)).contents
770
+ d = {}
771
+ d['version'] = f"{h.version}.{h.revision}.{h.minor_rev}"
772
+ d['commit_id'] = h.commit_id.decode()
773
+ d['sha1sum'] = h.sha1sum.decode()
774
+ d['compile_machine'] = h.compile_machine.decode()
775
+ d['compile_flags'] = h.compile_flags.decode()
776
+ d['compile_date'] = datetime.utcfromtimestamp(h.compile_date).strftime('%c')
777
+ d['run_date'] = datetime.utcfromtimestamp(h.run_date).strftime('%c')
778
+ d['io_data'] = datetime.utcfromtimestamp(h.io_date).strftime('%c')
779
+ return d
780
+
624
781
 
625
782
  def get_member_name(name):
626
783
  sname = name.decode()
@@ -628,7 +785,7 @@ def get_member_name(name):
628
785
  or (i >= "0" and i <= "9")) else "_" \
629
786
  for i in sname])
630
787
 
631
- def read(filename, convert=False, derived=True):
788
+ def read(filename, convert=False, mmap=0, dict=False, derived=True):
632
789
  """Reads the SDF data and returns a dictionary of NumPy arrays.
633
790
 
634
791
  Parameters
@@ -637,8 +794,23 @@ def read(filename, convert=False, derived=True):
637
794
  The name of the SDF file to open.
638
795
  convert : bool, optional
639
796
  Convert double precision data to single when reading file.
797
+ dict : bool, optional
798
+ Return file contents as a dictionary rather than member names.
640
799
  derived : bool, optional
641
800
  Include derived variables in the data structure.
642
801
  """
643
802
 
644
- return BlockList(filename, convert, derived)
803
+ import warnings
804
+
805
+ if mmap != 0:
806
+ warnings.warn("mmap flag ignored")
807
+
808
+ blocklist = BlockList(filename, convert, derived)
809
+
810
+ if isinstance(dict, str):
811
+ if dict == "id" or dict == "ids":
812
+ return blocklist._block_ids
813
+ elif isinstance(dict, bool) and dict:
814
+ return blocklist._block_names
815
+
816
+ return blocklist
sdfr/__init__.py CHANGED
@@ -17,8 +17,8 @@
17
17
 
18
18
  _module_name = "sdfr"
19
19
 
20
- from .SDF import read
21
- from .sdf_helper import *
20
+ from .SDF import *
21
+ from . import sdf_helper
22
22
  from ._commit_info import (
23
23
  __commit_date__,
24
24
  __commit_id__,
sdfr/_commit_info.py CHANGED
@@ -1,2 +1,2 @@
1
- __commit_date__ = "Mon Feb 17 16:26:23 2025 +0000"
2
- __commit_id__ = "65c7798d61fed5d13311f7484b897d4ad8df4add"
1
+ __commit_date__ = "Thu Mar 6 21:34:01 2025 +0000"
2
+ __commit_id__ = "658f397aca1fa9cfcef3a31d2ea4ba9291c4aa96"